{"schemaVersion":1,"id":"recommended.stillmade-release-visuals","version":"1.0.0","name":"Release Visuals workflow","description":"An editable production workflow using Release Visuals v1.0.0.","stages":[{"id":"main","blockId":"stillmade.release-visuals","version":"1.0.0","label":"Release Visuals"}],"connections":[],"packages":[{"manifest":{"schemaVersion":1,"sdkVersion":"0.1.0","id":"stillmade.release-visuals","version":"1.0.0","name":"Release Visuals","description":"Build an editable social release teaser or timed lyric excerpt from original cover art and a supplied recording.","kind":"task","runtime":"javascript","entry":"src/run.js","license":"MIT","inputs":{"assets":{"type":"asset[]","default":[],"description":"One cover image and one audio recording.","primary":true,"required":true,"semantic":"legacy.asset-list.assets","sources":["upstream","user"]},"purpose":{"type":"text","default":"release-teaser","description":"Release teaser or lyric excerpt.","semantic":"stillmade.release_visuals.purpose","sources":["user","default"],"required":false},"title":{"type":"text","default":"","description":"Exact release title, up to 56 characters.","required":true,"semantic":"stillmade.release_visuals.title","sources":["user","default"]},"artist":{"type":"text","default":"","description":"Exact artist name, up to 56 characters.","required":true,"semantic":"stillmade.release_visuals.artist","sources":["user","default"]},"cta":{"type":"text","default":"","description":"Approved release message or destination. Teasers only; lyrics occupy this space.","semantic":"stillmade.release_visuals.cta","sources":["user","default"],"required":false},"duration":{"type":"number","default":20,"description":"Excerpt duration, 8–60 seconds.","min":8,"max":60,"semantic":"stillmade.release_visuals.duration","sources":["user","default"],"required":false},"offset":{"type":"number","default":0,"description":"Start time within the original song, in seconds.","min":0,"max":7200,"semantic":"stillmade.release_visuals.offset","sources":["user","default"],"required":false},"lyrics":{"type":"text","default":"","description":"Reviewed lyric lines relative to this excerpt: 0-3.5 | exact words. One line per phrase; no automatic alignment.","semantic":"stillmade.release_visuals.lyrics","sources":["user","default"],"required":false},"aspect":{"type":"text","default":"9:16","description":"Output frame shape.","semantic":"stillmade.release_visuals.aspect","sources":["user","default"],"required":false},"disclosure":{"type":"text","default":"","description":"Optional source or demonstration disclosure.","semantic":"stillmade.release_visuals.disclosure","sources":["user","default"],"required":false},"rightsConfirmed":{"type":"boolean","default":false,"description":"I have rights to the cover art, recording, lyrics and supplied statements.","required":true,"sources":["user"],"semantic":"stillmade.release_visuals.rightsconfirmed"}},"outputs":{"timeline":{"type":"timeline","primary":true,"semantic":"legacy.timeline.updatededitor","description":"Complete editable timeline using original source media."},"review":{"type":"json","semantic":"stillmade.release_visuals.review","description":"Production scope and remaining human review.","schema":{"schemaVersion":"integer","state":"string","humanApproved":"boolean","purpose":"string","durationSec":"number","sourceOffset":"number","lyricCount":"integer","providerCalls":"integer","warnings":"string[]"}}},"permissions":{"project":["asset.read"],"network":[],"filesystem":[],"secrets":[]},"ui":[{"port":"purpose","control":"select","options":["release-teaser","lyric-excerpt"]},{"port":"duration","control":"slider","min":8,"max":60,"step":1},{"port":"aspect","control":"select","options":["9:16","16:9","1:1"]}],"platforms":{"phone":{"supported":true},"browser":{"supported":true},"desktop":{"supported":true}},"provenance":{"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","portableSources":[{"kind":"original","license":"MIT","paths":["LICENSE","src/run.js"],"evidence":["upstream/0/LICENSE","upstream/0/src/run.js"],"changes":"Original implementation declared by the packager; no reused repository or dependency code."}]},"semantics":[{"name":"stillmade.release_visuals.purpose","description":"Release teaser or lyric excerpt.","parents":[]},{"name":"stillmade.release_visuals.title","description":"Exact release title, up to 56 characters.","parents":[]},{"name":"stillmade.release_visuals.artist","description":"Exact artist name, up to 56 characters.","parents":[]},{"name":"stillmade.release_visuals.cta","description":"Approved release message or destination. Teasers only; lyrics occupy this space.","parents":[]},{"name":"stillmade.release_visuals.duration","description":"Excerpt duration, 8–60 seconds.","parents":[]},{"name":"stillmade.release_visuals.offset","description":"Start time within the original song, in seconds.","parents":[]},{"name":"stillmade.release_visuals.lyrics","description":"Reviewed lyric lines relative to this excerpt: 0-3.5 | exact words. One line per phrase; no automatic alignment.","parents":[]},{"name":"stillmade.release_visuals.aspect","description":"Output frame shape.","parents":[]},{"name":"stillmade.release_visuals.disclosure","description":"Optional source or demonstration disclosure.","parents":[]},{"name":"stillmade.release_visuals.rightsconfirmed","description":"I have rights to the cover art, recording, lyrics and supplied statements.","parents":[]},{"name":"stillmade.release_visuals.review","description":"Production scope and remaining human review.","parents":[]}]},"code":"// Original release-art and lyric-excerpt composition. No inference or I/O.\nconst copy=x=>JSON.parse(JSON.stringify(x)),check=(ok,message)=>{if(!ok)throw Error(message);};\nconst short=(v,label,n=80)=>{check(typeof v==='string'&&v.length<=n&&!/[\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]/.test(v),label+' must be short plain text.');return v.trim();};\ncheck(input.rightsConfirmed===true,'Confirm rights to the cover art, recording and any lyrics.');\nconst assets=input.assets;check(Array.isArray(assets)&&assets.length===2,'Choose exactly one cover image and one audio recording.');\nconst cover=assets.find(a=>a.kind==='image'),song=assets.find(a=>a.kind==='audio');check(cover&&song,'Supply one original cover image and one audio recording.');\nfor(const a of assets)check(typeof a.assetId==='string'&&a.assetId&&typeof a.versionId==='string'&&a.versionId&&typeof a.url==='string'&&/^(https:\\/\\/|http:\\/\\/(localhost|127\\.0\\.0\\.1)(:\\d+)?\\/|\\/api\\/media\\/|sm-media:|blob:)/.test(a.url)&&!/^https?:\\/\\/[^/?#]*@/.test(a.url),'Use exact saved media references.');\ncheck(Number.isFinite(cover.width)&&cover.width>0&&Number.isFinite(cover.height)&&cover.height>0,'Upload cover art again to record its dimensions.');\ncheck(Number.isFinite(song.duration)&&song.duration>0,'Upload the recording again to measure its duration.');\nconst duration=input.duration??20,offset=input.offset??0;\ncheck(Number.isFinite(duration)&&duration>=8&&duration<=60&&Number.isFinite(offset)&&offset>=0&&offset+duration<=song.duration+.02,'Choose an available 8–60 second song excerpt.');\nconst title=short(input.title||'','Release title',56),artist=short(input.artist||'','Artist',56),cta=short(input.cta||'','Release message',64),disclosure=short(input.disclosure||'','Disclosure',100);check(title&&artist,'Supply the release title and artist.');\nconst aspect=input.aspect||'9:16';check(['9:16','1:1','16:9'].includes(aspect),'Choose an output frame shape.');\nconst purpose=input.purpose||'release-teaser';check(['release-teaser','lyric-excerpt'].includes(purpose),'Choose a release teaser or lyric excerpt.');\nconst raw=input.lyrics||'';check(typeof raw==='string'&&raw.length<=8000,'Use up to 8,000 characters of timed lyrics.');\n// Human-approved lyric timing is relative to this excerpt, not the full song.\nconst lyrics=raw.trim()?raw.trim().split('\\n').map(line=>{const m=line.match(/^(\\d+(?:\\.\\d+)?)\\s*-\\s*(\\d+(?:\\.\\d+)?)\\s*\\|\\s*(.+)$/);check(m,'Use lyric lines like 0-3.5 | exact words');const from=+m[1],to=+m[2],value=short(m[3],'Lyric line',100);check(to>from&&from>=0&&to<=duration,'A lyric line is outside the excerpt.');return{from,to,text:value};}):[];\ncheck(lyrics.length<=40,'Use at most 40 lyric lines.');for(let i=1;i<lyrics.length;i++)check(lyrics[i].from>=lyrics[i-1].to,'Lyric lines must be ordered without overlap.');check(purpose!=='lyric-excerpt'||lyrics.length,'Supply reviewed timed lyrics for a lyric excerpt.');\nconst portrait=aspect==='9:16',square=aspect==='1:1',W=369*Number(aspect.split(':')[0])/Number(aspect.split(':')[1]);\nconst fit=Math.min(W/cover.width,369/cover.height),scale=Math.min(W*.84/(cover.width*fit),369*(portrait?.46:.6)/(cover.height*fit));\nconst clips=[{id:'original-cover',kind:'image',trackId:'art',asset:copy(cover),assetId:cover.assetId,versionId:cover.versionId,url:cover.url,title:cover.name||'Original artwork',start:0,duration,trimStart:0,volume:0,speed:1,transform:{fit:'contain',scale,x:0,y:portrait?-22:-10,rotation:0,opacity:1},motion:{type:'zoom',intensity:100,zoomAmount:1.035,zoomDirection:'in',zoomAnchor:'center',easing:'ease-in-out',loop:false,['window']:[0,100]},transition:{type:'Cut',duration:0}}];\nconst overlays=[],stickers=[];\nconst add=(id,value,start,end,y,size,color='#F7F0DB')=>{if(value)overlays.push({id,type:'text',trackId:'copy',text:value,start,end,font:'Hanken Grotesk',size,color,background:'none',width:.84,x:50,y,position:'center',animation:'fade',animIn:.25,animOut:.2});};\nadd('artist',artist,0,duration,portrait?13:9,portrait?10:14);\nadd('release-title',title,0,duration,portrait?70:79,portrait?21:25);\nadd('release-message',lyrics.length?'':cta,0,duration,portrait?86:92,portrait?10:13);\nfor(const [i,line]of lyrics.entries())add('lyric-'+i,line.text,line.from,line.to,portrait?82:91,portrait?12:15);\n// The progress row indicates excerpt time only; it makes no beat-detection claim.\nfor(let i=0;i<16;i++)stickers.push({id:'progress-'+i,trackId:'detail',shape:'underline',color:'#F7F0DB',x:20+i*4,y:portrait?92:97,scale:.04,stretchX:.55,stretchY:.4,opacity:.75,rotation:0,start:duration*i/16,end:duration});\nadd('disclosure',disclosure,0,duration,97,portrait?5:7);\nconst audioItems=[{id:'original-song',trackId:'song',asset:copy(song),assetId:song.assetId,versionId:song.versionId,url:song.url,title:song.name||'Original song',start:0,duration,sourceOffset:offset,trimStart:offset,volume:100,rate:1,fadeIn:.15,fadeOut:.7}];\nconst timeline={schemaVersion:1,activeTimelineId:'release-visuals',name:title,aspect,aspectRatio:aspect,previewH:369,backgroundColor:'#0A0A0A',tracks:[{id:'art',type:'video',label:'Original artwork'},{id:'song',type:'audio',label:'Original recording'},{id:'copy',type:'text',label:'Release copy and lyrics'},{id:'detail',type:'overlay',label:'Excerpt progress'}],trackOrder:['art','song','detail','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,purpose,durationSec:duration,sourceOffset:offset,lyricCount:lyrics.length,providerCalls:0,warnings:['Listen to the export and review the artwork, names, date, exact lyric text and timing.','This is a social release visual, not a generated music video or a certified Spotify/Apple Music asset.','No beat detection, automatic lyric alignment, generated vocals or music licensing is included.']}};\n","tests":[{"name":"Release Visuals original-media example 1","input":{"assets":[{"kind":"image","assetId":"photo-1","versionId":"v1","url":"https://media.example/photo-1.jpg","width":1600,"height":1200},{"kind":"audio","assetId":"original-song","versionId":"v1","url":"https://media.example/song.wav","duration":180}],"title":"A new chapter","artist":"Example artist","cta":"Listen to the release","lyrics":"0-5 | This is an original demo line\n5-10 | Not a copied song","duration":20,"rightsConfirmed":true},"expected":{"timeline":{"schemaVersion":1,"activeTimelineId":"release-visuals","name":"A new chapter","aspect":"9:16","aspectRatio":"9:16","previewH":369,"backgroundColor":"#0A0A0A","tracks":[{"id":"art","type":"video","label":"Original artwork"},{"id":"song","type":"audio","label":"Original recording"},{"id":"copy","type":"text","label":"Release copy and lyrics"},{"id":"detail","type":"overlay","label":"Excerpt progress"}],"trackOrder":["art","song","detail","copy"],"clips":[{"id":"original-cover","kind":"image","trackId":"art","asset":{"kind":"image","assetId":"photo-1","versionId":"v1","url":"https://media.example/photo-1.jpg","width":1600,"height":1200},"assetId":"photo-1","versionId":"v1","url":"https://media.example/photo-1.jpg","title":"Original artwork","start":0,"duration":20,"trimStart":0,"volume":0,"speed":1,"transform":{"fit":"contain","scale":0.84,"x":0,"y":-22,"rotation":0,"opacity":1},"motion":{"type":"zoom","intensity":100,"zoomAmount":1.035,"zoomDirection":"in","zoomAnchor":"center","easing":"ease-in-out","loop":false,"window":[0,100]},"transition":{"type":"Cut","duration":0}}],"audioItems":[{"id":"original-song","trackId":"song","asset":{"kind":"audio","assetId":"original-song","versionId":"v1","url":"https://media.example/song.wav","duration":180},"assetId":"original-song","versionId":"v1","url":"https://media.example/song.wav","title":"Original song","start":0,"duration":20,"sourceOffset":0,"trimStart":0,"volume":100,"rate":1,"fadeIn":0.15,"fadeOut":0.7}],"textOverlays":[{"id":"artist","type":"text","trackId":"copy","text":"Example artist","start":0,"end":20,"font":"Hanken Grotesk","size":10,"color":"#F7F0DB","background":"none","width":0.84,"x":50,"y":13,"position":"center","animation":"fade","animIn":0.25,"animOut":0.2},{"id":"release-title","type":"text","trackId":"copy","text":"A new chapter","start":0,"end":20,"font":"Hanken Grotesk","size":21,"color":"#F7F0DB","background":"none","width":0.84,"x":50,"y":70,"position":"center","animation":"fade","animIn":0.25,"animOut":0.2},{"id":"lyric-0","type":"text","trackId":"copy","text":"This is an original demo line","start":0,"end":5,"font":"Hanken Grotesk","size":12,"color":"#F7F0DB","background":"none","width":0.84,"x":50,"y":82,"position":"center","animation":"fade","animIn":0.25,"animOut":0.2},{"id":"lyric-1","type":"text","trackId":"copy","text":"Not a copied song","start":5,"end":10,"font":"Hanken Grotesk","size":12,"color":"#F7F0DB","background":"none","width":0.84,"x":50,"y":82,"position":"center","animation":"fade","animIn":0.25,"animOut":0.2}],"captions":[],"stickers":[{"id":"progress-0","trackId":"detail","shape":"underline","color":"#F7F0DB","x":20,"y":92,"scale":0.04,"stretchX":0.55,"stretchY":0.4,"opacity":0.75,"rotation":0,"start":0,"end":20},{"id":"progress-1","trackId":"detail","shape":"underline","color":"#F7F0DB","x":24,"y":92,"scale":0.04,"stretchX":0.55,"stretchY":0.4,"opacity":0.75,"rotation":0,"start":1.25,"end":20},{"id":"progress-2","trackId":"detail","shape":"underline","color":"#F7F0DB","x":28,"y":92,"scale":0.04,"stretchX":0.55,"stretchY":0.4,"opacity":0.75,"rotation":0,"start":2.5,"end":20},{"id":"progress-3","trackId":"detail","shape":"underline","color":"#F7F0DB","x":32,"y":92,"scale":0.04,"stretchX":0.55,"stretchY":0.4,"opacity":0.75,"rotation":0,"start":3.75,"end":20},{"id":"progress-4","trackId":"detail","shape":"underline","color":"#F7F0DB","x":36,"y":92,"scale":0.04,"stretchX":0.55,"stretchY":0.4,"opacity":0.75,"rotation":0,"start":5,"end":20},{"id":"progress-5","trackId":"detail","shape":"underline","color":"#F7F0DB","x":40,"y":92,"scale":0.04,"stretchX":0.55,"stretchY":0.4,"opacity":0.75,"rotation":0,"start":6.25,"end":20},{"id":"progress-6","trackId":"detail","shape":"underline","color":"#F7F0DB","x":44,"y":92,"scale":0.04,"stretchX":0.55,"stretchY":0.4,"opacity":0.75,"rotation":0,"start":7.5,"end":20},{"id":"progress-7","trackId":"detail","shape":"underline","color":"#F7F0DB","x":48,"y":92,"scale":0.04,"stretchX":0.55,"stretchY":0.4,"opacity":0.75,"rotation":0,"start":8.75,"end":20},{"id":"progress-8","trackId":"detail","shape":"underline","color":"#F7F0DB","x":52,"y":92,"scale":0.04,"stretchX":0.55,"stretchY":0.4,"opacity":0.75,"rotation":0,"start":10,"end":20},{"id":"progress-9","trackId":"detail","shape":"underline","color":"#F7F0DB","x":56,"y":92,"scale":0.04,"stretchX":0.55,"stretchY":0.4,"opacity":0.75,"rotation":0,"start":11.25,"end":20},{"id":"progress-10","trackId":"detail","shape":"underline","color":"#F7F0DB","x":60,"y":92,"scale":0.04,"stretchX":0.55,"stretchY":0.4,"opacity":0.75,"rotation":0,"start":12.5,"end":20},{"id":"progress-11","trackId":"detail","shape":"underline","color":"#F7F0DB","x":64,"y":92,"scale":0.04,"stretchX":0.55,"stretchY":0.4,"opacity":0.75,"rotation":0,"start":13.75,"end":20},{"id":"progress-12","trackId":"detail","shape":"underline","color":"#F7F0DB","x":68,"y":92,"scale":0.04,"stretchX":0.55,"stretchY":0.4,"opacity":0.75,"rotation":0,"start":15,"end":20},{"id":"progress-13","trackId":"detail","shape":"underline","color":"#F7F0DB","x":72,"y":92,"scale":0.04,"stretchX":0.55,"stretchY":0.4,"opacity":0.75,"rotation":0,"start":16.25,"end":20},{"id":"progress-14","trackId":"detail","shape":"underline","color":"#F7F0DB","x":76,"y":92,"scale":0.04,"stretchX":0.55,"stretchY":0.4,"opacity":0.75,"rotation":0,"start":17.5,"end":20},{"id":"progress-15","trackId":"detail","shape":"underline","color":"#F7F0DB","x":80,"y":92,"scale":0.04,"stretchX":0.55,"stretchY":0.4,"opacity":0.75,"rotation":0,"start":18.75,"end":20}],"effects":[],"audio":[{"id":"original-song","trackId":"song","asset":{"kind":"audio","assetId":"original-song","versionId":"v1","url":"https://media.example/song.wav","duration":180},"assetId":"original-song","versionId":"v1","url":"https://media.example/song.wav","title":"Original song","start":0,"duration":20,"sourceOffset":0,"trimStart":0,"volume":100,"rate":1,"fadeIn":0.15,"fadeOut":0.7}],"overlays":[{"id":"artist","type":"text","trackId":"copy","text":"Example artist","start":0,"end":20,"font":"Hanken Grotesk","size":10,"color":"#F7F0DB","background":"none","width":0.84,"x":50,"y":13,"position":"center","animation":"fade","animIn":0.25,"animOut":0.2},{"id":"release-title","type":"text","trackId":"copy","text":"A new chapter","start":0,"end":20,"font":"Hanken Grotesk","size":21,"color":"#F7F0DB","background":"none","width":0.84,"x":50,"y":70,"position":"center","animation":"fade","animIn":0.25,"animOut":0.2},{"id":"lyric-0","type":"text","trackId":"copy","text":"This is an original demo line","start":0,"end":5,"font":"Hanken Grotesk","size":12,"color":"#F7F0DB","background":"none","width":0.84,"x":50,"y":82,"position":"center","animation":"fade","animIn":0.25,"animOut":0.2},{"id":"lyric-1","type":"text","trackId":"copy","text":"Not a copied song","start":5,"end":10,"font":"Hanken Grotesk","size":12,"color":"#F7F0DB","background":"none","width":0.84,"x":50,"y":82,"position":"center","animation":"fade","animIn":0.25,"animOut":0.2}],"targetDuration":20,"exportSettings":{"aspect":"9:16","fps":30,"resolution":"1080p","quality":"high"}},"review":{"schemaVersion":1,"state":"needs-human-review","humanApproved":false,"purpose":"release-teaser","durationSec":20,"sourceOffset":0,"lyricCount":2,"providerCalls":0,"warnings":["Listen to the export and review the artwork, names, date, exact lyric text and timing.","This is a social release visual, not a generated music video or a certified Spotify/Apple Music asset.","No beat detection, automatic lyric alignment, generated vocals or music licensing is included."]}}},{"name":"Release Visuals original-media example 2","input":{"assets":[{"kind":"image","assetId":"photo-1","versionId":"v1","url":"https://media.example/photo-1.jpg","width":1600,"height":1200},{"kind":"audio","assetId":"original-song","versionId":"v1","url":"https://media.example/song.wav","duration":180}],"title":"A new chapter","artist":"Example artist","purpose":"lyric-excerpt","lyrics":"0-5 | This is an original demo line\n5-10 | Not a copied song","duration":20,"rightsConfirmed":true},"expected":{"timeline":{"schemaVersion":1,"activeTimelineId":"release-visuals","name":"A new chapter","aspect":"9:16","aspectRatio":"9:16","previewH":369,"backgroundColor":"#0A0A0A","tracks":[{"id":"art","type":"video","label":"Original artwork"},{"id":"song","type":"audio","label":"Original recording"},{"id":"copy","type":"text","label":"Release copy and lyrics"},{"id":"detail","type":"overlay","label":"Excerpt progress"}],"trackOrder":["art","song","detail","copy"],"clips":[{"id":"original-cover","kind":"image","trackId":"art","asset":{"kind":"image","assetId":"photo-1","versionId":"v1","url":"https://media.example/photo-1.jpg","width":1600,"height":1200},"assetId":"photo-1","versionId":"v1","url":"https://media.example/photo-1.jpg","title":"Original artwork","start":0,"duration":20,"trimStart":0,"volume":0,"speed":1,"transform":{"fit":"contain","scale":0.84,"x":0,"y":-22,"rotation":0,"opacity":1},"motion":{"type":"zoom","intensity":100,"zoomAmount":1.035,"zoomDirection":"in","zoomAnchor":"center","easing":"ease-in-out","loop":false,"window":[0,100]},"transition":{"type":"Cut","duration":0}}],"audioItems":[{"id":"original-song","trackId":"song","asset":{"kind":"audio","assetId":"original-song","versionId":"v1","url":"https://media.example/song.wav","duration":180},"assetId":"original-song","versionId":"v1","url":"https://media.example/song.wav","title":"Original song","start":0,"duration":20,"sourceOffset":0,"trimStart":0,"volume":100,"rate":1,"fadeIn":0.15,"fadeOut":0.7}],"textOverlays":[{"id":"artist","type":"text","trackId":"copy","text":"Example artist","start":0,"end":20,"font":"Hanken Grotesk","size":10,"color":"#F7F0DB","background":"none","width":0.84,"x":50,"y":13,"position":"center","animation":"fade","animIn":0.25,"animOut":0.2},{"id":"release-title","type":"text","trackId":"copy","text":"A new chapter","start":0,"end":20,"font":"Hanken Grotesk","size":21,"color":"#F7F0DB","background":"none","width":0.84,"x":50,"y":70,"position":"center","animation":"fade","animIn":0.25,"animOut":0.2},{"id":"lyric-0","type":"text","trackId":"copy","text":"This is an original demo line","start":0,"end":5,"font":"Hanken Grotesk","size":12,"color":"#F7F0DB","background":"none","width":0.84,"x":50,"y":82,"position":"center","animation":"fade","animIn":0.25,"animOut":0.2},{"id":"lyric-1","type":"text","trackId":"copy","text":"Not a copied song","start":5,"end":10,"font":"Hanken Grotesk","size":12,"color":"#F7F0DB","background":"none","width":0.84,"x":50,"y":82,"position":"center","animation":"fade","animIn":0.25,"animOut":0.2}],"captions":[],"stickers":[{"id":"progress-0","trackId":"detail","shape":"underline","color":"#F7F0DB","x":20,"y":92,"scale":0.04,"stretchX":0.55,"stretchY":0.4,"opacity":0.75,"rotation":0,"start":0,"end":20},{"id":"progress-1","trackId":"detail","shape":"underline","color":"#F7F0DB","x":24,"y":92,"scale":0.04,"stretchX":0.55,"stretchY":0.4,"opacity":0.75,"rotation":0,"start":1.25,"end":20},{"id":"progress-2","trackId":"detail","shape":"underline","color":"#F7F0DB","x":28,"y":92,"scale":0.04,"stretchX":0.55,"stretchY":0.4,"opacity":0.75,"rotation":0,"start":2.5,"end":20},{"id":"progress-3","trackId":"detail","shape":"underline","color":"#F7F0DB","x":32,"y":92,"scale":0.04,"stretchX":0.55,"stretchY":0.4,"opacity":0.75,"rotation":0,"start":3.75,"end":20},{"id":"progress-4","trackId":"detail","shape":"underline","color":"#F7F0DB","x":36,"y":92,"scale":0.04,"stretchX":0.55,"stretchY":0.4,"opacity":0.75,"rotation":0,"start":5,"end":20},{"id":"progress-5","trackId":"detail","shape":"underline","color":"#F7F0DB","x":40,"y":92,"scale":0.04,"stretchX":0.55,"stretchY":0.4,"opacity":0.75,"rotation":0,"start":6.25,"end":20},{"id":"progress-6","trackId":"detail","shape":"underline","color":"#F7F0DB","x":44,"y":92,"scale":0.04,"stretchX":0.55,"stretchY":0.4,"opacity":0.75,"rotation":0,"start":7.5,"end":20},{"id":"progress-7","trackId":"detail","shape":"underline","color":"#F7F0DB","x":48,"y":92,"scale":0.04,"stretchX":0.55,"stretchY":0.4,"opacity":0.75,"rotation":0,"start":8.75,"end":20},{"id":"progress-8","trackId":"detail","shape":"underline","color":"#F7F0DB","x":52,"y":92,"scale":0.04,"stretchX":0.55,"stretchY":0.4,"opacity":0.75,"rotation":0,"start":10,"end":20},{"id":"progress-9","trackId":"detail","shape":"underline","color":"#F7F0DB","x":56,"y":92,"scale":0.04,"stretchX":0.55,"stretchY":0.4,"opacity":0.75,"rotation":0,"start":11.25,"end":20},{"id":"progress-10","trackId":"detail","shape":"underline","color":"#F7F0DB","x":60,"y":92,"scale":0.04,"stretchX":0.55,"stretchY":0.4,"opacity":0.75,"rotation":0,"start":12.5,"end":20},{"id":"progress-11","trackId":"detail","shape":"underline","color":"#F7F0DB","x":64,"y":92,"scale":0.04,"stretchX":0.55,"stretchY":0.4,"opacity":0.75,"rotation":0,"start":13.75,"end":20},{"id":"progress-12","trackId":"detail","shape":"underline","color":"#F7F0DB","x":68,"y":92,"scale":0.04,"stretchX":0.55,"stretchY":0.4,"opacity":0.75,"rotation":0,"start":15,"end":20},{"id":"progress-13","trackId":"detail","shape":"underline","color":"#F7F0DB","x":72,"y":92,"scale":0.04,"stretchX":0.55,"stretchY":0.4,"opacity":0.75,"rotation":0,"start":16.25,"end":20},{"id":"progress-14","trackId":"detail","shape":"underline","color":"#F7F0DB","x":76,"y":92,"scale":0.04,"stretchX":0.55,"stretchY":0.4,"opacity":0.75,"rotation":0,"start":17.5,"end":20},{"id":"progress-15","trackId":"detail","shape":"underline","color":"#F7F0DB","x":80,"y":92,"scale":0.04,"stretchX":0.55,"stretchY":0.4,"opacity":0.75,"rotation":0,"start":18.75,"end":20}],"effects":[],"audio":[{"id":"original-song","trackId":"song","asset":{"kind":"audio","assetId":"original-song","versionId":"v1","url":"https://media.example/song.wav","duration":180},"assetId":"original-song","versionId":"v1","url":"https://media.example/song.wav","title":"Original song","start":0,"duration":20,"sourceOffset":0,"trimStart":0,"volume":100,"rate":1,"fadeIn":0.15,"fadeOut":0.7}],"overlays":[{"id":"artist","type":"text","trackId":"copy","text":"Example artist","start":0,"end":20,"font":"Hanken Grotesk","size":10,"color":"#F7F0DB","background":"none","width":0.84,"x":50,"y":13,"position":"center","animation":"fade","animIn":0.25,"animOut":0.2},{"id":"release-title","type":"text","trackId":"copy","text":"A new chapter","start":0,"end":20,"font":"Hanken Grotesk","size":21,"color":"#F7F0DB","background":"none","width":0.84,"x":50,"y":70,"position":"center","animation":"fade","animIn":0.25,"animOut":0.2},{"id":"lyric-0","type":"text","trackId":"copy","text":"This is an original demo line","start":0,"end":5,"font":"Hanken Grotesk","size":12,"color":"#F7F0DB","background":"none","width":0.84,"x":50,"y":82,"position":"center","animation":"fade","animIn":0.25,"animOut":0.2},{"id":"lyric-1","type":"text","trackId":"copy","text":"Not a copied song","start":5,"end":10,"font":"Hanken Grotesk","size":12,"color":"#F7F0DB","background":"none","width":0.84,"x":50,"y":82,"position":"center","animation":"fade","animIn":0.25,"animOut":0.2}],"targetDuration":20,"exportSettings":{"aspect":"9:16","fps":30,"resolution":"1080p","quality":"high"}},"review":{"schemaVersion":1,"state":"needs-human-review","humanApproved":false,"purpose":"lyric-excerpt","durationSec":20,"sourceOffset":0,"lyricCount":2,"providerCalls":0,"warnings":["Listen to the export and review the artwork, names, date, exact lyric text and timing.","This is a social release visual, not a generated music video or a certified Spotify/Apple Music asset.","No beat detection, automatic lyric alignment, generated vocals or music licensing is included."]}}}],"portable":{"format":"stillmade-block/1","dependencies":[],"sources":[{"kind":"original","license":"MIT","paths":["LICENSE","src/run.js"],"evidence":["upstream/0/LICENSE","upstream/0/src/run.js"],"changes":"Original implementation declared by the packager; no reused repository or dependency code."}],"files":{"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","upstream/0/src/run.js":"// Original release-art and lyric-excerpt composition. No inference or I/O.\nconst copy=x=>JSON.parse(JSON.stringify(x)),check=(ok,message)=>{if(!ok)throw Error(message);};\nconst short=(v,label,n=80)=>{check(typeof v==='string'&&v.length<=n&&!/[\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f]/.test(v),label+' must be short plain text.');return v.trim();};\ncheck(input.rightsConfirmed===true,'Confirm rights to the cover art, recording and any lyrics.');\nconst assets=input.assets;check(Array.isArray(assets)&&assets.length===2,'Choose exactly one cover image and one audio recording.');\nconst cover=assets.find(a=>a.kind==='image'),song=assets.find(a=>a.kind==='audio');check(cover&&song,'Supply one original cover image and one audio recording.');\nfor(const a of assets)check(typeof a.assetId==='string'&&a.assetId&&typeof a.versionId==='string'&&a.versionId&&typeof a.url==='string'&&/^(https:\\/\\/|http:\\/\\/(localhost|127\\.0\\.0\\.1)(:\\d+)?\\/|\\/api\\/media\\/|sm-media:|blob:)/.test(a.url)&&!/^https?:\\/\\/[^/?#]*@/.test(a.url),'Use exact saved media references.');\ncheck(Number.isFinite(cover.width)&&cover.width>0&&Number.isFinite(cover.height)&&cover.height>0,'Upload cover art again to record its dimensions.');\ncheck(Number.isFinite(song.duration)&&song.duration>0,'Upload the recording again to measure its duration.');\nconst duration=input.duration??20,offset=input.offset??0;\ncheck(Number.isFinite(duration)&&duration>=8&&duration<=60&&Number.isFinite(offset)&&offset>=0&&offset+duration<=song.duration+.02,'Choose an available 8–60 second song excerpt.');\nconst title=short(input.title||'','Release title',56),artist=short(input.artist||'','Artist',56),cta=short(input.cta||'','Release message',64),disclosure=short(input.disclosure||'','Disclosure',100);check(title&&artist,'Supply the release title and artist.');\nconst aspect=input.aspect||'9:16';check(['9:16','1:1','16:9'].includes(aspect),'Choose an output frame shape.');\nconst purpose=input.purpose||'release-teaser';check(['release-teaser','lyric-excerpt'].includes(purpose),'Choose a release teaser or lyric excerpt.');\nconst raw=input.lyrics||'';check(typeof raw==='string'&&raw.length<=8000,'Use up to 8,000 characters of timed lyrics.');\n// Human-approved lyric timing is relative to this excerpt, not the full song.\nconst lyrics=raw.trim()?raw.trim().split('\\n').map(line=>{const m=line.match(/^(\\d+(?:\\.\\d+)?)\\s*-\\s*(\\d+(?:\\.\\d+)?)\\s*\\|\\s*(.+)$/);check(m,'Use lyric lines like 0-3.5 | exact words');const from=+m[1],to=+m[2],value=short(m[3],'Lyric line',100);check(to>from&&from>=0&&to<=duration,'A lyric line is outside the excerpt.');return{from,to,text:value};}):[];\ncheck(lyrics.length<=40,'Use at most 40 lyric lines.');for(let i=1;i<lyrics.length;i++)check(lyrics[i].from>=lyrics[i-1].to,'Lyric lines must be ordered without overlap.');check(purpose!=='lyric-excerpt'||lyrics.length,'Supply reviewed timed lyrics for a lyric excerpt.');\nconst portrait=aspect==='9:16',square=aspect==='1:1',W=369*Number(aspect.split(':')[0])/Number(aspect.split(':')[1]);\nconst fit=Math.min(W/cover.width,369/cover.height),scale=Math.min(W*.84/(cover.width*fit),369*(portrait?.46:.6)/(cover.height*fit));\nconst clips=[{id:'original-cover',kind:'image',trackId:'art',asset:copy(cover),assetId:cover.assetId,versionId:cover.versionId,url:cover.url,title:cover.name||'Original artwork',start:0,duration,trimStart:0,volume:0,speed:1,transform:{fit:'contain',scale,x:0,y:portrait?-22:-10,rotation:0,opacity:1},motion:{type:'zoom',intensity:100,zoomAmount:1.035,zoomDirection:'in',zoomAnchor:'center',easing:'ease-in-out',loop:false,['window']:[0,100]},transition:{type:'Cut',duration:0}}];\nconst overlays=[],stickers=[];\nconst add=(id,value,start,end,y,size,color='#F7F0DB')=>{if(value)overlays.push({id,type:'text',trackId:'copy',text:value,start,end,font:'Hanken Grotesk',size,color,background:'none',width:.84,x:50,y,position:'center',animation:'fade',animIn:.25,animOut:.2});};\nadd('artist',artist,0,duration,portrait?13:9,portrait?10:14);\nadd('release-title',title,0,duration,portrait?70:79,portrait?21:25);\nadd('release-message',lyrics.length?'':cta,0,duration,portrait?86:92,portrait?10:13);\nfor(const [i,line]of lyrics.entries())add('lyric-'+i,line.text,line.from,line.to,portrait?82:91,portrait?12:15);\n// The progress row indicates excerpt time only; it makes no beat-detection claim.\nfor(let i=0;i<16;i++)stickers.push({id:'progress-'+i,trackId:'detail',shape:'underline',color:'#F7F0DB',x:20+i*4,y:portrait?92:97,scale:.04,stretchX:.55,stretchY:.4,opacity:.75,rotation:0,start:duration*i/16,end:duration});\nadd('disclosure',disclosure,0,duration,97,portrait?5:7);\nconst audioItems=[{id:'original-song',trackId:'song',asset:copy(song),assetId:song.assetId,versionId:song.versionId,url:song.url,title:song.name||'Original song',start:0,duration,sourceOffset:offset,trimStart:offset,volume:100,rate:1,fadeIn:.15,fadeOut:.7}];\nconst timeline={schemaVersion:1,activeTimelineId:'release-visuals',name:title,aspect,aspectRatio:aspect,previewH:369,backgroundColor:'#0A0A0A',tracks:[{id:'art',type:'video',label:'Original artwork'},{id:'song',type:'audio',label:'Original recording'},{id:'copy',type:'text',label:'Release copy and lyrics'},{id:'detail',type:'overlay',label:'Excerpt progress'}],trackOrder:['art','song','detail','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,purpose,durationSec:duration,sourceOffset:offset,lyricCount:lyrics.length,providerCalls:0,warnings:['Listen to the export and review the artwork, names, date, exact lyric text and timing.','This is a social release visual, not a generated music video or a certified Spotify/Apple Music asset.','No beat detection, automatic lyric alignment, generated vocals or music licensing is included.']}};\n"},"lineage":{"parents":[],"changes":"Packaged original Block source for StillMade."}}}],"license":"MIT"}