@clipform/mcp-server 1.8.1 → 1.9.1
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-context.js +9 -0
- package/dist/auth-context.js.map +1 -0
- package/dist/chunk-ESDD3WVD.js +24686 -0
- package/dist/chunk-ESDD3WVD.js.map +1 -0
- package/dist/chunk-YEDU3G7I.js +48 -0
- package/dist/chunk-YEDU3G7I.js.map +1 -0
- package/dist/index.js +108 -11
- package/dist/index.js.map +1 -1
- package/dist/server.js +7 -74
- package/dist/server.js.map +1 -1
- package/package.json +7 -8
- package/dist/__tests__/api-parity.test.d.ts +0 -1
- package/dist/__tests__/api-parity.test.js +0 -157
- package/dist/__tests__/api-parity.test.js.map +0 -1
- package/dist/__tests__/config-sync.test.d.ts +0 -1
- package/dist/__tests__/config-sync.test.js +0 -16
- package/dist/__tests__/config-sync.test.js.map +0 -1
- package/dist/index.d.ts +0 -2
- package/dist/lib/api-client.d.ts +0 -35
- package/dist/lib/api-client.js +0 -126
- package/dist/lib/api-client.js.map +0 -1
- package/dist/lib/auth-context.d.ts +0 -17
- package/dist/lib/auth-context.js +0 -9
- package/dist/lib/auth-context.js.map +0 -1
- package/dist/lib/config.d.ts +0 -23
- package/dist/lib/config.js +0 -6
- package/dist/lib/config.js.map +0 -1
- package/dist/lib/format-form.d.ts +0 -2
- package/dist/lib/format-form.js +0 -32
- package/dist/lib/format-form.js.map +0 -1
- package/dist/lib/render-jobs.d.ts +0 -17
- package/dist/lib/render-jobs.js +0 -44
- package/dist/lib/render-jobs.js.map +0 -1
- package/dist/lib/schemas.d.ts +0 -64
- package/dist/lib/schemas.js +0 -140
- package/dist/lib/schemas.js.map +0 -1
- package/dist/lib/session-context.d.ts +0 -1
- package/dist/lib/session-context.js +0 -38
- package/dist/lib/session-context.js.map +0 -1
- package/dist/prompts.d.ts +0 -2
- package/dist/prompts.js +0 -272
- package/dist/prompts.js.map +0 -1
- package/dist/resources.d.ts +0 -2
- package/dist/resources.js +0 -336
- package/dist/resources.js.map +0 -1
- package/dist/server.d.ts +0 -2
- package/dist/tools/add-node.d.ts +0 -2
- package/dist/tools/add-node.js +0 -48
- package/dist/tools/add-node.js.map +0 -1
- package/dist/tools/attach-node-audio.d.ts +0 -2
- package/dist/tools/attach-node-audio.js +0 -35
- package/dist/tools/attach-node-audio.js.map +0 -1
- package/dist/tools/check-render.d.ts +0 -2
- package/dist/tools/check-render.js +0 -47
- package/dist/tools/check-render.js.map +0 -1
- package/dist/tools/create-form.d.ts +0 -2
- package/dist/tools/create-form.js +0 -199
- package/dist/tools/create-form.js.map +0 -1
- package/dist/tools/delete-form.d.ts +0 -2
- package/dist/tools/delete-form.js +0 -26
- package/dist/tools/delete-form.js.map +0 -1
- package/dist/tools/delete-node-media.d.ts +0 -2
- package/dist/tools/delete-node-media.js +0 -25
- package/dist/tools/delete-node-media.js.map +0 -1
- package/dist/tools/delete-node.d.ts +0 -2
- package/dist/tools/delete-node.js +0 -28
- package/dist/tools/delete-node.js.map +0 -1
- package/dist/tools/generate-slideshow.d.ts +0 -2
- package/dist/tools/generate-slideshow.js +0 -155
- package/dist/tools/generate-slideshow.js.map +0 -1
- package/dist/tools/generate-tts.d.ts +0 -2
- package/dist/tools/generate-tts.js +0 -73
- package/dist/tools/generate-tts.js.map +0 -1
- package/dist/tools/generate-video.d.ts +0 -2
- package/dist/tools/generate-video.js +0 -119
- package/dist/tools/generate-video.js.map +0 -1
- package/dist/tools/get-form.d.ts +0 -2
- package/dist/tools/get-form.js +0 -25
- package/dist/tools/get-form.js.map +0 -1
- package/dist/tools/get-node-media.d.ts +0 -2
- package/dist/tools/get-node-media.js +0 -35
- package/dist/tools/get-node-media.js.map +0 -1
- package/dist/tools/list-assets.d.ts +0 -2
- package/dist/tools/list-assets.js +0 -45
- package/dist/tools/list-assets.js.map +0 -1
- package/dist/tools/list-compositions.d.ts +0 -2
- package/dist/tools/list-compositions.js +0 -34
- package/dist/tools/list-compositions.js.map +0 -1
- package/dist/tools/list-forms.d.ts +0 -2
- package/dist/tools/list-forms.js +0 -86
- package/dist/tools/list-forms.js.map +0 -1
- package/dist/tools/log-generation.d.ts +0 -2
- package/dist/tools/log-generation.js +0 -33
- package/dist/tools/log-generation.js.map +0 -1
- package/dist/tools/render-composition.d.ts +0 -2
- package/dist/tools/render-composition.js +0 -50
- package/dist/tools/render-composition.js.map +0 -1
- package/dist/tools/search-media.d.ts +0 -2
- package/dist/tools/search-media.js +0 -40
- package/dist/tools/search-media.js.map +0 -1
- package/dist/tools/search-music.d.ts +0 -2
- package/dist/tools/search-music.js +0 -40
- package/dist/tools/search-music.js.map +0 -1
- package/dist/tools/search-news.d.ts +0 -2
- package/dist/tools/search-news.js +0 -47
- package/dist/tools/search-news.js.map +0 -1
- package/dist/tools/set-node-logic.d.ts +0 -2
- package/dist/tools/set-node-logic.js +0 -54
- package/dist/tools/set-node-logic.js.map +0 -1
- package/dist/tools/update-form.d.ts +0 -2
- package/dist/tools/update-form.js +0 -155
- package/dist/tools/update-form.js.map +0 -1
- package/dist/tools/update-node.d.ts +0 -2
- package/dist/tools/update-node.js +0 -70
- package/dist/tools/update-node.js.map +0 -1
- package/dist/tools/upload-node-media.d.ts +0 -2
- package/dist/tools/upload-node-media.js +0 -105
- package/dist/tools/upload-node-media.js.map +0 -1
package/dist/tools/add-node.js
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
import { NodeSchema, NODE_TYPES_DESCRIPTION } from "../lib/schemas.js";
|
|
3
|
-
import { callApi, errorResult, textResult } from "../lib/api-client.js";
|
|
4
|
-
import { fetchAndFormatFormState } from "../lib/format-form.js";
|
|
5
|
-
export function registerAddNodeTool(server) {
|
|
6
|
-
server.registerTool("clipform_add_node", {
|
|
7
|
-
title: "Add Node",
|
|
8
|
-
description: `Add a new node to an existing form. By default, the node is inserted before the end screen (appended to the end of the flow). Use after_node_id to insert at a specific position.
|
|
9
|
-
|
|
10
|
-
${NODE_TYPES_DESCRIPTION}
|
|
11
|
-
|
|
12
|
-
All type definitions and config schemas are derived from @vid-master/config (answer-types).`,
|
|
13
|
-
inputSchema: {
|
|
14
|
-
form_id: z.string().uuid().describe("The form UUID (returned by clipform_create_form, not the short share_id from the URL)"),
|
|
15
|
-
question: NodeSchema.describe("The node to add"),
|
|
16
|
-
after_node_id: z
|
|
17
|
-
.string()
|
|
18
|
-
.optional()
|
|
19
|
-
.describe("Insert after this node ID. Omit to append before the end screen."),
|
|
20
|
-
},
|
|
21
|
-
annotations: {
|
|
22
|
-
readOnlyHint: false,
|
|
23
|
-
destructiveHint: false,
|
|
24
|
-
idempotentHint: false,
|
|
25
|
-
openWorldHint: true,
|
|
26
|
-
},
|
|
27
|
-
}, async ({ form_id, question, after_node_id }) => {
|
|
28
|
-
const body = { question };
|
|
29
|
-
if (after_node_id)
|
|
30
|
-
body.after_node_id = after_node_id;
|
|
31
|
-
const result = await callApi(`/forms/${form_id}/nodes`, {
|
|
32
|
-
method: "POST",
|
|
33
|
-
body,
|
|
34
|
-
});
|
|
35
|
-
if (!result.ok) {
|
|
36
|
-
return errorResult(result.error);
|
|
37
|
-
}
|
|
38
|
-
const confirmMsg = [
|
|
39
|
-
`Node added successfully!`,
|
|
40
|
-
`Node ID: ${result.data.node_id}`,
|
|
41
|
-
`Type: ${question.type}`,
|
|
42
|
-
`Prompt: ${question.prompt}`,
|
|
43
|
-
].join("\n");
|
|
44
|
-
const formState = await fetchAndFormatFormState(form_id);
|
|
45
|
-
return textResult(formState ? `${confirmMsg}\n\n---\n\n${formState}` : confirmMsg);
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
//# sourceMappingURL=add-node.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"add-node.js","sourceRoot":"","sources":["../../src/tools/add-node.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAEhE,MAAM,UAAU,mBAAmB,CAAC,MAAiB;IACnD,MAAM,CAAC,YAAY,CACjB,mBAAmB,EACnB;QACE,KAAK,EAAE,UAAU;QACjB,WAAW,EAAE;;EAEjB,sBAAsB;;4FAEoE;QACtF,WAAW,EAAE;YACX,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,uFAAuF,CAAC;YAC5H,QAAQ,EAAE,UAAU,CAAC,QAAQ,CAAC,iBAAiB,CAAC;YAChD,aAAa,EAAE,CAAC;iBACb,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CACP,kEAAkE,CACnE;SACJ;QACD,WAAW,EAAE;YACX,YAAY,EAAE,KAAK;YACnB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,KAAK;YACrB,aAAa,EAAE,IAAI;SACpB;KACF,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,EAAE,EAAE;QAC7C,MAAM,IAAI,GAA4B,EAAE,QAAQ,EAAE,CAAC;QACnD,IAAI,aAAa;YAAE,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QAEtD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,UAAU,OAAO,QAAQ,EAAE;YACtD,MAAM,EAAE,MAAM;YACd,IAAI;SACL,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;QAED,MAAM,UAAU,GAAG;YACjB,0BAA0B;YAC1B,YAAY,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE;YACjC,SAAS,QAAQ,CAAC,IAAI,EAAE;YACxB,WAAW,QAAQ,CAAC,MAAM,EAAE;SAC7B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEb,MAAM,SAAS,GAAG,MAAM,uBAAuB,CAAC,OAAO,CAAC,CAAC;QACzD,OAAO,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,UAAU,cAAc,SAAS,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IACrF,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
import { callApi, errorResult, textResult } from "../lib/api-client.js";
|
|
3
|
-
export function registerAttachNodeAudioTool(server) {
|
|
4
|
-
server.registerTool("clipform_attach_audio", {
|
|
5
|
-
title: "Attach Audio to Node",
|
|
6
|
-
description: `Attach a sound effect or audio file to a node with existing media (stills only). The audio auto-plays once when a respondent reaches this node. Provide a public URL to the audio file (WAV, MP3, or OGG). The node must already have media uploaded (use clipform_upload_node_media first).`,
|
|
7
|
-
inputSchema: {
|
|
8
|
-
form_id: z.string().uuid().describe("The form UUID (returned by clipform_create_form, not the short share_id from the URL)"),
|
|
9
|
-
node_id: z
|
|
10
|
-
.string()
|
|
11
|
-
.describe("The node ID (must already have media attached)"),
|
|
12
|
-
url: z
|
|
13
|
-
.string()
|
|
14
|
-
.url()
|
|
15
|
-
.describe("Public URL to the audio file (WAV, MP3, or OGG)"),
|
|
16
|
-
},
|
|
17
|
-
annotations: {
|
|
18
|
-
readOnlyHint: false,
|
|
19
|
-
destructiveHint: false,
|
|
20
|
-
idempotentHint: true,
|
|
21
|
-
openWorldHint: true,
|
|
22
|
-
},
|
|
23
|
-
}, async ({ form_id, node_id, url }) => {
|
|
24
|
-
const result = await callApi(`/forms/${form_id}/nodes/${node_id}/audio`, {
|
|
25
|
-
method: "PUT",
|
|
26
|
-
body: { url },
|
|
27
|
-
});
|
|
28
|
-
if (!result.ok) {
|
|
29
|
-
return errorResult(result.error);
|
|
30
|
-
}
|
|
31
|
-
return textResult(`Audio attached to node ${node_id}.\n` +
|
|
32
|
-
`Audio path: ${result.data.audio_storage_path}`);
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
//# sourceMappingURL=attach-node-audio.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"attach-node-audio.js","sourceRoot":"","sources":["../../src/tools/attach-node-audio.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAExE,MAAM,UAAU,2BAA2B,CAAC,MAAiB;IAC3D,MAAM,CAAC,YAAY,CACjB,uBAAuB,EACvB;QACE,KAAK,EAAE,sBAAsB;QAC7B,WAAW,EAAE,8RAA8R;QAC3S,WAAW,EAAE;YACX,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,uFAAuF,CAAC;YAC5H,OAAO,EAAE,CAAC;iBACP,MAAM,EAAE;iBACR,QAAQ,CAAC,gDAAgD,CAAC;YAC7D,GAAG,EAAE,CAAC;iBACH,MAAM,EAAE;iBACR,GAAG,EAAE;iBACL,QAAQ,CAAC,iDAAiD,CAAC;SAC/D;QACD,WAAW,EAAE;YACX,YAAY,EAAE,KAAK;YACnB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,IAAI;SACpB;KACF,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE;QAClC,MAAM,MAAM,GAAG,MAAM,OAAO,CAC1B,UAAU,OAAO,UAAU,OAAO,QAAQ,EAC1C;YACE,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,EAAE,GAAG,EAAE;SACd,CACF,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;QAED,OAAO,UAAU,CACf,0BAA0B,OAAO,KAAK;YACpC,eAAe,MAAM,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAClD,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
import { errorResult, textResult } from "../lib/api-client.js";
|
|
3
|
-
import { getJob, pruneJobs, RENDER_TIMING } from "../lib/render-jobs.js";
|
|
4
|
-
export function registerCheckRenderTool(server) {
|
|
5
|
-
server.registerTool("clipform_check_render", {
|
|
6
|
-
title: "Check Render Status",
|
|
7
|
-
description: `Check the status of a render job started by clipform_generate_video, clipform_generate_slideshow, or clipform_render_composition.
|
|
8
|
-
|
|
9
|
-
Returns the current status and, when complete, the output URL. If still rendering, wait ${RENDER_TIMING.pollDelay} before checking again.`,
|
|
10
|
-
inputSchema: {
|
|
11
|
-
job_id: z.string().uuid().describe("The job ID returned by the render tool"),
|
|
12
|
-
},
|
|
13
|
-
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
14
|
-
}, async ({ job_id }) => {
|
|
15
|
-
pruneJobs();
|
|
16
|
-
const job = getJob(job_id);
|
|
17
|
-
if (!job) {
|
|
18
|
-
return errorResult(`No render job found with ID ${job_id}. Jobs expire after 30 minutes.`);
|
|
19
|
-
}
|
|
20
|
-
if (job.status === "rendering") {
|
|
21
|
-
const elapsed = Math.round((Date.now() - job.createdAt) / 1000);
|
|
22
|
-
return textResult([
|
|
23
|
-
`Status: rendering (${elapsed}s elapsed)`,
|
|
24
|
-
`Tool: ${job.tool}`,
|
|
25
|
-
``,
|
|
26
|
-
`Still in progress. Check again in ${RENDER_TIMING.pollDelay}.`,
|
|
27
|
-
].join("\n"));
|
|
28
|
-
}
|
|
29
|
-
if (job.status === "failed") {
|
|
30
|
-
return errorResult(`Render failed: ${job.error}`);
|
|
31
|
-
}
|
|
32
|
-
const data = job.result;
|
|
33
|
-
return textResult([
|
|
34
|
-
`Status: complete`,
|
|
35
|
-
`Tool: ${job.tool}`,
|
|
36
|
-
``,
|
|
37
|
-
...(data.public_url ? [`Public URL: ${data.public_url}`] : []),
|
|
38
|
-
...(data.storage_path ? [`Storage path: ${data.storage_path}`] : []),
|
|
39
|
-
...(data.duration_seconds ? [`Duration: ${data.duration_seconds}s`] : []),
|
|
40
|
-
...(data.outputPath ? [`Output: ${data.outputPath}`] : []),
|
|
41
|
-
...(data.format ? [`Format: ${data.format}`] : []),
|
|
42
|
-
``,
|
|
43
|
-
`Use clipform_upload_node_media with the public URL to attach this video to a node.`,
|
|
44
|
-
].join("\n"));
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
//# sourceMappingURL=check-render.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"check-render.js","sourceRoot":"","sources":["../../src/tools/check-render.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEzE,MAAM,UAAU,uBAAuB,CAAC,MAAiB;IACvD,MAAM,CAAC,YAAY,CACjB,uBAAuB,EACvB;QACE,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EAAE;;0FAEuE,aAAa,CAAC,SAAS,yBAAyB;QACpI,WAAW,EAAE;YACX,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,wCAAwC,CAAC;SAC7E;QACD,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE;KACxG,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QACnB,SAAS,EAAE,CAAC;QACZ,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;QAE3B,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,WAAW,CAAC,+BAA+B,MAAM,iCAAiC,CAAC,CAAC;QAC7F,CAAC;QAED,IAAI,GAAG,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YAC/B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC;YAChE,OAAO,UAAU,CACf;gBACE,sBAAsB,OAAO,YAAY;gBACzC,SAAS,GAAG,CAAC,IAAI,EAAE;gBACnB,EAAE;gBACF,qCAAqC,aAAa,CAAC,SAAS,GAAG;aAChE,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;QACJ,CAAC;QAED,IAAI,GAAG,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC5B,OAAO,WAAW,CAAC,kBAAkB,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;QACpD,CAAC;QAED,MAAM,IAAI,GAAG,GAAG,CAAC,MAAa,CAAC;QAC/B,OAAO,UAAU,CACf;YACE,kBAAkB;YAClB,SAAS,GAAG,CAAC,IAAI,EAAE;YACnB,EAAE;YACF,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,eAAe,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9D,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,iBAAiB,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACpE,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACzE,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1D,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAClD,EAAE;YACF,oFAAoF;SACrF,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
import { BUSINESS } from "@vid-master/config";
|
|
3
|
-
import { NodeSchema, NODE_TYPES_DESCRIPTION, } from "../lib/schemas.js";
|
|
4
|
-
import { callApi, errorResult, textResult } from "../lib/api-client.js";
|
|
5
|
-
export function registerCreateFormTool(server) {
|
|
6
|
-
server.registerTool("clipform_create_form", {
|
|
7
|
-
title: "Create Clipform",
|
|
8
|
-
description: `Create a new Clipform (interactive video-style form). Returns a viewer URL and form ID. When connected via an authenticated MCP client (e.g. claude.ai), the form lands directly in the user's workspace. Anonymous sessions get a claim URL to transfer ownership later.
|
|
9
|
-
|
|
10
|
-
${NODE_TYPES_DESCRIPTION}
|
|
11
|
-
|
|
12
|
-
All type definitions and config schemas are derived from @vid-master/config (answer-types). Refer to the config descriptions above for the correct keys and shapes.
|
|
13
|
-
|
|
14
|
-
Example: A form that asks a question, collects contact info, then finishes:
|
|
15
|
-
{
|
|
16
|
-
title: "Quick Survey",
|
|
17
|
-
questions: [
|
|
18
|
-
{ type: "open", prompt: "What's your biggest challenge?" },
|
|
19
|
-
{ type: "contact", prompt: "Leave your details", config: { fields: [{ id: "first_name", required: true }, { id: "email", required: true }] } },
|
|
20
|
-
{ type: "end_screen", prompt: "Thanks for your response!" }
|
|
21
|
-
]
|
|
22
|
-
}`,
|
|
23
|
-
inputSchema: {
|
|
24
|
-
title: z.string().describe("Form title"),
|
|
25
|
-
questions: z
|
|
26
|
-
.array(NodeSchema)
|
|
27
|
-
.min(1)
|
|
28
|
-
.describe("Ordered list of questions/steps"),
|
|
29
|
-
show_step_counter: z
|
|
30
|
-
.boolean()
|
|
31
|
-
.optional()
|
|
32
|
-
.describe("Show step counter (e.g. '1/5'). Set true for quizzes."),
|
|
33
|
-
disable_back_navigation: z
|
|
34
|
-
.boolean()
|
|
35
|
-
.optional()
|
|
36
|
-
.describe("Prevent going back. Set true for quizzes."),
|
|
37
|
-
primary_color: z
|
|
38
|
-
.string()
|
|
39
|
-
.optional()
|
|
40
|
-
.describe("Primary/brand color (hex or CSS color). Used for buttons and accents."),
|
|
41
|
-
background_color: z
|
|
42
|
-
.string()
|
|
43
|
-
.optional()
|
|
44
|
-
.describe("Background color (hex, rgba, or CSS color)."),
|
|
45
|
-
font_family: z
|
|
46
|
-
.string()
|
|
47
|
-
.optional()
|
|
48
|
-
.describe("Font family name (e.g. 'Inter', 'Roboto', 'Playfair Display')."),
|
|
49
|
-
embed_autoplay: z
|
|
50
|
-
.boolean()
|
|
51
|
-
.optional()
|
|
52
|
-
.describe("Auto-play video when embedded (default: false). When off, embeds show a thumbnail + play button."),
|
|
53
|
-
tags: z
|
|
54
|
-
.array(z.string())
|
|
55
|
-
.optional()
|
|
56
|
-
.describe("Tags for indexing (e.g. ['quiz', 'trivia', 'arsenal']). Include format, genre, and topics."),
|
|
57
|
-
},
|
|
58
|
-
annotations: {
|
|
59
|
-
readOnlyHint: false,
|
|
60
|
-
destructiveHint: false,
|
|
61
|
-
idempotentHint: false,
|
|
62
|
-
openWorldHint: true,
|
|
63
|
-
},
|
|
64
|
-
}, async ({ title, questions, show_step_counter, disable_back_navigation, primary_color, background_color, font_family, embed_autoplay, tags }) => {
|
|
65
|
-
// 0. Pre-flight: resolve the caller's plan and reject up-front if the
|
|
66
|
-
// requested question count exceeds it. Without this we'd build a
|
|
67
|
-
// scaffold + N-1 questions, then 403 on the Nth, leaving an orphan.
|
|
68
|
-
// /v1/me is the single source for plan info; PLAN_LIMITS lives in
|
|
69
|
-
// @vid-master/config and is read there. The MCP tool is intentionally
|
|
70
|
-
// thin and never duplicates limit numbers.
|
|
71
|
-
let planContext = null;
|
|
72
|
-
const meResult = await callApi("/me", { method: "GET" });
|
|
73
|
-
if (!meResult.ok) {
|
|
74
|
-
return errorResult(`Unable to determine workspace: ${meResult.error}`);
|
|
75
|
-
}
|
|
76
|
-
const me = meResult.data;
|
|
77
|
-
const workspaceId = me.workspace?.id ?? null;
|
|
78
|
-
if (!workspaceId) {
|
|
79
|
-
return errorResult("No workspace available. Connect your Clipform account in claude.ai → Settings → Connectors, or ensure MCP_WORKSPACE_ID is configured for anonymous mode.");
|
|
80
|
-
}
|
|
81
|
-
planContext = {
|
|
82
|
-
auth_mode: me.auth_mode,
|
|
83
|
-
workspace_id: workspaceId,
|
|
84
|
-
workspace_name: me.workspace?.name ?? null,
|
|
85
|
-
plan_name: me.plan?.name ?? "Free",
|
|
86
|
-
node_limit: me.plan?.node_limit ?? null,
|
|
87
|
-
};
|
|
88
|
-
// questions includes any end_screen the user supplied; the scaffold
|
|
89
|
-
// already has one so we count "real" content nodes only.
|
|
90
|
-
const contentCount = questions.filter((q) => q.type !== "end_screen").length;
|
|
91
|
-
if (planContext.node_limit !== null && contentCount > planContext.node_limit) {
|
|
92
|
-
const upgradeUrl = `${BUSINESS.urls.dashboard}/billing`;
|
|
93
|
-
const message = planContext.auth_mode === "oauth"
|
|
94
|
-
? `Your '${planContext.workspace_name}' workspace is on the ${planContext.plan_name} plan, capped at ${planContext.node_limit} questions per form. You asked for ${contentCount}. Either rerun with ${planContext.node_limit} questions or upgrade at ${upgradeUrl}.`
|
|
95
|
-
: `Anonymous sessions are capped at ${planContext.node_limit} questions per form (${planContext.plan_name} plan). You asked for ${contentCount}. Either rerun with ${planContext.node_limit} questions, or connect your Clipform account in claude.ai → Settings → Connectors so forms land in your workspace with your real plan limits.`;
|
|
96
|
-
return errorResult(message);
|
|
97
|
-
}
|
|
98
|
-
// 1. Create bare scaffold
|
|
99
|
-
const createResult = await callApi("/forms", {
|
|
100
|
-
method: "POST",
|
|
101
|
-
body: { title, workspace_id: workspaceId },
|
|
102
|
-
});
|
|
103
|
-
if (!createResult.ok) {
|
|
104
|
-
return errorResult(createResult.error);
|
|
105
|
-
}
|
|
106
|
-
const { data } = createResult;
|
|
107
|
-
const formId = data.form_id;
|
|
108
|
-
const claimUrl = data.claim_url ?? undefined;
|
|
109
|
-
// 2. Apply form settings and theme if provided
|
|
110
|
-
const settingsBody = {};
|
|
111
|
-
if (show_step_counter !== undefined)
|
|
112
|
-
settingsBody.show_step_counter = show_step_counter;
|
|
113
|
-
if (disable_back_navigation !== undefined)
|
|
114
|
-
settingsBody.disable_back_navigation = disable_back_navigation;
|
|
115
|
-
if (primary_color !== undefined)
|
|
116
|
-
settingsBody.primary_color = primary_color;
|
|
117
|
-
if (background_color !== undefined)
|
|
118
|
-
settingsBody.background_color = background_color;
|
|
119
|
-
if (font_family !== undefined)
|
|
120
|
-
settingsBody.font_family = font_family;
|
|
121
|
-
if (embed_autoplay !== undefined)
|
|
122
|
-
settingsBody.embed_autoplay = embed_autoplay;
|
|
123
|
-
if (Object.keys(settingsBody).length > 0) {
|
|
124
|
-
await callApi(`/forms/${formId}`, {
|
|
125
|
-
method: "PATCH",
|
|
126
|
-
body: settingsBody,
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
// 3. Add each question via the add-question endpoint
|
|
130
|
-
for (const q of questions) {
|
|
131
|
-
// If it's an end_screen, update the default one instead of adding another
|
|
132
|
-
if (q.type === "end_screen") {
|
|
133
|
-
// The scaffold already has an end_screen — find it and update its prompt
|
|
134
|
-
const getResult = await callApi(`/forms/${formId}`, {
|
|
135
|
-
method: "GET",
|
|
136
|
-
});
|
|
137
|
-
if (getResult.ok) {
|
|
138
|
-
const questions_list = getResult.data.questions;
|
|
139
|
-
const endScreen = questions_list?.find((qq) => qq.type === "end_screen");
|
|
140
|
-
if (endScreen) {
|
|
141
|
-
await callApi(`/forms/${formId}/nodes/${endScreen.id}`, {
|
|
142
|
-
method: "PATCH",
|
|
143
|
-
body: { prompt: q.prompt, ...(q.config ? { config: q.config } : {}) },
|
|
144
|
-
});
|
|
145
|
-
continue;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
// Fallback: add it normally if we couldn't find the default
|
|
149
|
-
}
|
|
150
|
-
const addResult = await callApi(`/forms/${formId}/nodes`, {
|
|
151
|
-
method: "POST",
|
|
152
|
-
body: { question: q },
|
|
153
|
-
});
|
|
154
|
-
if (!addResult.ok) {
|
|
155
|
-
return errorResult(`Failed to add question "${q.prompt}": ${addResult.error}`);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
// 4. Publish the form
|
|
159
|
-
await callApi(`/forms/${formId}`, {
|
|
160
|
-
method: "PATCH",
|
|
161
|
-
body: { is_published: true },
|
|
162
|
-
});
|
|
163
|
-
// 5. Tag the form (best-effort)
|
|
164
|
-
if (tags && tags.length > 0) {
|
|
165
|
-
await callApi(`/forms/${formId}/tags`, {
|
|
166
|
-
method: "PUT",
|
|
167
|
-
body: { tags },
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
const lines = [
|
|
171
|
-
`Form created successfully!`,
|
|
172
|
-
``,
|
|
173
|
-
`Title: ${title}`,
|
|
174
|
-
`Questions: ${questions.length}`,
|
|
175
|
-
`Form ID: ${formId}`,
|
|
176
|
-
``,
|
|
177
|
-
`FORM URL (share this with respondents): ${data.viewer_url}`,
|
|
178
|
-
];
|
|
179
|
-
if (claimUrl) {
|
|
180
|
-
lines.push(`CLAIM URL (transfer ownership to your account): ${claimUrl}`);
|
|
181
|
-
}
|
|
182
|
-
lines.push(``, `IMPORTANT: Always show the user the exact URLs above — do not rewrite or modify them.`, `Pass form_id on follow-up tools (get_form, add_node, upload_node_media, etc.).`);
|
|
183
|
-
// One-line plan/auth summary so the model can mention it ONCE and not
|
|
184
|
-
// re-prompt on every follow-up call.
|
|
185
|
-
if (planContext) {
|
|
186
|
-
const limitNote = planContext.node_limit === null
|
|
187
|
-
? "unlimited questions"
|
|
188
|
-
: `up to ${planContext.node_limit} questions per form`;
|
|
189
|
-
if (planContext.auth_mode === "oauth") {
|
|
190
|
-
lines.push(``, `Plan: ${planContext.plan_name} (${limitNote}) in workspace '${planContext.workspace_name}'.`);
|
|
191
|
-
}
|
|
192
|
-
else {
|
|
193
|
-
lines.push(``, `Plan: anonymous ${planContext.plan_name} (${limitNote}). Mention this once: the user can connect their Clipform account in claude.ai → Settings → Connectors → ${BUSINESS.urls.mcp} so future forms land directly in their workspace - do not repeat on follow-up calls.`);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
return textResult(lines.join("\n"));
|
|
197
|
-
});
|
|
198
|
-
}
|
|
199
|
-
//# sourceMappingURL=create-form.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"create-form.js","sourceRoot":"","sources":["../../src/tools/create-form.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
import { callApi, errorResult, textResult } from "../lib/api-client.js";
|
|
3
|
-
export function registerDeleteFormTool(server) {
|
|
4
|
-
server.registerTool("clipform_delete_form", {
|
|
5
|
-
title: "Delete Clipform",
|
|
6
|
-
description: `Permanently delete an unclaimed form and all its questions. This cannot be undone. Only works on forms that haven't been claimed yet.`,
|
|
7
|
-
inputSchema: {
|
|
8
|
-
form_id: z.string().uuid().describe("The form UUID to delete (returned by clipform_create_form, not the short share_id from the URL)"),
|
|
9
|
-
},
|
|
10
|
-
annotations: {
|
|
11
|
-
readOnlyHint: false,
|
|
12
|
-
destructiveHint: true,
|
|
13
|
-
idempotentHint: false,
|
|
14
|
-
openWorldHint: true,
|
|
15
|
-
},
|
|
16
|
-
}, async ({ form_id }) => {
|
|
17
|
-
const result = await callApi(`/forms/${form_id}`, {
|
|
18
|
-
method: "DELETE",
|
|
19
|
-
});
|
|
20
|
-
if (!result.ok) {
|
|
21
|
-
return errorResult(result.error);
|
|
22
|
-
}
|
|
23
|
-
return textResult(`Form ${form_id} has been permanently deleted.`);
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
//# sourceMappingURL=delete-form.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"delete-form.js","sourceRoot":"","sources":["../../src/tools/delete-form.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAExE,MAAM,UAAU,sBAAsB,CAAC,MAAiB;IACtD,MAAM,CAAC,YAAY,CACjB,sBAAsB,EACtB;QACE,KAAK,EAAE,iBAAiB;QACxB,WAAW,EAAE,uIAAuI;QACpJ,WAAW,EAAE;YACX,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,iGAAiG,CAAC;SACvI;QACD,WAAW,EAAE;YACX,YAAY,EAAE,KAAK;YACnB,eAAe,EAAE,IAAI;YACrB,cAAc,EAAE,KAAK;YACrB,aAAa,EAAE,IAAI;SACpB;KACF,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;QACpB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,UAAU,OAAO,EAAE,EAAE;YAChD,MAAM,EAAE,QAAQ;SACjB,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;QAED,OAAO,UAAU,CAAC,QAAQ,OAAO,gCAAgC,CAAC,CAAC;IACrE,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
import { callApi, errorResult, textResult } from "../lib/api-client.js";
|
|
3
|
-
export function registerDeleteNodeMediaTool(server) {
|
|
4
|
-
server.registerTool("clipform_delete_node_media", {
|
|
5
|
-
title: "Delete Node Media",
|
|
6
|
-
description: `Remove media from a node. Deletes the media record and cleans up external resources (Mux video asset, storage file).`,
|
|
7
|
-
inputSchema: {
|
|
8
|
-
form_id: z.string().uuid().describe("The form UUID (returned by clipform_create_form, not the short share_id from the URL)"),
|
|
9
|
-
node_id: z.string().describe("The node ID"),
|
|
10
|
-
},
|
|
11
|
-
annotations: {
|
|
12
|
-
readOnlyHint: false,
|
|
13
|
-
destructiveHint: true,
|
|
14
|
-
idempotentHint: false,
|
|
15
|
-
openWorldHint: true,
|
|
16
|
-
},
|
|
17
|
-
}, async ({ form_id, node_id }) => {
|
|
18
|
-
const result = await callApi(`/forms/${form_id}/nodes/${node_id}/media`, { method: "DELETE" });
|
|
19
|
-
if (!result.ok) {
|
|
20
|
-
return errorResult(result.error);
|
|
21
|
-
}
|
|
22
|
-
return textResult("Media removed from node.");
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
//# sourceMappingURL=delete-node-media.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"delete-node-media.js","sourceRoot":"","sources":["../../src/tools/delete-node-media.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAExE,MAAM,UAAU,2BAA2B,CAAC,MAAiB;IAC3D,MAAM,CAAC,YAAY,CACjB,4BAA4B,EAC5B;QACE,KAAK,EAAE,mBAAmB;QAC1B,WAAW,EAAE,sHAAsH;QACnI,WAAW,EAAE;YACX,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,uFAAuF,CAAC;YAC5H,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC;SAC5C;QACD,WAAW,EAAE;YACX,YAAY,EAAE,KAAK;YACnB,eAAe,EAAE,IAAI;YACrB,cAAc,EAAE,KAAK;YACrB,aAAa,EAAE,IAAI;SACpB;KACF,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE;QAC7B,MAAM,MAAM,GAAG,MAAM,OAAO,CAC1B,UAAU,OAAO,UAAU,OAAO,QAAQ,EAC1C,EAAE,MAAM,EAAE,QAAQ,EAAE,CACrB,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;QAED,OAAO,UAAU,CAAC,0BAA0B,CAAC,CAAC;IAChD,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
import { callApi, errorResult, textResult } from "../lib/api-client.js";
|
|
3
|
-
import { fetchAndFormatFormState } from "../lib/format-form.js";
|
|
4
|
-
export function registerDeleteNodeTool(server) {
|
|
5
|
-
server.registerTool("clipform_delete_node", {
|
|
6
|
-
title: "Delete Node",
|
|
7
|
-
description: `Delete a node from a form. The logic chain is automatically re-linked (the previous node will point to the next one). Cannot delete the start node or the last end screen.`,
|
|
8
|
-
inputSchema: {
|
|
9
|
-
form_id: z.string().uuid().describe("The form UUID (returned by clipform_create_form, not the short share_id from the URL)"),
|
|
10
|
-
node_id: z.string().describe("The node ID to delete"),
|
|
11
|
-
},
|
|
12
|
-
annotations: {
|
|
13
|
-
readOnlyHint: false,
|
|
14
|
-
destructiveHint: true,
|
|
15
|
-
idempotentHint: false,
|
|
16
|
-
openWorldHint: true,
|
|
17
|
-
},
|
|
18
|
-
}, async ({ form_id, node_id }) => {
|
|
19
|
-
const result = await callApi(`/forms/${form_id}/nodes/${node_id}`, { method: "DELETE" });
|
|
20
|
-
if (!result.ok) {
|
|
21
|
-
return errorResult(result.error);
|
|
22
|
-
}
|
|
23
|
-
const confirmMsg = `Node ${node_id} deleted. The logic chain has been re-linked.`;
|
|
24
|
-
const formState = await fetchAndFormatFormState(form_id);
|
|
25
|
-
return textResult(formState ? `${confirmMsg}\n\n---\n\n${formState}` : confirmMsg);
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
//# sourceMappingURL=delete-node.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"delete-node.js","sourceRoot":"","sources":["../../src/tools/delete-node.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAEhE,MAAM,UAAU,sBAAsB,CAAC,MAAiB;IACtD,MAAM,CAAC,YAAY,CACjB,sBAAsB,EACtB;QACE,KAAK,EAAE,aAAa;QACpB,WAAW,EAAE,4KAA4K;QACzL,WAAW,EAAE;YACX,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,uFAAuF,CAAC;YAC5H,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,uBAAuB,CAAC;SACtD;QACD,WAAW,EAAE;YACX,YAAY,EAAE,KAAK;YACnB,eAAe,EAAE,IAAI;YACrB,cAAc,EAAE,KAAK;YACrB,aAAa,EAAE,IAAI;SACpB;KACF,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE;QAC7B,MAAM,MAAM,GAAG,MAAM,OAAO,CAC1B,UAAU,OAAO,UAAU,OAAO,EAAE,EACpC,EAAE,MAAM,EAAE,QAAQ,EAAE,CACrB,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;QAED,MAAM,UAAU,GAAG,QAAQ,OAAO,+CAA+C,CAAC;QAClF,MAAM,SAAS,GAAG,MAAM,uBAAuB,CAAC,OAAO,CAAC,CAAC;QACzD,OAAO,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,UAAU,cAAc,SAAS,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IACrF,CAAC,CACF,CAAC;AACJ,CAAC"}
|