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.
Files changed (33) hide show
  1. package/README.md +5 -0
  2. package/lib/actions/captions.js +1 -1
  3. package/lib/actions/images.d.ts +7 -3
  4. package/lib/actions/images.js +61 -17
  5. package/lib/actions/movie.d.ts +2 -2
  6. package/lib/actions/movie.js +21 -6
  7. package/lib/agents/combine_audio_files_agent.js +9 -5
  8. package/lib/agents/index.d.ts +2 -1
  9. package/lib/agents/index.js +2 -1
  10. package/lib/agents/movie_replicate_agent.d.ts +23 -0
  11. package/lib/agents/movie_replicate_agent.js +93 -0
  12. package/lib/cli/commands/tool/scripting/builder.d.ts +3 -1
  13. package/lib/cli/commands/tool/scripting/builder.js +5 -0
  14. package/lib/cli/commands/tool/scripting/handler.d.ts +1 -0
  15. package/lib/cli/commands/tool/scripting/handler.js +13 -4
  16. package/lib/cli/commands/tool/story_to_script/builder.d.ts +1 -1
  17. package/lib/cli/helpers.js +8 -3
  18. package/lib/methods/mulmo_presentation_style.d.ts +2 -1
  19. package/lib/methods/mulmo_presentation_style.js +21 -2
  20. package/lib/methods/mulmo_studio_context.js +1 -1
  21. package/lib/tools/create_mulmo_script_from_url.d.ts +1 -0
  22. package/lib/tools/create_mulmo_script_from_url.js +129 -43
  23. package/lib/types/schema.d.ts +1123 -163
  24. package/lib/types/schema.js +38 -1
  25. package/lib/types/type.d.ts +9 -2
  26. package/lib/utils/ffmpeg_utils.d.ts +1 -1
  27. package/lib/utils/ffmpeg_utils.js +2 -2
  28. package/lib/utils/preprocess.d.ts +41 -6
  29. package/lib/utils/utils.d.ts +1 -0
  30. package/lib/utils/utils.js +5 -0
  31. package/package.json +3 -2
  32. package/scripts/templates/presentation.json +123 -0
  33. package/scripts/templates/presentation.json~ +119 -0
@@ -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 text2MovieProviderSchema = z.union([z.literal("openai"), z.literal("google")]).default("google");
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,
@@ -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;
@@ -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;
@@ -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.22",
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.8",
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
+ }