var c=new Map;addEventListener("message",e=>{let t=e.data;switch(t.type){case"UPLOAD_FILE":k(t).catch(r=>postMessage({type:"ERROR",fileId:t.fileId,error:r.message||String(r)}));break;case"PAUSE_UPLOAD":{let r=c.get(t.fileId);r&&(r.paused=!0,postMessage({type:"PAUSED",fileId:t.fileId}));break}case"RESUME_UPLOAD":{let r=c.get(t.fileId);r&&r.paused&&(r.paused=!1,postMessage({type:"RESUMED",fileId:t.fileId}));break}case"CANCEL_UPLOAD":{let r=c.get(t.fileId);r&&(r.canceled=!0,c.delete(t.fileId),postMessage({type:"CANCELED",fileId:t.fileId}));break}}});async function k(e){let t=e.file,r=Math.max(1,Math.ceil(t.size/e.chunkSize)),s={file:t,uploadUrl:e.uploadUrl,chunkSize:e.chunkSize,totalChunks:r,uploadedBytes:0,blockIds:[],canceled:!1,paused:!1,concurrency:e.concurrency??3,maxRetries:e.maxRetries??3,retryDelayMs:e.retryDelayMs??500,extraForm:e.extraForm??{}};c.set(e.fileId,s);let i=0,a=0;await new Promise((n,o)=>{let d=()=>{if(s.canceled)return o(new Error("Canceled"));if(i>=s.totalChunks&&a===0)return n();for(;a<s.concurrency&&i<s.totalChunks;){let l=i++,u=l*s.chunkSize,f=Math.min(t.size,u+s.chunkSize),p=btoa(String(l).padStart(8,"0"));s.blockIds[l]=p;let y=t.slice(u,f);a++,E(s,e.fileId,y,p,l).then(I=>{s.uploadedBytes+=I;let m=Math.min(100,s.uploadedBytes/t.size*100);postMessage({type:"PROGRESS",fileId:e.fileId,percent:m}),postMessage({type:"CHUNK_OK",fileId:e.fileId,currentChunk:l+1,totalChunks:s.totalChunks}),a--,d()}).catch(o)}};d()});try{await h(s),c.delete(e.fileId),postMessage({type:"FILE_DONE",fileId:e.fileId})}catch(n){c.delete(e.fileId),postMessage({type:"ERROR",fileId:e.fileId,error:n.message||String(n)})}}async function E(e,t,r,s,i){let a=0,n=e.retryDelayMs;for(;;){if(e.canceled)throw new Error("Canceled");e.paused&&await new Promise(o=>setTimeout(o,100));try{return await b(e,t,r,s,i),r.size}catch(o){if(a++,a>e.maxRetries)throw new Error(`Block ${i} failed after ${e.maxRetries} retries: ${o.message||String(o)}`);await new Promise(d=>setTimeout(d,n)),n*=2}}}function b(e,t,r,s,i){return new Promise((a,n)=>{let o=new XMLHttpRequest,d=e.uploadUrl.includes("?")?"&":"?";o.open("PUT",`${e.uploadUrl}${d}comp=block&blockid=${encodeURIComponent(s)}`,!0);try{o.setRequestHeader("x-ms-blob-type","BlockBlob")}catch{}if(e.extraForm)for(let[l,u]of Object.entries(e.extraForm))try{o.setRequestHeader(l,u)}catch{}o.onload=()=>{o.status>=200&&o.status<300?a():n(new Error(`Block ${i} HTTP ${o.status}`))},o.onerror=()=>n(new Error(`Network error block ${i}`)),o.onabort=()=>n(new Error("Aborted")),o.send(r)})}function h(e){let t=`<?xml version="1.0" encoding="utf-8"?><BlockList>${e.blockIds.map(i=>`<Latest>${i}</Latest>`).join("")}</BlockList>`,r=e.uploadUrl.includes("?")?"&":"?",s=`${e.uploadUrl}${r}comp=blocklist`;return new Promise((i,a)=>{let n=new XMLHttpRequest;n.open("PUT",s,!0);try{n.setRequestHeader("Content-Type","application/xml")}catch{}n.onload=()=>n.status>=200&&n.status<300?i():a(new Error(`Commit HTTP ${n.status}`)),n.onerror=()=>a(new Error("Network error commit")),n.send(t)})}
