stillmade-sdk 0.1.41 → 0.1.43

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 (285) hide show
  1. package/.stillmade/sdk-baseline.json +19 -21
  2. package/AGENTS.md +17 -12
  3. package/FRAME_VIEWS.md +113 -0
  4. package/INTERFACE_DESIGN.md +67 -22
  5. package/MOBILE_UI.md +4 -2
  6. package/MODULES.md +152 -6
  7. package/PASTE_TO_LLM.md +42 -32
  8. package/README.md +3 -2
  9. package/SDK.md +1028 -563
  10. package/UI_AESTHETIC.md +30 -3
  11. package/blocks/generate/package.js +1 -0
  12. package/blocks/generate/versions/1.0.0/package.js +463 -0
  13. package/docs/build/audio-to-editor.md +36 -0
  14. package/docs/build/block-builder-contract.md +150 -0
  15. package/docs/build/comfyui.md +227 -0
  16. package/docs/build/concepts.md +40 -0
  17. package/docs/build/context.md +159 -0
  18. package/docs/build/cookbook.md +57 -0
  19. package/docs/build/custom-interface.md +617 -0
  20. package/docs/build/data-types.md +83 -0
  21. package/docs/build/frame-views.md +259 -0
  22. package/docs/build/generate-media.md +59 -0
  23. package/docs/build/github-applications.md +314 -0
  24. package/docs/build/hosted-images.md +214 -0
  25. package/docs/build/hosted-music.md +39 -0
  26. package/docs/build/hosted-speech.md +157 -0
  27. package/docs/build/hosted-text.md +246 -0
  28. package/docs/build/image-description.md +49 -0
  29. package/docs/build/interface-design.md +343 -0
  30. package/docs/build/javascript.md +63 -0
  31. package/docs/build/local-preview.md +61 -0
  32. package/docs/build/media-analysis.md +27 -0
  33. package/docs/build/media.md +400 -0
  34. package/docs/build/mobile-ui.md +106 -0
  35. package/docs/build/modules.md +487 -0
  36. package/docs/build/original-blocks.md +70 -0
  37. package/docs/build/outside-apis.md +128 -0
  38. package/docs/build/production-context-templates.md +12 -0
  39. package/docs/build/project-storage.md +94 -0
  40. package/docs/build/quickstart.md +48 -0
  41. package/docs/build/recipes.md +103 -0
  42. package/docs/build/script-handoff.md +45 -0
  43. package/docs/build/script-writer.md +34 -0
  44. package/docs/build/state.md +223 -0
  45. package/docs/build/testing.md +112 -0
  46. package/docs/build/timeline-edits.md +116 -0
  47. package/docs/build/timeline-proposals.md +76 -0
  48. package/docs/build/transcription.md +59 -0
  49. package/docs/build/triggers.md +59 -0
  50. package/docs/build/tutorial.md +52 -0
  51. package/docs/build/typescript.md +34 -0
  52. package/docs/build/video-generation.md +61 -0
  53. package/docs/build/web-reading.md +37 -0
  54. package/docs/build/with-your-ai.md +27 -0
  55. package/docs/changelog.md +9 -0
  56. package/docs/creators.md +21 -0
  57. package/docs/distribute/discovery.md +43 -0
  58. package/docs/distribute/imports.md +58 -0
  59. package/docs/distribute/publishing.md +29 -0
  60. package/docs/distribute/sdk-versions.md +36 -0
  61. package/docs/distribute/selling.md +14 -0
  62. package/docs/distribute/teams.md +60 -0
  63. package/docs/distribute/versioning.md +28 -0
  64. package/docs/examples.md +23 -0
  65. package/docs/gallery.md +26 -0
  66. package/docs/index.md +50 -0
  67. package/docs/native-mcp.md +307 -0
  68. package/docs/project-types/automation.md +43 -0
  69. package/docs/project-types/batches.md +50 -0
  70. package/docs/project-types/build.md +42 -0
  71. package/docs/project-types/completion.md +15 -0
  72. package/docs/project-types/conditions.md +21 -0
  73. package/docs/project-types/hosted-review.md +115 -0
  74. package/docs/project-types/onboarding.md +75 -0
  75. package/docs/project-types/running.md +309 -0
  76. package/docs/project-types/testing.md +72 -0
  77. package/docs/reference/application-artifacts.md +87 -0
  78. package/docs/reference/authoring-guide.md +134 -0
  79. package/docs/reference/browser-applications.md +267 -0
  80. package/docs/reference/capabilities.md +45 -0
  81. package/docs/reference/cli.md +71 -0
  82. package/docs/reference/connection-api.md +59 -0
  83. package/docs/reference/cooperative-jobs.md +13 -0
  84. package/docs/reference/desktop-capabilities.md +172 -0
  85. package/docs/reference/desktop-execution.md +77 -0
  86. package/docs/reference/errors.md +233 -0
  87. package/docs/reference/execution.md +800 -0
  88. package/docs/reference/first-party-blocks.md +40 -0
  89. package/docs/reference/generation-models.md +59 -0
  90. package/docs/reference/limits.md +306 -0
  91. package/docs/reference/manifest-kinds-controls.md +36 -0
  92. package/docs/reference/manifest.md +181 -0
  93. package/docs/reference/operations.md +36 -0
  94. package/docs/reference/package-jobs.md +35 -0
  95. package/docs/reference/parity.md +55 -0
  96. package/docs/reference/permissions.md +86 -0
  97. package/docs/reference/ports.md +26 -0
  98. package/docs/reference/types.md +268 -0
  99. package/docs/reference/universal-resolver.md +303 -0
  100. package/docs/reference/view-bridge.md +60 -0
  101. package/docs/reference/view-rules.md +15 -0
  102. package/docs/reference/workspace-sync.md +25 -0
  103. package/docs/sdk.md +34 -0
  104. package/docs/tools/block-remix.md +211 -0
  105. package/docs/tools/llm.md +2213 -0
  106. package/docs/tools/repository-adaptation.md +613 -0
  107. package/examples/check-clip.stillmade.json +8 -1
  108. package/examples/clean-text.stillmade.json +4 -0
  109. package/examples/custom-interface.stillmade.json +4 -0
  110. package/examples/describe-image.stillmade.json +4 -0
  111. package/examples/foley-cue.stillmade.json +4 -0
  112. package/examples/generate-image.stillmade.json +4 -0
  113. package/examples/generate-video.stillmade.json +10 -2
  114. package/examples/module-word-stats/stillmade.block.json +4 -0
  115. package/examples/narrate-script.stillmade.json +4 -0
  116. package/examples/numbered-takes.stillmade.json +4 -0
  117. package/examples/research-topic.stillmade.json +9 -1
  118. package/examples/score-a-scene.stillmade.json +4 -0
  119. package/examples/script-draft.stillmade.json +4 -0
  120. package/examples/summarize-page.stillmade.json +4 -0
  121. package/examples/text-workflow.stillmade.json +7 -32
  122. package/examples/thicken-lines.stillmade.json +4 -0
  123. package/examples/timeline-polish.stillmade.json +15 -3
  124. package/examples/transcribe-audio.stillmade.json +15 -3
  125. package/examples/word-count.stillmade.json +4 -0
  126. package/package.json +1 -1
  127. package/packages/block-cli/cli.js +13 -6
  128. package/packages/block-cli/dev-host/assets/host.js +81 -38
  129. package/packages/block-cli/dev-host/assets/index.css +1 -1
  130. package/packages/block-cli/format.js +1 -1
  131. package/packages/block-cli/ready-gate.js +4 -0
  132. package/packages/block-cli/templates.js +37 -19
  133. package/packages/block-cli/type-packages.js +119 -0
  134. package/packages/block-platform/block-readiness.js +8 -1
  135. package/packages/block-platform/canvas.js +2 -1
  136. package/packages/block-platform/catalog.js +27 -48
  137. package/packages/block-platform/native-host-inventory.js +0 -226
  138. package/packages/block-platform/plain-descriptions.js +1 -25
  139. package/packages/block-platform/project-type-starters.js +13 -53
  140. package/packages/block-platform/script-handoff.js +2 -4
  141. package/packages/block-platform/type-workspace.js +2 -0
  142. package/packages/block-sdk/appearance.js +3 -1
  143. package/packages/block-sdk/audio-generation-example.js +2 -2
  144. package/packages/block-sdk/block-tier.js +1 -1
  145. package/packages/block-sdk/builder-contract.js +13 -11
  146. package/packages/block-sdk/capabilities.js +1 -1
  147. package/packages/block-sdk/capability-example.js +1 -1
  148. package/packages/block-sdk/contracts.js +6 -2
  149. package/packages/block-sdk/examples.js +3 -3
  150. package/packages/block-sdk/first-party-identities.js +1 -84
  151. package/packages/block-sdk/first-party-packages.js +3 -85
  152. package/packages/block-sdk/generation-catalog.js +15 -3
  153. package/packages/block-sdk/image-description-example.js +1 -1
  154. package/packages/block-sdk/image-generation-example.js +1 -1
  155. package/packages/block-sdk/index.d.ts +2 -1
  156. package/packages/block-sdk/media-analysis-example.js +2 -2
  157. package/packages/block-sdk/mock-host.js +7 -1
  158. package/packages/block-sdk/module-example.js +1 -1
  159. package/packages/block-sdk/module-host-calls.js +35 -10
  160. package/packages/block-sdk/module-hosted.js +15 -2
  161. package/packages/block-sdk/module-media-access.js +71 -0
  162. package/packages/block-sdk/module-node.js +1 -1
  163. package/packages/block-sdk/portable-media-actions.js +1 -1
  164. package/packages/block-sdk/runtime.js +1 -1
  165. package/packages/block-sdk/speech-example.js +1 -1
  166. package/packages/block-sdk/state-example.js +1 -1
  167. package/packages/block-sdk/timeline-proposal-example.js +1 -1
  168. package/packages/block-sdk/transcription-example.js +1 -1
  169. package/packages/block-sdk/trigger-examples.js +2 -2
  170. package/packages/block-sdk/video-generation-example.js +1 -1
  171. package/packages/block-sdk/view-bridge.js +4 -1
  172. package/packages/block-sdk/view-design.js +44 -15
  173. package/packages/block-sdk/web-example.js +2 -2
  174. package/packages/design-system/block-kit.css +53 -12
  175. package/packages/design-system/block-kit.html +3 -2
  176. package/blocks/mcp-motion-planner/versions/1.1.0/package.js +0 -97
  177. package/blocks/motion-designer/versions/1.0.1/package.js +0 -173318
  178. package/blocks/motion-designer/versions/1.0.2/package.js +0 -173318
  179. package/blocks/motion-frame-review/versions/1.1.1/package.js +0 -465
  180. package/blocks/motion-frame-review/versions/1.1.2/package.snapshot.js +0 -572
  181. package/blocks/narration/package.js +0 -1
  182. package/blocks/narration/versions/1.0.0/package.js +0 -221
  183. package/blocks/narration/versions/1.0.1/package.js +0 -221
  184. package/blocks/native/sm.animated-scene/versions/2.0.0/package.js +0 -475
  185. package/blocks/native/sm.animated-scene/versions/2.1.0/package.js +0 -498
  186. package/blocks/native/sm.animated-scene/versions/2.2.0/package.js +0 -524
  187. package/blocks/native/sm.animated-scene/versions/2.3.0/package.js +0 -618
  188. package/blocks/native/sm.animated-scene/versions/2.3.1/package.js +0 -618
  189. package/blocks/native/sm.animated-scene/versions/2.3.2/package.js +0 -723
  190. package/blocks/native/sm.animated-scene/versions/2.3.3/package.js +0 -723
  191. package/blocks/native/sm.animated-scene/versions/2.3.4/package.js +0 -676
  192. package/blocks/native/sm.animated-scene/versions/2.3.5/package.js +0 -693
  193. package/blocks/native/sm.animated-scene/versions/2.3.6/package.js +0 -700
  194. package/blocks/native/sm.animated-scene/versions/2.3.7/package.js +0 -747
  195. package/blocks/native/sm.animated-scene/versions/2.3.8/package.js +0 -769
  196. package/blocks/native/sm.animated-scene/versions/2.3.9/package.js +0 -769
  197. package/blocks/native/sm.animated-scene-assistant/versions/1.0.0/package.js +0 -183
  198. package/blocks/native/sm.blueprint/versions/2.0.0/package.js +0 -358
  199. package/blocks/native/sm.blueprint/versions/2.1.0/package.js +0 -358
  200. package/blocks/native/sm.blueprint/versions/2.1.1/package.js +0 -358
  201. package/blocks/native/sm.blueprint/versions/2.1.2/package.js +0 -358
  202. package/blocks/native/sm.blueprint/versions/2.1.3/package.js +0 -381
  203. package/blocks/native/sm.blueprint/versions/2.1.4/package.js +0 -381
  204. package/blocks/native/sm.blueprint/versions/2.1.5/package.js +0 -339
  205. package/blocks/native/sm.blueprint/versions/2.1.6/package.js +0 -356
  206. package/blocks/native/sm.blueprint/versions/2.1.7/package.js +0 -363
  207. package/blocks/native/sm.blueprint/versions/2.1.8/package.js +0 -410
  208. package/blocks/native/sm.blueprint/versions/2.1.9/package.js +0 -422
  209. package/blocks/native/sm.blueprint-assistant/versions/1.0.0/package.js +0 -172
  210. package/blocks/native/sm.chat/versions/2.0.0/package.js +0 -144
  211. package/blocks/native/sm.chat/versions/2.0.1/package.js +0 -97
  212. package/blocks/native/sm.chat/versions/2.0.2/package.js +0 -100
  213. package/blocks/native/sm.chat/versions/2.0.3/package.js +0 -100
  214. package/blocks/native/sm.continue-if/versions/1.0.0/package.js +0 -168
  215. package/blocks/native/sm.describe-media/versions/2.0.0/package.js +0 -153
  216. package/blocks/native/sm.describe-media/versions/2.0.1/package.js +0 -156
  217. package/blocks/native/sm.describe-media/versions/2.1.0/package.js +0 -140
  218. package/blocks/native/sm.image-editor/versions/2.0.0/package.js +0 -183
  219. package/blocks/native/sm.image-editor/versions/2.0.1/package.js +0 -190
  220. package/blocks/native/sm.new-items/versions/1.0.0/package.js +0 -191
  221. package/blocks/native/sm.pick-photos/versions/1.0.0/package.js +0 -334
  222. package/blocks/native/sm.quality-audit/versions/1.0.0/package.js +0 -192
  223. package/blocks/native/sm.quality-audit/versions/1.0.1/package.js +0 -192
  224. package/blocks/native/sm.quality-audit/versions/1.0.2/package.js +0 -195
  225. package/blocks/native/sm.research/versions/2.0.0/package.js +0 -175
  226. package/blocks/native/sm.research/versions/2.0.1/package.js +0 -184
  227. package/blocks/native/sm.research/versions/2.0.2/package.js +0 -187
  228. package/blocks/native/sm.script/versions/2.0.0/package.js +0 -144
  229. package/blocks/native/sm.script/versions/2.1.0/package.js +0 -144
  230. package/blocks/native/sm.script/versions/2.1.1/package.js +0 -144
  231. package/blocks/native/sm.script/versions/2.1.2/package.js +0 -105
  232. package/blocks/native/sm.script/versions/2.1.3/package.js +0 -152
  233. package/blocks/native/sm.script/versions/2.1.4/package.js +0 -156
  234. package/blocks/native/sm.script/versions/2.1.5/package.js +0 -156
  235. package/blocks/native/sm.shot-plan/versions/2.0.0/package.js +0 -301
  236. package/blocks/native/sm.shot-plan/versions/2.1.0/package.js +0 -528
  237. package/blocks/native/sm.shot-plan/versions/2.1.1/package.js +0 -528
  238. package/blocks/native/sm.shot-plan/versions/2.1.2/package.js +0 -528
  239. package/blocks/native/sm.shot-plan/versions/2.1.3/package.js +0 -536
  240. package/blocks/native/sm.shot-plan/versions/2.2.0/package.js +0 -800
  241. package/blocks/native/sm.shot-plan/versions/2.2.1/package.js +0 -920
  242. package/blocks/native/sm.shot-plan-assistant/versions/1.0.0/package.js +0 -173
  243. package/blocks/native/sm.stock-search/versions/2.0.0/package.js +0 -174
  244. package/blocks/native/sm.thumbnail/versions/2.0.0/package.js +0 -137
  245. package/blocks/native/sm.thumbnail/versions/2.0.1/package.js +0 -140
  246. package/blocks/native/sm.transcribe/versions/2.0.0/package.js +0 -163
  247. package/blocks/native/sm.transcribe/versions/2.0.1/package.js +0 -168
  248. package/blocks/native/sm.whiteboard-assistant/versions/1.0.0/package.js +0 -175
  249. package/blocks/native/sm.youtube/versions/2.0.0/package.js +0 -217
  250. package/blocks/occasion-story/package.js +0 -1
  251. package/blocks/occasion-story/versions/1.0.0/package.js +0 -1658
  252. package/blocks/occasion-story/versions/1.0.1/package.js +0 -1699
  253. package/blocks/occasion-story/versions/1.0.2/package.js +0 -1682
  254. package/blocks/photo-reel-composer/versions/1.0.0/package.js +0 -3043
  255. package/blocks/photo-reel-composer/versions/1.0.1/package.js +0 -3026
  256. package/blocks/photo-reel-composer/versions/1.0.2/package.js +0 -4149
  257. package/blocks/product-ad-variants/versions/1.0.0/package.js +0 -2911
  258. package/blocks/product-launch-director/versions/1.0.0/package.js +0 -103
  259. package/blocks/release-visuals/package.js +0 -1
  260. package/blocks/release-visuals/versions/1.0.0/package.js +0 -1492
  261. package/blocks/release-visuals/versions/1.0.1/package.js +0 -1517
  262. package/blocks/release-visuals/versions/1.0.2/package.js +0 -1500
  263. package/blocks/screen-recorder/package.js +0 -1
  264. package/blocks/screen-recorder/versions/1.0.0/package.js +0 -223
  265. package/blocks/screen-recorder/versions/1.0.1/package.js +0 -223
  266. package/blocks/short-form-finish/package.js +0 -1
  267. package/blocks/short-form-finish/versions/1.0.0/package.js +0 -1043
  268. package/blocks/short-form-finish/versions/1.0.1/package.js +0 -1043
  269. package/blocks/short-form-finish/versions/1.0.2/package.js +0 -1043
  270. package/blocks/short-form-finish/versions/1.0.3/package.js +0 -1026
  271. package/examples/saas-product-launch-reviewed-source.stillmade.json +0 -383
  272. package/examples/saas-product-launch.stillmade.json +0 -304
  273. package/packages/block-platform/dealer-inventory-video-project-type.js +0 -38
  274. package/packages/block-platform/first-revenue-project-types.js +0 -46
  275. package/packages/block-platform/fixture-starters.js +0 -13
  276. package/packages/block-platform/launch-project-source.js +0 -10
  277. package/packages/block-platform/launch-project.js +0 -30
  278. package/packages/block-platform/motion-project-types.js +0 -55
  279. package/packages/block-platform/motion-starters.js +0 -14
  280. package/packages/block-platform/product-ad-variants-project-type.js +0 -30
  281. package/packages/block-platform/product-launch-updated.js +0 -90
  282. package/packages/block-platform/revenue-review-project-types.js +0 -36
  283. package/packages/block-platform/revenue-review-starters.js +0 -13
  284. package/packages/block-platform/script-writer.js +0 -29
  285. package/packages/block-platform/website-source-block.js +0 -14
@@ -1,1682 +0,0 @@
1
- // Generated from independently owned versioned source.
2
- export default {
3
- "manifest": {
4
- "schemaVersion": 1,
5
- "sdkVersion": "0.1.0",
6
- "id": "stillmade.occasion-story",
7
- "version": "1.0.2",
8
- "name": "Occasion Story",
9
- "description": "Arrange already-collected photos and video messages into an editable birthday, anniversary or farewell story, preserving source sound.",
10
- "kind": "task",
11
- "runtime": "javascript",
12
- "entry": "src/run.js",
13
- "license": "MIT",
14
- "inputs": {
15
- "assets": {
16
- "type": "asset[]",
17
- "default": [],
18
- "description": "3–24 ordered original photos or video messages.",
19
- "primary": true,
20
- "required": true,
21
- "semantic": "legacy.asset-list.assets",
22
- "sources": [
23
- "upstream",
24
- "user"
25
- ]
26
- },
27
- "occasion": {
28
- "type": "text",
29
- "default": "birthday",
30
- "description": "The occasion for this story.",
31
- "semantic": "stillmade.occasion_story.occasion",
32
- "sources": [
33
- "user",
34
- "default"
35
- ],
36
- "required": false
37
- },
38
- "title": {
39
- "type": "text",
40
- "default": "",
41
- "description": "Exact opening dedication, up to 64 characters.",
42
- "required": true,
43
- "semantic": "stillmade.occasion_story.title",
44
- "sources": [
45
- "user",
46
- "default"
47
- ]
48
- },
49
- "ending": {
50
- "type": "text",
51
- "default": "",
52
- "description": "Exact closing dedication, up to 100 characters.",
53
- "required": true,
54
- "semantic": "stillmade.occasion_story.ending",
55
- "sources": [
56
- "user",
57
- "default"
58
- ]
59
- },
60
- "notes": {
61
- "type": "text",
62
- "default": "",
63
- "description": "One short memory or speaker label per item, one line each. Blank lines omit labels.",
64
- "semantic": "stillmade.occasion_story.notes",
65
- "sources": [
66
- "user",
67
- "default"
68
- ],
69
- "required": false
70
- },
71
- "selections": {
72
- "type": "text",
73
- "default": "",
74
- "description": "Optional one line per item: seconds for photos (4), source start-end for messages (2-12).",
75
- "semantic": "stillmade.occasion_story.selections",
76
- "sources": [
77
- "user",
78
- "default"
79
- ],
80
- "required": false
81
- },
82
- "music": {
83
- "type": "audio[]",
84
- "default": [],
85
- "description": "Optional single rights-cleared soundtrack covering the full story.",
86
- "semantic": "stillmade.occasion_story.music",
87
- "sources": [
88
- "user",
89
- "default"
90
- ],
91
- "required": false
92
- },
93
- "musicVolume": {
94
- "type": "number",
95
- "default": 32,
96
- "description": "Soundtrack volume, 0–100. Music stays lower under preserved video sound.",
97
- "min": 0,
98
- "max": 100,
99
- "semantic": "stillmade.occasion_story.musicvolume",
100
- "sources": [
101
- "user",
102
- "default"
103
- ],
104
- "required": false
105
- },
106
- "muteVideoAudio": {
107
- "type": "boolean",
108
- "default": false,
109
- "description": "Mute ALL video sound. Leave off for spoken messages; use only for silent decorative footage.",
110
- "semantic": "stillmade.occasion_story.mutevideoaudio",
111
- "sources": [
112
- "user",
113
- "default"
114
- ],
115
- "required": false
116
- },
117
- "aspect": {
118
- "type": "text",
119
- "default": "16:9",
120
- "description": "Output frame shape.",
121
- "semantic": "stillmade.occasion_story.aspect",
122
- "sources": [
123
- "user",
124
- "default"
125
- ],
126
- "required": false
127
- },
128
- "disclosure": {
129
- "type": "text",
130
- "default": "",
131
- "description": "Optional source or demonstration disclosure.",
132
- "semantic": "stillmade.occasion_story.disclosure",
133
- "sources": [
134
- "user",
135
- "default"
136
- ],
137
- "required": false
138
- }
139
- },
140
- "outputs": {
141
- "timeline": {
142
- "type": "timeline",
143
- "primary": true,
144
- "semantic": "legacy.timeline.updatededitor",
145
- "description": "Complete editable timeline using original source media."
146
- },
147
- "review": {
148
- "type": "json",
149
- "semantic": "stillmade.occasion_story.review",
150
- "description": "Production scope and remaining human review.",
151
- "schema": {
152
- "schemaVersion": "integer",
153
- "state": "string",
154
- "humanApproved": "boolean",
155
- "occasion": "string",
156
- "durationSec": "number",
157
- "itemCount": "integer",
158
- "messageCount": "integer",
159
- "providerCalls": "integer",
160
- "warnings": "string[]"
161
- }
162
- }
163
- },
164
- "permissions": {
165
- "project": [
166
- "asset.read"
167
- ],
168
- "network": [],
169
- "filesystem": [],
170
- "secrets": []
171
- },
172
- "ui": [
173
- {
174
- "port": "musicVolume",
175
- "control": "slider",
176
- "min": 0,
177
- "max": 100,
178
- "step": 1
179
- },
180
- {
181
- "port": "occasion",
182
- "control": "select",
183
- "options": [
184
- "birthday",
185
- "anniversary",
186
- "farewell"
187
- ]
188
- },
189
- {
190
- "port": "aspect",
191
- "control": "select",
192
- "options": [
193
- "9:16",
194
- "16:9",
195
- "1:1"
196
- ]
197
- }
198
- ],
199
- "platforms": {
200
- "phone": {
201
- "supported": true
202
- },
203
- "browser": {
204
- "supported": true
205
- },
206
- "desktop": {
207
- "supported": true
208
- }
209
- },
210
- "provenance": {
211
- "notice": "Original source (authorship declared by the packager)\nLicense: MIT\nChanges: Original implementation declared by the packager; no reused repository or dependency code.\nFiles: LICENSE, src/run.js\n\nMIT License\n\nCopyright (c) <year> <copyright holders>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and \nassociated documentation files (the \"Software\"), to deal in the Software without restriction, including \nwithout limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell \ncopies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the \nfollowing conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial \nportions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT \nLIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO \nEVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER \nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE \nUSE OR OTHER DEALINGS IN THE SOFTWARE.\n",
212
- "portableSources": [
213
- {
214
- "kind": "original",
215
- "license": "MIT",
216
- "paths": [
217
- "LICENSE",
218
- "src/run.js"
219
- ],
220
- "evidence": [
221
- "upstream/0/LICENSE",
222
- "upstream/0/src/run.js"
223
- ],
224
- "changes": "Original implementation declared by the packager; no reused repository or dependency code."
225
- }
226
- ]
227
- },
228
- "semantics": [
229
- {
230
- "name": "stillmade.occasion_story.occasion",
231
- "description": "The occasion for this story.",
232
- "parents": []
233
- },
234
- {
235
- "name": "stillmade.occasion_story.title",
236
- "description": "Exact opening dedication, up to 64 characters.",
237
- "parents": []
238
- },
239
- {
240
- "name": "stillmade.occasion_story.ending",
241
- "description": "Exact closing dedication, up to 100 characters.",
242
- "parents": []
243
- },
244
- {
245
- "name": "stillmade.occasion_story.notes",
246
- "description": "One short memory or speaker label per item, one line each. Blank lines omit labels.",
247
- "parents": []
248
- },
249
- {
250
- "name": "stillmade.occasion_story.selections",
251
- "description": "Optional one line per item: seconds for photos (4), source start-end for messages (2-12).",
252
- "parents": []
253
- },
254
- {
255
- "name": "stillmade.occasion_story.music",
256
- "description": "Optional single rights-cleared soundtrack covering the full story.",
257
- "parents": []
258
- },
259
- {
260
- "name": "stillmade.occasion_story.musicvolume",
261
- "description": "Soundtrack volume, 0–100. Music stays lower under preserved video sound.",
262
- "parents": []
263
- },
264
- {
265
- "name": "stillmade.occasion_story.mutevideoaudio",
266
- "description": "Mute ALL video sound. Leave off for spoken messages; use only for silent decorative footage.",
267
- "parents": []
268
- },
269
- {
270
- "name": "stillmade.occasion_story.aspect",
271
- "description": "Output frame shape.",
272
- "parents": []
273
- },
274
- {
275
- "name": "stillmade.occasion_story.disclosure",
276
- "description": "Optional source or demonstration disclosure.",
277
- "parents": []
278
- },
279
- {
280
- "name": "stillmade.occasion_story.review",
281
- "description": "Production scope and remaining human review.",
282
- "parents": []
283
- }
284
- ]
285
- },
286
- "code": "// Original occasion-story assembly. Runs entirely in the JavaScript sandbox.\nconst copy=value=>JSON.parse(JSON.stringify(value));\nconst check=(ok,message)=>{if(!ok)throw Error(message);};\nconst round=n=>Math.round(n*1000000)/1000000;\nconst short=(value,label,max=80)=>{check(typeof value==='string'&&value.length<=max&&!/[\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]/.test(value),label+' must be short plain text.');return value.trim();};\n\nconst musicVolume=input.musicVolume??32,muteVideoAudio=input.muteVideoAudio??false;\ncheck(Number.isFinite(musicVolume)&&musicVolume>=0&&musicVolume<=100,'Music volume must be 0–100.');check(typeof muteVideoAudio==='boolean','Choose whether to mute all video sound.');\nconst assets=input.assets;\ncheck(Array.isArray(assets)&&assets.length>=3&&assets.length<=24,'Choose 3–24 photos or video messages in story order.');\nconst valid=asset=>{check(asset&&['image','video','audio'].includes(asset.kind)&&typeof asset.assetId==='string'&&asset.assetId&&typeof asset.versionId==='string'&&asset.versionId,'Use exact saved media versions.');check(typeof asset.url==='string'&&/^(https:\\/\\/|http:\\/\\/(localhost|127\\.0\\.0\\.1)(:\\d+)?\\/|\\/api\\/media\\/|sm-media:|blob:)/.test(asset.url)&&!/^https?:\\/\\/[^/?#]*@/.test(asset.url),'Use authorized media references.');if(asset.kind!=='audio')check(Number.isFinite(asset.width)&&asset.width>0&&Number.isFinite(asset.height)&&asset.height>0,'Upload original media again to measure its dimensions.');if(asset.kind!=='image')check(Number.isFinite(asset.duration)&&asset.duration>0,'Upload the media again to measure its duration.');return copy(asset);};\nconst media=assets.map(valid);check(media.every(a=>a.kind!=='audio'),'Choose photos and video messages here; use the music input for a soundtrack.');\nconst occasion=input.occasion||'birthday';check(['birthday','anniversary','farewell'].includes(occasion),'Choose an occasion.');\nconst title=short(input.title||'','Opening dedication',64),ending=short(input.ending||'','Closing dedication',100),disclosure=short(input.disclosure||'','Disclosure',100);\ncheck(title&&ending,'Supply the exact opening and closing dedication.');\nconst notes=(input.notes||'').replace(/\\r/g,'').split('\\n');check(notes.length===1&&!notes[0]||notes.length===media.length,'Use one short memory or speaker label per item, with blank lines for no label.');notes.forEach(n=>short(n,'Memory label',80));\nconst raw=(input.selections||'').trim();check(raw.length<=2000,'Use a bounded source selection list.');\nconst rows=raw?raw.split('\\n').map(line=>line.trim()):[];check(!rows.length||rows.length===media.length,'Use one selection per item: image seconds, or video start-end seconds.');\nconst durations=media.map((asset,i)=>{\n const row=rows[i];if(asset.kind==='image'){const duration=row?Number(row):4;check(Number.isFinite(duration)&&duration>=2&&duration<=12,'Photos need 2–12 seconds.');return {from:0,duration};}\n const m=row?.match(/^(\\d+(?:\\.\\d+)?)\\s*-\\s*(\\d+(?:\\.\\d+)?)$/);check(!row||m,'Video selections use source seconds, for example 2-12.');const from=m?+m[1]:0,to=m?+m[2]:Math.min(asset.duration,20);check(to>from&&from>=0&&to<=asset.duration+.02&&to-from<=45,'Video messages need an available interval of up to 45 seconds.');return {from,duration:to-from};\n});\nconst aspect=input.aspect||'16:9';check(['16:9','9:16','1:1'].includes(aspect),'Choose a supported frame shape.');\nconst musicItems=input.music||[];check(Array.isArray(musicItems)&&musicItems.length<=1,'Choose one optional music track.');const music=musicItems.length?valid(musicItems[0]):null;check(!music||music.kind==='audio','The soundtrack must be an audio file.');\nconst opening=3,closing=4,duration=round(opening+closing+durations.reduce((n,d)=>n+d.duration,0));check(duration<=180,'Keep this first story under three minutes. Shorten messages or use fewer items.');check(!music||music.duration>=duration,'Choose a soundtrack long enough for the entire story.');\nconst clips=[],audioItems=[],overlays=[];\nconst portrait=aspect==='9:16', W=369*Number(aspect.split(':')[0])/Number(aspect.split(':')[1]);\nconst addText=(id,value,start,end,y,size)=>{if(value)overlays.push({id,type:'text',trackId:'copy',text:value,start:round(start),end:round(end),font:'Hanken Grotesk',size,color:'#F7F0DB',background:'#0A0A0A',backgroundOpacity:65,backgroundPadding:4,width:.82,x:50,y,position:'center',animation:'fade',animIn:.35,animOut:.25});};\nconst imageClip=(asset,id,start,len,card=false)=>({id,kind:asset.kind,trackId:'story',asset:copy(asset),assetId:asset.assetId,versionId:asset.versionId,url:asset.url,title:asset.name||'Original memory',start:round(start),duration:round(len),trimStart:0,speed:1,volume:0,transform:{fit:'contain',scale:card?.66:.94,x:0,y:card?-30:0,opacity:1,rotation:0},motion:{type:'none'},transition:{type:asset.kind==='image'?'Cross dissolve':'Cut',duration:asset.kind==='image'?.4:0}});\n// Photos can frame a dedication; video messages never start silently behind it.\nif(media[0].kind==='image')clips.push(imageClip(media[0],'opening-photo',0,opening,true));\naddText('opening',title,0,opening,media[0].kind==='image'?80:48,portrait?19:28);\nlet cursor=opening;\nmedia.forEach((asset,index)=>{const selection=durations[index],clip=imageClip(asset,'memory-'+(index+1),cursor,selection.duration);clip.trimStart=selection.from;clips.push(clip);addText('label-'+index,notes[index]||'',cursor+.15,cursor+selection.duration-.1,portrait?83:88,portrait?11:16);\n if(asset.kind==='video'&&!muteVideoAudio)audioItems.push({id:'message-'+index,trackId:'messages',asset:copy(asset),assetId:asset.assetId,versionId:asset.versionId,url:asset.url,title:'Original message '+(index+1),embedded:true,start:round(cursor),duration:round(selection.duration),sourceOffset:selection.from,trimStart:selection.from,volume:100,rate:1});\n if(music)audioItems.push({id:'bed-'+index,trackId:'music',asset:copy(music),assetId:music.assetId,versionId:music.versionId,url:music.url,start:round(cursor),duration:round(selection.duration),sourceOffset:round(cursor),volume:asset.kind==='video'&&!muteVideoAudio?Math.min(8,musicVolume):musicVolume,fadeIn:.18,fadeOut:.18,rate:1});cursor+=selection.duration;\n});\nif(media.at(-1).kind==='image')clips.push(imageClip(media.at(-1),'closing-photo',cursor,closing,true));\naddText('ending',ending,cursor,duration,media.at(-1).kind==='image'?80:48,portrait?17:25);\naddText('disclosure',disclosure,0,duration,96,portrait?5.5:8);\nif(music)for(const [id,start,len]of[['intro',0,opening],['outro',cursor,closing]])audioItems.push({id:'music-'+id,trackId:'music',asset:copy(music),assetId:music.assetId,versionId:music.versionId,url:music.url,start:round(start),duration:len,sourceOffset:round(start),volume:musicVolume,fadeIn:id==='intro'?.5:.15,fadeOut:id==='outro'?1:.15,rate:1});\nconst timeline={schemaVersion:1,activeTimelineId:'occasion-story',name:title,aspect,aspectRatio:aspect,previewH:369,backgroundColor:'#0A0A0A',tracks:[{id:'story',type:'video',label:'Original memories'},{id:'messages',type:'audio',label:'Original messages'},{id:'music',type:'audio',label:'Soundtrack'},{id:'copy',type:'text',label:'Dedications and names'}],trackOrder:['story','messages','music','copy'],clips,audioItems,textOverlays:overlays,captions:[],stickers:[],effects:[],audio:copy(audioItems),overlays:copy(overlays),targetDuration:duration,exportSettings:{aspect,fps:30,resolution:'1080p',quality:'high'}};\nreturn {timeline,review:{schemaVersion:1,state:'needs-human-review',humanApproved:false,occasion,durationSec:duration,itemCount:media.length,messageCount:media.filter(a=>a.kind==='video').length,providerCalls:0,warnings:['Review names, sequence, source trims and sound levels. Music is lowered during messages; loudness normalization and silence removal are not automatic.','This workflow uses already-collected media. It does not invite contributors or send reminders.',...(!music?['No background music was supplied. Original video messages retain their sound.']:[])]}};\n",
287
- "tests": [
288
- {
289
- "name": "Occasion Story original-media example 1",
290
- "input": {
291
- "assets": [
292
- {
293
- "kind": "image",
294
- "assetId": "photo-1",
295
- "versionId": "v1",
296
- "url": "https://media.example/photo-1.jpg",
297
- "width": 1600,
298
- "height": 1200
299
- },
300
- {
301
- "kind": "image",
302
- "assetId": "photo-2",
303
- "versionId": "v1",
304
- "url": "https://media.example/photo-2.jpg",
305
- "width": 1600,
306
- "height": 1200
307
- },
308
- {
309
- "kind": "image",
310
- "assetId": "photo-3",
311
- "versionId": "v1",
312
- "url": "https://media.example/photo-3.jpg",
313
- "width": 1600,
314
- "height": 1200
315
- }
316
- ],
317
- "title": "Happy birthday, Alex",
318
- "ending": "With love from all of us",
319
- "notes": "A first adventure\nA favorite memory\nMore to come",
320
- "music": [
321
- {
322
- "kind": "audio",
323
- "assetId": "original-song",
324
- "versionId": "v1",
325
- "url": "https://media.example/song.wav",
326
- "duration": 180
327
- }
328
- ]
329
- },
330
- "expected": {
331
- "timeline": {
332
- "schemaVersion": 1,
333
- "activeTimelineId": "occasion-story",
334
- "name": "Happy birthday, Alex",
335
- "aspect": "16:9",
336
- "aspectRatio": "16:9",
337
- "previewH": 369,
338
- "backgroundColor": "#0A0A0A",
339
- "tracks": [
340
- {
341
- "id": "story",
342
- "type": "video",
343
- "label": "Original memories"
344
- },
345
- {
346
- "id": "messages",
347
- "type": "audio",
348
- "label": "Original messages"
349
- },
350
- {
351
- "id": "music",
352
- "type": "audio",
353
- "label": "Soundtrack"
354
- },
355
- {
356
- "id": "copy",
357
- "type": "text",
358
- "label": "Dedications and names"
359
- }
360
- ],
361
- "trackOrder": [
362
- "story",
363
- "messages",
364
- "music",
365
- "copy"
366
- ],
367
- "clips": [
368
- {
369
- "id": "opening-photo",
370
- "kind": "image",
371
- "trackId": "story",
372
- "asset": {
373
- "kind": "image",
374
- "assetId": "photo-1",
375
- "versionId": "v1",
376
- "url": "https://media.example/photo-1.jpg",
377
- "width": 1600,
378
- "height": 1200
379
- },
380
- "assetId": "photo-1",
381
- "versionId": "v1",
382
- "url": "https://media.example/photo-1.jpg",
383
- "title": "Original memory",
384
- "start": 0,
385
- "duration": 3,
386
- "trimStart": 0,
387
- "speed": 1,
388
- "volume": 0,
389
- "transform": {
390
- "fit": "contain",
391
- "scale": 0.66,
392
- "x": 0,
393
- "y": -30,
394
- "opacity": 1,
395
- "rotation": 0
396
- },
397
- "motion": {
398
- "type": "none"
399
- },
400
- "transition": {
401
- "type": "Cross dissolve",
402
- "duration": 0.4
403
- }
404
- },
405
- {
406
- "id": "memory-1",
407
- "kind": "image",
408
- "trackId": "story",
409
- "asset": {
410
- "kind": "image",
411
- "assetId": "photo-1",
412
- "versionId": "v1",
413
- "url": "https://media.example/photo-1.jpg",
414
- "width": 1600,
415
- "height": 1200
416
- },
417
- "assetId": "photo-1",
418
- "versionId": "v1",
419
- "url": "https://media.example/photo-1.jpg",
420
- "title": "Original memory",
421
- "start": 3,
422
- "duration": 4,
423
- "trimStart": 0,
424
- "speed": 1,
425
- "volume": 0,
426
- "transform": {
427
- "fit": "contain",
428
- "scale": 0.94,
429
- "x": 0,
430
- "y": 0,
431
- "opacity": 1,
432
- "rotation": 0
433
- },
434
- "motion": {
435
- "type": "none"
436
- },
437
- "transition": {
438
- "type": "Cross dissolve",
439
- "duration": 0.4
440
- }
441
- },
442
- {
443
- "id": "memory-2",
444
- "kind": "image",
445
- "trackId": "story",
446
- "asset": {
447
- "kind": "image",
448
- "assetId": "photo-2",
449
- "versionId": "v1",
450
- "url": "https://media.example/photo-2.jpg",
451
- "width": 1600,
452
- "height": 1200
453
- },
454
- "assetId": "photo-2",
455
- "versionId": "v1",
456
- "url": "https://media.example/photo-2.jpg",
457
- "title": "Original memory",
458
- "start": 7,
459
- "duration": 4,
460
- "trimStart": 0,
461
- "speed": 1,
462
- "volume": 0,
463
- "transform": {
464
- "fit": "contain",
465
- "scale": 0.94,
466
- "x": 0,
467
- "y": 0,
468
- "opacity": 1,
469
- "rotation": 0
470
- },
471
- "motion": {
472
- "type": "none"
473
- },
474
- "transition": {
475
- "type": "Cross dissolve",
476
- "duration": 0.4
477
- }
478
- },
479
- {
480
- "id": "memory-3",
481
- "kind": "image",
482
- "trackId": "story",
483
- "asset": {
484
- "kind": "image",
485
- "assetId": "photo-3",
486
- "versionId": "v1",
487
- "url": "https://media.example/photo-3.jpg",
488
- "width": 1600,
489
- "height": 1200
490
- },
491
- "assetId": "photo-3",
492
- "versionId": "v1",
493
- "url": "https://media.example/photo-3.jpg",
494
- "title": "Original memory",
495
- "start": 11,
496
- "duration": 4,
497
- "trimStart": 0,
498
- "speed": 1,
499
- "volume": 0,
500
- "transform": {
501
- "fit": "contain",
502
- "scale": 0.94,
503
- "x": 0,
504
- "y": 0,
505
- "opacity": 1,
506
- "rotation": 0
507
- },
508
- "motion": {
509
- "type": "none"
510
- },
511
- "transition": {
512
- "type": "Cross dissolve",
513
- "duration": 0.4
514
- }
515
- },
516
- {
517
- "id": "closing-photo",
518
- "kind": "image",
519
- "trackId": "story",
520
- "asset": {
521
- "kind": "image",
522
- "assetId": "photo-3",
523
- "versionId": "v1",
524
- "url": "https://media.example/photo-3.jpg",
525
- "width": 1600,
526
- "height": 1200
527
- },
528
- "assetId": "photo-3",
529
- "versionId": "v1",
530
- "url": "https://media.example/photo-3.jpg",
531
- "title": "Original memory",
532
- "start": 15,
533
- "duration": 4,
534
- "trimStart": 0,
535
- "speed": 1,
536
- "volume": 0,
537
- "transform": {
538
- "fit": "contain",
539
- "scale": 0.66,
540
- "x": 0,
541
- "y": -30,
542
- "opacity": 1,
543
- "rotation": 0
544
- },
545
- "motion": {
546
- "type": "none"
547
- },
548
- "transition": {
549
- "type": "Cross dissolve",
550
- "duration": 0.4
551
- }
552
- }
553
- ],
554
- "audioItems": [
555
- {
556
- "id": "bed-0",
557
- "trackId": "music",
558
- "asset": {
559
- "kind": "audio",
560
- "assetId": "original-song",
561
- "versionId": "v1",
562
- "url": "https://media.example/song.wav",
563
- "duration": 180
564
- },
565
- "assetId": "original-song",
566
- "versionId": "v1",
567
- "url": "https://media.example/song.wav",
568
- "start": 3,
569
- "duration": 4,
570
- "sourceOffset": 3,
571
- "volume": 32,
572
- "fadeIn": 0.18,
573
- "fadeOut": 0.18,
574
- "rate": 1
575
- },
576
- {
577
- "id": "bed-1",
578
- "trackId": "music",
579
- "asset": {
580
- "kind": "audio",
581
- "assetId": "original-song",
582
- "versionId": "v1",
583
- "url": "https://media.example/song.wav",
584
- "duration": 180
585
- },
586
- "assetId": "original-song",
587
- "versionId": "v1",
588
- "url": "https://media.example/song.wav",
589
- "start": 7,
590
- "duration": 4,
591
- "sourceOffset": 7,
592
- "volume": 32,
593
- "fadeIn": 0.18,
594
- "fadeOut": 0.18,
595
- "rate": 1
596
- },
597
- {
598
- "id": "bed-2",
599
- "trackId": "music",
600
- "asset": {
601
- "kind": "audio",
602
- "assetId": "original-song",
603
- "versionId": "v1",
604
- "url": "https://media.example/song.wav",
605
- "duration": 180
606
- },
607
- "assetId": "original-song",
608
- "versionId": "v1",
609
- "url": "https://media.example/song.wav",
610
- "start": 11,
611
- "duration": 4,
612
- "sourceOffset": 11,
613
- "volume": 32,
614
- "fadeIn": 0.18,
615
- "fadeOut": 0.18,
616
- "rate": 1
617
- },
618
- {
619
- "id": "music-intro",
620
- "trackId": "music",
621
- "asset": {
622
- "kind": "audio",
623
- "assetId": "original-song",
624
- "versionId": "v1",
625
- "url": "https://media.example/song.wav",
626
- "duration": 180
627
- },
628
- "assetId": "original-song",
629
- "versionId": "v1",
630
- "url": "https://media.example/song.wav",
631
- "start": 0,
632
- "duration": 3,
633
- "sourceOffset": 0,
634
- "volume": 32,
635
- "fadeIn": 0.5,
636
- "fadeOut": 0.15,
637
- "rate": 1
638
- },
639
- {
640
- "id": "music-outro",
641
- "trackId": "music",
642
- "asset": {
643
- "kind": "audio",
644
- "assetId": "original-song",
645
- "versionId": "v1",
646
- "url": "https://media.example/song.wav",
647
- "duration": 180
648
- },
649
- "assetId": "original-song",
650
- "versionId": "v1",
651
- "url": "https://media.example/song.wav",
652
- "start": 15,
653
- "duration": 4,
654
- "sourceOffset": 15,
655
- "volume": 32,
656
- "fadeIn": 0.15,
657
- "fadeOut": 1,
658
- "rate": 1
659
- }
660
- ],
661
- "textOverlays": [
662
- {
663
- "id": "opening",
664
- "type": "text",
665
- "trackId": "copy",
666
- "text": "Happy birthday, Alex",
667
- "start": 0,
668
- "end": 3,
669
- "font": "Hanken Grotesk",
670
- "size": 28,
671
- "color": "#F7F0DB",
672
- "background": "#0A0A0A",
673
- "backgroundOpacity": 65,
674
- "backgroundPadding": 4,
675
- "width": 0.82,
676
- "x": 50,
677
- "y": 80,
678
- "position": "center",
679
- "animation": "fade",
680
- "animIn": 0.35,
681
- "animOut": 0.25
682
- },
683
- {
684
- "id": "label-0",
685
- "type": "text",
686
- "trackId": "copy",
687
- "text": "A first adventure",
688
- "start": 3.15,
689
- "end": 6.9,
690
- "font": "Hanken Grotesk",
691
- "size": 16,
692
- "color": "#F7F0DB",
693
- "background": "#0A0A0A",
694
- "backgroundOpacity": 65,
695
- "backgroundPadding": 4,
696
- "width": 0.82,
697
- "x": 50,
698
- "y": 88,
699
- "position": "center",
700
- "animation": "fade",
701
- "animIn": 0.35,
702
- "animOut": 0.25
703
- },
704
- {
705
- "id": "label-1",
706
- "type": "text",
707
- "trackId": "copy",
708
- "text": "A favorite memory",
709
- "start": 7.15,
710
- "end": 10.9,
711
- "font": "Hanken Grotesk",
712
- "size": 16,
713
- "color": "#F7F0DB",
714
- "background": "#0A0A0A",
715
- "backgroundOpacity": 65,
716
- "backgroundPadding": 4,
717
- "width": 0.82,
718
- "x": 50,
719
- "y": 88,
720
- "position": "center",
721
- "animation": "fade",
722
- "animIn": 0.35,
723
- "animOut": 0.25
724
- },
725
- {
726
- "id": "label-2",
727
- "type": "text",
728
- "trackId": "copy",
729
- "text": "More to come",
730
- "start": 11.15,
731
- "end": 14.9,
732
- "font": "Hanken Grotesk",
733
- "size": 16,
734
- "color": "#F7F0DB",
735
- "background": "#0A0A0A",
736
- "backgroundOpacity": 65,
737
- "backgroundPadding": 4,
738
- "width": 0.82,
739
- "x": 50,
740
- "y": 88,
741
- "position": "center",
742
- "animation": "fade",
743
- "animIn": 0.35,
744
- "animOut": 0.25
745
- },
746
- {
747
- "id": "ending",
748
- "type": "text",
749
- "trackId": "copy",
750
- "text": "With love from all of us",
751
- "start": 15,
752
- "end": 19,
753
- "font": "Hanken Grotesk",
754
- "size": 25,
755
- "color": "#F7F0DB",
756
- "background": "#0A0A0A",
757
- "backgroundOpacity": 65,
758
- "backgroundPadding": 4,
759
- "width": 0.82,
760
- "x": 50,
761
- "y": 80,
762
- "position": "center",
763
- "animation": "fade",
764
- "animIn": 0.35,
765
- "animOut": 0.25
766
- }
767
- ],
768
- "captions": [],
769
- "stickers": [],
770
- "effects": [],
771
- "audio": [
772
- {
773
- "id": "bed-0",
774
- "trackId": "music",
775
- "asset": {
776
- "kind": "audio",
777
- "assetId": "original-song",
778
- "versionId": "v1",
779
- "url": "https://media.example/song.wav",
780
- "duration": 180
781
- },
782
- "assetId": "original-song",
783
- "versionId": "v1",
784
- "url": "https://media.example/song.wav",
785
- "start": 3,
786
- "duration": 4,
787
- "sourceOffset": 3,
788
- "volume": 32,
789
- "fadeIn": 0.18,
790
- "fadeOut": 0.18,
791
- "rate": 1
792
- },
793
- {
794
- "id": "bed-1",
795
- "trackId": "music",
796
- "asset": {
797
- "kind": "audio",
798
- "assetId": "original-song",
799
- "versionId": "v1",
800
- "url": "https://media.example/song.wav",
801
- "duration": 180
802
- },
803
- "assetId": "original-song",
804
- "versionId": "v1",
805
- "url": "https://media.example/song.wav",
806
- "start": 7,
807
- "duration": 4,
808
- "sourceOffset": 7,
809
- "volume": 32,
810
- "fadeIn": 0.18,
811
- "fadeOut": 0.18,
812
- "rate": 1
813
- },
814
- {
815
- "id": "bed-2",
816
- "trackId": "music",
817
- "asset": {
818
- "kind": "audio",
819
- "assetId": "original-song",
820
- "versionId": "v1",
821
- "url": "https://media.example/song.wav",
822
- "duration": 180
823
- },
824
- "assetId": "original-song",
825
- "versionId": "v1",
826
- "url": "https://media.example/song.wav",
827
- "start": 11,
828
- "duration": 4,
829
- "sourceOffset": 11,
830
- "volume": 32,
831
- "fadeIn": 0.18,
832
- "fadeOut": 0.18,
833
- "rate": 1
834
- },
835
- {
836
- "id": "music-intro",
837
- "trackId": "music",
838
- "asset": {
839
- "kind": "audio",
840
- "assetId": "original-song",
841
- "versionId": "v1",
842
- "url": "https://media.example/song.wav",
843
- "duration": 180
844
- },
845
- "assetId": "original-song",
846
- "versionId": "v1",
847
- "url": "https://media.example/song.wav",
848
- "start": 0,
849
- "duration": 3,
850
- "sourceOffset": 0,
851
- "volume": 32,
852
- "fadeIn": 0.5,
853
- "fadeOut": 0.15,
854
- "rate": 1
855
- },
856
- {
857
- "id": "music-outro",
858
- "trackId": "music",
859
- "asset": {
860
- "kind": "audio",
861
- "assetId": "original-song",
862
- "versionId": "v1",
863
- "url": "https://media.example/song.wav",
864
- "duration": 180
865
- },
866
- "assetId": "original-song",
867
- "versionId": "v1",
868
- "url": "https://media.example/song.wav",
869
- "start": 15,
870
- "duration": 4,
871
- "sourceOffset": 15,
872
- "volume": 32,
873
- "fadeIn": 0.15,
874
- "fadeOut": 1,
875
- "rate": 1
876
- }
877
- ],
878
- "overlays": [
879
- {
880
- "id": "opening",
881
- "type": "text",
882
- "trackId": "copy",
883
- "text": "Happy birthday, Alex",
884
- "start": 0,
885
- "end": 3,
886
- "font": "Hanken Grotesk",
887
- "size": 28,
888
- "color": "#F7F0DB",
889
- "background": "#0A0A0A",
890
- "backgroundOpacity": 65,
891
- "backgroundPadding": 4,
892
- "width": 0.82,
893
- "x": 50,
894
- "y": 80,
895
- "position": "center",
896
- "animation": "fade",
897
- "animIn": 0.35,
898
- "animOut": 0.25
899
- },
900
- {
901
- "id": "label-0",
902
- "type": "text",
903
- "trackId": "copy",
904
- "text": "A first adventure",
905
- "start": 3.15,
906
- "end": 6.9,
907
- "font": "Hanken Grotesk",
908
- "size": 16,
909
- "color": "#F7F0DB",
910
- "background": "#0A0A0A",
911
- "backgroundOpacity": 65,
912
- "backgroundPadding": 4,
913
- "width": 0.82,
914
- "x": 50,
915
- "y": 88,
916
- "position": "center",
917
- "animation": "fade",
918
- "animIn": 0.35,
919
- "animOut": 0.25
920
- },
921
- {
922
- "id": "label-1",
923
- "type": "text",
924
- "trackId": "copy",
925
- "text": "A favorite memory",
926
- "start": 7.15,
927
- "end": 10.9,
928
- "font": "Hanken Grotesk",
929
- "size": 16,
930
- "color": "#F7F0DB",
931
- "background": "#0A0A0A",
932
- "backgroundOpacity": 65,
933
- "backgroundPadding": 4,
934
- "width": 0.82,
935
- "x": 50,
936
- "y": 88,
937
- "position": "center",
938
- "animation": "fade",
939
- "animIn": 0.35,
940
- "animOut": 0.25
941
- },
942
- {
943
- "id": "label-2",
944
- "type": "text",
945
- "trackId": "copy",
946
- "text": "More to come",
947
- "start": 11.15,
948
- "end": 14.9,
949
- "font": "Hanken Grotesk",
950
- "size": 16,
951
- "color": "#F7F0DB",
952
- "background": "#0A0A0A",
953
- "backgroundOpacity": 65,
954
- "backgroundPadding": 4,
955
- "width": 0.82,
956
- "x": 50,
957
- "y": 88,
958
- "position": "center",
959
- "animation": "fade",
960
- "animIn": 0.35,
961
- "animOut": 0.25
962
- },
963
- {
964
- "id": "ending",
965
- "type": "text",
966
- "trackId": "copy",
967
- "text": "With love from all of us",
968
- "start": 15,
969
- "end": 19,
970
- "font": "Hanken Grotesk",
971
- "size": 25,
972
- "color": "#F7F0DB",
973
- "background": "#0A0A0A",
974
- "backgroundOpacity": 65,
975
- "backgroundPadding": 4,
976
- "width": 0.82,
977
- "x": 50,
978
- "y": 80,
979
- "position": "center",
980
- "animation": "fade",
981
- "animIn": 0.35,
982
- "animOut": 0.25
983
- }
984
- ],
985
- "targetDuration": 19,
986
- "exportSettings": {
987
- "aspect": "16:9",
988
- "fps": 30,
989
- "resolution": "1080p",
990
- "quality": "high"
991
- }
992
- },
993
- "review": {
994
- "schemaVersion": 1,
995
- "state": "needs-human-review",
996
- "humanApproved": false,
997
- "occasion": "birthday",
998
- "durationSec": 19,
999
- "itemCount": 3,
1000
- "messageCount": 0,
1001
- "providerCalls": 0,
1002
- "warnings": [
1003
- "Review names, sequence, source trims and sound levels. Music is lowered during messages; loudness normalization and silence removal are not automatic.",
1004
- "This workflow uses already-collected media. It does not invite contributors or send reminders."
1005
- ]
1006
- }
1007
- }
1008
- },
1009
- {
1010
- "name": "Occasion Story original-media example 2",
1011
- "input": {
1012
- "assets": [
1013
- {
1014
- "kind": "image",
1015
- "assetId": "photo-1",
1016
- "versionId": "v1",
1017
- "url": "https://media.example/photo-1.jpg",
1018
- "width": 1600,
1019
- "height": 1200
1020
- },
1021
- {
1022
- "kind": "video",
1023
- "assetId": "message",
1024
- "versionId": "v1",
1025
- "url": "https://media.example/message.mp4",
1026
- "width": 1080,
1027
- "height": 1920,
1028
- "duration": 10
1029
- },
1030
- {
1031
- "kind": "image",
1032
- "assetId": "photo-2",
1033
- "versionId": "v1",
1034
- "url": "https://media.example/photo-2.jpg",
1035
- "width": 1600,
1036
- "height": 1200
1037
- }
1038
- ],
1039
- "occasion": "farewell",
1040
- "title": "Thank you, Alex",
1041
- "ending": "On to the next chapter",
1042
- "music": [
1043
- {
1044
- "kind": "audio",
1045
- "assetId": "original-song",
1046
- "versionId": "v1",
1047
- "url": "https://media.example/song.wav",
1048
- "duration": 180
1049
- }
1050
- ]
1051
- },
1052
- "expected": {
1053
- "timeline": {
1054
- "schemaVersion": 1,
1055
- "activeTimelineId": "occasion-story",
1056
- "name": "Thank you, Alex",
1057
- "aspect": "16:9",
1058
- "aspectRatio": "16:9",
1059
- "previewH": 369,
1060
- "backgroundColor": "#0A0A0A",
1061
- "tracks": [
1062
- {
1063
- "id": "story",
1064
- "type": "video",
1065
- "label": "Original memories"
1066
- },
1067
- {
1068
- "id": "messages",
1069
- "type": "audio",
1070
- "label": "Original messages"
1071
- },
1072
- {
1073
- "id": "music",
1074
- "type": "audio",
1075
- "label": "Soundtrack"
1076
- },
1077
- {
1078
- "id": "copy",
1079
- "type": "text",
1080
- "label": "Dedications and names"
1081
- }
1082
- ],
1083
- "trackOrder": [
1084
- "story",
1085
- "messages",
1086
- "music",
1087
- "copy"
1088
- ],
1089
- "clips": [
1090
- {
1091
- "id": "opening-photo",
1092
- "kind": "image",
1093
- "trackId": "story",
1094
- "asset": {
1095
- "kind": "image",
1096
- "assetId": "photo-1",
1097
- "versionId": "v1",
1098
- "url": "https://media.example/photo-1.jpg",
1099
- "width": 1600,
1100
- "height": 1200
1101
- },
1102
- "assetId": "photo-1",
1103
- "versionId": "v1",
1104
- "url": "https://media.example/photo-1.jpg",
1105
- "title": "Original memory",
1106
- "start": 0,
1107
- "duration": 3,
1108
- "trimStart": 0,
1109
- "speed": 1,
1110
- "volume": 0,
1111
- "transform": {
1112
- "fit": "contain",
1113
- "scale": 0.66,
1114
- "x": 0,
1115
- "y": -30,
1116
- "opacity": 1,
1117
- "rotation": 0
1118
- },
1119
- "motion": {
1120
- "type": "none"
1121
- },
1122
- "transition": {
1123
- "type": "Cross dissolve",
1124
- "duration": 0.4
1125
- }
1126
- },
1127
- {
1128
- "id": "memory-1",
1129
- "kind": "image",
1130
- "trackId": "story",
1131
- "asset": {
1132
- "kind": "image",
1133
- "assetId": "photo-1",
1134
- "versionId": "v1",
1135
- "url": "https://media.example/photo-1.jpg",
1136
- "width": 1600,
1137
- "height": 1200
1138
- },
1139
- "assetId": "photo-1",
1140
- "versionId": "v1",
1141
- "url": "https://media.example/photo-1.jpg",
1142
- "title": "Original memory",
1143
- "start": 3,
1144
- "duration": 4,
1145
- "trimStart": 0,
1146
- "speed": 1,
1147
- "volume": 0,
1148
- "transform": {
1149
- "fit": "contain",
1150
- "scale": 0.94,
1151
- "x": 0,
1152
- "y": 0,
1153
- "opacity": 1,
1154
- "rotation": 0
1155
- },
1156
- "motion": {
1157
- "type": "none"
1158
- },
1159
- "transition": {
1160
- "type": "Cross dissolve",
1161
- "duration": 0.4
1162
- }
1163
- },
1164
- {
1165
- "id": "memory-2",
1166
- "kind": "video",
1167
- "trackId": "story",
1168
- "asset": {
1169
- "kind": "video",
1170
- "assetId": "message",
1171
- "versionId": "v1",
1172
- "url": "https://media.example/message.mp4",
1173
- "width": 1080,
1174
- "height": 1920,
1175
- "duration": 10
1176
- },
1177
- "assetId": "message",
1178
- "versionId": "v1",
1179
- "url": "https://media.example/message.mp4",
1180
- "title": "Original memory",
1181
- "start": 7,
1182
- "duration": 10,
1183
- "trimStart": 0,
1184
- "speed": 1,
1185
- "volume": 0,
1186
- "transform": {
1187
- "fit": "contain",
1188
- "scale": 0.94,
1189
- "x": 0,
1190
- "y": 0,
1191
- "opacity": 1,
1192
- "rotation": 0
1193
- },
1194
- "motion": {
1195
- "type": "none"
1196
- },
1197
- "transition": {
1198
- "type": "Cut",
1199
- "duration": 0
1200
- }
1201
- },
1202
- {
1203
- "id": "memory-3",
1204
- "kind": "image",
1205
- "trackId": "story",
1206
- "asset": {
1207
- "kind": "image",
1208
- "assetId": "photo-2",
1209
- "versionId": "v1",
1210
- "url": "https://media.example/photo-2.jpg",
1211
- "width": 1600,
1212
- "height": 1200
1213
- },
1214
- "assetId": "photo-2",
1215
- "versionId": "v1",
1216
- "url": "https://media.example/photo-2.jpg",
1217
- "title": "Original memory",
1218
- "start": 17,
1219
- "duration": 4,
1220
- "trimStart": 0,
1221
- "speed": 1,
1222
- "volume": 0,
1223
- "transform": {
1224
- "fit": "contain",
1225
- "scale": 0.94,
1226
- "x": 0,
1227
- "y": 0,
1228
- "opacity": 1,
1229
- "rotation": 0
1230
- },
1231
- "motion": {
1232
- "type": "none"
1233
- },
1234
- "transition": {
1235
- "type": "Cross dissolve",
1236
- "duration": 0.4
1237
- }
1238
- },
1239
- {
1240
- "id": "closing-photo",
1241
- "kind": "image",
1242
- "trackId": "story",
1243
- "asset": {
1244
- "kind": "image",
1245
- "assetId": "photo-2",
1246
- "versionId": "v1",
1247
- "url": "https://media.example/photo-2.jpg",
1248
- "width": 1600,
1249
- "height": 1200
1250
- },
1251
- "assetId": "photo-2",
1252
- "versionId": "v1",
1253
- "url": "https://media.example/photo-2.jpg",
1254
- "title": "Original memory",
1255
- "start": 21,
1256
- "duration": 4,
1257
- "trimStart": 0,
1258
- "speed": 1,
1259
- "volume": 0,
1260
- "transform": {
1261
- "fit": "contain",
1262
- "scale": 0.66,
1263
- "x": 0,
1264
- "y": -30,
1265
- "opacity": 1,
1266
- "rotation": 0
1267
- },
1268
- "motion": {
1269
- "type": "none"
1270
- },
1271
- "transition": {
1272
- "type": "Cross dissolve",
1273
- "duration": 0.4
1274
- }
1275
- }
1276
- ],
1277
- "audioItems": [
1278
- {
1279
- "id": "bed-0",
1280
- "trackId": "music",
1281
- "asset": {
1282
- "kind": "audio",
1283
- "assetId": "original-song",
1284
- "versionId": "v1",
1285
- "url": "https://media.example/song.wav",
1286
- "duration": 180
1287
- },
1288
- "assetId": "original-song",
1289
- "versionId": "v1",
1290
- "url": "https://media.example/song.wav",
1291
- "start": 3,
1292
- "duration": 4,
1293
- "sourceOffset": 3,
1294
- "volume": 32,
1295
- "fadeIn": 0.18,
1296
- "fadeOut": 0.18,
1297
- "rate": 1
1298
- },
1299
- {
1300
- "id": "message-1",
1301
- "trackId": "messages",
1302
- "asset": {
1303
- "kind": "video",
1304
- "assetId": "message",
1305
- "versionId": "v1",
1306
- "url": "https://media.example/message.mp4",
1307
- "width": 1080,
1308
- "height": 1920,
1309
- "duration": 10
1310
- },
1311
- "assetId": "message",
1312
- "versionId": "v1",
1313
- "url": "https://media.example/message.mp4",
1314
- "title": "Original message 2",
1315
- "embedded": true,
1316
- "start": 7,
1317
- "duration": 10,
1318
- "sourceOffset": 0,
1319
- "trimStart": 0,
1320
- "volume": 100,
1321
- "rate": 1
1322
- },
1323
- {
1324
- "id": "bed-1",
1325
- "trackId": "music",
1326
- "asset": {
1327
- "kind": "audio",
1328
- "assetId": "original-song",
1329
- "versionId": "v1",
1330
- "url": "https://media.example/song.wav",
1331
- "duration": 180
1332
- },
1333
- "assetId": "original-song",
1334
- "versionId": "v1",
1335
- "url": "https://media.example/song.wav",
1336
- "start": 7,
1337
- "duration": 10,
1338
- "sourceOffset": 7,
1339
- "volume": 8,
1340
- "fadeIn": 0.18,
1341
- "fadeOut": 0.18,
1342
- "rate": 1
1343
- },
1344
- {
1345
- "id": "bed-2",
1346
- "trackId": "music",
1347
- "asset": {
1348
- "kind": "audio",
1349
- "assetId": "original-song",
1350
- "versionId": "v1",
1351
- "url": "https://media.example/song.wav",
1352
- "duration": 180
1353
- },
1354
- "assetId": "original-song",
1355
- "versionId": "v1",
1356
- "url": "https://media.example/song.wav",
1357
- "start": 17,
1358
- "duration": 4,
1359
- "sourceOffset": 17,
1360
- "volume": 32,
1361
- "fadeIn": 0.18,
1362
- "fadeOut": 0.18,
1363
- "rate": 1
1364
- },
1365
- {
1366
- "id": "music-intro",
1367
- "trackId": "music",
1368
- "asset": {
1369
- "kind": "audio",
1370
- "assetId": "original-song",
1371
- "versionId": "v1",
1372
- "url": "https://media.example/song.wav",
1373
- "duration": 180
1374
- },
1375
- "assetId": "original-song",
1376
- "versionId": "v1",
1377
- "url": "https://media.example/song.wav",
1378
- "start": 0,
1379
- "duration": 3,
1380
- "sourceOffset": 0,
1381
- "volume": 32,
1382
- "fadeIn": 0.5,
1383
- "fadeOut": 0.15,
1384
- "rate": 1
1385
- },
1386
- {
1387
- "id": "music-outro",
1388
- "trackId": "music",
1389
- "asset": {
1390
- "kind": "audio",
1391
- "assetId": "original-song",
1392
- "versionId": "v1",
1393
- "url": "https://media.example/song.wav",
1394
- "duration": 180
1395
- },
1396
- "assetId": "original-song",
1397
- "versionId": "v1",
1398
- "url": "https://media.example/song.wav",
1399
- "start": 21,
1400
- "duration": 4,
1401
- "sourceOffset": 21,
1402
- "volume": 32,
1403
- "fadeIn": 0.15,
1404
- "fadeOut": 1,
1405
- "rate": 1
1406
- }
1407
- ],
1408
- "textOverlays": [
1409
- {
1410
- "id": "opening",
1411
- "type": "text",
1412
- "trackId": "copy",
1413
- "text": "Thank you, Alex",
1414
- "start": 0,
1415
- "end": 3,
1416
- "font": "Hanken Grotesk",
1417
- "size": 28,
1418
- "color": "#F7F0DB",
1419
- "background": "#0A0A0A",
1420
- "backgroundOpacity": 65,
1421
- "backgroundPadding": 4,
1422
- "width": 0.82,
1423
- "x": 50,
1424
- "y": 80,
1425
- "position": "center",
1426
- "animation": "fade",
1427
- "animIn": 0.35,
1428
- "animOut": 0.25
1429
- },
1430
- {
1431
- "id": "ending",
1432
- "type": "text",
1433
- "trackId": "copy",
1434
- "text": "On to the next chapter",
1435
- "start": 21,
1436
- "end": 25,
1437
- "font": "Hanken Grotesk",
1438
- "size": 25,
1439
- "color": "#F7F0DB",
1440
- "background": "#0A0A0A",
1441
- "backgroundOpacity": 65,
1442
- "backgroundPadding": 4,
1443
- "width": 0.82,
1444
- "x": 50,
1445
- "y": 80,
1446
- "position": "center",
1447
- "animation": "fade",
1448
- "animIn": 0.35,
1449
- "animOut": 0.25
1450
- }
1451
- ],
1452
- "captions": [],
1453
- "stickers": [],
1454
- "effects": [],
1455
- "audio": [
1456
- {
1457
- "id": "bed-0",
1458
- "trackId": "music",
1459
- "asset": {
1460
- "kind": "audio",
1461
- "assetId": "original-song",
1462
- "versionId": "v1",
1463
- "url": "https://media.example/song.wav",
1464
- "duration": 180
1465
- },
1466
- "assetId": "original-song",
1467
- "versionId": "v1",
1468
- "url": "https://media.example/song.wav",
1469
- "start": 3,
1470
- "duration": 4,
1471
- "sourceOffset": 3,
1472
- "volume": 32,
1473
- "fadeIn": 0.18,
1474
- "fadeOut": 0.18,
1475
- "rate": 1
1476
- },
1477
- {
1478
- "id": "message-1",
1479
- "trackId": "messages",
1480
- "asset": {
1481
- "kind": "video",
1482
- "assetId": "message",
1483
- "versionId": "v1",
1484
- "url": "https://media.example/message.mp4",
1485
- "width": 1080,
1486
- "height": 1920,
1487
- "duration": 10
1488
- },
1489
- "assetId": "message",
1490
- "versionId": "v1",
1491
- "url": "https://media.example/message.mp4",
1492
- "title": "Original message 2",
1493
- "embedded": true,
1494
- "start": 7,
1495
- "duration": 10,
1496
- "sourceOffset": 0,
1497
- "trimStart": 0,
1498
- "volume": 100,
1499
- "rate": 1
1500
- },
1501
- {
1502
- "id": "bed-1",
1503
- "trackId": "music",
1504
- "asset": {
1505
- "kind": "audio",
1506
- "assetId": "original-song",
1507
- "versionId": "v1",
1508
- "url": "https://media.example/song.wav",
1509
- "duration": 180
1510
- },
1511
- "assetId": "original-song",
1512
- "versionId": "v1",
1513
- "url": "https://media.example/song.wav",
1514
- "start": 7,
1515
- "duration": 10,
1516
- "sourceOffset": 7,
1517
- "volume": 8,
1518
- "fadeIn": 0.18,
1519
- "fadeOut": 0.18,
1520
- "rate": 1
1521
- },
1522
- {
1523
- "id": "bed-2",
1524
- "trackId": "music",
1525
- "asset": {
1526
- "kind": "audio",
1527
- "assetId": "original-song",
1528
- "versionId": "v1",
1529
- "url": "https://media.example/song.wav",
1530
- "duration": 180
1531
- },
1532
- "assetId": "original-song",
1533
- "versionId": "v1",
1534
- "url": "https://media.example/song.wav",
1535
- "start": 17,
1536
- "duration": 4,
1537
- "sourceOffset": 17,
1538
- "volume": 32,
1539
- "fadeIn": 0.18,
1540
- "fadeOut": 0.18,
1541
- "rate": 1
1542
- },
1543
- {
1544
- "id": "music-intro",
1545
- "trackId": "music",
1546
- "asset": {
1547
- "kind": "audio",
1548
- "assetId": "original-song",
1549
- "versionId": "v1",
1550
- "url": "https://media.example/song.wav",
1551
- "duration": 180
1552
- },
1553
- "assetId": "original-song",
1554
- "versionId": "v1",
1555
- "url": "https://media.example/song.wav",
1556
- "start": 0,
1557
- "duration": 3,
1558
- "sourceOffset": 0,
1559
- "volume": 32,
1560
- "fadeIn": 0.5,
1561
- "fadeOut": 0.15,
1562
- "rate": 1
1563
- },
1564
- {
1565
- "id": "music-outro",
1566
- "trackId": "music",
1567
- "asset": {
1568
- "kind": "audio",
1569
- "assetId": "original-song",
1570
- "versionId": "v1",
1571
- "url": "https://media.example/song.wav",
1572
- "duration": 180
1573
- },
1574
- "assetId": "original-song",
1575
- "versionId": "v1",
1576
- "url": "https://media.example/song.wav",
1577
- "start": 21,
1578
- "duration": 4,
1579
- "sourceOffset": 21,
1580
- "volume": 32,
1581
- "fadeIn": 0.15,
1582
- "fadeOut": 1,
1583
- "rate": 1
1584
- }
1585
- ],
1586
- "overlays": [
1587
- {
1588
- "id": "opening",
1589
- "type": "text",
1590
- "trackId": "copy",
1591
- "text": "Thank you, Alex",
1592
- "start": 0,
1593
- "end": 3,
1594
- "font": "Hanken Grotesk",
1595
- "size": 28,
1596
- "color": "#F7F0DB",
1597
- "background": "#0A0A0A",
1598
- "backgroundOpacity": 65,
1599
- "backgroundPadding": 4,
1600
- "width": 0.82,
1601
- "x": 50,
1602
- "y": 80,
1603
- "position": "center",
1604
- "animation": "fade",
1605
- "animIn": 0.35,
1606
- "animOut": 0.25
1607
- },
1608
- {
1609
- "id": "ending",
1610
- "type": "text",
1611
- "trackId": "copy",
1612
- "text": "On to the next chapter",
1613
- "start": 21,
1614
- "end": 25,
1615
- "font": "Hanken Grotesk",
1616
- "size": 25,
1617
- "color": "#F7F0DB",
1618
- "background": "#0A0A0A",
1619
- "backgroundOpacity": 65,
1620
- "backgroundPadding": 4,
1621
- "width": 0.82,
1622
- "x": 50,
1623
- "y": 80,
1624
- "position": "center",
1625
- "animation": "fade",
1626
- "animIn": 0.35,
1627
- "animOut": 0.25
1628
- }
1629
- ],
1630
- "targetDuration": 25,
1631
- "exportSettings": {
1632
- "aspect": "16:9",
1633
- "fps": 30,
1634
- "resolution": "1080p",
1635
- "quality": "high"
1636
- }
1637
- },
1638
- "review": {
1639
- "schemaVersion": 1,
1640
- "state": "needs-human-review",
1641
- "humanApproved": false,
1642
- "occasion": "farewell",
1643
- "durationSec": 25,
1644
- "itemCount": 3,
1645
- "messageCount": 1,
1646
- "providerCalls": 0,
1647
- "warnings": [
1648
- "Review names, sequence, source trims and sound levels. Music is lowered during messages; loudness normalization and silence removal are not automatic.",
1649
- "This workflow uses already-collected media. It does not invite contributors or send reminders."
1650
- ]
1651
- }
1652
- }
1653
- }
1654
- ],
1655
- "portable": {
1656
- "format": "stillmade-block/1",
1657
- "dependencies": [],
1658
- "sources": [
1659
- {
1660
- "kind": "original",
1661
- "license": "MIT",
1662
- "paths": [
1663
- "LICENSE",
1664
- "src/run.js"
1665
- ],
1666
- "evidence": [
1667
- "upstream/0/LICENSE",
1668
- "upstream/0/src/run.js"
1669
- ],
1670
- "changes": "Original implementation declared by the packager; no reused repository or dependency code."
1671
- }
1672
- ],
1673
- "files": {
1674
- "upstream/0/LICENSE": "MIT License\n\nCopyright (c) <year> <copyright holders>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and \nassociated documentation files (the \"Software\"), to deal in the Software without restriction, including \nwithout limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell \ncopies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the \nfollowing conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial \nportions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT \nLIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO \nEVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER \nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE \nUSE OR OTHER DEALINGS IN THE SOFTWARE.\n",
1675
- "upstream/0/src/run.js": "// Original occasion-story assembly. Runs entirely in the JavaScript sandbox.\nconst copy=value=>JSON.parse(JSON.stringify(value));\nconst check=(ok,message)=>{if(!ok)throw Error(message);};\nconst round=n=>Math.round(n*1000000)/1000000;\nconst short=(value,label,max=80)=>{check(typeof value==='string'&&value.length<=max&&!/[\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]/.test(value),label+' must be short plain text.');return value.trim();};\n\nconst musicVolume=input.musicVolume??32,muteVideoAudio=input.muteVideoAudio??false;\ncheck(Number.isFinite(musicVolume)&&musicVolume>=0&&musicVolume<=100,'Music volume must be 0–100.');check(typeof muteVideoAudio==='boolean','Choose whether to mute all video sound.');\nconst assets=input.assets;\ncheck(Array.isArray(assets)&&assets.length>=3&&assets.length<=24,'Choose 3–24 photos or video messages in story order.');\nconst valid=asset=>{check(asset&&['image','video','audio'].includes(asset.kind)&&typeof asset.assetId==='string'&&asset.assetId&&typeof asset.versionId==='string'&&asset.versionId,'Use exact saved media versions.');check(typeof asset.url==='string'&&/^(https:\\/\\/|http:\\/\\/(localhost|127\\.0\\.0\\.1)(:\\d+)?\\/|\\/api\\/media\\/|sm-media:|blob:)/.test(asset.url)&&!/^https?:\\/\\/[^/?#]*@/.test(asset.url),'Use authorized media references.');if(asset.kind!=='audio')check(Number.isFinite(asset.width)&&asset.width>0&&Number.isFinite(asset.height)&&asset.height>0,'Upload original media again to measure its dimensions.');if(asset.kind!=='image')check(Number.isFinite(asset.duration)&&asset.duration>0,'Upload the media again to measure its duration.');return copy(asset);};\nconst media=assets.map(valid);check(media.every(a=>a.kind!=='audio'),'Choose photos and video messages here; use the music input for a soundtrack.');\nconst occasion=input.occasion||'birthday';check(['birthday','anniversary','farewell'].includes(occasion),'Choose an occasion.');\nconst title=short(input.title||'','Opening dedication',64),ending=short(input.ending||'','Closing dedication',100),disclosure=short(input.disclosure||'','Disclosure',100);\ncheck(title&&ending,'Supply the exact opening and closing dedication.');\nconst notes=(input.notes||'').replace(/\\r/g,'').split('\\n');check(notes.length===1&&!notes[0]||notes.length===media.length,'Use one short memory or speaker label per item, with blank lines for no label.');notes.forEach(n=>short(n,'Memory label',80));\nconst raw=(input.selections||'').trim();check(raw.length<=2000,'Use a bounded source selection list.');\nconst rows=raw?raw.split('\\n').map(line=>line.trim()):[];check(!rows.length||rows.length===media.length,'Use one selection per item: image seconds, or video start-end seconds.');\nconst durations=media.map((asset,i)=>{\n const row=rows[i];if(asset.kind==='image'){const duration=row?Number(row):4;check(Number.isFinite(duration)&&duration>=2&&duration<=12,'Photos need 2–12 seconds.');return {from:0,duration};}\n const m=row?.match(/^(\\d+(?:\\.\\d+)?)\\s*-\\s*(\\d+(?:\\.\\d+)?)$/);check(!row||m,'Video selections use source seconds, for example 2-12.');const from=m?+m[1]:0,to=m?+m[2]:Math.min(asset.duration,20);check(to>from&&from>=0&&to<=asset.duration+.02&&to-from<=45,'Video messages need an available interval of up to 45 seconds.');return {from,duration:to-from};\n});\nconst aspect=input.aspect||'16:9';check(['16:9','9:16','1:1'].includes(aspect),'Choose a supported frame shape.');\nconst musicItems=input.music||[];check(Array.isArray(musicItems)&&musicItems.length<=1,'Choose one optional music track.');const music=musicItems.length?valid(musicItems[0]):null;check(!music||music.kind==='audio','The soundtrack must be an audio file.');\nconst opening=3,closing=4,duration=round(opening+closing+durations.reduce((n,d)=>n+d.duration,0));check(duration<=180,'Keep this first story under three minutes. Shorten messages or use fewer items.');check(!music||music.duration>=duration,'Choose a soundtrack long enough for the entire story.');\nconst clips=[],audioItems=[],overlays=[];\nconst portrait=aspect==='9:16', W=369*Number(aspect.split(':')[0])/Number(aspect.split(':')[1]);\nconst addText=(id,value,start,end,y,size)=>{if(value)overlays.push({id,type:'text',trackId:'copy',text:value,start:round(start),end:round(end),font:'Hanken Grotesk',size,color:'#F7F0DB',background:'#0A0A0A',backgroundOpacity:65,backgroundPadding:4,width:.82,x:50,y,position:'center',animation:'fade',animIn:.35,animOut:.25});};\nconst imageClip=(asset,id,start,len,card=false)=>({id,kind:asset.kind,trackId:'story',asset:copy(asset),assetId:asset.assetId,versionId:asset.versionId,url:asset.url,title:asset.name||'Original memory',start:round(start),duration:round(len),trimStart:0,speed:1,volume:0,transform:{fit:'contain',scale:card?.66:.94,x:0,y:card?-30:0,opacity:1,rotation:0},motion:{type:'none'},transition:{type:asset.kind==='image'?'Cross dissolve':'Cut',duration:asset.kind==='image'?.4:0}});\n// Photos can frame a dedication; video messages never start silently behind it.\nif(media[0].kind==='image')clips.push(imageClip(media[0],'opening-photo',0,opening,true));\naddText('opening',title,0,opening,media[0].kind==='image'?80:48,portrait?19:28);\nlet cursor=opening;\nmedia.forEach((asset,index)=>{const selection=durations[index],clip=imageClip(asset,'memory-'+(index+1),cursor,selection.duration);clip.trimStart=selection.from;clips.push(clip);addText('label-'+index,notes[index]||'',cursor+.15,cursor+selection.duration-.1,portrait?83:88,portrait?11:16);\n if(asset.kind==='video'&&!muteVideoAudio)audioItems.push({id:'message-'+index,trackId:'messages',asset:copy(asset),assetId:asset.assetId,versionId:asset.versionId,url:asset.url,title:'Original message '+(index+1),embedded:true,start:round(cursor),duration:round(selection.duration),sourceOffset:selection.from,trimStart:selection.from,volume:100,rate:1});\n if(music)audioItems.push({id:'bed-'+index,trackId:'music',asset:copy(music),assetId:music.assetId,versionId:music.versionId,url:music.url,start:round(cursor),duration:round(selection.duration),sourceOffset:round(cursor),volume:asset.kind==='video'&&!muteVideoAudio?Math.min(8,musicVolume):musicVolume,fadeIn:.18,fadeOut:.18,rate:1});cursor+=selection.duration;\n});\nif(media.at(-1).kind==='image')clips.push(imageClip(media.at(-1),'closing-photo',cursor,closing,true));\naddText('ending',ending,cursor,duration,media.at(-1).kind==='image'?80:48,portrait?17:25);\naddText('disclosure',disclosure,0,duration,96,portrait?5.5:8);\nif(music)for(const [id,start,len]of[['intro',0,opening],['outro',cursor,closing]])audioItems.push({id:'music-'+id,trackId:'music',asset:copy(music),assetId:music.assetId,versionId:music.versionId,url:music.url,start:round(start),duration:len,sourceOffset:round(start),volume:musicVolume,fadeIn:id==='intro'?.5:.15,fadeOut:id==='outro'?1:.15,rate:1});\nconst timeline={schemaVersion:1,activeTimelineId:'occasion-story',name:title,aspect,aspectRatio:aspect,previewH:369,backgroundColor:'#0A0A0A',tracks:[{id:'story',type:'video',label:'Original memories'},{id:'messages',type:'audio',label:'Original messages'},{id:'music',type:'audio',label:'Soundtrack'},{id:'copy',type:'text',label:'Dedications and names'}],trackOrder:['story','messages','music','copy'],clips,audioItems,textOverlays:overlays,captions:[],stickers:[],effects:[],audio:copy(audioItems),overlays:copy(overlays),targetDuration:duration,exportSettings:{aspect,fps:30,resolution:'1080p',quality:'high'}};\nreturn {timeline,review:{schemaVersion:1,state:'needs-human-review',humanApproved:false,occasion,durationSec:duration,itemCount:media.length,messageCount:media.filter(a=>a.kind==='video').length,providerCalls:0,warnings:['Review names, sequence, source trims and sound levels. Music is lowered during messages; loudness normalization and silence removal are not automatic.','This workflow uses already-collected media. It does not invite contributors or send reminders.',...(!music?['No background music was supplied. Original video messages retain their sound.']:[])]}};\n"
1676
- },
1677
- "lineage": {
1678
- "parents": [],
1679
- "changes": "Packaged original Block source for StillMade."
1680
- }
1681
- }
1682
- };