function FlowChunk(flowObj,fileObj,offset){this.flowObj=flowObj;this.fileObj=fileObj;this.fileObjSize=fileObj.size;this.offset=offset;this.retries=0;this.pendingRetry=false;this.loaded=0;this._lastLoaded=0;this.total=0;if(this.flowObj.opts.chunkSize){this.startByte=fileObj.offset+this.offset*this.flowObj.opts.chunkSize}else{this.startByte=0}if(this.flowObj.opts.chunkSize){this.endByte=Math.min(this.fileObjSize,this.startByte+this.flowObj.opts.chunkSize)}else{this.endByte=this.fileObjSize}this.size=this.endByte-this.startByte;this.xhr=null;var $=this;this.progressHandler=function(event){if(event.lengthComputable){$.loaded=Math.min(event.loaded,$.size);$.total=Math.min(event.total,$.size);if($.loaded>$._lastLoaded){var loadedNow=$.loaded-$._lastLoaded;$.fileObj.completedBytes+=loadedNow;$.flowObj.completedBytes+=loadedNow}$._lastLoaded=$.loaded}$.fileObj.chunkEvent("progress")};this.doneHandler=function(event){var status=$.status();var message=$.message();if(status==="success"){$.retries=0;$.fileObj.completedChunks++;$.fileObj.chunkEvent("success",message)}else{$.fileObj.uploadingChunk=false;$.abort();if(status==="error"){$.retries=0;$.fileObj.chunkEvent("error",message)}else{if($.retries<$.flowObj.opts.maxChunkRetries){$.retries++;var retryInterval=$.flowObj.opts.chunkRetryInterval;if(retryInterval!==null){if($.retries>1){retryInterval=retryInterval*$.retries}setTimeout(function(){$.send()},retryInterval)}else{$.send()}}else{$.retries=0;$.fileObj.chunkEvent("error",message)}}}}}FlowChunk.prototype={getParams:function(){var params={flowTotalSize:this.fileObjSize,flowIsFirstChunk:this.startByte==0?1:0,flowIsLastChunk:this.endByte==this.fileObjSize?1:0};if(this.fileObj.relativePath){params.flowRelativePath=this.fileObj.relativePath}if(navigator.userAgent.toLowerCase().indexOf("firefox")>-1){params.flowFilename=this.fileObj.name}return params},send:function(){this.fileObj.uploadingChunk=this;this.loaded=0;this._lastLoaded=0;this.total=0;this.pendingRetry=false;var func=this.fileObj.file.slice?"slice":this.fileObj.file.mozSlice?"mozSlice":this.fileObj.file.webkitSlice?"webkitSlice":"slice";var bytes=this.fileObj.file[func](this.startByte,this.endByte);this.xhr=new XMLHttpRequest;this.xhr.upload.addEventListener("progress",this.progressHandler,false);this.xhr.addEventListener("load",this.doneHandler,false);this.xhr.addEventListener("error",this.doneHandler,false);var data=this.prepareXhrRequest(bytes);this.xhr.send(data)},abort:function(){if(this.xhr){this.xhr.abort();if(this.loaded){this.fileObj.completedBytes-=this.loaded;this.flowObj.completedBytes-=this.loaded}}this.fileObj.chunkEvent("abort")},status:function(){if(this.pendingRetry){return"uploading"}else if(!this.xhr){return"pending"}else if(this.xhr.readyState<4){return"uploading"}else{return this.flowObj.opts.validateChunkResponse.call(this.flowObj.opts.validateChunkResponseScope||this,this.xhr.status,this.xhr.responseText)}},message:function(){return this.xhr?this.xhr.responseText:""},prepareXhrRequest:function(blob){var query=this.fileObj.query;if(typeof query==="function"){query=query(this.fileObj,this)}query=this.flowObj.extend(this.getParams(),query);var data=new FormData;this.flowObj.each(query,function(v,k){data.append(k,v)});data.append(this.flowObj.opts.fileParameterName,blob,this.fileObj.name);this.xhr.open("POST",this.flowObj.opts.target);this.xhr.withCredentials=this.flowObj.opts.withCredentials;this.flowObj.each(this.flowObj.opts.headers,function(v,k){this.xhr.setRequestHeader(k,v)},this);return data}};