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