@vanillaskyai/video 0.8.8 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +30 -0
- package/PUBLIC-API.md +5 -8
- package/dist/{builtin-server-CUYPIDE7.js → builtin-server-HW6HGXCZ.js} +2 -2
- package/dist/{catalog-types-BIhSpOWK.d.ts → catalog-types-WTbLP6Jh.d.ts} +5 -1
- package/dist/chapter-title-YRLIQY3V.js +7 -0
- package/dist/check-runtime.js +6 -15
- package/dist/{chunk-2USVB3CY.js → chunk-3ZTEFJIR.js} +285 -178
- package/dist/chunk-4YM2M62S.js +13 -0
- package/dist/chunk-77VY4O7A.js +390 -0
- package/dist/{chunk-MMUXVA47.js → chunk-7M56IUUX.js} +9 -8
- package/dist/chunk-7NZOMTAL.js +63 -0
- package/dist/{chunk-2DOLF4QN.js → chunk-AUPC6MDK.js} +12 -14
- package/dist/{chunk-352ZZCET.js → chunk-EGVQODKU.js} +2 -2
- package/dist/chunk-EWWCQFTI.js +18 -0
- package/dist/{chunk-MXZSDGZQ.js → chunk-G7IZBBWF.js} +14 -9
- package/dist/{chunk-KT3M7KDL.js → chunk-HKUI5BTB.js} +3 -3
- package/dist/{chunk-LMG3GHLL.js → chunk-IQMYK5DX.js} +29 -3
- package/dist/chunk-LH4BPALA.js +564 -0
- package/dist/{chunk-OWBT45EN.js → chunk-MQILEEXC.js} +1 -1
- package/dist/chunk-MXEYPK7M.js +552 -0
- package/dist/{chunk-AITKH6QT.js → chunk-OR52UMSF.js} +13 -39
- package/dist/{chunk-5SLENAJW.js → chunk-PAJ44TFW.js} +1 -2
- package/dist/{chunk-L7QGGKJ2.js → chunk-PDQFQIQW.js} +1 -1
- package/dist/{chunk-WJ6FLKNC.js → chunk-R3XAOMKP.js} +14 -0
- package/dist/{chunk-2OKB27TG.js → chunk-RXTN2CW6.js} +2 -2
- package/dist/{chunk-XWWLKRNU.js → chunk-TVIU23OM.js} +38 -49
- package/dist/{chunk-224QNWRA.js → chunk-UDIODEDK.js} +1 -5
- package/dist/{chunk-3VRMKFM7.js → chunk-ZDJNFA52.js} +11 -24
- package/dist/cinema-media-YQHSIFDA.js +11 -0
- package/dist/cli.js +18 -9
- package/dist/comparison-RZMMHZR2.js +27 -0
- package/dist/compose-video-TBFTONUC.js +12 -0
- package/dist/editorial-timeline-OZX7OS6G.js +36 -0
- package/dist/{events-BQ6z264n.d.ts → events-B4YCc4vc.d.ts} +1 -1
- package/dist/focus-cards-TJ72BT7U.js +20 -0
- package/dist/index.d.ts +4 -6
- package/dist/index.js +3 -7
- package/dist/key-figure-GYENXKH3.js +20 -0
- package/dist/{kit-tQnCPMOM.d.ts → kit-DrRpdn0p.d.ts} +2 -2
- package/dist/mobile-message-UZUPIKHD.js +49 -0
- package/dist/{preload-media-LJXWKTWG.js → preload-media-CFTZIMZL.js} +1 -1
- package/dist/quote-EW5HQA6H.js +23 -0
- package/dist/react.d.ts +21 -11
- package/dist/react.js +590 -833
- package/dist/scene-video-backdrop-PCTARAAJ.js +7 -0
- package/dist/server.d.ts +7 -8
- package/dist/server.js +91 -74
- package/dist/{system-prompt-RRXIWDDD.js → system-prompt-SYRT5DWM.js} +1 -1
- package/dist/template-catalog.d.ts +257 -16
- package/dist/template-catalog.js +1 -1
- package/dist/templates.d.ts +5 -5
- package/dist/test.d.ts +3 -3
- package/dist/test.js +18 -18
- package/dist/text-stream-LD364KBI.js +9 -0
- package/dist/{types-DWFO6qca.d.ts → types-CdBmNTGD.d.ts} +1 -1
- package/dist/{types-CEh9eUFu.d.ts → types-DdZw4GRQ.d.ts} +17 -48
- package/dist/validate-4OUD2CLX.js +10 -0
- package/docs/architecture.md +1 -1
- package/docs/concepts.md +1 -1
- package/docs/custom-templates.md +13 -28
- package/docs/customization.md +11 -59
- package/docs/getting-started.md +2 -2
- package/docs/immersive-interface.md +3 -4
- package/docs/maintainers/cinematic-migration.md +34 -0
- package/docs/media-and-audio.md +14 -14
- package/docs/motion-and-effects.md +6 -14
- package/docs/persistence.md +3 -3
- package/docs/production.md +11 -9
- package/docs/provider-integration.md +9 -16
- package/docs/reference/design-system.html +1 -1
- package/docs/reference/protocol.md +14 -4
- package/docs/testing.md +1 -1
- package/package.json +6 -3
- package/registry/items/backgrounds.json +1 -1
- package/registry/items/chapterTitle.json +80 -0
- package/registry/items/cinemaMedia.json +136 -0
- package/registry/items/comparison.json +101 -0
- package/registry/items/editorialTimeline.json +105 -0
- package/registry/items/focusCards.json +90 -0
- package/registry/items/keyFigure.json +97 -0
- package/registry/items/mobileMessage.json +153 -0
- package/registry/items/quote.json +94 -0
- package/registry/items/template-context.json +1 -1
- package/registry/items/theme.json +1 -1
- package/starters/video-chat/README.md +24 -26
- package/starters/video-chat/package.json +1 -1
- package/starters/video-chat/providers/video.ts +6 -5
- package/starters/video-chat/stock.ts +35 -151
- package/styles/fonts/OFL.txt +93 -0
- package/styles/fonts/manifest.json +66 -0
- package/styles/fonts/roboto-v51-cyrillic-ext.woff2 +0 -0
- package/styles/fonts/roboto-v51-cyrillic.woff2 +0 -0
- package/styles/fonts/roboto-v51-greek-ext.woff2 +0 -0
- package/styles/fonts/roboto-v51-greek.woff2 +0 -0
- package/styles/fonts/roboto-v51-latin-ext.woff2 +0 -0
- package/styles/fonts/roboto-v51-latin.woff2 +0 -0
- package/styles/fonts/roboto-v51-math.woff2 +0 -0
- package/styles/fonts/roboto-v51-symbols.woff2 +0 -0
- package/styles/fonts/roboto-v51-vietnamese.woff2 +0 -0
- package/styles/fonts/roboto.css +91 -0
- package/styles/video-chat.css +30 -22
- package/dist/bg-confetti-HITCGLGD.js +0 -89
- package/dist/bg-emoji-VU4UZYZN.js +0 -150
- package/dist/bg-media-L34PDQXJ.js +0 -106
- package/dist/brand-message-FUJ4STFO.js +0 -256
- package/dist/chart-bar-EGPHJATL.js +0 -310
- package/dist/chart-counter-5FFWQNZO.js +0 -306
- package/dist/chart-progress-ring-JMXQLMLC.js +0 -302
- package/dist/chunk-4UNKZEAT.js +0 -3575
- package/dist/chunk-5CDAM24P.js +0 -31
- package/dist/chunk-AOWSXU2K.js +0 -18
- package/dist/chunk-CJ7F2CE6.js +0 -104
- package/dist/chunk-FRN6WKHA.js +0 -185
- package/dist/chunk-G5JPHBX7.js +0 -336
- package/dist/chunk-L5BTTCZV.js +0 -97
- package/dist/chunk-P22HHFDK.js +0 -43
- package/dist/chunk-PP3MCPN4.js +0 -1998
- package/dist/chunk-QAAO7OAY.js +0 -19
- package/dist/chunk-S7HFLYNN.js +0 -35
- package/dist/chunk-W3VDIBGR.js +0 -217
- package/dist/chunk-XGRA2MUV.js +0 -242
- package/dist/chunk-XTOXFMLM.js +0 -105
- package/dist/chunk-YJJC4N4D.js +0 -761
- package/dist/compose-video-2NFH4DZY.js +0 -13
- package/dist/cta-logo-YR7LYUR5.js +0 -212
- package/dist/cta-media-DQJBKUO2.js +0 -221
- package/dist/incoming-call-54KQ7O5A.js +0 -323
- package/dist/infographic-before-after-ROS52GOW.js +0 -460
- package/dist/infographic-feature-list-E7MGUDAN.js +0 -272
- package/dist/infographic-problem-solution-3S6NGO5N.js +0 -343
- package/dist/infographic-stat-row-SYB7AB7H.js +0 -247
- package/dist/infographic-steps-KCE6JWE2.js +0 -406
- package/dist/prompt-input-MHX4O42G.js +0 -239
- package/dist/reaction-SLEGR3BE.js +0 -122
- package/dist/scene-video-backdrop-XFPX4O3I.js +0 -10
- package/dist/showcase-code-2HLAVKBM.js +0 -357
- package/dist/showcase-phone-Q4HEO4LH.js +0 -278
- package/dist/showcase-terminal-DL45LUFG.js +0 -312
- package/dist/showcase-web-2QZO73FZ.js +0 -396
- package/dist/social-conversation-75SD2637.js +0 -695
- package/dist/social-milestone-GEFUQSBF.js +0 -296
- package/dist/social-notification-FJ5VHVLK.js +0 -247
- package/dist/social-review-stack-KXQCKFRP.js +0 -242
- package/dist/social-testimonial-JZ7CHC7S.js +0 -287
- package/dist/social-tweet-UCDXM25F.js +0 -298
- package/dist/text-stream-54LXABJW.js +0 -10
- package/dist/validate-T7GBU2YF.js +0 -8
- package/registry/items/barChart.json +0 -245
- package/registry/items/beforeAfter.json +0 -180
- package/registry/items/bigNumber.json +0 -232
- package/registry/items/brandMessage.json +0 -164
- package/registry/items/cardList.json +0 -214
- package/registry/items/chatMessenger.json +0 -151
- package/registry/items/chatWhatsapp.json +0 -151
- package/registry/items/codeEditor.json +0 -191
- package/registry/items/confetti.json +0 -107
- package/registry/items/ctaLogo.json +0 -167
- package/registry/items/ctaMedia.json +0 -200
- package/registry/items/emojiBurst.json +0 -101
- package/registry/items/incomingCall.json +0 -177
- package/registry/items/media.json +0 -187
- package/registry/items/milestone.json +0 -212
- package/registry/items/notification.json +0 -189
- package/registry/items/phoneMockup.json +0 -261
- package/registry/items/problemSolution.json +0 -193
- package/registry/items/progressRing.json +0 -206
- package/registry/items/promptInput.json +0 -155
- package/registry/items/reaction.json +0 -176
- package/registry/items/reviewStack.json +0 -231
- package/registry/items/steps.json +0 -215
- package/registry/items/terminal.json +0 -219
- package/registry/items/testimonial.json +0 -171
- package/registry/items/tripleStats.json +0 -235
- package/registry/items/tweet.json +0 -210
- package/registry/items/webMockup.json +0 -280
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
validateTemplateSchemaValue
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-EGVQODKU.js";
|
|
4
4
|
import {
|
|
5
5
|
getTemplateSchemaGates,
|
|
6
6
|
isMeaningfullyPresentTemplateValue
|
|
@@ -29,7 +29,7 @@ function schemaValues(schema, variables) {
|
|
|
29
29
|
}
|
|
30
30
|
return values;
|
|
31
31
|
}
|
|
32
|
-
function
|
|
32
|
+
function validateTemplateSceneStructure(schema, value, deferMediaUrls = false) {
|
|
33
33
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
34
34
|
throw new Error("Template variable variables must be object");
|
|
35
35
|
}
|
|
@@ -45,6 +45,7 @@ function validateSchema(schema, value) {
|
|
|
45
45
|
}
|
|
46
46
|
for (const [name, property] of Object.entries(schema.properties)) {
|
|
47
47
|
if (Object.hasOwn(object, name)) validateTemplateSchemaValue(property, object[name], name, {
|
|
48
|
+
deferMediaUrls,
|
|
48
49
|
errorPrefix: "Template variable ",
|
|
49
50
|
includeTypeArticle: true,
|
|
50
51
|
allowEmptyOptionalMedia: property.default === "",
|
|
@@ -66,6 +67,24 @@ function suppliedUrls(input) {
|
|
|
66
67
|
}
|
|
67
68
|
return urls;
|
|
68
69
|
}
|
|
70
|
+
function containsSuppliedQuantity(input, value) {
|
|
71
|
+
if (typeof value !== "string" && typeof value !== "number") return false;
|
|
72
|
+
const normalize = (text) => text.normalize("NFKC").replace(/\u2212/g, "-").replace(/\s+/gu, " ").replace(/([\p{Sc}]) (?=[+−-]?\d)/gu, "$1").replace(/(\d) (?=[%‰])/gu, "$1").trim();
|
|
73
|
+
const quantity = normalize(String(value));
|
|
74
|
+
if (!/\d/u.test(quantity)) return false;
|
|
75
|
+
const source = normalize(input);
|
|
76
|
+
let offset = source.indexOf(quantity);
|
|
77
|
+
while (offset !== -1) {
|
|
78
|
+
const before = source.slice(0, offset);
|
|
79
|
+
const after = source.slice(offset + quantity.length);
|
|
80
|
+
const beginsInside = /[\p{L}\p{N}\p{Sc}%‰+−-]$/u.test(before) || /\d[.,]$/u.test(before);
|
|
81
|
+
const endsInside = /^[\p{L}\p{N}\p{Sc}%‰]/u.test(after) || /^[.,]\d/u.test(after);
|
|
82
|
+
const dropsUnit = /\d$/u.test(quantity) && /^ (?:%|‰|percent\b|per cent\b|thousand\b|million\b|billion\b|trillion\b|usd\b|eur\b|gbp\b|dollars?\b|euros?\b|pounds?\b)/iu.test(after);
|
|
83
|
+
if (!beginsInside && !endsInside && !dropsUnit) return true;
|
|
84
|
+
offset = source.indexOf(quantity, offset + 1);
|
|
85
|
+
}
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
69
88
|
function createTemplateSceneValidator(options) {
|
|
70
89
|
return (scene, context) => {
|
|
71
90
|
const template = options.kit.getTemplateMetadata(scene.templateId);
|
|
@@ -73,7 +92,7 @@ function createTemplateSceneValidator(options) {
|
|
|
73
92
|
const schema = template.schema;
|
|
74
93
|
const gates = getTemplateSchemaGates(schema);
|
|
75
94
|
validateConditionalPresence(scene.templateId, gates.requiredAnyOf, scene.variables);
|
|
76
|
-
|
|
95
|
+
validateTemplateSceneStructure(schema, scene.variables);
|
|
77
96
|
const values = schemaValues(schema, scene.variables);
|
|
78
97
|
const allowedUrls = suppliedUrls(context.input);
|
|
79
98
|
const suppliedImageUrls = new Set((context.input.suppliedMedia ?? []).filter(({ type }) => type === "image").map(({ url }) => url));
|
|
@@ -93,6 +112,12 @@ function createTemplateSceneValidator(options) {
|
|
|
93
112
|
});
|
|
94
113
|
if (!permitted) throw new Error(`Template variable ${path} must use supplied media`);
|
|
95
114
|
}
|
|
115
|
+
if (gates.requiresStat) {
|
|
116
|
+
const quantities = values.filter(({ property }) => property.format === "grounded-stat");
|
|
117
|
+
if (!quantities.length || quantities.some(({ value }) => !containsSuppliedQuantity(context.input.input, value))) {
|
|
118
|
+
throw new Error(`Template ${scene.templateId} requires an exact supplied quantity, preserving its unit`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
96
121
|
if (gates.requiresQuote) {
|
|
97
122
|
const quoteValues = values.filter(({ property, value }) => property.format === "grounded-quote" && typeof value === "string" && value.trim()).map(({ value }) => String(value).trim());
|
|
98
123
|
if (!quoteValues.length || quoteValues.some((quote) => !context.input.input.includes(quote))) {
|
|
@@ -103,5 +128,6 @@ function createTemplateSceneValidator(options) {
|
|
|
103
128
|
}
|
|
104
129
|
|
|
105
130
|
export {
|
|
131
|
+
validateTemplateSceneStructure,
|
|
106
132
|
createTemplateSceneValidator
|
|
107
133
|
};
|
|
@@ -0,0 +1,564 @@
|
|
|
1
|
+
// src/visual-system/catalog/catalog.generated.ts
|
|
2
|
+
var GENERATED_BUILTIN_TEMPLATE_CATALOG = [
|
|
3
|
+
{
|
|
4
|
+
"label": "Full-bleed",
|
|
5
|
+
"description": "Immersive photo or video without a headline.",
|
|
6
|
+
"usesGlobalTextEffect": false,
|
|
7
|
+
"usesGlobalTransition": false,
|
|
8
|
+
"usesGlobalBackgroundEffect": false,
|
|
9
|
+
"textCanvas": "tight",
|
|
10
|
+
"id": "cinemaMedia",
|
|
11
|
+
"family": "Media & motion",
|
|
12
|
+
"jobs": [
|
|
13
|
+
"setup",
|
|
14
|
+
"atmosphere",
|
|
15
|
+
"payoff"
|
|
16
|
+
],
|
|
17
|
+
"register": "motion-led",
|
|
18
|
+
"useWhen": "Show a relevant place, activity or subject. The asset is resolved separately from a shot description. ",
|
|
19
|
+
"avoidWhen": "No relevant asset can be resolved or the scene needs structured explanation.",
|
|
20
|
+
"minDuration": 3,
|
|
21
|
+
"preferredDuration": 6,
|
|
22
|
+
"timing": {
|
|
23
|
+
"contentFields": [],
|
|
24
|
+
"contentUnit": "words",
|
|
25
|
+
"revealSeconds": 0,
|
|
26
|
+
"holdSeconds": 3,
|
|
27
|
+
"exitSeconds": 0
|
|
28
|
+
},
|
|
29
|
+
"schema": {
|
|
30
|
+
"type": "object",
|
|
31
|
+
"properties": {
|
|
32
|
+
"mediaKeyword": {
|
|
33
|
+
"type": "string",
|
|
34
|
+
"format": "stock-media-keyword",
|
|
35
|
+
"minLength": 1,
|
|
36
|
+
"maxLength": 80,
|
|
37
|
+
"description": "2\u20138 word literal subject/action search intent, maximum 80 characters. Host resolves URLs.",
|
|
38
|
+
"examples": [
|
|
39
|
+
"Ocean waves breaking on a rocky shore"
|
|
40
|
+
]
|
|
41
|
+
},
|
|
42
|
+
"mediaUrl": {
|
|
43
|
+
"type": "string",
|
|
44
|
+
"format": "uri",
|
|
45
|
+
"description": "Host-only approved photo or video URL.",
|
|
46
|
+
"default": ""
|
|
47
|
+
},
|
|
48
|
+
"mediaType": {
|
|
49
|
+
"type": "string",
|
|
50
|
+
"enum": [
|
|
51
|
+
"photo",
|
|
52
|
+
"video"
|
|
53
|
+
],
|
|
54
|
+
"default": "video",
|
|
55
|
+
"description": "Host-resolved asset kind."
|
|
56
|
+
},
|
|
57
|
+
"mediaPoster": {
|
|
58
|
+
"type": "string",
|
|
59
|
+
"format": "uri",
|
|
60
|
+
"description": "Host-only approved poster URL for video decoding.",
|
|
61
|
+
"default": ""
|
|
62
|
+
},
|
|
63
|
+
"shotDirection": {
|
|
64
|
+
"type": "string",
|
|
65
|
+
"maxLength": 220,
|
|
66
|
+
"description": "Optional action, framing and continuity for generation. Preserve the subject; do not request rendered text."
|
|
67
|
+
},
|
|
68
|
+
"mediaSource": {
|
|
69
|
+
"type": "string",
|
|
70
|
+
"enum": [
|
|
71
|
+
"generate",
|
|
72
|
+
"stock"
|
|
73
|
+
],
|
|
74
|
+
"description": "Generate distinctive illustrative shots; use approved stock for familiar observable subjects."
|
|
75
|
+
},
|
|
76
|
+
"fallbackText": {
|
|
77
|
+
"type": "string",
|
|
78
|
+
"maxLength": 65,
|
|
79
|
+
"description": "Optional grounded concise chapter text if this shot cannot be resolved; not visible over footage."
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
"required": [],
|
|
83
|
+
"additionalProperties": false,
|
|
84
|
+
"x-vanillasky": {
|
|
85
|
+
"allowsStockMedia": true,
|
|
86
|
+
"requiredAnyOf": [
|
|
87
|
+
[
|
|
88
|
+
"mediaKeyword",
|
|
89
|
+
"mediaUrl"
|
|
90
|
+
]
|
|
91
|
+
]
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"label": "Chapter",
|
|
97
|
+
"description": "Centered white typography fades in, holds, and fades out on black.",
|
|
98
|
+
"usesGlobalTextEffect": false,
|
|
99
|
+
"usesGlobalTransition": false,
|
|
100
|
+
"usesGlobalBackgroundEffect": false,
|
|
101
|
+
"textCanvas": "tight",
|
|
102
|
+
"id": "chapterTitle",
|
|
103
|
+
"family": "Explainers",
|
|
104
|
+
"jobs": [
|
|
105
|
+
"setup",
|
|
106
|
+
"payoff"
|
|
107
|
+
],
|
|
108
|
+
"register": "motion-led",
|
|
109
|
+
"useWhen": "An opening, new chapter or deliberate short takeaway needs its own visual beat. ",
|
|
110
|
+
"avoidWhen": "A headline would merely repeat subtitles over an ordinary footage scene.",
|
|
111
|
+
"minDuration": 3,
|
|
112
|
+
"preferredDuration": 4,
|
|
113
|
+
"timing": {
|
|
114
|
+
"contentFields": [
|
|
115
|
+
"title"
|
|
116
|
+
],
|
|
117
|
+
"contentUnit": "words",
|
|
118
|
+
"revealSeconds": 0.8,
|
|
119
|
+
"holdSeconds": 1.5,
|
|
120
|
+
"exitSeconds": 0.8
|
|
121
|
+
},
|
|
122
|
+
"schema": {
|
|
123
|
+
"type": "object",
|
|
124
|
+
"properties": {
|
|
125
|
+
"title": {
|
|
126
|
+
"type": "string",
|
|
127
|
+
"maxLength": 65,
|
|
128
|
+
"description": "Short title. Line breaks optional.",
|
|
129
|
+
"default": "A different perspective"
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
"required": [
|
|
133
|
+
"title"
|
|
134
|
+
],
|
|
135
|
+
"additionalProperties": false
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"label": "Focus cards",
|
|
140
|
+
"description": "Two to four short phrases fade in sequentially on black; no boxes or heading.",
|
|
141
|
+
"usesGlobalTextEffect": false,
|
|
142
|
+
"usesGlobalTransition": false,
|
|
143
|
+
"usesGlobalBackgroundEffect": false,
|
|
144
|
+
"textCanvas": "tight",
|
|
145
|
+
"id": "focusCards",
|
|
146
|
+
"family": "Explainers",
|
|
147
|
+
"jobs": [
|
|
148
|
+
"setup",
|
|
149
|
+
"proof"
|
|
150
|
+
],
|
|
151
|
+
"register": "card-led",
|
|
152
|
+
"useWhen": "Two to four short parallel points support an explanation. ",
|
|
153
|
+
"avoidWhen": "The points require an order, long paragraphs, numerical data or additional images to make sense.",
|
|
154
|
+
"minDuration": 4,
|
|
155
|
+
"preferredDuration": 5,
|
|
156
|
+
"timing": {
|
|
157
|
+
"contentFields": [
|
|
158
|
+
"items"
|
|
159
|
+
],
|
|
160
|
+
"contentUnit": "items",
|
|
161
|
+
"revealSeconds": 2.4,
|
|
162
|
+
"holdSeconds": 1.8,
|
|
163
|
+
"exitSeconds": 0
|
|
164
|
+
},
|
|
165
|
+
"schema": {
|
|
166
|
+
"type": "object",
|
|
167
|
+
"properties": {
|
|
168
|
+
"items": {
|
|
169
|
+
"type": "array",
|
|
170
|
+
"minItems": 2,
|
|
171
|
+
"maxItems": 4,
|
|
172
|
+
"items": {
|
|
173
|
+
"type": "string",
|
|
174
|
+
"minLength": 1,
|
|
175
|
+
"maxLength": 55
|
|
176
|
+
},
|
|
177
|
+
"default": [
|
|
178
|
+
"Listen closely",
|
|
179
|
+
"Notice the pattern",
|
|
180
|
+
"Make room for change"
|
|
181
|
+
],
|
|
182
|
+
"description": "2\u20134 parallel phrases, about 2\u20136 words each; no heading or numbering."
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
"required": [
|
|
186
|
+
"items"
|
|
187
|
+
],
|
|
188
|
+
"additionalProperties": false
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
"label": "Timeline",
|
|
193
|
+
"description": "Three to five events on a fine continuous line on black; without dates.",
|
|
194
|
+
"usesGlobalTextEffect": false,
|
|
195
|
+
"usesGlobalTransition": false,
|
|
196
|
+
"usesGlobalBackgroundEffect": false,
|
|
197
|
+
"textCanvas": "tight",
|
|
198
|
+
"id": "editorialTimeline",
|
|
199
|
+
"family": "Explainers",
|
|
200
|
+
"jobs": [
|
|
201
|
+
"setup",
|
|
202
|
+
"proof"
|
|
203
|
+
],
|
|
204
|
+
"register": "card-led",
|
|
205
|
+
"useWhen": "Events unfold in an order, or actions form a process. No dates or heading. ",
|
|
206
|
+
"avoidWhen": "The points are unordered or the story needs branching relationships.",
|
|
207
|
+
"minDuration": 5,
|
|
208
|
+
"preferredDuration": 6,
|
|
209
|
+
"timing": {
|
|
210
|
+
"contentFields": [
|
|
211
|
+
"events"
|
|
212
|
+
],
|
|
213
|
+
"contentUnit": "items",
|
|
214
|
+
"revealSeconds": 3.2,
|
|
215
|
+
"holdSeconds": 1.8,
|
|
216
|
+
"exitSeconds": 0
|
|
217
|
+
},
|
|
218
|
+
"schema": {
|
|
219
|
+
"type": "object",
|
|
220
|
+
"properties": {
|
|
221
|
+
"events": {
|
|
222
|
+
"type": "array",
|
|
223
|
+
"minItems": 3,
|
|
224
|
+
"maxItems": 5,
|
|
225
|
+
"items": {
|
|
226
|
+
"type": "object",
|
|
227
|
+
"properties": {
|
|
228
|
+
"label": {
|
|
229
|
+
"type": "string",
|
|
230
|
+
"minLength": 1,
|
|
231
|
+
"maxLength": 45
|
|
232
|
+
}
|
|
233
|
+
},
|
|
234
|
+
"required": [
|
|
235
|
+
"label"
|
|
236
|
+
],
|
|
237
|
+
"additionalProperties": false
|
|
238
|
+
},
|
|
239
|
+
"default": [
|
|
240
|
+
{
|
|
241
|
+
"label": "Observe"
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
"label": "Understand"
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
"label": "Act"
|
|
248
|
+
}
|
|
249
|
+
],
|
|
250
|
+
"description": "3\u20135 ordered events or actions, each with one short label; no dates."
|
|
251
|
+
}
|
|
252
|
+
},
|
|
253
|
+
"required": [
|
|
254
|
+
"events"
|
|
255
|
+
],
|
|
256
|
+
"additionalProperties": false
|
|
257
|
+
}
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
"label": "Reach out",
|
|
261
|
+
"description": "A frosted glass message over resolved media, without sender or timestamp.",
|
|
262
|
+
"usesGlobalTextEffect": false,
|
|
263
|
+
"usesGlobalTransition": false,
|
|
264
|
+
"usesGlobalBackgroundEffect": false,
|
|
265
|
+
"textCanvas": "tight",
|
|
266
|
+
"id": "mobileMessage",
|
|
267
|
+
"family": "Social & messaging",
|
|
268
|
+
"jobs": [
|
|
269
|
+
"setup"
|
|
270
|
+
],
|
|
271
|
+
"register": "card-led",
|
|
272
|
+
"useWhen": "A person or organization reaches out with a short message, alert or invitation. Message must be supplied or explicitly illustrative.",
|
|
273
|
+
"avoidWhen": "The scene is a generic fact, a long exchange, or a message that would fabricate evidence.",
|
|
274
|
+
"minDuration": 4,
|
|
275
|
+
"preferredDuration": 6,
|
|
276
|
+
"timing": {
|
|
277
|
+
"contentFields": [
|
|
278
|
+
"message",
|
|
279
|
+
"app"
|
|
280
|
+
],
|
|
281
|
+
"contentUnit": "words",
|
|
282
|
+
"revealSeconds": 1,
|
|
283
|
+
"holdSeconds": 2.2,
|
|
284
|
+
"exitSeconds": 0
|
|
285
|
+
},
|
|
286
|
+
"schema": {
|
|
287
|
+
"type": "object",
|
|
288
|
+
"properties": {
|
|
289
|
+
"mediaKeyword": {
|
|
290
|
+
"type": "string",
|
|
291
|
+
"format": "stock-media-keyword",
|
|
292
|
+
"minLength": 1,
|
|
293
|
+
"maxLength": 80,
|
|
294
|
+
"description": "2\u20138 word literal subject/action search intent, maximum 80 characters. Host resolves URLs.",
|
|
295
|
+
"examples": [
|
|
296
|
+
"Ocean waves breaking on a rocky shore"
|
|
297
|
+
]
|
|
298
|
+
},
|
|
299
|
+
"mediaUrl": {
|
|
300
|
+
"type": "string",
|
|
301
|
+
"format": "uri",
|
|
302
|
+
"description": "Host-only approved photo or video URL.",
|
|
303
|
+
"default": ""
|
|
304
|
+
},
|
|
305
|
+
"mediaType": {
|
|
306
|
+
"type": "string",
|
|
307
|
+
"enum": [
|
|
308
|
+
"photo",
|
|
309
|
+
"video"
|
|
310
|
+
],
|
|
311
|
+
"default": "video",
|
|
312
|
+
"description": "Host-resolved asset kind."
|
|
313
|
+
},
|
|
314
|
+
"mediaPoster": {
|
|
315
|
+
"type": "string",
|
|
316
|
+
"format": "uri",
|
|
317
|
+
"description": "Host-only approved poster URL for video decoding.",
|
|
318
|
+
"default": ""
|
|
319
|
+
},
|
|
320
|
+
"message": {
|
|
321
|
+
"type": "string",
|
|
322
|
+
"maxLength": 120,
|
|
323
|
+
"default": "Can we talk?",
|
|
324
|
+
"description": "Exact supplied or explicitly illustrative message, preferably 6\u201316 words."
|
|
325
|
+
},
|
|
326
|
+
"app": {
|
|
327
|
+
"type": "string",
|
|
328
|
+
"maxLength": 24,
|
|
329
|
+
"default": "Messages",
|
|
330
|
+
"description": "Optional app label; Messages is the visual default."
|
|
331
|
+
},
|
|
332
|
+
"shotDirection": {
|
|
333
|
+
"type": "string",
|
|
334
|
+
"maxLength": 220,
|
|
335
|
+
"description": "Optional action, framing and continuity for generation. Preserve the subject; do not request rendered text."
|
|
336
|
+
},
|
|
337
|
+
"mediaSource": {
|
|
338
|
+
"type": "string",
|
|
339
|
+
"enum": [
|
|
340
|
+
"generate",
|
|
341
|
+
"stock"
|
|
342
|
+
],
|
|
343
|
+
"description": "Generate distinctive illustrative shots; use approved stock for familiar observable subjects."
|
|
344
|
+
}
|
|
345
|
+
},
|
|
346
|
+
"required": [
|
|
347
|
+
"message"
|
|
348
|
+
],
|
|
349
|
+
"additionalProperties": false,
|
|
350
|
+
"x-vanillasky": {
|
|
351
|
+
"allowsStockMedia": true
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
},
|
|
355
|
+
{
|
|
356
|
+
"label": "Comparison",
|
|
357
|
+
"description": "Two short statements with equal weight on black, side by side or stacked in portrait.",
|
|
358
|
+
"usesGlobalTextEffect": false,
|
|
359
|
+
"usesGlobalTransition": false,
|
|
360
|
+
"usesGlobalBackgroundEffect": false,
|
|
361
|
+
"textCanvas": "tight",
|
|
362
|
+
"id": "comparison",
|
|
363
|
+
"family": "Explainers",
|
|
364
|
+
"jobs": [
|
|
365
|
+
"proof"
|
|
366
|
+
],
|
|
367
|
+
"register": "motion-led",
|
|
368
|
+
"useWhen": "Explain a before/after change or two alternatives with short parallel statements. ",
|
|
369
|
+
"avoidWhen": "There are more than two alternatives or a numerical chart is needed.",
|
|
370
|
+
"minDuration": 4,
|
|
371
|
+
"preferredDuration": 6,
|
|
372
|
+
"timing": {
|
|
373
|
+
"contentFields": [
|
|
374
|
+
"leftText",
|
|
375
|
+
"rightText",
|
|
376
|
+
"leftLabel",
|
|
377
|
+
"rightLabel"
|
|
378
|
+
],
|
|
379
|
+
"contentUnit": "words",
|
|
380
|
+
"revealSeconds": 1.2,
|
|
381
|
+
"holdSeconds": 2.5,
|
|
382
|
+
"exitSeconds": 0
|
|
383
|
+
},
|
|
384
|
+
"schema": {
|
|
385
|
+
"type": "object",
|
|
386
|
+
"properties": {
|
|
387
|
+
"leftLabel": {
|
|
388
|
+
"type": "string",
|
|
389
|
+
"maxLength": 20,
|
|
390
|
+
"description": "Optional short identifier for the first alternative."
|
|
391
|
+
},
|
|
392
|
+
"rightLabel": {
|
|
393
|
+
"type": "string",
|
|
394
|
+
"maxLength": 20,
|
|
395
|
+
"description": "Optional short identifier for the second alternative."
|
|
396
|
+
},
|
|
397
|
+
"leftText": {
|
|
398
|
+
"type": "string",
|
|
399
|
+
"minLength": 1,
|
|
400
|
+
"maxLength": 60,
|
|
401
|
+
"default": "More distractions",
|
|
402
|
+
"description": "First real alternative in one short phrase."
|
|
403
|
+
},
|
|
404
|
+
"rightText": {
|
|
405
|
+
"type": "string",
|
|
406
|
+
"minLength": 1,
|
|
407
|
+
"maxLength": 60,
|
|
408
|
+
"default": "More room to think",
|
|
409
|
+
"description": "Second real alternative, parallel to the first."
|
|
410
|
+
}
|
|
411
|
+
},
|
|
412
|
+
"required": [
|
|
413
|
+
"leftText",
|
|
414
|
+
"rightText"
|
|
415
|
+
],
|
|
416
|
+
"additionalProperties": false
|
|
417
|
+
}
|
|
418
|
+
},
|
|
419
|
+
{
|
|
420
|
+
"label": "Quote",
|
|
421
|
+
"description": "A short exact quotation with a legible attribution on black.",
|
|
422
|
+
"usesGlobalTextEffect": false,
|
|
423
|
+
"usesGlobalTransition": false,
|
|
424
|
+
"usesGlobalBackgroundEffect": false,
|
|
425
|
+
"textCanvas": "tight",
|
|
426
|
+
"id": "quote",
|
|
427
|
+
"family": "Explainers",
|
|
428
|
+
"jobs": [
|
|
429
|
+
"proof"
|
|
430
|
+
],
|
|
431
|
+
"register": "motion-led",
|
|
432
|
+
"useWhen": "A supplied quotation deserves its own moment. Use exact source words and attribution only.",
|
|
433
|
+
"avoidWhen": "No exact quotation or reliable attribution is supplied; never invent testimony.",
|
|
434
|
+
"minDuration": 5,
|
|
435
|
+
"preferredDuration": 7,
|
|
436
|
+
"timing": {
|
|
437
|
+
"contentFields": [
|
|
438
|
+
"quote",
|
|
439
|
+
"attribution"
|
|
440
|
+
],
|
|
441
|
+
"contentUnit": "words",
|
|
442
|
+
"revealSeconds": 1.2,
|
|
443
|
+
"holdSeconds": 3,
|
|
444
|
+
"exitSeconds": 0
|
|
445
|
+
},
|
|
446
|
+
"schema": {
|
|
447
|
+
"type": "object",
|
|
448
|
+
"properties": {
|
|
449
|
+
"quote": {
|
|
450
|
+
"type": "string",
|
|
451
|
+
"minLength": 1,
|
|
452
|
+
"maxLength": 140,
|
|
453
|
+
"format": "grounded-quote",
|
|
454
|
+
"examples": [
|
|
455
|
+
"Look closely. There is always more to see."
|
|
456
|
+
],
|
|
457
|
+
"description": "Exact supplied quotation; do not paraphrase or invent."
|
|
458
|
+
},
|
|
459
|
+
"attribution": {
|
|
460
|
+
"type": "string",
|
|
461
|
+
"minLength": 1,
|
|
462
|
+
"maxLength": 60,
|
|
463
|
+
"examples": [
|
|
464
|
+
"Illustrative example"
|
|
465
|
+
],
|
|
466
|
+
"description": "Grounded attribution belonging to these exact quoted words."
|
|
467
|
+
}
|
|
468
|
+
},
|
|
469
|
+
"required": [
|
|
470
|
+
"quote",
|
|
471
|
+
"attribution"
|
|
472
|
+
],
|
|
473
|
+
"additionalProperties": false
|
|
474
|
+
}
|
|
475
|
+
},
|
|
476
|
+
{
|
|
477
|
+
"label": "Key figure",
|
|
478
|
+
"description": "One supplied figure with one short label on black.",
|
|
479
|
+
"usesGlobalTextEffect": false,
|
|
480
|
+
"usesGlobalTransition": false,
|
|
481
|
+
"usesGlobalBackgroundEffect": false,
|
|
482
|
+
"textCanvas": "tight",
|
|
483
|
+
"id": "keyFigure",
|
|
484
|
+
"family": "Explainers",
|
|
485
|
+
"jobs": [
|
|
486
|
+
"proof"
|
|
487
|
+
],
|
|
488
|
+
"register": "motion-led",
|
|
489
|
+
"useWhen": "One verified quantity or supplied target anchors the explanation. Value, unit and context must match supplied evidence.",
|
|
490
|
+
"avoidWhen": "No reliable figure is supplied or multiple values require a chart.",
|
|
491
|
+
"minDuration": 4,
|
|
492
|
+
"preferredDuration": 5,
|
|
493
|
+
"timing": {
|
|
494
|
+
"contentFields": [
|
|
495
|
+
"value",
|
|
496
|
+
"label"
|
|
497
|
+
],
|
|
498
|
+
"contentUnit": "words",
|
|
499
|
+
"revealSeconds": 0.8,
|
|
500
|
+
"holdSeconds": 2.5,
|
|
501
|
+
"exitSeconds": 0
|
|
502
|
+
},
|
|
503
|
+
"schema": {
|
|
504
|
+
"type": "object",
|
|
505
|
+
"properties": {
|
|
506
|
+
"value": {
|
|
507
|
+
"type": "string",
|
|
508
|
+
"minLength": 1,
|
|
509
|
+
"maxLength": 14,
|
|
510
|
+
"format": "grounded-stat",
|
|
511
|
+
"examples": [
|
|
512
|
+
"42%"
|
|
513
|
+
],
|
|
514
|
+
"description": "One supplied supported quantity, preserving its unit."
|
|
515
|
+
},
|
|
516
|
+
"label": {
|
|
517
|
+
"type": "string",
|
|
518
|
+
"minLength": 1,
|
|
519
|
+
"maxLength": 50,
|
|
520
|
+
"examples": [
|
|
521
|
+
"Illustrative example"
|
|
522
|
+
],
|
|
523
|
+
"description": "Exactly one short label identifying the quantity and its context."
|
|
524
|
+
}
|
|
525
|
+
},
|
|
526
|
+
"required": [
|
|
527
|
+
"value",
|
|
528
|
+
"label"
|
|
529
|
+
],
|
|
530
|
+
"additionalProperties": false,
|
|
531
|
+
"x-vanillasky": {
|
|
532
|
+
"requiresStat": true
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
];
|
|
537
|
+
|
|
538
|
+
// src/visual-system/catalog/builtin-metadata.ts
|
|
539
|
+
function freezeValue(value) {
|
|
540
|
+
if (value && typeof value === "object" && !Object.isFrozen(value)) {
|
|
541
|
+
for (const nested of Object.values(value)) freezeValue(nested);
|
|
542
|
+
Object.freeze(value);
|
|
543
|
+
}
|
|
544
|
+
return value;
|
|
545
|
+
}
|
|
546
|
+
var BUILTIN_TEMPLATE_CATALOG = freezeValue(
|
|
547
|
+
[...GENERATED_BUILTIN_TEMPLATE_CATALOG]
|
|
548
|
+
);
|
|
549
|
+
var metadataById = new Map(BUILTIN_TEMPLATE_CATALOG.map((template) => [template.id, template]));
|
|
550
|
+
var BUILTIN_TEMPLATE_CAPABILITIES = freezeValue({
|
|
551
|
+
templates: BUILTIN_TEMPLATE_CATALOG.map(({ id }) => id).sort()
|
|
552
|
+
});
|
|
553
|
+
function listBuiltinTemplateMetadata() {
|
|
554
|
+
return BUILTIN_TEMPLATE_CATALOG;
|
|
555
|
+
}
|
|
556
|
+
function getBuiltinTemplateMetadata(id) {
|
|
557
|
+
return metadataById.get(id);
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
export {
|
|
561
|
+
BUILTIN_TEMPLATE_CATALOG,
|
|
562
|
+
listBuiltinTemplateMetadata,
|
|
563
|
+
getBuiltinTemplateMetadata
|
|
564
|
+
};
|