mulmocast 0.0.22 → 0.0.23
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/README.md +5 -0
- package/lib/actions/captions.js +1 -1
- package/lib/actions/images.d.ts +7 -3
- package/lib/actions/images.js +61 -17
- package/lib/actions/movie.d.ts +2 -2
- package/lib/actions/movie.js +21 -6
- package/lib/agents/combine_audio_files_agent.js +9 -5
- package/lib/agents/index.d.ts +2 -1
- package/lib/agents/index.js +2 -1
- package/lib/agents/movie_replicate_agent.d.ts +23 -0
- package/lib/agents/movie_replicate_agent.js +93 -0
- package/lib/cli/commands/tool/scripting/builder.d.ts +3 -1
- package/lib/cli/commands/tool/scripting/builder.js +5 -0
- package/lib/cli/commands/tool/scripting/handler.d.ts +1 -0
- package/lib/cli/commands/tool/scripting/handler.js +13 -4
- package/lib/cli/commands/tool/story_to_script/builder.d.ts +1 -1
- package/lib/cli/helpers.js +8 -3
- package/lib/methods/mulmo_presentation_style.d.ts +2 -1
- package/lib/methods/mulmo_presentation_style.js +21 -2
- package/lib/methods/mulmo_studio_context.js +1 -1
- package/lib/tools/create_mulmo_script_from_url.d.ts +1 -0
- package/lib/tools/create_mulmo_script_from_url.js +129 -43
- package/lib/types/schema.d.ts +1123 -163
- package/lib/types/schema.js +38 -1
- package/lib/types/type.d.ts +9 -2
- package/lib/utils/ffmpeg_utils.d.ts +1 -1
- package/lib/utils/ffmpeg_utils.js +2 -2
- package/lib/utils/preprocess.d.ts +41 -6
- package/lib/utils/utils.d.ts +1 -0
- package/lib/utils/utils.js +5 -0
- package/package.json +3 -2
- package/scripts/templates/presentation.json +123 -0
- package/scripts/templates/presentation.json~ +119 -0
package/lib/types/schema.js
CHANGED
|
@@ -84,6 +84,18 @@ export const mulmoTextSlideMediaSchema = z
|
|
|
84
84
|
}),
|
|
85
85
|
})
|
|
86
86
|
.strict();
|
|
87
|
+
export const mulmoCaptionParamsSchema = z
|
|
88
|
+
.object({
|
|
89
|
+
lang: langSchema.optional(),
|
|
90
|
+
textColor: z.string().default("#FFFFFF"),
|
|
91
|
+
backgroundColor: z.string().default("#000000"),
|
|
92
|
+
fontSize: z.number().default(16),
|
|
93
|
+
fontFamily: z.string().default("Arial"),
|
|
94
|
+
fontWeight: z.string().default("normal"),
|
|
95
|
+
textAlign: z.string().default("left"),
|
|
96
|
+
textDecoration: z.string().default("none"),
|
|
97
|
+
})
|
|
98
|
+
.strict();
|
|
87
99
|
export const mulmoChartMediaSchema = z
|
|
88
100
|
.object({
|
|
89
101
|
type: z.literal("chart"),
|
|
@@ -141,6 +153,11 @@ const mulmoMidiMediaSchema = z
|
|
|
141
153
|
export const mulmoAudioAssetSchema = z.union([mulmoAudioMediaSchema, mulmoMidiMediaSchema]);
|
|
142
154
|
const imageIdSchema = z.string();
|
|
143
155
|
export const mulmoImageParamsImagesSchema = z.record(imageIdSchema, mulmoImageMediaSchema);
|
|
156
|
+
export const mulmoFillOptionSchema = z
|
|
157
|
+
.object({
|
|
158
|
+
style: z.enum(["aspectFit", "aspectFill"]).default("aspectFit"),
|
|
159
|
+
})
|
|
160
|
+
.describe("How to handle aspect ratio differences between image and canvas");
|
|
144
161
|
export const mulmoImageParamsSchema = z
|
|
145
162
|
.object({
|
|
146
163
|
model: z.string().optional(), // default: provider specific
|
|
@@ -159,6 +176,11 @@ export const beatAudioParamsSchema = z
|
|
|
159
176
|
padding: z.number().optional().describe("Padding between beats"), // seconds
|
|
160
177
|
})
|
|
161
178
|
.strict();
|
|
179
|
+
export const mulmoHtmlImageParamsSchema = z
|
|
180
|
+
.object({
|
|
181
|
+
model: z.string().optional(), // default: provider specific
|
|
182
|
+
})
|
|
183
|
+
.strict();
|
|
162
184
|
// Note: we can't extend beatAudioParamsSchema because it has padding as optional
|
|
163
185
|
export const audioParamsSchema = z
|
|
164
186
|
.object({
|
|
@@ -190,8 +212,15 @@ export const mulmoBeatSchema = z
|
|
|
190
212
|
duration: z.number().optional().describe("Duration of the beat. Used only when the text is empty"),
|
|
191
213
|
imageParams: mulmoImageParamsSchema.optional(), // beat specific parameters
|
|
192
214
|
audioParams: beatAudioParamsSchema.optional(), // beat specific parameters
|
|
215
|
+
movieParams: z
|
|
216
|
+
.object({
|
|
217
|
+
fillOption: mulmoFillOptionSchema,
|
|
218
|
+
})
|
|
219
|
+
.optional(),
|
|
220
|
+
htmlImageParams: mulmoHtmlImageParamsSchema.optional(),
|
|
193
221
|
speechOptions: speechOptionsSchema.optional(),
|
|
194
222
|
textSlideParams: textSlideParamsSchema.optional(),
|
|
223
|
+
captionParams: mulmoCaptionParamsSchema.optional(),
|
|
195
224
|
imageNames: z.array(imageIdSchema).optional(), // list of image names to use for image generation. The default is all images in the imageParams.images.
|
|
196
225
|
imagePrompt: z.string().optional(),
|
|
197
226
|
moviePrompt: z.string().optional(),
|
|
@@ -218,7 +247,8 @@ export const mulmoSpeechParamsSchema = z
|
|
|
218
247
|
})
|
|
219
248
|
.strict();
|
|
220
249
|
export const text2ImageProviderSchema = z.union([z.literal("openai"), z.literal("google")]).default("openai");
|
|
221
|
-
export const
|
|
250
|
+
export const text2HtmlImageProviderSchema = z.union([z.literal("openai"), z.literal("anthropic")]).default("openai");
|
|
251
|
+
export const text2MovieProviderSchema = z.union([z.literal("openai"), z.literal("google"), z.literal("replicate")]).default("google");
|
|
222
252
|
export const mulmoTransitionSchema = z.object({
|
|
223
253
|
type: z.enum(["fade", "slideout_left"]),
|
|
224
254
|
duration: z.number().min(0).max(2).default(0.3), // transition duration in seconds
|
|
@@ -228,6 +258,7 @@ export const mulmoMovieParamsSchema = z
|
|
|
228
258
|
provider: text2MovieProviderSchema.optional(),
|
|
229
259
|
model: z.string().optional(), // default: provider specific
|
|
230
260
|
transition: mulmoTransitionSchema.optional(),
|
|
261
|
+
fillOption: mulmoFillOptionSchema.optional(),
|
|
231
262
|
})
|
|
232
263
|
.strict();
|
|
233
264
|
export const mulmoPresentationStyleSchema = z.object({
|
|
@@ -249,8 +280,14 @@ export const mulmoPresentationStyleSchema = z.object({
|
|
|
249
280
|
})
|
|
250
281
|
.optional(),
|
|
251
282
|
movieParams: mulmoMovieParamsSchema.optional(),
|
|
283
|
+
htmlImageParams: mulmoHtmlImageParamsSchema
|
|
284
|
+
.extend({
|
|
285
|
+
provider: text2HtmlImageProviderSchema,
|
|
286
|
+
})
|
|
287
|
+
.optional(),
|
|
252
288
|
// for textSlides
|
|
253
289
|
textSlideParams: textSlideParamsSchema.optional(),
|
|
290
|
+
captionParams: mulmoCaptionParamsSchema.optional(),
|
|
254
291
|
audioParams: audioParamsSchema.default({
|
|
255
292
|
introPadding: 1.0,
|
|
256
293
|
padding: 0.3,
|
package/lib/types/type.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { langSchema, localizedTextSchema, mulmoBeatSchema, mulmoScriptSchema, mulmoStudioSchema, mulmoStudioBeatSchema, mulmoStoryboardSchema, mulmoStoryboardSceneSchema, mulmoStudioMultiLingualSchema, mulmoStudioMultiLingualDataSchema, speakerDictionarySchema, mulmoImageParamsSchema, mulmoImageParamsImagesSchema, mulmoMovieParamsSchema, mulmoSpeechParamsSchema, textSlideParamsSchema, speechOptionsSchema, speakerDataSchema, mulmoCanvasDimensionSchema, mulmoScriptTemplateSchema, mulmoScriptTemplateFileSchema, text2ImageProviderSchema, text2MovieProviderSchema, text2SpeechProviderSchema, mulmoPresentationStyleSchema, multiLingualTextsSchema, mulmoMermaidMediaSchema, mulmoTextSlideMediaSchema, mulmoMarkdownMediaSchema, mulmoImageMediaSchema, mulmoChartMediaSchema, mediaSourceSchema, mulmoSessionStateSchema } from "./schema.js";
|
|
1
|
+
import { langSchema, localizedTextSchema, mulmoBeatSchema, mulmoScriptSchema, mulmoStudioSchema, mulmoStudioBeatSchema, mulmoStoryboardSchema, mulmoStoryboardSceneSchema, mulmoStudioMultiLingualSchema, mulmoStudioMultiLingualDataSchema, speakerDictionarySchema, mulmoImageParamsSchema, mulmoImageParamsImagesSchema, mulmoFillOptionSchema, mulmoMovieParamsSchema, mulmoSpeechParamsSchema, textSlideParamsSchema, speechOptionsSchema, speakerDataSchema, mulmoCanvasDimensionSchema, mulmoScriptTemplateSchema, mulmoScriptTemplateFileSchema, text2ImageProviderSchema, text2HtmlImageProviderSchema, text2MovieProviderSchema, text2SpeechProviderSchema, mulmoPresentationStyleSchema, multiLingualTextsSchema, mulmoMermaidMediaSchema, mulmoTextSlideMediaSchema, mulmoMarkdownMediaSchema, mulmoImageMediaSchema, mulmoChartMediaSchema, mediaSourceSchema, mulmoSessionStateSchema } from "./schema.js";
|
|
2
2
|
import { pdf_modes, pdf_sizes, storyToScriptGenerateMode } from "../utils/const.js";
|
|
3
3
|
import { LLM } from "../utils/utils.js";
|
|
4
4
|
import { z } from "zod";
|
|
@@ -10,8 +10,10 @@ export type SpeechOptions = z.infer<typeof speechOptionsSchema>;
|
|
|
10
10
|
export type SpeakerData = z.infer<typeof speakerDataSchema>;
|
|
11
11
|
export type MulmoImageParams = z.infer<typeof mulmoImageParamsSchema>;
|
|
12
12
|
export type MulmoImageParamsImages = z.infer<typeof mulmoImageParamsImagesSchema>;
|
|
13
|
+
export type MulmoFillOption = z.infer<typeof mulmoFillOptionSchema>;
|
|
13
14
|
export type TextSlideParams = z.infer<typeof textSlideParamsSchema>;
|
|
14
15
|
export type Text2ImageProvider = z.infer<typeof text2ImageProviderSchema>;
|
|
16
|
+
export type Text2HtmlImageProvider = z.infer<typeof text2HtmlImageProviderSchema>;
|
|
15
17
|
export type Text2MovieProvider = z.infer<typeof text2MovieProviderSchema>;
|
|
16
18
|
export type Text2SpeechProvider = z.infer<typeof text2SpeechProviderSchema>;
|
|
17
19
|
export type LocalizedText = z.infer<typeof localizedTextSchema>;
|
|
@@ -49,7 +51,6 @@ export type MulmoStudioContext = {
|
|
|
49
51
|
lang?: string;
|
|
50
52
|
dryRun?: boolean;
|
|
51
53
|
force: boolean;
|
|
52
|
-
caption?: string;
|
|
53
54
|
sessionState: MulmoSessionState;
|
|
54
55
|
presentationStyle: MulmoPresentationStyle;
|
|
55
56
|
multiLingual: MulmoStudioMultiLingual;
|
|
@@ -62,6 +63,7 @@ export type ScriptingParams = {
|
|
|
62
63
|
filename: string;
|
|
63
64
|
llm_model?: string;
|
|
64
65
|
llm?: LLM;
|
|
66
|
+
verbose?: boolean;
|
|
65
67
|
};
|
|
66
68
|
export type ImageProcessorParams = {
|
|
67
69
|
beat: MulmoBeat;
|
|
@@ -77,6 +79,11 @@ export type Text2ImageAgentInfo = {
|
|
|
77
79
|
agent: string;
|
|
78
80
|
imageParams: MulmoImageParams;
|
|
79
81
|
};
|
|
82
|
+
export type Text2HtmlAgentInfo = {
|
|
83
|
+
provider: Text2HtmlImageProvider;
|
|
84
|
+
agent: string;
|
|
85
|
+
model: string;
|
|
86
|
+
};
|
|
80
87
|
export type BeatMediaType = "movie" | "image";
|
|
81
88
|
export type StoryToScriptGenerateMode = (typeof storyToScriptGenerateMode)[keyof typeof storyToScriptGenerateMode];
|
|
82
89
|
export type SessionType = "audio" | "image" | "video" | "multiLingual" | "caption" | "pdf";
|
|
@@ -7,7 +7,7 @@ export type FfmpegContext = {
|
|
|
7
7
|
export declare const FfmpegContextInit: () => FfmpegContext;
|
|
8
8
|
export declare const FfmpegContextAddInput: (context: FfmpegContext, input: string, inputOptions?: string[]) => number;
|
|
9
9
|
export declare const FfmpegContextPushFormattedAudio: (context: FfmpegContext, sourceId: string, outputId: string, duration?: number | undefined) => void;
|
|
10
|
-
export declare const FfmpegContextInputFormattedAudio: (context: FfmpegContext, input: string, duration?: number | undefined) => string;
|
|
10
|
+
export declare const FfmpegContextInputFormattedAudio: (context: FfmpegContext, input: string, duration?: number | undefined, inputOptions?: string[]) => string;
|
|
11
11
|
export declare const FfmpegContextGenerateOutput: (context: FfmpegContext, output: string, options?: string[]) => Promise<number>;
|
|
12
12
|
export declare const ffmpegGetMediaDuration: (filePath: string) => Promise<number>;
|
|
13
13
|
export declare const extractImageFromMovie: (movieFile: string, imagePath: string) => Promise<void>;
|
|
@@ -25,8 +25,8 @@ export const FfmpegContextPushFormattedAudio = (context, sourceId, outputId, dur
|
|
|
25
25
|
context.filterComplex.push(`${sourceId}aformat=sample_fmts=fltp:sample_rates=44100:channel_layouts=stereo${outputId}`);
|
|
26
26
|
}
|
|
27
27
|
};
|
|
28
|
-
export const FfmpegContextInputFormattedAudio = (context, input, duration = undefined) => {
|
|
29
|
-
const index = FfmpegContextAddInput(context, input);
|
|
28
|
+
export const FfmpegContextInputFormattedAudio = (context, input, duration = undefined, inputOptions) => {
|
|
29
|
+
const index = FfmpegContextAddInput(context, input, inputOptions);
|
|
30
30
|
const audioId = `[a${index}]`;
|
|
31
31
|
FfmpegContextPushFormattedAudio(context, `[${index}:a]`, audioId, duration);
|
|
32
32
|
return audioId;
|
|
@@ -182,8 +182,8 @@ export declare const createOrUpdateStudioData: (_mulmoScript: MulmoScript, curre
|
|
|
182
182
|
} | undefined;
|
|
183
183
|
description?: string | undefined;
|
|
184
184
|
imageParams?: {
|
|
185
|
-
model?: string | undefined;
|
|
186
185
|
style?: string | undefined;
|
|
186
|
+
model?: string | undefined;
|
|
187
187
|
moderation?: string | undefined;
|
|
188
188
|
images?: Record<string, {
|
|
189
189
|
type: "image";
|
|
@@ -205,9 +205,27 @@ export declare const createOrUpdateStudioData: (_mulmoScript: MulmoScript, curre
|
|
|
205
205
|
audioParams?: {
|
|
206
206
|
padding?: number | undefined;
|
|
207
207
|
} | undefined;
|
|
208
|
+
movieParams?: {
|
|
209
|
+
fillOption: {
|
|
210
|
+
style: "aspectFit" | "aspectFill";
|
|
211
|
+
};
|
|
212
|
+
} | undefined;
|
|
213
|
+
htmlImageParams?: {
|
|
214
|
+
model?: string | undefined;
|
|
215
|
+
} | undefined;
|
|
208
216
|
textSlideParams?: {
|
|
209
217
|
cssStyles: string | string[];
|
|
210
218
|
} | undefined;
|
|
219
|
+
captionParams?: {
|
|
220
|
+
textColor: string;
|
|
221
|
+
backgroundColor: string;
|
|
222
|
+
fontSize: number;
|
|
223
|
+
fontFamily: string;
|
|
224
|
+
fontWeight: string;
|
|
225
|
+
textAlign: string;
|
|
226
|
+
textDecoration: string;
|
|
227
|
+
lang?: string | undefined;
|
|
228
|
+
} | undefined;
|
|
211
229
|
imageNames?: string[] | undefined;
|
|
212
230
|
imagePrompt?: string | undefined;
|
|
213
231
|
moviePrompt?: string | undefined;
|
|
@@ -223,8 +241,8 @@ export declare const createOrUpdateStudioData: (_mulmoScript: MulmoScript, curre
|
|
|
223
241
|
description?: string | undefined;
|
|
224
242
|
imageParams?: {
|
|
225
243
|
provider: "openai" | "google";
|
|
226
|
-
model?: string | undefined;
|
|
227
244
|
style?: string | undefined;
|
|
245
|
+
model?: string | undefined;
|
|
228
246
|
moderation?: string | undefined;
|
|
229
247
|
images?: Record<string, {
|
|
230
248
|
type: "image";
|
|
@@ -243,17 +261,34 @@ export declare const createOrUpdateStudioData: (_mulmoScript: MulmoScript, curre
|
|
|
243
261
|
};
|
|
244
262
|
}> | undefined;
|
|
245
263
|
} | undefined;
|
|
246
|
-
textSlideParams?: {
|
|
247
|
-
cssStyles: string | string[];
|
|
248
|
-
} | undefined;
|
|
249
264
|
movieParams?: {
|
|
250
|
-
provider?: "openai" | "google" | undefined;
|
|
265
|
+
provider?: "openai" | "google" | "replicate" | undefined;
|
|
251
266
|
model?: string | undefined;
|
|
267
|
+
fillOption?: {
|
|
268
|
+
style: "aspectFit" | "aspectFill";
|
|
269
|
+
} | undefined;
|
|
252
270
|
transition?: {
|
|
253
271
|
type: "fade" | "slideout_left";
|
|
254
272
|
duration: number;
|
|
255
273
|
} | undefined;
|
|
256
274
|
} | undefined;
|
|
275
|
+
htmlImageParams?: {
|
|
276
|
+
provider: "openai" | "anthropic";
|
|
277
|
+
model?: string | undefined;
|
|
278
|
+
} | undefined;
|
|
279
|
+
textSlideParams?: {
|
|
280
|
+
cssStyles: string | string[];
|
|
281
|
+
} | undefined;
|
|
282
|
+
captionParams?: {
|
|
283
|
+
textColor: string;
|
|
284
|
+
backgroundColor: string;
|
|
285
|
+
fontSize: number;
|
|
286
|
+
fontFamily: string;
|
|
287
|
+
fontWeight: string;
|
|
288
|
+
textAlign: string;
|
|
289
|
+
textDecoration: string;
|
|
290
|
+
lang?: string | undefined;
|
|
291
|
+
} | undefined;
|
|
257
292
|
references?: {
|
|
258
293
|
type: "image" | "audio" | "article" | "paper" | "video";
|
|
259
294
|
url: string;
|
package/lib/utils/utils.d.ts
CHANGED
|
@@ -16,3 +16,4 @@ export declare const isHttp: (fileOrUrl: string) => boolean;
|
|
|
16
16
|
export declare const text2hash: (input: string) => string;
|
|
17
17
|
export declare const localizedText: (beat: MulmoBeat, multiLingualData?: MulmoStudioMultiLingualData, lang?: string) => string;
|
|
18
18
|
export declare const sleep: (milliseconds: number) => Promise<unknown>;
|
|
19
|
+
export declare function userAssert(condition: boolean, message: string): asserts condition;
|
package/lib/utils/utils.js
CHANGED
|
@@ -55,3 +55,8 @@ export const localizedText = (beat, multiLingualData, lang) => {
|
|
|
55
55
|
export const sleep = async (milliseconds) => {
|
|
56
56
|
return await new Promise((resolve) => setTimeout(resolve, milliseconds));
|
|
57
57
|
};
|
|
58
|
+
export function userAssert(condition, message) {
|
|
59
|
+
if (!condition) {
|
|
60
|
+
throw new Error(message);
|
|
61
|
+
}
|
|
62
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mulmocast",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.23",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -74,11 +74,12 @@
|
|
|
74
74
|
"dotenv": "^16.4.7",
|
|
75
75
|
"fluent-ffmpeg": "^2.1.3",
|
|
76
76
|
"google-auth-library": "^9.15.1",
|
|
77
|
-
"graphai": "^2.0.
|
|
77
|
+
"graphai": "^2.0.9",
|
|
78
78
|
"inquirer": "^12.6.1",
|
|
79
79
|
"marked": "^15.0.12",
|
|
80
80
|
"ora": "^8.2.0",
|
|
81
81
|
"puppeteer": "^24.10.2",
|
|
82
|
+
"replicate": "^1.0.1",
|
|
82
83
|
"yaml": "^2.8.0",
|
|
83
84
|
"yargs": "^17.7.2",
|
|
84
85
|
"zod": "^3.25.67",
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$mulmocast": {
|
|
3
|
+
"version": "1.0",
|
|
4
|
+
"credit": "closing"
|
|
5
|
+
},
|
|
6
|
+
"htmlImageParams": {
|
|
7
|
+
"provider": "anthropic",
|
|
8
|
+
"model": "claude-3-7-sonnet-20250219"
|
|
9
|
+
},
|
|
10
|
+
"title": "Sample Title",
|
|
11
|
+
"references": [
|
|
12
|
+
{
|
|
13
|
+
"url": "https://www.somegreatwebsite.com/article/123",
|
|
14
|
+
"title": "Title of the article we are referencing",
|
|
15
|
+
"type": "article"
|
|
16
|
+
}
|
|
17
|
+
],
|
|
18
|
+
"lang": "en",
|
|
19
|
+
"beats": [
|
|
20
|
+
{
|
|
21
|
+
"speaker": "Presenter",
|
|
22
|
+
"text": "Book rooms with locals, not hotels.",
|
|
23
|
+
"htmlPrompt": {
|
|
24
|
+
"prompt": "Create a clean and bold title slide featuring the original name 'AirBed & Breakfast' with the tagline: 'Book rooms with locals, not hotels'. Include the old logo and a travel-themed background."
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"speaker": "Presenter",
|
|
29
|
+
"text": "Hotels are expensive and detached from local culture.",
|
|
30
|
+
"htmlPrompt": {
|
|
31
|
+
"prompt": "Design a slide that lists the main problems with hotels: high prices, lack of personality, and cultural disconnection. Use simple icons for cost, generic room, and traveler."
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"speaker": "Presenter",
|
|
36
|
+
"text": "Airbnb lets people rent out their spaces, offering affordable, authentic experiences.",
|
|
37
|
+
"htmlPrompt": {
|
|
38
|
+
"prompt": "Illustrate Airbnb's solution: locals listing their spare rooms or homes, travelers booking directly, and both benefiting. Use a flow diagram to represent this."
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"speaker": "Presenter",
|
|
43
|
+
"text": "Craigslist and Couchsurfing prove the demand for alternative lodging.",
|
|
44
|
+
"htmlPrompt": {
|
|
45
|
+
"prompt": "Show a bar graph comparing Craigslist listings, Couchsurfing users, and early Airbnb listings to demonstrate existing demand and opportunity."
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"speaker": "Presenter",
|
|
50
|
+
"text": "A massive market: over 630 million travel bookings annually.",
|
|
51
|
+
"htmlPrompt": {
|
|
52
|
+
"prompt": "Visualize the global travel booking market. Use a world map and large numbers to emphasize the size and growth potential."
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"speaker": "Presenter",
|
|
57
|
+
"text": "Our platform enables hosts to list once and earn; guests search, book, and review.",
|
|
58
|
+
"htmlPrompt": {
|
|
59
|
+
"prompt": "Create a product overview slide showing how the platform works from host listing to guest review. Highlight simplicity and trust."
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"speaker": "Presenter",
|
|
64
|
+
"text": "We charge a 10% commission per booking.",
|
|
65
|
+
"htmlPrompt": {
|
|
66
|
+
"prompt": "Display a slide with the monetization strategy—Airbnb earns through a 10% commission. Use a simple pie chart or booking flow with fee annotation."
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"speaker": "Presenter",
|
|
71
|
+
"text": "Competitors include hotels, Craigslist, Couchsurfing — we offer a better, scalable solution.",
|
|
72
|
+
"htmlPrompt": {
|
|
73
|
+
"prompt": "Design a comparison table: price, uniqueness, trust, scalability. Airbnb should clearly stand out on all dimensions."
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"speaker": "Presenter",
|
|
78
|
+
"text": "Key advantages: lower price, wide selection, ease of use, host incentives, trusted system.",
|
|
79
|
+
"htmlPrompt": {
|
|
80
|
+
"prompt": "List Airbnb’s competitive advantages using 6 icons or badges, one for each feature."
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"speaker": "Presenter",
|
|
85
|
+
"text": "Founders: Brian Chesky (Design), Joe Gebbia (Marketing), Nathan Blecharczyk (Engineering).",
|
|
86
|
+
"htmlPrompt": {
|
|
87
|
+
"prompt": "Introduce the founding team with photos and brief bios. Highlight their roles and strengths in product, marketing, and tech."
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"speaker": "Presenter",
|
|
92
|
+
"text": "Media buzz: featured on TechCrunch and buzz from SXSW.",
|
|
93
|
+
"htmlPrompt": {
|
|
94
|
+
"prompt": "Showcase media recognition. Include TechCrunch logo and SXSW quotes or metrics. This adds credibility and traction."
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"speaker": "Presenter",
|
|
99
|
+
"text": "Early users love the authentic and affordable experiences.",
|
|
100
|
+
"htmlPrompt": {
|
|
101
|
+
"prompt": "Add 2–3 short testimonials from early users (guests and hosts), displayed in speech bubbles with faces or usernames."
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"speaker": "Presenter",
|
|
106
|
+
"text": "We’re raising $600K to support 12 months of growth and reach 80K bookings with $2M in revenue.",
|
|
107
|
+
"htmlPrompt": {
|
|
108
|
+
"prompt": "Closing investment slide. Include fund usage (pie chart: 40% marketing, 30% product, 30% ops), and KPIs: 80K bookings, $2M revenue.",
|
|
109
|
+
"data": {
|
|
110
|
+
"ask": 600000,
|
|
111
|
+
"duration_months": 12,
|
|
112
|
+
"target_bookings": 80000,
|
|
113
|
+
"target_revenue": 2000000,
|
|
114
|
+
"use_of_funds": {
|
|
115
|
+
"marketing": 40,
|
|
116
|
+
"product": 30,
|
|
117
|
+
"operations": 30
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
]
|
|
123
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$mulmocast": {
|
|
3
|
+
"version": "1.0",
|
|
4
|
+
"credit": "closing"
|
|
5
|
+
},
|
|
6
|
+
"title": "Sample Title",
|
|
7
|
+
"references": [
|
|
8
|
+
{
|
|
9
|
+
"url": "https://www.somegreatwebsite.com/article/123",
|
|
10
|
+
"title": "Title of the article we are referencing",
|
|
11
|
+
"type": "article"
|
|
12
|
+
}
|
|
13
|
+
],
|
|
14
|
+
"lang": "en",
|
|
15
|
+
"beats": [
|
|
16
|
+
{
|
|
17
|
+
"speaker": "Presenter",
|
|
18
|
+
"text": "Book rooms with locals, not hotels.",
|
|
19
|
+
"htmlPrompt": {
|
|
20
|
+
"prompt": "Create a clean and bold title slide featuring the original name 'AirBed & Breakfast' with the tagline: 'Book rooms with locals, not hotels'. Include the old logo and a travel-themed background."
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"speaker": "Presenter",
|
|
25
|
+
"text": "Hotels are expensive and detached from local culture.",
|
|
26
|
+
"htmlPrompt": {
|
|
27
|
+
"prompt": "Design a slide that lists the main problems with hotels: high prices, lack of personality, and cultural disconnection. Use simple icons for cost, generic room, and traveler."
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"speaker": "Presenter",
|
|
32
|
+
"text": "Airbnb lets people rent out their spaces, offering affordable, authentic experiences.",
|
|
33
|
+
"htmlPrompt": {
|
|
34
|
+
"prompt": "Illustrate Airbnb's solution: locals listing their spare rooms or homes, travelers booking directly, and both benefiting. Use a flow diagram to represent this."
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"speaker": "Presenter",
|
|
39
|
+
"text": "Craigslist and Couchsurfing prove the demand for alternative lodging.",
|
|
40
|
+
"htmlPrompt": {
|
|
41
|
+
"prompt": "Show a bar graph comparing Craigslist listings, Couchsurfing users, and early Airbnb listings to demonstrate existing demand and opportunity."
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"speaker": "Presenter",
|
|
46
|
+
"text": "A massive market: over 630 million travel bookings annually.",
|
|
47
|
+
"htmlPrompt": {
|
|
48
|
+
"prompt": "Visualize the global travel booking market. Use a world map and large numbers to emphasize the size and growth potential."
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"speaker": "Presenter",
|
|
53
|
+
"text": "Our platform enables hosts to list once and earn; guests search, book, and review.",
|
|
54
|
+
"htmlPrompt": {
|
|
55
|
+
"prompt": "Create a product overview slide showing how the platform works from host listing to guest review. Highlight simplicity and trust."
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"speaker": "Presenter",
|
|
60
|
+
"text": "We charge a 10% commission per booking.",
|
|
61
|
+
"htmlPrompt": {
|
|
62
|
+
"prompt": "Display a slide with the monetization strategy—Airbnb earns through a 10% commission. Use a simple pie chart or booking flow with fee annotation."
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"speaker": "Presenter",
|
|
67
|
+
"text": "Competitors include hotels, Craigslist, Couchsurfing — we offer a better, scalable solution.",
|
|
68
|
+
"htmlPrompt": {
|
|
69
|
+
"prompt": "Design a comparison table: price, uniqueness, trust, scalability. Airbnb should clearly stand out on all dimensions."
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"speaker": "Presenter",
|
|
74
|
+
"text": "Key advantages: lower price, wide selection, ease of use, host incentives, trusted system.",
|
|
75
|
+
"htmlPrompt": {
|
|
76
|
+
"prompt": "List Airbnb’s competitive advantages using 6 icons or badges, one for each feature."
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"speaker": "Presenter",
|
|
81
|
+
"text": "Founders: Brian Chesky (Design), Joe Gebbia (Marketing), Nathan Blecharczyk (Engineering).",
|
|
82
|
+
"htmlPrompt": {
|
|
83
|
+
"prompt": "Introduce the founding team with photos and brief bios. Highlight their roles and strengths in product, marketing, and tech."
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"speaker": "Presenter",
|
|
88
|
+
"text": "Media buzz: featured on TechCrunch and buzz from SXSW.",
|
|
89
|
+
"htmlPrompt": {
|
|
90
|
+
"prompt": "Showcase media recognition. Include TechCrunch logo and SXSW quotes or metrics. This adds credibility and traction."
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"speaker": "Presenter",
|
|
95
|
+
"text": "Early users love the authentic and affordable experiences.",
|
|
96
|
+
"htmlPrompt": {
|
|
97
|
+
"prompt": "Add 2–3 short testimonials from early users (guests and hosts), displayed in speech bubbles with faces or usernames."
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"speaker": "Presenter",
|
|
102
|
+
"text": "We’re raising $600K to support 12 months of growth and reach 80K bookings with $2M in revenue.",
|
|
103
|
+
"htmlPrompt": {
|
|
104
|
+
"prompt": "Closing investment slide. Include fund usage (pie chart: 40% marketing, 30% product, 30% ops), and KPIs: 80K bookings, $2M revenue.",
|
|
105
|
+
"data": {
|
|
106
|
+
"ask": 600000,
|
|
107
|
+
"duration_months": 12,
|
|
108
|
+
"target_bookings": 80000,
|
|
109
|
+
"target_revenue": 2000000,
|
|
110
|
+
"use_of_funds": {
|
|
111
|
+
"marketing": 40,
|
|
112
|
+
"product": 30,
|
|
113
|
+
"operations": 30
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
]
|
|
119
|
+
}
|