PageSourceSearch

https://auphonic.com/static/CACHE/js/output.cf25b51921cc.js

js auphonic.com collected 2026-10-01 08:45:31 UTC 8,673 bytes, 16 lines download raw bytes

1const S3_UPLOAD_CHUNK_SIZE=20*1024*1024;const MAX_CONCURRENT_UPLOADS=3;const fetchWithRetry=async(url,options,{maxRetries=6,signal}={})=>{let lastError;for(let attempt=0;attempt<=maxRetries;attempt++){if(signal&&signal.aborted){throw new DOMException('Upload cancelled','AbortError');}
2try{const response=await fetch(url,{...options,signal});return response;}catch(error){if(error.name==='AbortError')throw error;lastError=error;if(attempt>=maxRetries)break;const backoffTime=Math.pow(2,attempt+2)*1000;console.warn(`Fetch attempt ${attempt + 1}/${maxRetries + 1} failed for ${url}: ${error.message}. Retrying in ${backoffTime}ms...`);await new Promise(resolve=>setTimeout(resolve,backoffTime));}}
3throw lastError;};const handleS3DirectUpload=async(config)=>{try{const{files,uuid,action,csrfToken,urls,onProgress,onError,batchProduction,signal,resetEdits}=config;if(!files||!files.length){throw new Error('No files provided for upload');}
4const filesInfo=files.map(file=>({filename:file.file.name,filesize:file.file.size,filetype:file.file.type,id:file.id,uuid:file.uuid||uuid}));const initResponse=await fetchWithRetry('/engine/file/s3multipart/init/',{method:'POST',headers:{'Content-Type':'application/json','X-CSRFToken':csrfToken},body:JSON.stringify({files:filesInfo,batchProduction:batchProduction||false})},{signal});if(!initResponse.ok){const errorData=await initResponse.json();throw new Error(errorData.error||'Failed to initialize multipart uploads');}
5const multipartDataArray=await initResponse.json();const fileUploads=files.map((cFile,index)=>{const multipartData=multipartDataArray[index];return{file:cFile.file,uploadId:multipartData.uploadId,key:multipartData.key,id:cFile.id,uuid:cFile.uuid||uuid,totalChunks:Math.ceil(cFile.file.size/S3_UPLOAD_CHUNK_SIZE),etags:[],chunkProgress:[]};});const totalChunksAllFiles=fileUploads.reduce((sum,fileUpload)=>sum+fileUpload.totalChunks,0);console.log(`Total chunks across all files: ${totalChunksAllFiles}`);let totalCompletedChunks=0;fileUploads.forEach(fileUpload=>{fileUpload.chunkProgress=new Array(fileUpload.totalChunks).fill(0);fileUpload.etags=new Array(fileUpload.totalChunks);});const updateOverallProgress=()=>{if(!onProgress)return;let totalProgress=0;let totalFileSize=0;fileUploads.forEach(fileUpload=>{const fileProgress=fileUpload.chunkProgress.reduce((sum,progress)=>sum+progress,0)/fileUpload.totalChunks;totalProgress+=fileProgress*fileUpload.file.size;totalFileSize+=fileUpload.file.size;});const overallProgress=totalFileSize>0?(totalProgress/totalFileSize)*100:0;onProgress(Math.min(99,Math.floor(overallProgress)));};const uploadChunkWithRetry=async(fileUpload,chunk,url,partNumber,chunkIndex,maxRetries=6)=>{let retryCount=0;let errorMessage='';while(retryCount<=maxRetries){try{const result=await new Promise((resolve,reject)=>{if(signal&&signal.aborted){reject(new DOMException('Upload cancelled','AbortError'));return;}
6const xhr=new XMLHttpRequest();let lastProgress=Date.now();if(signal){signal.addEventListener('abort',()=>xhr.abort(),{once:true});}
7xhr.onload=function(){if(this.status>=200&&this.status<300){const etag=xhr.getResponseHeader('ETag');resolve({success:true,etag:etag});}else{try{const errorResponse=JSON.parse(xhr.responseText);if(errorResponse&&errorResponse.error){reject(new Error(errorResponse.error));}else{reject(new Error(`Failed to upload part ${partNumber}: ${this.status} ${this.statusText}`));}}catch(e){reject(new Error(`Failed to upload part ${partNumber}: ${this.status} ${this.statusText}`));}}};xhr.onerror=function(){let currentErrorMessage=`Network error occurred while uploading part ${partNumber}/${fileUpload.totalChunks} of "${fileUpload.file.name}"`;currentErrorMessage+=`, Attempt: ${retryCount + 1}/${maxRetries + 1}`;if(errorMessage){currentErrorMessage+=`, Error: ${errorMessage}`;}
8reject(new Error(currentErrorMessage));};const stallCheckInterval=setInterval(()=>{if(Date.now()-lastProgress>29000*(retryCount+1)){clearInterval(stallCheckInterval);xhr.abort();reject(new Error('Upload stalled'));}},30000*(retryCount+1));xhr.ontimeout=function(){reject(new Error(`Timeout occurred while uploading part ${partNumber}`));};xhr.open('PUT',url,true);xhr.setRequestHeader('Content-Type','application/octet-stream');xhr.setRequestHeader('Cache-Control','no-cache');xhr.upload.onprogress=(e)=>{lastProgress=Date.now();if(e.lengthComputable){fileUpload.chunkProgress[chunkIndex]=e.loaded/e.total;updateOverallProgress();}};xhr.send(chunk);});fileUpload.chunkProgress[chunkIndex]=1;updateOverallProgress();return result;}catch(error){if(error.name==='AbortError')throw error;retryCount++;
8if(retryCount>maxRetries){console.error(`Failed to upload part ${partNumber} after ${maxRetries} attempts: ${error.message}`);errorMessage=error.message;throw error;}
9console.warn(`Attempt ${retryCount}/${maxRetries} failed for part ${partNumber}: ${error.message}. Retrying...`);const backoffTime=Math.pow(2,(retryCount+2))*1000;console.log(`Waiting ${backoffTime}ms before retry`);await new Promise(resolve=>setTimeout(resolve,backoffTime));}}};console.log(`Starting parallel upload of ${totalChunksAllFiles} total chunks with max ${MAX_CONCURRENT_UPLOADS} concurrent uploads`);const chunksQueue=[];fileUploads.forEach((fileUpload,fileIndex)=>{for(let chunkIndex=0;chunkIndex<fileUpload.totalChunks;chunkIndex++){chunksQueue.push({fileUpload,fileIndex,chunkIndex,partNumber:chunkIndex+1});}});let activeUploads=0;let nextChunkQueueIndex=0;const allChunksUploaded=new Promise(async(resolveAll,rejectAll)=>{const startNextChunkUpload=async()=>{if((signal&&signal.aborted)||nextChunkQueueIndex>=chunksQueue.length){return;}
10activeUploads++;const currentQueueIndex=nextChunkQueueIndex++;const{fileUpload,chunkIndex,partNumber}=chunksQueue[currentQueueIndex];try{const start=chunkIndex*S3_UPLOAD_CHUNK_SIZE;const end=Math.min(fileUpload.file.size,start+S3_UPLOAD_CHUNK_SIZE);const chunk=fileUpload.file.slice(start,end);console.log(`Starting upload for file ${fileUpload.file.name}, part ${partNumber}/${fileUpload.totalChunks} (${activeUploads} active uploads)`);const partResponse=await fetchWithRetry('/engine/file/s3multipart/part/',{method:'POST',headers:{'Content-Type':'application/json','X-CSRFToken':csrfToken},body:JSON.stringify({key:fileUpload.key,uploadId:fileUpload.uploadId,id:fileUpload.id,partNumber:partNumber,uuid:fileUpload.uuid,size:chunk.size})},{signal});if(!partResponse.ok){const errorData=await partResponse.json();throw new Error(errorData.error||'Failed to get part upload URL');}
11const partData=await partResponse.json();const result=await uploadChunkWithRetry(fileUpload,chunk,partData.presignedUrl,partNumber,chunkIndex);let etag=result.etag;if(!etag){throw new Error(`Failed to get ETag for part ${partNumber}`);}
12fileUpload.etags[chunkIndex]={PartNumber:partNumber,ETag:etag};totalCompletedChunks++;console.log(`Completed chunk ${totalCompletedChunks}/${totalChunksAllFiles} (${activeUploads - 1} still active)`);}catch(error){rejectAll(error);return;}finally{activeUploads--;if(totalCompletedChunks<totalChunksAllFiles){startNextChunkUpload();}else if(activeUploads===0){resolveAll();}}};const initialUploads=Math.min(MAX_CONCURRENT_UPLOADS,chunksQueue.length);const initialUploadPromises=[];for(let i=0;i<initialUploads;i++){initialUploadPromises.push(startNextChunkUpload());}
13if(initialUploads===chunksQueue.length){await Promise.all(initialUploadPromises);resolveAll();}});await allChunksUploaded;const completionData=fileUploads.map(fileUpload=>{const validEtags=fileUpload.etags.filter(etag=>etag!==undefined);return{key:fileUpload.key,uploadId:fileUpload.uploadId,parts:validEtags,filesize:fileUpload.file.size,id:fileUpload.id,uuid:fileUpload.uuid};});const completeResponse=await fetchWithRetry('/engine/file/s3multipart/complete/',{method:'POST',headers:{'Content-Type':'application/json','X-CSRFToken':csrfToken},body:JSON.stringify({uploads:completionData,batchProduction:batchProduction||false,action:action,resetEdits:!!resetEdits})},{signal});if(!completeResponse.ok){const errorData=await completeResponse.json();throw new Error(errorData.error||'Failed to complete multipart S3 uploads');}
14if(onProgress)onProgress(100);return{success:true,redirectUrl:(action==='start'||action==='preview')?urls.statusUrl:urls.editUrl};}catch(error){console.error('S3 Direct Upload Error:',error);if(config.onError){config.onError(error.message||'Failed to upload files to S3');}
15return{success:false,error:error.message||'Failed to upload files to S3'};}};if(typeof window!=='undefined'){window.handleS3DirectUpload=handleS3DirectUpload;}
16try{if(typeof module!=='undefined'){module.exports={handleS3DirectUpload};}}catch(e){};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.