'use strict'; const $=id=>document.getElementById(id); const REV='b08c2bf3be8e67039c363781e6eaacc9713340cd'; const BASE='https://huggingface.co/ZhengmingYu/DMAD/resolve/'+REV+'/'; const ROUTER='https://router.huggingface.co/wavespeed'; const LORA=BASE+'minimax_h3/dmad_minimax_h3_4step_full_critic.safetensors'; const examples={guitar:['dmad_h3_4step_5s_8gb_guitar.mp4','5 seconds, 4-step DMAD. Source reports its 8 GB workflow was tested with low-VRAM optimizations.'],podcast:['dmad_h3_4step_15s_podcast.mp4','15 seconds, 4-step DMAD, with native audio.'],wok:['dmad_h3_8step_15s_wok.mp4','15 seconds, 8-step example. See the source for its checkpoint details.']}; function selectSample(){const [file,description]=examples[$('sample').value];const url=BASE+'minimax_h3/workflows/'+file;$('example').src=url;$('exampleLink').href=url;$('sampletext').textContent=description} $('sample').addEventListener('change',selectSample);selectSample(); let used=false;const sleep=ms=>new Promise(resolve=>setTimeout(resolve,ms)); function status(msg){$('status').textContent=msg} function fail(text){status(text);$('reset').classList.remove('hide')} async function generate(){ if(used)return; const prompt=$('prompt').value.trim(), token=$('token').value.trim(); if(!prompt||!token||!$('consent').checked){status('Please add a prompt, your inference token, and approve the request.');return} used=true;$('generate').disabled=true;$('reset').classList.add('hide');$('result').classList.add('hide'); const headers={'Content-Type':'application/json','Authorization':'Bearer '+token}; let jobId=''; status('Submitting one request. Please keep this page open; do not submit again if the connection fails.'); try{ const resp=await fetch(ROUTER+'/api/v3/wavespeed-ai/minimax-h3/text-to-video-lora',{method:'POST',headers,body:JSON.stringify({prompt,aspect_ratio:$('ratio').value,resolution:$('resolution').value,duration:5,loras:[{path:LORA,scale:1}]})}); if(!resp.ok){let message='';try{const j=await resp.json();message=String(j.message||j.error||j.detail||'')}catch(_){}throw new Error('Submission HTTP '+resp.status+'. '+message)} const submitted=await resp.json();const info=submitted.data||{};const id=String(info.id||'');jobId=id;const resultUrl=info.urls?.get;if(typeof resultUrl!=='string')throw new Error('Provider did not return a status URL. Check provider history before retrying.'); const u=new URL(resultUrl);if(u.protocol!=='https:'||!['api.wavespeed.ai','router.huggingface.co'].includes(u.hostname)||!u.pathname.startsWith('/api/v3/'))throw new Error('Provider returned an unexpected status URL. Check provider history before retrying.'); status('Submitted'+(id?' · Job ID: '+id:'')+'\nGeneration is in progress. This may take several minutes.'); for(let i=0;i<180;i++){ await sleep(5000);const r=await fetch(ROUTER+u.pathname,{headers:{Authorization:'Bearer '+token},cache:'no-store'});if(!r.ok)throw new Error('Status check HTTP '+r.status+'. Job may still be running.'); const j=await r.json(),d=j.data||{}; if(d.status==='failed')throw new Error('Provider reports generation failed: '+String(d.error||'unknown error')); if(d.status==='completed'){ const out=d.outputs?.[0];if(typeof out!=='string')throw new Error('Generation finished, but no video URL was returned.');const output=new URL(out);if(output.protocol!=='https:')throw new Error('Unexpected output URL.'); $('generated').src=output.href;$('download').href=output.href;$('result').classList.remove('hide');status('Generation finished'+(id?' · Job ID: '+id:'')+'.');return; } } throw new Error('Status checks timed out. The job may still be running.'); }catch(e){const safe=String(e.message||e).split(token).join('[redacted]');fail(safe+(jobId?'\nJob ID: '+jobId:'')+'\nCheck provider history and charges before any retry. A submitted request may still finish or be billed.');} } $('generate').addEventListener('click',generate); $('reset').addEventListener('click',()=>{if(!confirm('A previous request may still be running or billed. Have you checked provider history before trying again?'))return;used=false;$('generate').disabled=false;$('reset').classList.add('hide');$('consent').checked=false;status('Ready for another request. Review pricing and approve again.');});