Index: typo3/classes/class.typo3_tcefile.php
===================================================================
--- typo3/classes/class.typo3_tcefile.php	(revision 9758)
+++ typo3/classes/class.typo3_tcefile.php	(revision )
@@ -166,13 +166,24 @@
 		$this->init();
 		$this->main();
 		$errors = $this->fileProcessor->getErrorMessages();
+		$uploaderType = t3lib_div::_GP('uploaderType');
 		if (count($errors)) {
 			$ajaxObj->setError(implode(',', $errors));
 		} else {
+			if ($uploaderType === 'plupload') {
-			$ajaxObj->addContent('result', $this->fileData);
+				$ajaxObj->addContent('result', $this->fileData);
+				if (count($this->fileData)) {
+					$ajaxObj->addContent('success', true);
+				} else {
+					$ajaxObj->addContent('success', false);
+				}
+			} else {
+				$ajaxObj->addContent('result', $this->fileData);
-			if ($this->redirect) {
-				$ajaxObj->addContent('redirect', $this->redirect);
-			}
+				if ($this->redirect) {
+					$ajaxObj->addContent('redirect', $this->redirect);
+				}
+			}
+
 			$ajaxObj->setContentFormat('json');
 		}
 	}
@@ -182,4 +193,4 @@
 	include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/classes/class.typo3_tcefile.php']);
 }
 
-?>
\ No newline at end of file
+?>
Index: typo3/contrib/plupload/js/plupload.min.js
===================================================================
--- typo3/contrib/plupload/js/plupload.min.js	(revision )
+++ typo3/contrib/plupload/js/plupload.min.js	(revision )
@@ -0,0 +1,1 @@
+(function(){var c=0,h=[],j={},f={},a={"<":"lt",">":"gt","&":"amp",'"':"quot","'":"#39"},i=/[<>&\"\']/g,b;function e(){this.returnValue=false}function g(){this.cancelBubble=true}(function(k){var l=k.split(/,/),m,o,n;for(m=0;m<l.length;m+=2){n=l[m+1].split(/ /);for(o=0;o<n.length;o++){f[n[o]]=l[m]}}})("application/msword,doc dot,application/pdf,pdf,application/pgp-signature,pgp,application/postscript,ps ai eps,application/rtf,rtf,application/vnd.ms-excel,xls xlb,application/vnd.ms-powerpoint,ppt pps pot,application/zip,zip,application/x-shockwave-flash,swf swfl,application/vnd.openxmlformats,docx pptx xlsx,audio/mpeg,mpga mpega mp2 mp3,audio/x-wav,wav,image/bmp,bmp,image/gif,gif,image/jpeg,jpeg jpg jpe,image/png,png,image/svg+xml,svg svgz,image/tiff,tiff tif,text/html,htm html xhtml,text/rtf,rtf,video/mpeg,mpeg mpg mpe,video/quicktime,qt mov,video/x-flv,flv,video/vnd.rn-realvideo,rv,text/plain,asc txt text diff log,application/octet-stream,exe");var d={STOPPED:1,STARTED:2,QUEUED:1,UPLOADING:2,FAILED:4,DONE:5,GENERIC_ERROR:-100,HTTP_ERROR:-200,IO_ERROR:-300,SECURITY_ERROR:-400,INIT_ERROR:-500,FILE_SIZE_ERROR:-600,FILE_EXTENSION_ERROR:-700,mimeTypes:f,extend:function(k){d.each(arguments,function(l,m){if(m>0){d.each(l,function(o,n){k[n]=o})}});return k},cleanName:function(k){var l,m;m=[/[\300-\306]/g,"A",/[\340-\346]/g,"a",/\307/g,"C",/\347/g,"c",/[\310-\313]/g,"E",/[\350-\353]/g,"e",/[\314-\317]/g,"I",/[\354-\357]/g,"i",/\321/g,"N",/\361/g,"n",/[\322-\330]/g,"O",/[\362-\370]/g,"o",/[\331-\334]/g,"U",/[\371-\374]/g,"u"];for(l=0;l<m.length;l+=2){k=k.replace(m[l],m[l+1])}k=k.replace(/\s+/g,"_");k=k.replace(/[^a-z0-9_\-\.]+/gi,"");return k},addRuntime:function(k,l){l.name=k;h[k]=l;h.push(l);return l},guid:function(){var k=new Date().getTime().toString(32),l;for(l=0;l<5;l++){k+=Math.floor(Math.random()*65535).toString(32)}return(d.guidPrefix||"p")+k+(c++).toString(32)},buildUrl:function(l,k){var m="";d.each(k,function(o,n){m+=(m?"&":"")+encodeURIComponent(n)+"="+encodeURIComponent(o)});if(m){l+=(l.indexOf("?")>0?"&":"?")+m}return l},each:function(n,o){var m,l,k;if(n){m=n.length;if(m===b){for(l in n){if(n.hasOwnProperty(l)){if(o(n[l],l)===false){return}}}}else{for(k=0;k<m;k++){if(o(n[k],k)===false){return}}}}},formatSize:function(k){if(k===b){return d.translate("N/A")}if(k>1048576){return Math.round(k/1048576,1)+" MB"}if(k>1024){return Math.round(k/1024,1)+" KB"}return k+" b"},getPos:function(l,p){var q=0,o=0,s,r=document,m,n;l=l;p=p||r.body;function k(w){var u,v,t=0,z=0;if(w){v=w.getBoundingClientRect();u=r.compatMode==="CSS1Compat"?r.documentElement:r.body;t=v.left+u.scrollLeft;z=v.top+u.scrollTop}return{x:t,y:z}}if(l.getBoundingClientRect&&(navigator.userAgent.indexOf("MSIE")>0&&r.documentMode!==8)){m=k(l);n=k(p);return{x:m.x-n.x,y:m.y-n.y}}s=l;while(s&&s!=p&&s.nodeType){q+=s.offsetLeft||0;o+=s.offsetTop||0;s=s.offsetParent}s=l.parentNode;while(s&&s!=p&&s.nodeType){q-=s.scrollLeft||0;o-=s.scrollTop||0;s=s.parentNode}return{x:q,y:o}},getSize:function(k){return{w:k.clientWidth||k.offsetWidth,h:k.clientHeight||k.offsetHeight}},parseSize:function(k){var l;if(typeof(k)=="string"){k=/^([0-9]+)([mgk]+)$/.exec(k.toLowerCase().replace(/[^0-9mkg]/g,""));l=k[2];k=+k[1];if(l=="g"){k*=1073741824}if(l=="m"){k*=1048576}if(l=="k"){k*=1024}}return k},xmlEncode:function(k){return k?(""+k).replace(i,function(l){return a[l]?"&"+a[l]+";":l}):k},toArray:function(m){var l,k=[];for(l=0;l<m.length;l++){k[l]=m[l]}return k},addI18n:function(k){return d.extend(j,k)},translate:function(k){return j[k]||k},addEvent:function(l,k,m){if(l.attachEvent){l.attachEvent("on"+k,function(){var n=window.event;if(!n.target){n.target=n.srcElement}n.preventDefault=e;n.stopPropagation=g;m(n)})}else{if(l.addEventListener){l.addEventListener(k,m,false)}}}};d.Uploader=function(n){var l={},q,p=[],r,m;q=new d.QueueProgress();n=d.extend({chunk_size:0,multipart:true,multi_selection:true,file_data_name:"file",filters:[]},n);function o(){var s;if(this.state==d.STARTED&&r<p.length){s=p[r++];if(s.status==d.QUEUED){this.trigger("BeforeUpload",s);this.trigger("UploadFile",s)}else{o.call(this)}}else{this.stop()}}function k(){var t,s;q.reset();for(t=0;t<p.length;t++){s=p[t];if(s.size!==b){q.size+=s.size;q.loaded+=s.loaded}else{q.size=b}if(s.status==d.DONE){q.uploaded++}else{if(s.status==d.FAILED){q.failed++}else{q.queued++}}}if(q.size===b){q.percent=p.length>0?Math.ceil(q.uploaded/p.length*100):0}else{q.bytesPerSec=Math.ceil(q.loaded/((+new Date()-m||1)/1000));q.percent=q.size>0?Math.ceil(q.loaded/q.size*100):0}}d.extend(this,{state:d.STOPPED,features:{},files:p,settings:n,total:q,id:d.guid(),init:function(){var x=this,y,u,t,w=0,v;n.page_url=n.page_url||document.location.pathname.replace(/\/[^\/]+$/g,"/");if(!/^(\w+:\/\/|\/)/.test(n.url)){n.url=n.page_url+n.url}n.chunk_size=d.parseSize(n.chunk_size);n.max_file_size=d.parseSize(n.max_file_size);x.bind("FilesAdded",function(z,C){var B,A,E=0,F,D=n.filters;if(D&&D.length){F=[];d.each(D,function(G){d.each(G.extensions.split(/,/),function(H){F.push("\\."+H.replace(new RegExp("["+("/^$.*+?|()[]{}\\".replace(/./g,"\\$&"))+"]","g"),"\\$&"))})});F=new RegExp(F.join("|")+"$","i")}for(B=0;B<C.length;B++){A=C[B];A.loaded=0;A.percent=0;A.status=d.QUEUED;if(F&&!F.test(A.name)){z.trigger("Error",{code:d.FILE_EXTENSION_ERROR,message:"File extension error.",file:A});continue}if(A.size!==b&&A.size>n.max_file_size){z.trigger("Error",{code:d.FILE_SIZE_ERROR,message:"File size error.",file:A});continue}p.push(A);E++}if(E){x.trigger("QueueChanged");x.refresh()}});if(n.unique_names){x.bind("UploadFile",function(z,A){var C=A.name.match(/\.([^.]+)$/),B="tmp";if(C){B=C[1]}A.target_name=A.id+"."+B})}x.bind("UploadProgress",function(z,A){if(A.status==d.QUEUED){A.status=d.UPLOADING}A.percent=A.size>0?Math.ceil(A.loaded/A.size*100):100;k()});x.bind("StateChanged",function(z){if(z.state==d.STARTED){m=(+new Date())}});x.bind("QueueChanged",k);x.bind("Error",function(z,A){if(A.file){A.file.status=d.FAILED;k();window.setTimeout(function(){o.call(x)})}});x.bind("FileUploaded",function(z,A){A.status=d.DONE;A.loaded=A.size;z.trigger("UploadProgress",A);o.call(x)});if(n.runtimes){u=[];v=n.runtimes.split(/\s?,\s?/);for(y=0;y<v.length;y++){if(h[v[y]]){u.push(h[v[y]])}}}else{u=h}function s(){var C=u[w++],B,z,A;if(C){B=C.getFeatures();z=x.settings.required_features;if(z){z=z.split(",");for(A=0;A<z.length;A++){if(!B[z[A]]){s();return}}}C.init(x,function(D){if(D&&D.success){x.features=B;x.trigger("Init",{runtime:C.name});x.trigger("PostInit");x.refresh()}else{s()}})}else{x.trigger("Error",{code:d.INIT_ERROR,message:"Init error."})}}s()},refresh:function(){this.trigger("Refresh")},start:function(){if(this.state!=d.STARTED){r=0;this.state=d.STARTED;this.trigger("StateChanged");o.call(this)}},stop:function(){if(this.state!=d.STOPPED){this.state=d.STOPPED;this.trigger("StateChanged")}},getFile:function(t){var s;for(s=p.length-1;s>=0;s--){if(p[s].id===t){return p[s]}}},removeFile:function(t){var s;for(s=p.length-1;s>=0;s--){if(p[s].id===t.id){return this.splice(s,1)[0]}}},splice:function(u,s){var t;t=p.splice(u,s);this.trigger("FilesRemoved",t);this.trigger("QueueChanged");return t},trigger:function(t){var v=l[t.toLowerCase()],u,s;if(v){s=Array.prototype.slice.call(arguments);s[0]=this;for(u=0;u<v.length;u++){if(v[u].func.apply(v[u].scope,s)===false){return false}}}return true},bind:function(s,u,t){var v;s=s.toLowerCase();v=l[s]||[];v.push({func:u,scope:t||this});l[s]=v},unbind:function(s,u){var v=l[s.toLowerCase()],t;if(v){for(t=v.length-1;t>=0;t--){if(v[t].func===u){v.splice(t,1)}}}}})};d.File=function(n,l,m){var k=this;k.id=n;k.name=l;k.size=m;k.loaded=0;k.percent=0;k.status=0};d.Runtime=function(){this.getFeatures=function(){};this.init=function(k,l){}};d.QueueProgress=function(){var k=this;k.size=0;k.loaded=0;k.uploaded=0;k.failed=0;k.queued=0;k.percent=0;k.bytesPerSec=0;k.reset=function(){k.size=k.loaded=k.uploaded=k.failed=k.queued=k.percent=k.bytesPerSec=0}};d.runtimes={};window.plupload=d})();
Index: typo3/contrib/plupload/js/plupload.html4.min.js
===================================================================
--- typo3/contrib/plupload/js/plupload.html4.min.js	(revision )
+++ typo3/contrib/plupload/js/plupload.html4.min.js	(revision )
@@ -0,0 +1,1 @@
+(function(a){a.runtimes.Html4=a.addRuntime("html4",{getFeatures:function(){return{multipart:true}},init:function(f,g){var d={},c,b;function e(l){var k,j,m=[],n,h;h=l.value.replace(/\\/g,"/");h=h.substring(h.length,h.lastIndexOf("/")+1);n=a.guid();k=new a.File(n,h);d[n]=k;k.input=l;m.push(k);if(m.length){f.trigger("FilesAdded",m)}}f.bind("Init",function(p){var h,x,v,t=[],o,u,m=p.settings.filters,l,s,r=/MSIE/.test(navigator.userAgent),k="javascript",w,j=document.body,n;if(f.settings.container){j=document.getElementById(f.settings.container);j.style.position="relative"}c=(typeof p.settings.form=="string")?document.getElementById(p.settings.form):p.settings.form;if(!c){n=document.getElementById(f.settings.browse_button);for(;n;n=n.parentNode){if(n.nodeName=="FORM"){c=n}}}if(!c){c=document.createElement("form");c.style.display="inline";n=document.getElementById(f.settings.container);n.parentNode.insertBefore(c,n);c.appendChild(n)}c.setAttribute("method","post");c.setAttribute("enctype","multipart/form-data");a.each(p.settings.multipart_params,function(z,y){var i=document.createElement("input");a.extend(i,{type:"hidden",name:y,value:z});c.appendChild(i)});b=document.createElement("iframe");b.setAttribute("src",k+':""');b.setAttribute("name",p.id+"_iframe");b.setAttribute("id",p.id+"_iframe");b.style.display="none";a.addEvent(b,"load",function(B){var C=B.target,z=f.currentfile,A;try{A=C.contentWindow.document||C.contentDocument||window.frames[C.id].document}catch(y){p.trigger("Error",{code:a.SECURITY_ERROR,message:"Security error.",file:z});return}if(A.location.href=="about:blank"||!z){return}var i=A.documentElement.innerText||A.documentElement.textContent;if(i!=""){z.status=a.DONE;z.loaded=1025;z.percent=100;if(z.input){z.input.removeAttribute("name")}p.trigger("UploadProgress",z);p.trigger("FileUploaded",z,{response:i});if(c.tmpAction){c.setAttribute("action",c.tmpAction)}if(c.tmpTarget){c.setAttribute("target",c.tmpTarget)}}});c.appendChild(b);if(r){window.frames[b.id].name=b.name}x=document.createElement("div");x.id=p.id+"_iframe_container";for(o=0;o<m.length;o++){l=m[o].extensions.split(/,/);for(u=0;u<l.length;u++){s=a.mimeTypes[l[u]];if(s){t.push(s)}}}a.extend(x.style,{position:"absolute",background:"transparent",width:"100px",height:"100px",overflow:"hidden",zIndex:99999,opacity:0});w=f.settings.shim_bgcolor;if(w){a.extend(x.style,{background:w,opacity:1})}x.className="plupload_iframe";j.appendChild(x);function q(){v=document.createElement("input");v.setAttribute("type","file");v.setAttribute("accept",t.join(","));v.setAttribute("size",1);a.extend(v.style,{width:"100%",height:"100%",opacity:0});if(r){a.extend(v.style,{filter:"alpha(opacity=0)"})}a.addEvent(v,"change",function(i){var y=i.target;if(y.value){q();y.style.display="none";e(y)}});x.appendChild(v);return true}q()});f.bind("Refresh",function(h){var i,j,k;i=document.getElementById(f.settings.browse_button);j=a.getPos(i,document.getElementById(h.settings.container));k=a.getSize(i);a.extend(document.getElementById(f.id+"_iframe_container").style,{top:j.y+"px",left:j.x+"px",width:k.w+"px",height:k.h+"px"})});f.bind("UploadFile",function(h,i){if(i.status==a.DONE||i.status==a.FAILED||h.state==a.STOPPED){return}if(!i.input){i.status=a.ERROR;return}i.input.setAttribute("name",h.settings.file_data_name);c.tmpAction=c.getAttribute("action");c.setAttribute("action",a.buildUrl(h.settings.url,{name:i.target_name||i.name}));c.tmpTarget=c.getAttribute("target");c.setAttribute("target",b.name);this.currentfile=i;c.submit()});f.bind("FilesRemoved",function(h,k){var j,l;for(j=0;j<k.length;j++){l=k[j].input;if(l){l.parentNode.removeChild(l)}}});g({success:true})}})})(plupload);
Index: typo3/sysext/setup/mod/locallang.xml
===================================================================
--- typo3/sysext/setup/mod/locallang.xml	(revision 9899)
+++ typo3/sysext/setup/mod/locallang.xml	(revision )
@@ -80,7 +80,10 @@
 			<label index="edit_wideDocument">Wide document background</label>
 			<label index="edit_RTE">Enable Rich Text Editor (if available)</label>
 			<label index="edit_docModuleUpload">File upload directly in Doc-module</label>
-			<label index="enableFlashUploader">Enable Flash Uploader (requires Flash 9+)</label>
+			<label index="enableFlashUploader">Select Uploader</label>
+			<label index="enableFlashUploader.disable">Classic Form Upload</label>
+			<label index="enableFlashUploader.flash">Flash Uploader (requires Flash 9+)</label>
+			<label index="enableFlashUploader.plupload">Plupload (HTML5, Flash, Silverlight, Form)</label>
 			<label index="resizeTextareas">Make Textareas resizable</label>
 			<label index="resizeTextareas_MaxHeight">Maximal Height of resizable Textarea in Pixel</label>
 			<label index="resizeTextareas_Flexible">Make Textareas flexible</label>
Index: typo3/contrib/plupload/readme.md
===================================================================
--- typo3/contrib/plupload/readme.md	(revision )
+++ typo3/contrib/plupload/readme.md	(revision )
@@ -0,0 +1,46 @@
+Plupload - Cross browser and platform uploader API
+===================================================
+
+What is Plupload
+-----------------
+Plupload is a JavaScript API for dealing with file uploads it supports features like multiple file selection, file type filtering,
+request chunking, client side image scaling and it uses different runtimes to achieve this such as HTML 5, Silverlight, Flash, Gears and BrowserPlus.
+
+What you need to build Plupload
+-------------------------------
+* Install the Java JDK or JRE packages you can find it at: [http://java.sun.com/javase/downloads/index.jsp](http://java.sun.com/javase/downloads/index.jsp)
+* Install Apache Ant you can find it at: [http://ant.apache.org/](http://ant.apache.org/)
+* Add Apache Ant to your systems path environment variable, this is not required but makes it easier to issue commands to Ant without having to type the full path for it.
+
+How to build Plupload
+----------------------
+
+In the root directory of Plupload where the build.xml file is you can run ant against different targets.
+
+`ant`
+
+Will combine, preprocess and minify the Plupload classes into the js directory. It will not build the Silverlight and Flash .xap and .swf files.
+
+`ant moxiedoc`
+
+Will generate API Documentation for the project using the Moxiedoc tool. The docs will be generated to the docs/api directory.
+
+`ant release`
+
+Will produce release packages. The release packages will be placed in the tmp directory.
+
+How to build Flash runtime
+---------------------------
+The Flash runtime uses a .swf file that can be built using the Flex SDK. This SDK can be downloaded from Adobe. [http://www.adobe.com/products/flex/flexdownloads/](http://www.adobe.com/products/flex/flexdownloads/)
+
+How to build Silverlight runtime
+---------------------------------
+The Silverlight runtime uses a .xap file that can be built using the Silverlight SDK or Visual Studio. [http://silverlight.net/getstarted/](http://silverlight.net/getstarted/)
+
+Running the development version
+--------------------------------
+The unminified development version of the javascript files can be executed by opening the examples/queue_widget_dev.html file running on a Web Server.
+
+Contributing to the Plupload project
+-------------------------------------
+You can read more about how to contribute to this project at [http://www.plupload.com/contributing](http://www.plupload.com/contributing)
Index: typo3/sysext/filelist/mod1/file_list.php
===================================================================
--- typo3/sysext/filelist/mod1/file_list.php	(revision 9758)
+++ typo3/sysext/filelist/mod1/file_list.php	(revision )
@@ -174,7 +174,7 @@
 			// There there was access to this file path, continue, make the list
 		if ($access)	{
 				// include the initialization for the flash uploader
-			if ($GLOBALS['BE_USER']->uc['enableFlashUploader']) {
+			if ($GLOBALS['BE_USER']->uc['enableFlashUploader'] == 1) {
 
 				$this->doc->JScodeArray['flashUploader'] = '
 					if (top.TYPO3.FileUploadWindow.isFlashAvailable()) {
@@ -185,7 +185,7 @@
 							function initFlashUploader(event) {
 									// set the page specific options for the flashUploader
 								var flashUploadOptions = {
-									uploadURL:           top.TS.PATH_typo3 + "ajax.php",
+									uploadURL:           top.TYPO3.configuration.PATH_typo3 + "ajax.php",
 									uploadFileSizeLimit: "' . t3lib_div::getMaxUploadFileSize() . '",
 									uploadFileTypes: {
 										allow:  "' . $GLOBALS['TYPO3_CONF_VARS']['BE']['fileExtensions']['webspace']['allow'] . '",
@@ -233,6 +233,22 @@
 						});
 					}
 				';
+			} elseif ($GLOBALS['BE_USER']->uc['enableFlashUploader'] == 2) {
+
+				$this->doc->JScodeArray['flashUploader'] = '
+						Ext.onReady(function() {
+							// monitor the button
+							$("button-upload").observe("click", function(event) {
+								event.stop();
+								top.TYPO3.configuration.FileUpload.targetDirectory = "'.$this->id.'";
+								// set window object to reload on finish.
+								top.TYPO3.PluploadWindow.reloadWindow = window;
+								top.TYPO3.PluploadWindow.show();
+
+							});
+						});
+				';
+
 			}
 				// Create filelisting object
 			$this->filelist = t3lib_div::makeInstance('fileList');
Index: typo3/contrib/plupload/readme.txt
===================================================================
--- typo3/contrib/plupload/readme.txt	(revision )
+++ typo3/contrib/plupload/readme.txt	(revision )
@@ -0,0 +1,9 @@
+build.bat
+build.xml
+examples/
+src/
+tests/
+tmp/
+tools/
+
+where not included from the original distribution.
Index: typo3/js/extjs/ext.ux.plupload.js
===================================================================
--- typo3/js/extjs/ext.ux.plupload.js	(revision )
+++ typo3/js/extjs/ext.ux.plupload.js	(revision )
@@ -0,0 +1,373 @@
+/*!
+ * Ext.ux.PluploadPanel
+ * (c) http://adtim.ru/extjs/ux_plupload
+ * 2010-04-28 v0.1
+ */
+
+Ext.ux.PluploadPanel = Ext.extend(Ext.Panel, {
+	constructor: function(config) {
+		this.autoScroll = false;
+		this.bodyCssClass = 'x-plupload-body';
+
+		this.success = [];
+		this.failed = [];
+
+		this.viewTpl = new Ext.XTemplate(
+				'<tpl for=".">',
+				'<dl id="{id}">',
+				'<dt style="width: 50%">{name}</dt>',
+				'<dt style="width: 15%">{size:fileSize}</dt>',
+				'<tpl exec="this.statusValue(status, percent, msg)"></tpl><dt style="width: 30%">{this.statusText}</dt>',
+				'<dt style="width: 5%" class="t3-plupload-remove"><span class="t3-icon t3-icon-actions t3-icon-actions-edit t3-icon-edit-delete">&nbsp;</span></dt>',
+				'<div class="x-clear"></div>',
+				'</dl>',
+				'</tpl>',
+			{   compiled: true,
+				statusText: '-',
+				statusTextQueued: config.statusQueuedText || 'Queued',
+				statusTextUploading: config.statusUploadingText || 'Uploaded ({0}%)',
+				statusTextFailed: config.statusFailedText || 'FAILED',
+				statusTextDone: config.statusDoneText || 'DONE',
+				statusValue: function (status, percent, msg) {
+					if (status == 1) {
+						this.statusText = this.statusTextQueued;
+					}
+					else if (status == 2) {
+						this.statusText = String.format(this.statusTextUploading, percent);
+					}
+					else if (status == 4) {
+						this.statusText = msg || this.statusTextFailed;
+					}
+					else if (status == 5) {
+						this.statusText = this.statusTextDone;
+					}
+				}
+			}
+		);
+
+		this.store = new Ext.data.JsonStore({
+			fields: [ 'id', 'loaded', 'name', 'size', 'percent', 'status', 'msg' ],
+			listeners: {
+				load: this.onStoreLoad,
+				remove: this.onStoreRemove,
+				update: this.onStoreUpdate,
+				scope: this
+			}
+		});
+
+		this.pbar = new Ext.ProgressBar({ flex: 1 });
+
+		this.bbar = new Ext.Toolbar({
+			layout: 'hbox',
+			style: { paddingLeft: '5px' },
+			items: [
+				this.pbar,
+				new Ext.Toolbar.TextItem({
+					text: '<i>uploader not initialized</i>',
+					itemId: 'status'
+				})
+			]
+		});
+
+		this.tbar = new Ext.Toolbar({
+			enableOverflow: true,
+			items: [
+				new Ext.Button({
+					text: config.addButtonText || 'Add files',
+					itemId: 'addButton',
+					iconCls: config.addButtonCls,
+					disabled: true
+				}),
+				new Ext.Button({
+					text: config.uploadButtonText || 'Upload',
+					handler: this.onStart,
+					scope: this,
+					disabled: true,
+					itemId: 'start',
+					iconCls: config.uploadButtonCls
+				}),
+				'->',
+				new Ext.Button({
+					text: config.cancelButtonText || 'Cancel',
+					handler: this.onCancel,
+					scope: this,
+					disabled: true,
+					itemId: 'cancel',
+					iconCls: config.cancelButtonCls
+				})
+			]
+		});
+
+		this.view = new Ext.DataView({
+			store: this.store,
+			tpl: this.viewTpl,
+			overClass: 'plupload_over',
+			selectedClass: 'plupload_selected',
+			itemSelector: 'dl',
+			emptyText: config.emptyText || '<div class="plupload_emptytext"><span>Queue is empty</span></div>',
+			emptyDropText: config.emptyDropText || '<div class="plupload_emptytext"><span>Drop files here</span></div>',
+			deferEmptyText: false,
+			listeners: {
+				click: function(dataView, index, node, event) {
+					dataView.store.remove(dataView.store.getAt(index));
+				}
+			},
+			plugins: Ext.DataView.DragSelector ? new Ext.DataView.DragSelector() : ''
+		});
+
+		this.items = this.view;
+
+		Ext.ux.PluploadPanel.superclass.constructor.apply(this, arguments);
+	},
+	initComponent: function() {
+		Ext.ux.PluploadPanel.superclass.initComponent.apply(this, arguments);
+	},
+	afterRender: function() {
+		Ext.ux.PluploadPanel.superclass.afterRender.apply(this, arguments);
+		this.initialize_uploader();
+	},
+	onDeleteAll: function () {
+		this.store.each(
+				function (record) {
+					this.remove_file(record.get('id'));
+				}, this
+				);
+	},
+	onDeleteUploaded: function () {
+		this.store.each(
+				function (record) {
+					if (record.get('status') == 5) {
+						this.remove_file(record.get('id'));
+					}
+				}, this
+				);
+	},
+	onCancel: function () {
+		this.uploader.stop();
+	},
+	onStart: function () {
+		this.fireEvent('beforestart', this);
+		if (this.multipart_params) {
+			this.uploader.settings.multipart_params = this.multipart_params;
+		}
+		this.uploader.start();
+	},
+	initialize_uploader: function () {
+		var runtimes = 'gears,browserplus,html5,html4';
+		if (this.flash_swf_url) {
+			runtimes = "flash," + runtimes;
+		}
+		if (this.silverlight_xap_url) {
+			runtimes = "silverlight," + runtimes;
+		}
+		var uploaderSettings = {
+			url: this.url,
+			runtimes: this.runtimes || runtimes,
+			browse_button: this.getTopToolbar().getComponent('addButton').getEl().dom.id,
+			container: this.getTopToolbar().getEl().dom.id,
+			max_file_size: this.max_file_size || '10mb',
+			resize: this.resize || '',
+			flash_swf_url: this.flash_swf_url || '',
+			silverlight_xap_url: this.silverlight_xap_url || '',
+			filters : this.filters || [],
+			unique_names: this.unique_names,
+			multipart: this.multipart,
+			multipart_params: this.multipart_params,
+			file_data_name: this.file_data_name,
+			drop_element: this.body.dom.id,
+			required_features: this.required_features
+		};
+		if (this.chunk_size) {
+			uploaderSettings.chunk_size = this.chunk_size;
+		}
+		this.uploader = new plupload.Uploader(uploaderSettings);
+		Ext.each(['Init', 'ChunkUploaded', 'FilesAdded', 'FilesRemoved', 'FileUploaded', 'PostInit',
+			'QueueChanged', 'Refresh', 'StateChanged', 'UploadFile', 'UploadProgress', 'Error'  ],
+				function (v) {
+					this.uploader.bind(v, eval("this." + v), this);
+				}, this
+		);
+		this.uploader.init();
+	},
+	remove_file: function (id) {
+		var fileObj = this.uploader.getFile(id);
+		if (fileObj) {
+			this.uploader.removeFile(fileObj);
+		}
+		else {
+			this.store.remove(this.store.getById(id));
+		}
+	},
+	update_pbar: function () {
+		var t = this.uploader.total;
+		var speed = Ext.util.Format.fileSize(t.bytesPerSec);
+		var total = this.store.data.length;
+		var failed = this.failed.length;
+		var success = this.success.length;
+		var sent = failed + success;
+		var queued = total - success - failed;
+		if (total) {
+			this.progressText = '';
+			var pbarText = String.format(this.progressText || '{2} of {1} uploaded ({5}/s)', sent, total, success, failed, queued, speed);
+			var percent = t.percent / 100;
+			// flash and html4 runtime fix (uploader.total contains outdated info about queue)
+			if (this.runtime == 'flash' || this.runtime == 'html4') {
+				if (total == sent || this.store.find('status', /1|2/) == -1) { //find queued or uploading status
+					percent = 1
+				}
+			}
+			// end fix
+
+			this.pbar.updateProgress(percent, pbarText);
+		}
+		else {
+			this.pbar.updateProgress(0, ' ');
+		}
+	},
+	update_store: function (v) {
+		if (!v.msg) {
+			v.msg = '';
+		}
+		var data = this.store.getById(v.id);
+		if (data) {
+			data.data = v;
+			data.commit();
+		}
+		else {
+			this.store.loadData(v, true);
+		}
+	},
+	onStoreLoad: function (store, record, operation) {
+		this.update_pbar();
+	},
+	onStoreRemove: function (store, record, operation) {
+		if (! store.data.length) {
+			this.getTopToolbar().getComponent('start').setDisabled(true);
+			this.uploader.total.reset();
+		}
+		var id = record.get('id');
+		this.remove_file(id);
+
+		Ext.each(this.success,
+				function (v) {
+					if (v && v.id == id) {
+						this.success.remove(v);
+					}
+				}, this
+				);
+
+		Ext.each(this.failed,
+				function (v) {
+					if (v && v.id == id) {
+						this.failed.remove(v);
+					}
+				}, this
+				);
+		this.update_pbar();
+	},
+	onStoreUpdate: function (store, record, operation) {
+		this.update_pbar();
+	},
+	Init: function(uploader, data) {
+		var bbar = this.getBottomToolbar();
+		var statusCmp = bbar.getComponent('status');
+		this.runtime = data.runtime;
+		if (this.runtime_visible == true) {
+			statusCmp.setText(" Uploader runtime: " + this.runtime);
+		}
+		else {
+			statusCmp.setText('');
+		}
+
+		bbar.syncSize();
+
+		if (this.uploader.features.dragdrop) {
+			var v = this.view;
+			v.emptyText = this.emptyDropText;
+			if (v.rendered) {
+				v.refresh();
+			}
+		}
+		this.getTopToolbar().getComponent('addButton').setDisabled(false);
+	},
+	ChunkUploaded: function() {
+	},
+	FilesAdded: function(uploader, files) {
+		this.getTopToolbar().getComponent('start').setDisabled(false);
+		Ext.each(files,
+				function (v) {
+					this.update_store(v);
+				}, this
+				);
+	},
+	FilesRemoved: function(uploader, files) {
+		Ext.each(files,
+				function (file) {
+					this.store.remove(this.store.getById(file.id));
+				}, this
+				);
+	},
+	FileUploaded: function(uploader, file, status) {
+		var response = Ext.decode(status.response);
+		if (response.success == true) {
+			file.server_error = 0;
+			this.success.push(file);
+		}
+		else {
+			if (response.message) {
+				file.msg = '<span style="color: red">' + response.message + '</span>';
+			}
+			file.server_error = 1;
+			this.failed.push(file);
+		}
+		this.update_store(file);
+	},
+	PostInit: function() {
+
+	},
+	QueueChanged: function(uploader) {
+	},
+	Refresh: function(uploader) {
+		Ext.each(uploader.files,
+				function (v) {
+					this.update_store(v);
+				}, this
+				);
+	},
+	StateChanged: function(uploader) {
+		if (uploader.state == 2) {
+			this.fireEvent('uploadstarted', this);
+			this.getTopToolbar().getComponent('cancel').setDisabled(false);
+			this.getTopToolbar().getComponent('start').setDisabled(true);
+		}
+		else {
+			this.fireEvent('uploadcomplete', this, this.success, this.failed);
+			this.getTopToolbar().getComponent('cancel').setDisabled(true);
+			this.getTopToolbar().getComponent('start').setDisabled(false);
+		}
+	},
+	UploadFile: function(uploader, file) {
+		this.fireEvent('uploadfile', this, uploader, file);
+	},
+	UploadProgress: function(uploader, file) {
+		if (file.server_error) {
+			file.status = 4;
+		}
+		this.update_store(file);
+	},
+	Error: function (uploader, data) {
+		data.file.status = 4;
+		if (data.code == -600) {
+			data.file.msg = String.format('<span style="color: red">{0}</span>', this.statusInvalidSizeText || 'Too big');
+		}
+		else if (data.code == -700) {
+			data.file.msg = String.format('<span style="color: red">{0}</span>', this.statusInvalidExtensionText || 'Invalid file type');
+		}
+		else {
+			data.file.msg = String.format('<span style="color: red">{2} ({0}: {1})</span>', data.code, data.details, data.message);
+		}
+		this.update_store(data.file);
+	}
+});
+
+Ext.reg('pluploadpanel', Ext.ux.PluploadPanel);
Index: typo3/contrib/plupload/js/plupload.html5.min.js
===================================================================
--- typo3/contrib/plupload/js/plupload.html5.min.js	(revision )
+++ typo3/contrib/plupload/js/plupload.html5.min.js	(revision )
@@ -0,0 +1,1 @@
+(function(b){function a(i,l,j,c,k){var e,d,h,g,f;e=document.createElement("canvas");e.style.display="none";document.body.appendChild(e);d=e.getContext("2d");h=new Image();h.onload=function(){var o,m,n;f=Math.min(l/h.width,j/h.height);if(f<1){o=Math.round(h.width*f);m=Math.round(h.height*f)}else{o=h.width;m=h.height}e.width=o;e.height=m;d.drawImage(h,0,0,o,m);g=e.toDataURL(c);g=g.substring(g.indexOf("base64,")+7);g=atob(g);e.parentNode.removeChild(e);k({success:true,data:g})};h.src=i}b.runtimes.Html5=b.addRuntime("html5",{getFeatures:function(){var g,d,f,e,c;d=f=e=c=false;if(window.XMLHttpRequest){g=new XMLHttpRequest();f=!!g.upload;d=!!(g.sendAsBinary||g.upload)}if(d){e=!!(File&&File.prototype.getAsDataURL);c=!!(File&&File.prototype.slice)}return{html5:d,dragdrop:window.mozInnerScreenX!==undefined||c,jpgresize:e,pngresize:e,multipart:e||!!window.FileReader||!!window.FormData,progress:f,chunking:c||e}},init:function(f,g){var c={},d;function e(l){var j,h,k=[],m;for(h=0;h<l.length;h++){j=l[h];m=b.guid();c[m]=j;k.push(new b.File(m,j.fileName,j.fileSize))}if(k.length){f.trigger("FilesAdded",k)}}d=this.getFeatures();if(!d.html5){g({success:false});return}f.bind("Init",function(m){var q,o=[],l,p,j=m.settings.filters,k,n,h=document.body;q=document.createElement("div");q.id=m.id+"_html5_container";for(l=0;l<j.length;l++){k=j[l].extensions.split(/,/);for(p=0;p<k.length;p++){n=b.mimeTypes[k[p]];if(n){o.push(n)}}}b.extend(q.style,{position:"absolute",background:f.settings.shim_bgcolor||"transparent",width:"100px",height:"100px",overflow:"hidden",zIndex:99999,opacity:f.settings.shim_bgcolor?"":0});q.className="plupload html5";if(f.settings.container){h=document.getElementById(f.settings.container);h.style.position="relative"}h.appendChild(q);q.innerHTML='<input id="'+f.id+'_html5" style="width:100%;" type="file" accept="'+o.join(",")+'" '+(f.settings.multi_selection?'multiple="multiple"':"")+" />";document.getElementById(f.id+"_html5").onchange=function(){e(this.files);this.value=""}});f.bind("PostInit",function(){var h=document.getElementById(f.settings.drop_element);if(h){b.addEvent(h,"dragover",function(i){i.preventDefault()});b.addEvent(h,"drop",function(j){var i=j.dataTransfer;if(i&&i.files){e(i.files)}j.preventDefault()})}});f.bind("Refresh",function(h){var i,j,k;i=document.getElementById(f.settings.browse_button);j=b.getPos(i,document.getElementById(h.settings.container));k=b.getSize(i);b.extend(document.getElementById(f.id+"_html5_container").style,{top:j.y+"px",left:j.x+"px",width:k.w+"px",height:k.h+"px"})});f.bind("UploadFile",function(h,j){var k=h.settings,m,i;function l(n){var q=0,p=0;function o(){var u=n,C,D,y,z,A=0,r="----pluploadboundary"+b.guid(),t,w,s="--",B="\r\n",x="";if(j.status==b.DONE||j.status==b.FAILED||h.state==b.STOPPED){return}z={name:j.target_name||j.name};if(k.chunk_size&&d.chunking){t=k.chunk_size;y=Math.ceil(j.size/t);w=Math.min(t,j.size-(q*t));if(typeof(n)=="string"){u=n.substring(q*t,q*t+w)}else{u=n.slice(q*t,w)}z.chunk=q;z.chunks=y}else{w=j.size}C=new XMLHttpRequest();D=C.upload;if(D){D.onprogress=function(E){j.loaded=Math.min(j.size,p+E.loaded-A);h.trigger("UploadProgress",j)}}C.open("post",b.buildUrl(h.settings.url,z),true);C.onreadystatechange=function(){var E,G;if(C.readyState==4){try{E=C.status}catch(F){E=0}if(E>=400){h.trigger("Error",{code:b.HTTP_ERROR,message:"HTTP Error.",file:j,status:E})}else{if(y){G={chunk:q,chunks:y,response:C.responseText,status:E};h.trigger("ChunkUploaded",j,G);p+=w;if(G.cancelled){j.status=b.FAILED;return}j.loaded=Math.min(j.size,(q+1)*t)}else{j.loaded=j.size}h.trigger("UploadProgress",j);if(!y||++q>=y){j.status=b.DONE;h.trigger("FileUploaded",j,{response:C.responseText,status:E})}else{o()}}}};b.each(h.settings.headers,function(F,E){C.setRequestHeader(E,F)});if(h.settings.multipart&&d.multipart){if(!C.sendAsBinary){var v=new FormData();b.each(h.settings.multipart_params,function(F,E){v.append(E,F)});v.append(h.settings.file_data_name,u);C.send(v);return}C.setRequestHeader("Content-Type","multipart/form-data; boundary="+r);b.each(h.settings.multipart_params,function(F,E){x+=s+r+B+'Content-Disposition: form-data; name="'+E+'"'+B+B;x+=F+B});x+=s+r+B+'Content-Disposition: form-data; name="'+h.settings.file_data_name+'"; filename="'+j.name+'"'+B+"Content-Type: application/octet-stream"+B+B+u+B+s+r+s+B;A=x.length-u.length;u=x}else{C.setRequestHeader("Content-Type","application/octet-stream")}if(C.sendAsBinary){C.sendAsBinary(u)}else{C.send(u)}}o()}m=c[j.id];i=h.settings.resize;if(d.jpgresize){if(i&&/\.(png|jpg|jpeg)$/i.test(j.name)){a(m.getAsDataURL(),i.width,i.height,/\.png$/i.test(j.name)?"image/png":"image/jpeg",function(n){if(n.success){j.size=n.data.length;l(n.data)}else{l(m.getAsBinary())}})}else{l(m.getAsBinary())}}else{l(m)}});g({success:true})}})})(plupload);
Index: typo3/alt_clickmenu.php
===================================================================
--- typo3/alt_clickmenu.php	(revision 9821)
+++ typo3/alt_clickmenu.php	(revision )
@@ -957,16 +957,24 @@
 		$script = 'file_upload.php';
 		$type = 'upload';
 		$image = 'upload.gif';
-		if ($GLOBALS['BE_USER']->uc['enableFlashUploader']) {
+		if ($GLOBALS['BE_USER']->uc['enableFlashUploader'] == 1) {
 			$loc = 'top.content.list_frame';
 
 			$editOnClick = 'if (top.TYPO3.FileUploadWindow.isFlashAvailable()) { initFlashUploader("' . rawurlencode($path) . '"); } else if(' . $loc . '){' . $loc . ".location.href=top.TS.PATH_typo3+'".$script.'?target=' . rawurlencode($path) . "';}";
 
 			return $this->linkItem(
 				$this->label($type),
-				$this->excludeIcon('<img'.t3lib_iconWorks::skinImg($this->PH_backPath,'gfx/'.$image,'width="12" height="12"').' alt="" />'),
+				$this->excludeIcon('<img' . t3lib_iconWorks::skinImg($this->PH_backPath, 'gfx/' . $image, 'width="12" height="12"').' alt="" />'),
 				$editOnClick . 'top.nav.refresh();return hideCM();'
 				);
+		} elseif ($GLOBALS['BE_USER']->uc['enableFlashUploader'] == 2) {
+			$editOnClick = 'top.TYPO3.configuration.FileUpload.targetDirectory = "' . $path . '"; top.TYPO3.PluploadWindow.reloadWindow = top.content.list_frame;	top.TYPO3.PluploadWindow.show();';
+			return $this->linkItem(
+				$this->label($type),
+				$this->excludeIcon('<img' . t3lib_iconWorks::skinImg($this->PH_backPath, 'gfx/' . $image, 'width="12" height="12"') . ' alt="" />'),
+				$editOnClick . 'return hideCM();'
+				);
+
 		} else {
 			return $this->FILE_launch($path, $script, $type, $image, true);
 		}
Index: typo3/sysext/setup/ext_tables.php
===================================================================
--- typo3/sysext/setup/ext_tables.php	(revision 9081)
+++ typo3/sysext/setup/ext_tables.php	(revision )
@@ -112,7 +112,12 @@
 			'csh' => 'simuser'
 		),
 		'enableFlashUploader' => array(
-			'type' => 'check',
+			'type' => 'select',
+			'items' => array(
+				0 => 'LLL:EXT:setup/mod/locallang.xml:enableFlashUploader.disable',
+				1 => 'LLL:EXT:setup/mod/locallang.xml:enableFlashUploader.flash',
+				2 => 'LLL:EXT:setup/mod/locallang.xml:enableFlashUploader.plupload',
+			),
 			'label' => 'LLL:EXT:setup/mod/locallang.xml:enableFlashUploader',
 			'csh' => 'enableFlashUploader',
 		),
@@ -150,4 +155,4 @@
 			--div--;LLL:EXT:setup/mod/locallang.xml:adminFunctions,simulate,debugInWindow,installToolEnableButton'
 
 );
-?>
\ No newline at end of file
+?>
Index: typo3/contrib/plupload/js/plupload.full.min.js
===================================================================
--- typo3/contrib/plupload/js/plupload.full.min.js	(revision )
+++ typo3/contrib/plupload/js/plupload.full.min.js	(revision )
@@ -0,0 +1,1 @@
+(function(){var c=0,h=[],j={},f={},a={"<":"lt",">":"gt","&":"amp",'"':"quot","'":"#39"},i=/[<>&\"\']/g,b;function e(){this.returnValue=false}function g(){this.cancelBubble=true}(function(k){var l=k.split(/,/),m,o,n;for(m=0;m<l.length;m+=2){n=l[m+1].split(/ /);for(o=0;o<n.length;o++){f[n[o]]=l[m]}}})("application/msword,doc dot,application/pdf,pdf,application/pgp-signature,pgp,application/postscript,ps ai eps,application/rtf,rtf,application/vnd.ms-excel,xls xlb,application/vnd.ms-powerpoint,ppt pps pot,application/zip,zip,application/x-shockwave-flash,swf swfl,application/vnd.openxmlformats,docx pptx xlsx,audio/mpeg,mpga mpega mp2 mp3,audio/x-wav,wav,image/bmp,bmp,image/gif,gif,image/jpeg,jpeg jpg jpe,image/png,png,image/svg+xml,svg svgz,image/tiff,tiff tif,text/html,htm html xhtml,text/rtf,rtf,video/mpeg,mpeg mpg mpe,video/quicktime,qt mov,video/x-flv,flv,video/vnd.rn-realvideo,rv,text/plain,asc txt text diff log,application/octet-stream,exe");var d={STOPPED:1,STARTED:2,QUEUED:1,UPLOADING:2,FAILED:4,DONE:5,GENERIC_ERROR:-100,HTTP_ERROR:-200,IO_ERROR:-300,SECURITY_ERROR:-400,INIT_ERROR:-500,FILE_SIZE_ERROR:-600,FILE_EXTENSION_ERROR:-700,mimeTypes:f,extend:function(k){d.each(arguments,function(l,m){if(m>0){d.each(l,function(o,n){k[n]=o})}});return k},cleanName:function(k){var l,m;m=[/[\300-\306]/g,"A",/[\340-\346]/g,"a",/\307/g,"C",/\347/g,"c",/[\310-\313]/g,"E",/[\350-\353]/g,"e",/[\314-\317]/g,"I",/[\354-\357]/g,"i",/\321/g,"N",/\361/g,"n",/[\322-\330]/g,"O",/[\362-\370]/g,"o",/[\331-\334]/g,"U",/[\371-\374]/g,"u"];for(l=0;l<m.length;l+=2){k=k.replace(m[l],m[l+1])}k=k.replace(/\s+/g,"_");k=k.replace(/[^a-z0-9_\-\.]+/gi,"");return k},addRuntime:function(k,l){l.name=k;h[k]=l;h.push(l);return l},guid:function(){var k=new Date().getTime().toString(32),l;for(l=0;l<5;l++){k+=Math.floor(Math.random()*65535).toString(32)}return(d.guidPrefix||"p")+k+(c++).toString(32)},buildUrl:function(l,k){var m="";d.each(k,function(o,n){m+=(m?"&":"")+encodeURIComponent(n)+"="+encodeURIComponent(o)});if(m){l+=(l.indexOf("?")>0?"&":"?")+m}return l},each:function(n,o){var m,l,k;if(n){m=n.length;if(m===b){for(l in n){if(n.hasOwnProperty(l)){if(o(n[l],l)===false){return}}}}else{for(k=0;k<m;k++){if(o(n[k],k)===false){return}}}}},formatSize:function(k){if(k===b){return d.translate("N/A")}if(k>1048576){return Math.round(k/1048576,1)+" MB"}if(k>1024){return Math.round(k/1024,1)+" KB"}return k+" b"},getPos:function(l,p){var q=0,o=0,s,r=document,m,n;l=l;p=p||r.body;function k(w){var u,v,t=0,z=0;if(w){v=w.getBoundingClientRect();u=r.compatMode==="CSS1Compat"?r.documentElement:r.body;t=v.left+u.scrollLeft;z=v.top+u.scrollTop}return{x:t,y:z}}if(l.getBoundingClientRect&&(navigator.userAgent.indexOf("MSIE")>0&&r.documentMode!==8)){m=k(l);n=k(p);return{x:m.x-n.x,y:m.y-n.y}}s=l;while(s&&s!=p&&s.nodeType){q+=s.offsetLeft||0;o+=s.offsetTop||0;s=s.offsetParent}s=l.parentNode;while(s&&s!=p&&s.nodeType){q-=s.scrollLeft||0;o-=s.scrollTop||0;s=s.parentNode}return{x:q,y:o}},getSize:function(k){return{w:k.clientWidth||k.offsetWidth,h:k.clientHeight||k.offsetHeight}},parseSize:function(k){var l;if(typeof(k)=="string"){k=/^([0-9]+)([mgk]+)$/.exec(k.toLowerCase().replace(/[^0-9mkg]/g,""));l=k[2];k=+k[1];if(l=="g"){k*=1073741824}if(l=="m"){k*=1048576}if(l=="k"){k*=1024}}return k},xmlEncode:function(k){return k?(""+k).replace(i,function(l){return a[l]?"&"+a[l]+";":l}):k},toArray:function(m){var l,k=[];for(l=0;l<m.length;l++){k[l]=m[l]}return k},addI18n:function(k){return d.extend(j,k)},translate:function(k){return j[k]||k},addEvent:function(l,k,m){if(l.attachEvent){l.attachEvent("on"+k,function(){var n=window.event;if(!n.target){n.target=n.srcElement}n.preventDefault=e;n.stopPropagation=g;m(n)})}else{if(l.addEventListener){l.addEventListener(k,m,false)}}}};d.Uploader=function(n){var l={},q,p=[],r,m;q=new d.QueueProgress();n=d.extend({chunk_size:0,multipart:true,multi_selection:true,file_data_name:"file",filters:[]},n);function o(){var s;if(this.state==d.STARTED&&r<p.length){s=p[r++];if(s.status==d.QUEUED){this.trigger("BeforeUpload",s);this.trigger("UploadFile",s)}else{o.call(this)}}else{this.stop()}}function k(){var t,s;q.reset();for(t=0;t<p.length;t++){s=p[t];if(s.size!==b){q.size+=s.size;q.loaded+=s.loaded}else{q.size=b}if(s.status==d.DONE){q.uploaded++}else{if(s.status==d.FAILED){q.failed++}else{q.queued++}}}if(q.size===b){q.percent=p.length>0?Math.ceil(q.uploaded/p.length*100):0}else{q.bytesPerSec=Math.ceil(q.loaded/((+new Date()-m||1)/1000));q.percent=q.size>0?Math.ceil(q.loaded/q.size*100):0}}d.extend(this,{state:d.STOPPED,features:{},files:p,settings:n,total:q,id:d.guid(),init:function(){var x=this,y,u,t,w=0,v;n.page_url=n.page_url||document.location.pathname.replace(/\/[^\/]+$/g,"/");if(!/^(\w+:\/\/|\/)/.test(n.url)){n.url=n.page_url+n.url}n.chunk_size=d.parseSize(n.chunk_size);n.max_file_size=d.parseSize(n.max_file_size);x.bind("FilesAdded",function(z,C){var B,A,E=0,F,D=n.filters;if(D&&D.length){F=[];d.each(D,function(G){d.each(G.extensions.split(/,/),function(H){F.push("\\."+H.replace(new RegExp("["+("/^$.*+?|()[]{}\\".replace(/./g,"\\$&"))+"]","g"),"\\$&"))})});F=new RegExp(F.join("|")+"$","i")}for(B=0;B<C.length;B++){A=C[B];A.loaded=0;A.percent=0;A.status=d.QUEUED;if(F&&!F.test(A.name)){z.trigger("Error",{code:d.FILE_EXTENSION_ERROR,message:"File extension error.",file:A});continue}if(A.size!==b&&A.size>n.max_file_size){z.trigger("Error",{code:d.FILE_SIZE_ERROR,message:"File size error.",file:A});continue}p.push(A);E++}if(E){x.trigger("QueueChanged");x.refresh()}});if(n.unique_names){x.bind("UploadFile",function(z,A){var C=A.name.match(/\.([^.]+)$/),B="tmp";if(C){B=C[1]}A.target_name=A.id+"."+B})}x.bind("UploadProgress",function(z,A){if(A.status==d.QUEUED){A.status=d.UPLOADING}A.percent=A.size>0?Math.ceil(A.loaded/A.size*100):100;k()});x.bind("StateChanged",function(z){if(z.state==d.STARTED){m=(+new Date())}});x.bind("QueueChanged",k);x.bind("Error",function(z,A){if(A.file){A.file.status=d.FAILED;k();window.setTimeout(function(){o.call(x)})}});x.bind("FileUploaded",function(z,A){A.status=d.DONE;A.loaded=A.size;z.trigger("UploadProgress",A);o.call(x)});if(n.runtimes){u=[];v=n.runtimes.split(/\s?,\s?/);for(y=0;y<v.length;y++){if(h[v[y]]){u.push(h[v[y]])}}}else{u=h}function s(){var C=u[w++],B,z,A;if(C){B=C.getFeatures();z=x.settings.required_features;if(z){z=z.split(",");for(A=0;A<z.length;A++){if(!B[z[A]]){s();return}}}C.init(x,function(D){if(D&&D.success){x.features=B;x.trigger("Init",{runtime:C.name});x.trigger("PostInit");x.refresh()}else{s()}})}else{x.trigger("Error",{code:d.INIT_ERROR,message:"Init error."})}}s()},refresh:function(){this.trigger("Refresh")},start:function(){if(this.state!=d.STARTED){r=0;this.state=d.STARTED;this.trigger("StateChanged");o.call(this)}},stop:function(){if(this.state!=d.STOPPED){this.state=d.STOPPED;this.trigger("StateChanged")}},getFile:function(t){var s;for(s=p.length-1;s>=0;s--){if(p[s].id===t){return p[s]}}},removeFile:function(t){var s;for(s=p.length-1;s>=0;s--){if(p[s].id===t.id){return this.splice(s,1)[0]}}},splice:function(u,s){var t;t=p.splice(u,s);this.trigger("FilesRemoved",t);this.trigger("QueueChanged");return t},trigger:function(t){var v=l[t.toLowerCase()],u,s;if(v){s=Array.prototype.slice.call(arguments);s[0]=this;for(u=0;u<v.length;u++){if(v[u].func.apply(v[u].scope,s)===false){return false}}}return true},bind:function(s,u,t){var v;s=s.toLowerCase();v=l[s]||[];v.push({func:u,scope:t||this});l[s]=v},unbind:function(s,u){var v=l[s.toLowerCase()],t;if(v){for(t=v.length-1;t>=0;t--){if(v[t].func===u){v.splice(t,1)}}}}})};d.File=function(n,l,m){var k=this;k.id=n;k.name=l;k.size=m;k.loaded=0;k.percent=0;k.status=0};d.Runtime=function(){this.getFeatures=function(){};this.init=function(k,l){}};d.QueueProgress=function(){var k=this;k.size=0;k.loaded=0;k.uploaded=0;k.failed=0;k.queued=0;k.percent=0;k.bytesPerSec=0;k.reset=function(){k.size=k.loaded=k.uploaded=k.failed=k.queued=k.percent=k.bytesPerSec=0}};d.runtimes={};window.plupload=d})();(function(b){var c={};function a(i,e,k,j,d){var l,g,f,h;g=google.gears.factory.create("beta.canvas");g.decode(i);h=Math.min(e/g.width,k/g.height);if(h<1){e=Math.round(g.width*h);k=Math.round(g.height*h)}else{e=g.width;k=g.height}g.resize(e,k);return g.encode(d,{quality:j/100})}b.runtimes.Gears=b.addRuntime("gears",{getFeatures:function(){return{dragdrop:true,jpgresize:true,pngresize:true,chunks:true,progress:true,multipart:true}},init:function(g,i){var h;if(!window.google||!google.gears){return i({success:false})}try{h=google.gears.factory.create("beta.desktop")}catch(f){return i({success:false})}function d(k){var j,e,l=[],m;for(e=0;e<k.length;e++){j=k[e];m=b.guid();c[m]=j.blob;l.push(new b.File(m,j.name,j.blob.length))}g.trigger("FilesAdded",l)}g.bind("PostInit",function(){var j=g.settings,e=document.getElementById(j.drop_element);if(e){b.addEvent(e,"dragover",function(k){h.setDropEffect(k,"copy");k.preventDefault()});b.addEvent(e,"drop",function(l){var k=h.getDragData(l,"application/x-gears-files");if(k){d(k.files)}l.preventDefault()});e=0}b.addEvent(document.getElementById(j.browse_button),"click",function(o){var n=[],l,k,m;o.preventDefault();for(l=0;l<j.filters.length;l++){m=j.filters[l].extensions.split(",");for(k=0;k<m.length;k++){n.push("."+m[k])}}h.openFiles(d,{singleFile:!j.multi_selection,filter:n})})});g.bind("UploadFile",function(o,l){var q=0,p,m,n=0,k=o.settings.resize,e;m=o.settings.chunk_size;e=m>0;p=Math.ceil(l.size/m);if(!e){m=l.size;p=1}if(k&&/\.(png|jpg|jpeg)$/i.test(l.name)){c[l.id]=a(c[l.id],k.width,k.height,k.quality||90,/\.png$/i.test(l.name)?"image/png":"image/jpeg")}l.size=c[l.id].length;function j(){var u,w,s=o.settings.multipart,r=0,v={name:l.target_name||l.name};function t(y){var x,C="----pluploadboundary"+b.guid(),A="--",B="\r\n",z;if(s){u.setRequestHeader("Content-Type","multipart/form-data; boundary="+C);x=google.gears.factory.create("beta.blobbuilder");b.each(o.settings.multipart_params,function(E,D){x.append(A+C+B+'Content-Disposition: form-data; name="'+D+'"'+B+B);x.append(E+B)});x.append(A+C+B+'Content-Disposition: form-data; name="'+o.settings.file_data_name+'"; filename="'+l.name+'"'+B+"Content-Type: application/octet-stream"+B+B);x.append(y);x.append(B+A+C+A+B);z=x.getAsBlob();r=z.length-y.length;y=z}u.send(y)}if(l.status==b.DONE||l.status==b.FAILED||o.state==b.STOPPED){return}if(e){v.chunk=q;v.chunks=p}w=Math.min(m,l.size-(q*m));u=google.gears.factory.create("beta.httprequest");u.open("POST",b.buildUrl(o.settings.url,v));if(!s){u.setRequestHeader("Content-Disposition",'attachment; filename="'+l.name+'"');u.setRequestHeader("Content-Type","application/octet-stream")}b.each(o.settings.headers,function(y,x){u.setRequestHeader(x,y)});u.upload.onprogress=function(x){l.loaded=n+x.loaded-r;o.trigger("UploadProgress",l)};u.onreadystatechange=function(){var x;if(u.readyState==4){if(u.status==200){x={chunk:q,chunks:p,response:u.responseText,status:u.status};o.trigger("ChunkUploaded",l,x);if(x.cancelled){l.status=b.FAILED;return}n+=w;if(++q>=p){l.status=b.DONE;o.trigger("FileUploaded",l,{response:u.responseText,status:u.status})}else{j()}}else{o.trigger("Error",{code:b.HTTP_ERROR,message:"HTTP Error.",file:l,chunk:q,chunks:p,status:u.status})}}};if(q<p){t(c[l.id].slice(q*m,w))}}j()});i({success:true})}})})(plupload);(function(c){var a={};function b(l){var k,j=typeof l,h,e,g,f;if(j==="string"){k="\bb\tt\nn\ff\rr\"\"''\\\\";return'"'+l.replace(/([\u0080-\uFFFF\x00-\x1f\"])/g,function(n,m){var i=k.indexOf(m);if(i+1){return"\\"+k.charAt(i+1)}n=m.charCodeAt().toString(16);return"\\u"+"0000".substring(n.length)+n})+'"'}if(j=="object"){e=l.length!==h;k="";if(e){for(g=0;g<l.length;g++){if(k){k+=","}k+=b(l[g])}k="["+k+"]"}else{for(f in l){if(l.hasOwnProperty(f)){if(k){k+=","}k+=b(f)+":"+b(l[f])}}k="{"+k+"}"}return k}if(l===h){return"null"}return""+l}function d(o){var r=false,f=null,k=null,g,h,i,q,j,m=0;try{try{k=new ActiveXObject("AgControl.AgControl");if(k.IsVersionSupported(o)){r=true}k=null}catch(n){var l=navigator.plugins["Silverlight Plug-In"];if(l){g=l.description;if(g==="1.0.30226.2"){g="2.0.30226.2"}h=g.split(".");while(h.length>3){h.pop()}while(h.length<4){h.push(0)}i=o.split(".");while(i.length>4){i.pop()}do{q=parseInt(i[m],10);j=parseInt(h[m],10);m++}while(m<i.length&&q===j);if(q<=j&&!isNaN(q)){r=true}}}}catch(p){r=false}return r}c.silverlight={trigger:function(j,f){var h=a[j],g,e;if(h){e=c.toArray(arguments).slice(1);e[0]="Silverlight:"+f;setTimeout(function(){h.trigger.apply(h,e)},0)}}};c.runtimes.Silverlight=c.addRuntime("silverlight",{getFeatures:function(){return{jpgresize:true,pngresize:true,chunks:true,progress:true,multipart:true}},init:function(l,m){var k,h="",j=l.settings.filters,g,f=document.body;if(!d("2.0.31005.0")||(window.opera&&window.opera.buildNumber)){m({success:false});return}a[l.id]=l;k=document.createElement("div");k.id=l.id+"_silverlight_container";c.extend(k.style,{position:"absolute",top:"0px",background:l.settings.shim_bgcolor||"transparent",zIndex:99999,width:"100px",height:"100px",overflow:"hidden",opacity:l.settings.shim_bgcolor?"":0.01});k.className="plupload silverlight";if(l.settings.container){f=document.getElementById(l.settings.container);f.style.position="relative"}f.appendChild(k);for(g=0;g<j.length;g++){h+=(h!=""?"|":"")+j[g].title+" | *."+j[g].extensions.replace(/,/g,";*.")}k.innerHTML='<object id="'+l.id+'_silverlight" data="data:application/x-silverlight," type="application/x-silverlight-2" style="outline:none;" width="1024" height="1024"><param name="source" value="'+l.settings.silverlight_xap_url+'"/><param name="background" value="Transparent"/><param name="windowless" value="true"/><param name="initParams" value="id='+l.id+",filter="+h+'"/></object>';function e(){return document.getElementById(l.id+"_silverlight").content.Upload}l.bind("Silverlight:Init",function(){var i,n={};l.bind("Silverlight:StartSelectFiles",function(o){i=[]});l.bind("Silverlight:SelectFile",function(o,r,p,q){var s;s=c.guid();n[s]=r;n[r]=s;i.push(new c.File(s,p,q))});l.bind("Silverlight:SelectSuccessful",function(){if(i.length){l.trigger("FilesAdded",i)}});l.bind("Silverlight:UploadChunkError",function(o,r,p,s,q){l.trigger("Error",{code:c.IO_ERROR,message:"IO Error.",details:q,file:o.getFile(n[r])})});l.bind("Silverlight:UploadFileProgress",function(o,s,p,r){var q=o.getFile(n[s]);if(q.status!=c.FAILED){q.size=r;q.loaded=p;o.trigger("UploadProgress",q)}});l.bind("Refresh",function(o){var p,q,r;p=document.getElementById(o.settings.browse_button);q=c.getPos(p,document.getElementById(o.settings.container));r=c.getSize(p);c.extend(document.getElementById(o.id+"_silverlight_container").style,{top:q.y+"px",left:q.x+"px",width:r.w+"px",height:r.h+"px"})});l.bind("Silverlight:UploadChunkSuccessful",function(o,r,p,u,t){var s,q=o.getFile(n[r]);s={chunk:p,chunks:u,response:t};o.trigger("ChunkUploaded",q,s);if(q.status!=c.FAILED){e().UploadNextChunk()}if(p==u-1){q.status=c.DONE;o.trigger("FileUploaded",q,{response:t})}});l.bind("Silverlight:UploadSuccessful",function(o,r,p){var q=o.getFile(n[r]);q.status=c.DONE;o.trigger("FileUploaded",q,{response:p})});l.bind("FilesRemoved",function(o,q){var p;for(p=0;p<q.length;p++){e().RemoveFile(n[q[p].id])}});l.bind("UploadFile",function(o,q){var r=o.settings,p=r.resize||{};e().UploadFile(n[q.id],c.buildUrl(o.settings.url,{name:q.target_name||q.name}),b({chunk_size:r.chunk_size,image_width:p.width,image_height:p.height,image_quality:p.quality||90,multipart:!!r.multipart,multipart_params:r.multipart_params||{},headers:r.headers}))});m({success:true})})}})})(plupload);(function(c){var a={};function b(){var d;try{d=navigator.plugins["Shockwave Flash"];d=d.description}catch(f){try{d=new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable("$version")}catch(e){d="0.0"}}d=d.match(/\d+/g);return parseFloat(d[0]+"."+d[1])}c.flash={trigger:function(f,d,e){setTimeout(function(){var j=a[f],h,g;if(j){j.trigger("Flash:"+d,e)}},0)}};c.runtimes.Flash=c.addRuntime("flash",{getFeatures:function(){return{jpgresize:true,pngresize:true,chunks:true,progress:true,multipart:true}},init:function(g,l){var k,f,h,e,m=0,d=document.body;if(b()<10){l({success:false});return}a[g.id]=g;k=document.getElementById(g.settings.browse_button);f=document.createElement("div");f.id=g.id+"_flash_container";c.extend(f.style,{position:"absolute",top:"0px",background:g.settings.shim_bgcolor||"transparent",zIndex:99999,width:"100%",height:"100%"});f.className="plupload flash";if(g.settings.container){d=document.getElementById(g.settings.container);d.style.position="relative"}d.appendChild(f);h="id="+escape(g.id);f.innerHTML='<object id="'+g.id+'_flash" width="100%" height="100%" style="outline:0" type="application/x-shockwave-flash" data="'+g.settings.flash_swf_url+'"><param name="movie" value="'+g.settings.flash_swf_url+'" /><param name="flashvars" value="'+h+'" /><param name="wmode" value="transparent" /><param name="allowscriptaccess" value="always" /></object>';function j(){return document.getElementById(g.id+"_flash")}function i(){if(m++>5000){l({success:false});return}if(!e){setTimeout(i,1)}}i();k=f=null;g.bind("Flash:Init",function(){var p={},o,n=g.settings.resize||{};e=true;j().setFileFilters(g.settings.filters,g.settings.multi_selection);g.bind("UploadFile",function(q,r){var s=q.settings;j().uploadFile(p[r.id],c.buildUrl(s.url,{name:r.target_name||r.name}),{chunk_size:s.chunk_size,width:n.width,height:n.height,quality:n.quality||90,multipart:s.multipart,multipart_params:s.multipart_params,file_data_name:s.file_data_name,format:/\.(jpg|jpeg)$/i.test(r.name)?"jpg":"png",headers:s.headers,urlstream_upload:s.urlstream_upload})});g.bind("Flash:UploadProcess",function(r,q){var s=r.getFile(p[q.id]);if(s.status!=c.FAILED){s.loaded=q.loaded;s.size=q.size;r.trigger("UploadProgress",s)}});g.bind("Flash:UploadChunkComplete",function(q,s){var t,r=q.getFile(p[s.id]);t={chunk:s.chunk,chunks:s.chunks,response:s.text};q.trigger("ChunkUploaded",r,t);if(r.status!=c.FAILED){j().uploadNextChunk()}if(s.chunk==s.chunks-1){r.status=c.DONE;q.trigger("FileUploaded",r,{response:s.text})}});g.bind("Flash:SelectFiles",function(q,t){var s,r,u=[],v;for(r=0;r<t.length;r++){s=t[r];v=c.guid();p[v]=s.id;p[s.id]=v;u.push(new c.File(v,s.name,s.size))}if(u.length){g.trigger("FilesAdded",u)}});g.bind("Flash:SecurityError",function(q,r){g.trigger("Error",{code:c.SECURITY_ERROR,message:"Security error.",details:r.message,file:g.getFile(p[r.id])})});g.bind("Flash:GenericError",function(q,r){g.trigger("Error",{code:c.GENERIC_ERROR,message:"Generic error.",details:r.message,file:g.getFile(p[r.id])})});g.bind("Flash:IOError",function(q,r){g.trigger("Error",{code:c.IO_ERROR,message:"IO error.",details:r.message,file:g.getFile(p[r.id])})});g.bind("QueueChanged",function(q){g.refresh()});g.bind("FilesRemoved",function(q,s){var r;for(r=0;r<s.length;r++){j().removeFile(p[s[r].id])}});g.bind("StateChanged",function(q){g.refresh()});g.bind("Refresh",function(q){var r,s,t;j().setFileFilters(g.settings.filters,g.settings.multi_selection);r=document.getElementById(q.settings.browse_button);s=c.getPos(r,document.getElementById(q.settings.container));t=c.getSize(r);c.extend(document.getElementById(q.id+"_flash_container").style,{top:s.y+"px",left:s.x+"px",width:t.w+"px",height:t.h+"px"})});l({success:true})})}})})(plupload);(function(a){a.runtimes.BrowserPlus=a.addRuntime("browserplus",{getFeatures:function(){return{dragdrop:true,jpgresize:true,pngresize:true,chunks:true,progress:true,multipart:true}},init:function(g,i){var e=window.BrowserPlus,h={},d=g.settings,c=d.resize;function f(n){var m,l,j=[],k,o;for(l=0;l<n.length;l++){k=n[l];o=a.guid();h[o]=k;j.push(new a.File(o,k.name,k.size))}if(l){g.trigger("FilesAdded",j)}}function b(){g.bind("PostInit",function(){var m,k=d.drop_element,o=g.id+"_droptarget",j=document.getElementById(k),l;function p(r,q){e.DragAndDrop.AddDropTarget({id:r},function(s){e.DragAndDrop.AttachCallbacks({id:r,hover:function(t){if(!t&&q){q()}},drop:function(t){if(q){q()}f(t)}},function(){})})}function n(){document.getElementById(o).style.top="-1000px"}if(j){if(document.attachEvent&&(/MSIE/gi).test(navigator.userAgent)){m=document.createElement("div");m.setAttribute("id",o);a.extend(m.style,{position:"absolute",top:"-1000px",background:"red",filter:"alpha(opacity=0)",opacity:0});document.body.appendChild(m);a.addEvent(j,"dragenter",function(r){var q,s;q=document.getElementById(k);s=a.getPos(q);a.extend(document.getElementById(o).style,{top:s.y+"px",left:s.x+"px",width:q.offsetWidth+"px",height:q.offsetHeight+"px"})});p(o,n)}else{p(k)}}a.addEvent(document.getElementById(d.browse_button),"click",function(v){var t=[],r,q,u=d.filters,s;v.preventDefault();for(r=0;r<u.length;r++){s=u[r].extensions.split(",");for(q=0;q<s.length;q++){t.push(a.mimeTypes[s[q]])}}e.FileBrowse.OpenBrowseDialog({mimeTypes:t},function(w){if(w.success){f(w.value)}})});j=m=null});g.bind("UploadFile",function(n,k){var m=h[k.id],j={},l=n.settings.chunk_size,o,p=[];function r(s,u){var t;if(k.status==a.FAILED){return}j.name=k.target_name||k.name;if(l){j.chunk=s;j.chunks=u}t=p.shift();e.Uploader.upload({url:a.buildUrl(n.settings.url,j),files:{file:t},cookies:document.cookies,postvars:n.settings.multipart_params,progressCallback:function(x){var w,v=0;o[s]=parseInt(x.filePercent*t.size/100,10);for(w=0;w<o.length;w++){v+=o[w]}k.loaded=v;n.trigger("UploadProgress",k)}},function(w){var v,x;if(w.success){v=w.value.statusCode;if(l){n.trigger("ChunkUploaded",k,{chunk:s,chunks:u,response:w.value.body,status:v})}if(p.length>0){r(++s,u)}else{k.status=a.DONE;n.trigger("FileUploaded",k,{response:w.value.body,status:v});if(v>=400){n.trigger("Error",{code:a.HTTP_ERROR,message:"HTTP Error.",file:k,status:v})}}}else{n.trigger("Error",{code:a.GENERIC_ERROR,message:"Generic Error.",file:k,details:w.error})}})}function q(s){k.size=s.size;if(l){e.FileAccess.chunk({file:s,chunkSize:l},function(v){if(v.success){var w=v.value,t=w.length;o=Array(t);for(var u=0;u<t;u++){o[u]=0;p.push(w[u])}r(0,t)}})}else{o=Array(1);p.push(s);r(0,1)}}if(c&&/\.(png|jpg|jpeg)$/i.test(k.name)){BrowserPlus.ImageAlter.transform({file:m,quality:c.quality||90,actions:[{scale:{maxwidth:c.width,maxheight:c.height}}]},function(s){if(s.success){q(s.value.file)}})}else{q(m)}});i({success:true})}if(e){e.init(function(k){var j=[{service:"Uploader",version:"3"},{service:"DragAndDrop",version:"1"},{service:"FileBrowse",version:"1"},{service:"FileAccess",version:"2"}];if(c){j.push({service:"ImageAlter",version:"4"})}if(k.success){e.require({services:j},function(l){if(l.success){b()}else{i()}})}else{i()}})}else{i()}}})})(plupload);(function(b){function a(i,l,j,c,k){var e,d,h,g,f;e=document.createElement("canvas");e.style.display="none";document.body.appendChild(e);d=e.getContext("2d");h=new Image();h.onload=function(){var o,m,n;f=Math.min(l/h.width,j/h.height);if(f<1){o=Math.round(h.width*f);m=Math.round(h.height*f)}else{o=h.width;m=h.height}e.width=o;e.height=m;d.drawImage(h,0,0,o,m);g=e.toDataURL(c);g=g.substring(g.indexOf("base64,")+7);g=atob(g);e.parentNode.removeChild(e);k({success:true,data:g})};h.src=i}b.runtimes.Html5=b.addRuntime("html5",{getFeatures:function(){var g,d,f,e,c;d=f=e=c=false;if(window.XMLHttpRequest){g=new XMLHttpRequest();f=!!g.upload;d=!!(g.sendAsBinary||g.upload)}if(d){e=!!(File&&File.prototype.getAsDataURL);c=!!(File&&File.prototype.slice)}return{html5:d,dragdrop:window.mozInnerScreenX!==undefined||c,jpgresize:e,pngresize:e,multipart:e||!!window.FileReader||!!window.FormData,progress:f,chunking:c||e}},init:function(f,g){var c={},d;function e(l){var j,h,k=[],m;for(h=0;h<l.length;h++){j=l[h];m=b.guid();c[m]=j;k.push(new b.File(m,j.fileName,j.fileSize))}if(k.length){f.trigger("FilesAdded",k)}}d=this.getFeatures();if(!d.html5){g({success:false});return}f.bind("Init",function(m){var q,o=[],l,p,j=m.settings.filters,k,n,h=document.body;q=document.createElement("div");q.id=m.id+"_html5_container";for(l=0;l<j.length;l++){k=j[l].extensions.split(/,/);for(p=0;p<k.length;p++){n=b.mimeTypes[k[p]];if(n){o.push(n)}}}b.extend(q.style,{position:"absolute",background:f.settings.shim_bgcolor||"transparent",width:"100px",height:"100px",overflow:"hidden",zIndex:99999,opacity:f.settings.shim_bgcolor?"":0});q.className="plupload html5";if(f.settings.container){h=document.getElementById(f.settings.container);h.style.position="relative"}h.appendChild(q);q.innerHTML='<input id="'+f.id+'_html5" style="width:100%;" type="file" accept="'+o.join(",")+'" '+(f.settings.multi_selection?'multiple="multiple"':"")+" />";document.getElementById(f.id+"_html5").onchange=function(){e(this.files);this.value=""}});f.bind("PostInit",function(){var h=document.getElementById(f.settings.drop_element);if(h){b.addEvent(h,"dragover",function(i){i.preventDefault()});b.addEvent(h,"drop",function(j){var i=j.dataTransfer;if(i&&i.files){e(i.files)}j.preventDefault()})}});f.bind("Refresh",function(h){var i,j,k;i=document.getElementById(f.settings.browse_button);j=b.getPos(i,document.getElementById(h.settings.container));k=b.getSize(i);b.extend(document.getElementById(f.id+"_html5_container").style,{top:j.y+"px",left:j.x+"px",width:k.w+"px",height:k.h+"px"})});f.bind("UploadFile",function(h,j){var k=h.settings,m,i;function l(n){var q=0,p=0;function o(){var u=n,C,D,y,z,A=0,r="----pluploadboundary"+b.guid(),t,w,s="--",B="\r\n",x="";if(j.status==b.DONE||j.status==b.FAILED||h.state==b.STOPPED){return}z={name:j.target_name||j.name};if(k.chunk_size&&d.chunking){t=k.chunk_size;y=Math.ceil(j.size/t);w=Math.min(t,j.size-(q*t));if(typeof(n)=="string"){u=n.substring(q*t,q*t+w)}else{u=n.slice(q*t,w)}z.chunk=q;z.chunks=y}else{w=j.size}C=new XMLHttpRequest();D=C.upload;if(D){D.onprogress=function(E){j.loaded=Math.min(j.size,p+E.loaded-A);h.trigger("UploadProgress",j)}}C.open("post",b.buildUrl(h.settings.url,z),true);C.onreadystatechange=function(){var E,G;if(C.readyState==4){try{E=C.status}catch(F){E=0}if(E>=400){h.trigger("Error",{code:b.HTTP_ERROR,message:"HTTP Error.",file:j,status:E})}else{if(y){G={chunk:q,chunks:y,response:C.responseText,status:E};h.trigger("ChunkUploaded",j,G);p+=w;if(G.cancelled){j.status=b.FAILED;return}j.loaded=Math.min(j.size,(q+1)*t)}else{j.loaded=j.size}h.trigger("UploadProgress",j);if(!y||++q>=y){j.status=b.DONE;h.trigger("FileUploaded",j,{response:C.responseText,status:E})}else{o()}}}};b.each(h.settings.headers,function(F,E){C.setRequestHeader(E,F)});if(h.settings.multipart&&d.multipart){if(!C.sendAsBinary){var v=new FormData();b.each(h.settings.multipart_params,function(F,E){v.append(E,F)});v.append(h.settings.file_data_name,u);C.send(v);return}C.setRequestHeader("Content-Type","multipart/form-data; boundary="+r);b.each(h.settings.multipart_params,function(F,E){x+=s+r+B+'Content-Disposition: form-data; name="'+E+'"'+B+B;x+=F+B});x+=s+r+B+'Content-Disposition: form-data; name="'+h.settings.file_data_name+'"; filename="'+j.name+'"'+B+"Content-Type: application/octet-stream"+B+B+u+B+s+r+s+B;A=x.length-u.length;u=x}else{C.setRequestHeader("Content-Type","application/octet-stream")}if(C.sendAsBinary){C.sendAsBinary(u)}else{C.send(u)}}o()}m=c[j.id];i=h.settings.resize;if(d.jpgresize){if(i&&/\.(png|jpg|jpeg)$/i.test(j.name)){a(m.getAsDataURL(),i.width,i.height,/\.png$/i.test(j.name)?"image/png":"image/jpeg",function(n){if(n.success){j.size=n.data.length;l(n.data)}else{l(m.getAsBinary())}})}else{l(m.getAsBinary())}}else{l(m)}});g({success:true})}})})(plupload);(function(a){a.runtimes.Html4=a.addRuntime("html4",{getFeatures:function(){return{multipart:true}},init:function(f,g){var d={},c,b;function e(l){var k,j,m=[],n,h;h=l.value.replace(/\\/g,"/");h=h.substring(h.length,h.lastIndexOf("/")+1);n=a.guid();k=new a.File(n,h);d[n]=k;k.input=l;m.push(k);if(m.length){f.trigger("FilesAdded",m)}}f.bind("Init",function(p){var h,x,v,t=[],o,u,m=p.settings.filters,l,s,r=/MSIE/.test(navigator.userAgent),k="javascript",w,j=document.body,n;if(f.settings.container){j=document.getElementById(f.settings.container);j.style.position="relative"}c=(typeof p.settings.form=="string")?document.getElementById(p.settings.form):p.settings.form;if(!c){n=document.getElementById(f.settings.browse_button);for(;n;n=n.parentNode){if(n.nodeName=="FORM"){c=n}}}if(!c){c=document.createElement("form");c.style.display="inline";n=document.getElementById(f.settings.container);n.parentNode.insertBefore(c,n);c.appendChild(n)}c.setAttribute("method","post");c.setAttribute("enctype","multipart/form-data");a.each(p.settings.multipart_params,function(z,y){var i=document.createElement("input");a.extend(i,{type:"hidden",name:y,value:z});c.appendChild(i)});b=document.createElement("iframe");b.setAttribute("src",k+':""');b.setAttribute("name",p.id+"_iframe");b.setAttribute("id",p.id+"_iframe");b.style.display="none";a.addEvent(b,"load",function(B){var C=B.target,z=f.currentfile,A;try{A=C.contentWindow.document||C.contentDocument||window.frames[C.id].document}catch(y){p.trigger("Error",{code:a.SECURITY_ERROR,message:"Security error.",file:z});return}if(A.location.href=="about:blank"||!z){return}var i=A.documentElement.innerText||A.documentElement.textContent;if(i!=""){z.status=a.DONE;z.loaded=1025;z.percent=100;if(z.input){z.input.removeAttribute("name")}p.trigger("UploadProgress",z);p.trigger("FileUploaded",z,{response:i});if(c.tmpAction){c.setAttribute("action",c.tmpAction)}if(c.tmpTarget){c.setAttribute("target",c.tmpTarget)}}});c.appendChild(b);if(r){window.frames[b.id].name=b.name}x=document.createElement("div");x.id=p.id+"_iframe_container";for(o=0;o<m.length;o++){l=m[o].extensions.split(/,/);for(u=0;u<l.length;u++){s=a.mimeTypes[l[u]];if(s){t.push(s)}}}a.extend(x.style,{position:"absolute",background:"transparent",width:"100px",height:"100px",overflow:"hidden",zIndex:99999,opacity:0});w=f.settings.shim_bgcolor;if(w){a.extend(x.style,{background:w,opacity:1})}x.className="plupload_iframe";j.appendChild(x);function q(){v=document.createElement("input");v.setAttribute("type","file");v.setAttribute("accept",t.join(","));v.setAttribute("size",1);a.extend(v.style,{width:"100%",height:"100%",opacity:0});if(r){a.extend(v.style,{filter:"alpha(opacity=0)"})}a.addEvent(v,"change",function(i){var y=i.target;if(y.value){q();y.style.display="none";e(y)}});x.appendChild(v);return true}q()});f.bind("Refresh",function(h){var i,j,k;i=document.getElementById(f.settings.browse_button);j=a.getPos(i,document.getElementById(h.settings.container));k=a.getSize(i);a.extend(document.getElementById(f.id+"_iframe_container").style,{top:j.y+"px",left:j.x+"px",width:k.w+"px",height:k.h+"px"})});f.bind("UploadFile",function(h,i){if(i.status==a.DONE||i.status==a.FAILED||h.state==a.STOPPED){return}if(!i.input){i.status=a.ERROR;return}i.input.setAttribute("name",h.settings.file_data_name);c.tmpAction=c.getAttribute("action");c.setAttribute("action",a.buildUrl(h.settings.url,{name:i.target_name||i.name}));c.tmpTarget=c.getAttribute("target");c.setAttribute("target",b.name);this.currentfile=i;c.submit()});f.bind("FilesRemoved",function(h,k){var j,l;for(j=0;j<k.length;j++){l=k[j].input;if(l){l.parentNode.removeChild(l)}}});g({success:true})}})})(plupload);
Index: typo3/contrib/plupload/changelog.txt
===================================================================
--- typo3/contrib/plupload/changelog.txt	(revision )
+++ typo3/contrib/plupload/changelog.txt	(revision )
@@ -0,0 +1,81 @@
+Version 1.2.x (2010-xx-xx)
+	Added support for crossdomain loading of the XAP and SWF files and crossdomain upload.
+	Added preinit/init options to to ease up the binding of custom events to queueWidget and the Uploader class.
+	Added drag/drop support for Safari kind of a hack until they release official drag/drop support like Chrome.
+	Added events example file that show how to bind all events and display event specific data.
+	Fixed logic issue with the upload.php example file. Chunking wasn't working correctly.
+	Fixed issue with HTML4 not handling the form encoding correctly on older IE versions. Patch contributed by jinxdone.
+	Fixed so the HTML4 runtime only submits the defined multipart_params arguments.
+	Fixes issue where it wasn't possible to dynamically override url or mutlipart_params for the HTML4 runtime.
+	Fixed so all runtimes pass the name, chunk and chunks parameters as multipart parameters instead of querystring parameters.
+	Fixed so files are read using the newer FileReader class if it's available if not it tries the older getAsXXX on Gecko.
+	Fixed bug where IE 9 beta 1 wouldn't render Silverlight properly.
+Version 1.2.4 (2010-09-08)
+	Added new BeforeUpload event to make it easier to override settings before a file is uploaded.
+	Added new automatic usage of FileReference in Flash if it's possible. Contributed by Marcel Jackwerth.
+	Added new chunking support for Chrome 5 and Firefox 3.6 using the HTML 5 runtime.
+	Added new multipart upload support for WebKit using the HTML 5 runtime and the FormData object.
+	Added new image scaling method for the Flash runtime contributed by rcoopman.
+	Added new alert error message if the user selected invalid files.
+	Added new automatic unique name generation to the example.php script. Contributed by Brandon Kelly.
+	Changed so the default upload method is multipart and the default chunk size is 0.
+	Fixed progress issue with the HTML5 runtime running on Gecko.
+	Fixed so longer extensions can be used such as .tar.gz.
+	Fixed so the file extension is retained when using the unique_names option.
+Version 1.2.3 (2010-05-27)
+	Added new drag/drop support for HTML5 running on Chrome beta.
+	Added new multipart state for the features object. It's now possible to detect multipart support.
+	Added new getFeatures function to all runtime. Basic concept by Javier Martinez Fernandez.
+	Fixed bug where runtimes where initialized even if they didn't match the required_features setting.
+Version 1.2.2.1 (2010-05-04)
+	Added new headers option, enables you to set custom headers for the upload requests.
+	Fixed bug where the file extension checking was case sensitive.
+Version 1.2.2 (2010-04-26)
+	Added new file_data_name option that enables you to set the multipart file data param. Patch contributed by Alex Ganov.
+	Added new FILE_SIZE_ERROR type that will be triggered if the user selected a file that is to large or zero bytes.
+	Added new FILE_EXTENSION_ERROR type that will be triggered if you add a file with an invalid file extension.
+	Added new required_features setting, enables you to specify a list of required features that the runtime must have.
+	Fixed so the plupload.buildUrl function uses the UTF compatible encodeURIComponent method instead of escape.
+	Fixed so that all file types can be selected if you don't specify a filter setting.
+	Fixed so more valid HTTP status codes are accepted as valid responses.
+	Fixed so all runtimes fills the features object with available features.
+	Fixed some issues with the HTML4 runtime if there wasn't any existing forms on the page.
+	Fixed some conflict issues with HTML4 runtime and forms with the input names of action or target.
+	Fixed bug where some Gecko versions would produce exceptions when checking the HTTP status of a XHR.
+Version 1.2.1 (2010-03-22)
+	Fixed bug with incorrect aspect ratio in Flash image scaling.
+	Fixed bug where chunked uploads could get scrambled in the Flash runtime. Patch contributed by Grady Werner.
+	Fixed bug where a beta version of Chrome wouldn't handle drag/drop correctly because of missing drag effect.
+	Fixed so the HTML 4 runtime displays N/A for file sizes and the progress is based on uploaded files instead of bytes.
+	Fixed so chunking can be disabled properly in Flash but that will affect the progress bar.
+	Fixed so queue widget displays the drag/drop message if file queue is emptied.
+	Fixed small files are uploaded as one single chunk and not forced into 4 chunks in the Flash runtime.
+Version 1.2 (2010-03-09)
+	Added new rename file support for jQuery queue widget, click on a file name to rename it if it's enabled.
+	Added official ChunkUploaded event, it similar to FileUploaded but executed for each chunk.
+	Added bytes per second support to total queue progress.
+	Added better error handling to core API using the new Error event.
+	Added better error handling to jQuery queue widget.
+	Fixed so chunking uploads is dispatch from JS not from inside Flash/Silverlight.
+Version 1.1.1 (2010-02-25)
+	Added new setup setting to queue widget. Makes it easier to bind custom events to uploader instance.
+	Fixed so it's possible to disable chunking compleatly. It's now disabled by default.
+	Fixed bug where multipart mode was enabled all the time in the Flash runtime.
+	Fixed bug where chunked uploading in Silverlight would fail.
+	Fixed bug where the delete button was visible while uploading.
+	Fixed bug where unique_names setting wasn't working when the core API was used.
+	Fixed bug where the queue widget wouldn't display the currently uploaded file if the unique_names was enabled.
+Version 1.1 (2010-02-24)
+	Added new multipart and multipart_params support.
+	Added new container option, enables you to specify where flash/silverlight objects would be added.
+	Added chunking support to BrowserPlus runtime, contributed by Steve Spencer.
+	Added FileUploaded event that fires when a file is uploaded.
+	Added more easily understandable buttons to queue widget.
+	Added html4 runtime, contributed by Ryan Demmer.
+	Fixed issues with i18n support and added a Swedish and Danish language pack.
+	Fixed bug where the Flash runtime could do empty requests if the image was scaled down.
+	Fixed bug where uploading small images in Silverlight would produce an exception.
+	Fixed so the runtime list can include whitespace or missing runtimes. Patch contributed by ?yvind Sean Kinsey.
+	Fixed so to large files are ignored and never dispatched to the FilesAdded event.
+Version 1.0 (2010-02-03)
+	First official release of Plupload.
Index: typo3/sysext/lang/locallang_misc.xml
===================================================================
--- typo3/sysext/lang/locallang_misc.xml	(revision 9717)
+++ typo3/sysext/lang/locallang_misc.xml	(revision )
@@ -104,11 +104,16 @@
 			<label index="switchtousershort">SU:</label>
 			<label index="fileUpload_windowTitle">File Upload Progress</label>
 			<label index="fileUpload_buttonSelectFiles">Select Files</label>
+			<label index="fileUpload_buttonStartUpload">Start Upload</label>
 			<label index="fileUpload_buttonCancelAll">Cancel All Uploads</label>
+			<label index="fileUpload_progressText">{2} of {1} file(s) uploaded (Speed: {5}/s)</label>
 			<label index="fileUpload_infoComponentMaxFileSize">You can upload files with a maximum size of {0}.</label>
 			<label index="fileUpload_infoComponentFileUploadLimit">You can upload a total of {0}.</label>
 			<label index="fileUpload_infoComponentFileTypeLimit">You can upload the following file types {0}.</label>
-			<label index="fileUpload_infoComponentOverrideFiles">Overwrite existing files</label>
+			<label index="fileUpload_infoFileQueueEmpty">no files queued</label>
+			<label index="fileUpload_infoFileQueued">File queued</label>
+			<label index="fileUpload_infoFileFinished">Upload finished</label>
+			<label index="fileUpload_infoFileUploading">Uploading ({0}%)</label>
 			<label index="fileUpload_processRunning">Another process is already uploading</label>
 			<label index="fileUpload_uploadWait">Waiting to start upload of {0}</label>
 			<label index="fileUpload_uploadStarting">Starting upload of {0}</label>
Index: typo3/contrib/plupload/js/gears_init.js
===================================================================
--- typo3/contrib/plupload/js/gears_init.js	(revision )
+++ typo3/contrib/plupload/js/gears_init.js	(revision )
@@ -0,0 +1,86 @@
+// Copyright 2007, Google Inc.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+//  1. Redistributions of source code must retain the above copyright notice,
+//     this list of conditions and the following disclaimer.
+//  2. Redistributions in binary form must reproduce the above copyright notice,
+//     this list of conditions and the following disclaimer in the documentation
+//     and/or other materials provided with the distribution.
+//  3. Neither the name of Google Inc. nor the names of its contributors may be
+//     used to endorse or promote products derived from this software without
+//     specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Sets up google.gears.*, which is *the only* supported way to access Gears.
+//
+// Circumvent this file at your own risk!
+//
+// In the future, Gears may automatically define google.gears.* without this
+// file. Gears may use these objects to transparently fix bugs and compatibility
+// issues. Applications that use the code below will continue to work seamlessly
+// when that happens.
+
+(function() {
+  // We are already defined. Hooray!
+  if (window.google && google.gears) {
+    return;
+  }
+
+  var factory = null;
+
+  // Firefox
+  if (typeof GearsFactory != 'undefined') {
+    factory = new GearsFactory();
+  } else {
+    // IE
+    try {
+      factory = new ActiveXObject('Gears.Factory');
+      // privateSetGlobalObject is only required and supported on WinCE.
+      if (factory.getBuildInfo().indexOf('ie_mobile') != -1) {
+        factory.privateSetGlobalObject(this);
+      }
+    } catch (e) {
+      // Safari
+      if ((typeof navigator.mimeTypes != 'undefined')
+           && navigator.mimeTypes["application/x-googlegears"]) {
+        factory = document.createElement("object");
+        factory.style.display = "none";
+        factory.width = 0;
+        factory.height = 0;
+        factory.type = "application/x-googlegears";
+        document.documentElement.appendChild(factory);
+      }
+    }
+  }
+
+  // *Do not* define any objects if Gears is not installed. This mimics the
+  // behavior of Gears defining the objects in the future.
+  if (!factory) {
+    return;
+  }
+
+  // Now set up the objects, being careful not to overwrite anything.
+  //
+  // Note: In Internet Explorer for Windows Mobile, you can't add properties to
+  // the window object. However, global objects are automatically added as
+  // properties of the window object in all browsers.
+  if (!window.google) {
+    google = {};
+  }
+
+  if (!google.gears) {
+    google.gears = {factory: factory};
+  }
+})();
Index: typo3/contrib/plupload/js/plupload.silverlight.min.js
===================================================================
--- typo3/contrib/plupload/js/plupload.silverlight.min.js	(revision )
+++ typo3/contrib/plupload/js/plupload.silverlight.min.js	(revision )
@@ -0,0 +1,1 @@
+(function(c){var a={};function b(l){var k,j=typeof l,h,e,g,f;if(j==="string"){k="\bb\tt\nn\ff\rr\"\"''\\\\";return'"'+l.replace(/([\u0080-\uFFFF\x00-\x1f\"])/g,function(n,m){var i=k.indexOf(m);if(i+1){return"\\"+k.charAt(i+1)}n=m.charCodeAt().toString(16);return"\\u"+"0000".substring(n.length)+n})+'"'}if(j=="object"){e=l.length!==h;k="";if(e){for(g=0;g<l.length;g++){if(k){k+=","}k+=b(l[g])}k="["+k+"]"}else{for(f in l){if(l.hasOwnProperty(f)){if(k){k+=","}k+=b(f)+":"+b(l[f])}}k="{"+k+"}"}return k}if(l===h){return"null"}return""+l}function d(o){var r=false,f=null,k=null,g,h,i,q,j,m=0;try{try{k=new ActiveXObject("AgControl.AgControl");if(k.IsVersionSupported(o)){r=true}k=null}catch(n){var l=navigator.plugins["Silverlight Plug-In"];if(l){g=l.description;if(g==="1.0.30226.2"){g="2.0.30226.2"}h=g.split(".");while(h.length>3){h.pop()}while(h.length<4){h.push(0)}i=o.split(".");while(i.length>4){i.pop()}do{q=parseInt(i[m],10);j=parseInt(h[m],10);m++}while(m<i.length&&q===j);if(q<=j&&!isNaN(q)){r=true}}}}catch(p){r=false}return r}c.silverlight={trigger:function(j,f){var h=a[j],g,e;if(h){e=c.toArray(arguments).slice(1);e[0]="Silverlight:"+f;setTimeout(function(){h.trigger.apply(h,e)},0)}}};c.runtimes.Silverlight=c.addRuntime("silverlight",{getFeatures:function(){return{jpgresize:true,pngresize:true,chunks:true,progress:true,multipart:true}},init:function(l,m){var k,h="",j=l.settings.filters,g,f=document.body;if(!d("2.0.31005.0")||(window.opera&&window.opera.buildNumber)){m({success:false});return}a[l.id]=l;k=document.createElement("div");k.id=l.id+"_silverlight_container";c.extend(k.style,{position:"absolute",top:"0px",background:l.settings.shim_bgcolor||"transparent",zIndex:99999,width:"100px",height:"100px",overflow:"hidden",opacity:l.settings.shim_bgcolor?"":0.01});k.className="plupload silverlight";if(l.settings.container){f=document.getElementById(l.settings.container);f.style.position="relative"}f.appendChild(k);for(g=0;g<j.length;g++){h+=(h!=""?"|":"")+j[g].title+" | *."+j[g].extensions.replace(/,/g,";*.")}k.innerHTML='<object id="'+l.id+'_silverlight" data="data:application/x-silverlight," type="application/x-silverlight-2" style="outline:none;" width="1024" height="1024"><param name="source" value="'+l.settings.silverlight_xap_url+'"/><param name="background" value="Transparent"/><param name="windowless" value="true"/><param name="initParams" value="id='+l.id+",filter="+h+'"/></object>';function e(){return document.getElementById(l.id+"_silverlight").content.Upload}l.bind("Silverlight:Init",function(){var i,n={};l.bind("Silverlight:StartSelectFiles",function(o){i=[]});l.bind("Silverlight:SelectFile",function(o,r,p,q){var s;s=c.guid();n[s]=r;n[r]=s;i.push(new c.File(s,p,q))});l.bind("Silverlight:SelectSuccessful",function(){if(i.length){l.trigger("FilesAdded",i)}});l.bind("Silverlight:UploadChunkError",function(o,r,p,s,q){l.trigger("Error",{code:c.IO_ERROR,message:"IO Error.",details:q,file:o.getFile(n[r])})});l.bind("Silverlight:UploadFileProgress",function(o,s,p,r){var q=o.getFile(n[s]);if(q.status!=c.FAILED){q.size=r;q.loaded=p;o.trigger("UploadProgress",q)}});l.bind("Refresh",function(o){var p,q,r;p=document.getElementById(o.settings.browse_button);q=c.getPos(p,document.getElementById(o.settings.container));r=c.getSize(p);c.extend(document.getElementById(o.id+"_silverlight_container").style,{top:q.y+"px",left:q.x+"px",width:r.w+"px",height:r.h+"px"})});l.bind("Silverlight:UploadChunkSuccessful",function(o,r,p,u,t){var s,q=o.getFile(n[r]);s={chunk:p,chunks:u,response:t};o.trigger("ChunkUploaded",q,s);if(q.status!=c.FAILED){e().UploadNextChunk()}if(p==u-1){q.status=c.DONE;o.trigger("FileUploaded",q,{response:t})}});l.bind("Silverlight:UploadSuccessful",function(o,r,p){var q=o.getFile(n[r]);q.status=c.DONE;o.trigger("FileUploaded",q,{response:p})});l.bind("FilesRemoved",function(o,q){var p;for(p=0;p<q.length;p++){e().RemoveFile(n[q[p].id])}});l.bind("UploadFile",function(o,q){var r=o.settings,p=r.resize||{};e().UploadFile(n[q.id],c.buildUrl(o.settings.url,{name:q.target_name||q.name}),b({chunk_size:r.chunk_size,image_width:p.width,image_height:p.height,image_quality:p.quality||90,multipart:!!r.multipart,multipart_params:r.multipart_params||{},headers:r.headers}))});m({success:true})})}})})(plupload);
Index: typo3/contrib/plupload/js/plupload.full.tmp.js
===================================================================
--- typo3/contrib/plupload/js/plupload.full.tmp.js	(revision )
+++ typo3/contrib/plupload/js/plupload.full.tmp.js	(revision )
@@ -0,0 +1,3447 @@
+/**
+ * plupload.js
+ *
+ * Copyright 2009, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+// JSLint defined globals
+/*global window:false, escape:false */
+
+(function() {
+	var count = 0, runtimes = [], i18n = {}, mimes = {},
+		xmlEncodeChars = {'<' : 'lt', '>' : 'gt', '&' : 'amp', '"' : 'quot', '\'' : '#39'},
+		xmlEncodeRegExp = /[<>&\"\']/g, undef, delay = window.setTimeout;
+
+	// IE W3C like event funcs
+	function preventDefault() {
+		this.returnValue = false;
+	}
+
+	function stopPropagation() {
+		this.cancelBubble = true;
+	}
+
+	// Parses the default mime types string into a mimes lookup map
+	(function(mime_data) {
+		var items = mime_data.split(/,/), i, y, ext;
+
+		for (i = 0; i < items.length; i += 2) {
+			ext = items[i + 1].split(/ /);
+
+			for (y = 0; y < ext.length; y++) {
+				mimes[ext[y]] = items[i];
+			}
+		}
+	})(
+		"application/msword,doc dot," +
+		"application/pdf,pdf," +
+		"application/pgp-signature,pgp," +
+		"application/postscript,ps ai eps," +
+		"application/rtf,rtf," +
+		"application/vnd.ms-excel,xls xlb," +
+		"application/vnd.ms-powerpoint,ppt pps pot," +
+		"application/zip,zip," +
+		"application/x-shockwave-flash,swf swfl," +
+		"application/vnd.openxmlformats,docx pptx xlsx," +
+		"audio/mpeg,mpga mpega mp2 mp3," +
+		"audio/x-wav,wav," +
+		"image/bmp,bmp," +
+		"image/gif,gif," +
+		"image/jpeg,jpeg jpg jpe," +
+		"image/png,png," +
+		"image/svg+xml,svg svgz," +
+		"image/tiff,tiff tif," +
+		"text/html,htm html xhtml," +
+		"text/rtf,rtf," +
+		"video/mpeg,mpeg mpg mpe," +
+		"video/quicktime,qt mov," +
+		"video/x-flv,flv," +
+		"video/vnd.rn-realvideo,rv," +
+		"text/plain,asc txt text diff log," +
+		"application/octet-stream,exe"
+	);
+
+	/**
+	 * Plupload class with some global constants and functions.
+	 *
+	 * @example
+	 * // Encode entities
+	 * console.log(plupload.xmlEncode("My string &lt;&gt;"));
+	 *
+	 * // Generate unique id
+	 * console.log(plupload.guid());
+	 *
+	 * @static
+	 * @class plupload
+	 */
+	var plupload = {
+		/**
+		 * Inital state of the queue and also the state ones it's finished all it's uploads.
+		 *
+		 * @property STOPPED
+		 * @final
+		 */
+		STOPPED : 1,
+
+		/**
+		 * Upload process is running
+		 *
+		 * @property STARTED
+		 * @final
+		 */
+		STARTED : 2,
+
+		/**
+		 * File is queued for upload
+		 *
+		 * @property QUEUED
+		 * @final
+		 */
+		QUEUED : 1,
+
+		/**
+		 * File is being uploaded
+		 *
+		 * @property UPLOADING
+		 * @final
+		 */
+		UPLOADING : 2,
+
+		/**
+		 * File has failed to be uploaded
+		 *
+		 * @property FAILED
+		 * @final
+		 */
+		FAILED : 4,
+
+		/**
+		 * File has been uploaded successfully
+		 *
+		 * @property DONE
+		 * @final
+		 */
+		DONE : 5,
+
+		// Error constants used by the Error event
+
+		/**
+		 * Generic error for example if an exception is thrown inside Silverlight.
+		 *
+		 * @property GENERIC_ERROR
+		 * @final
+		 */
+		GENERIC_ERROR : -100,
+
+		/**
+		 * HTTP transport error. For example if the server produces a HTTP status other than 200.
+		 *
+		 * @property HTTP_ERROR
+		 * @final
+		 */
+		HTTP_ERROR : -200,
+
+		/**
+		 * Generic I/O error. For exampe if it wasn't possible to open the file stream on local machine.
+		 *
+		 * @property IO_ERROR
+		 * @final
+		 */
+		IO_ERROR : -300,
+
+		/**
+		 * Generic I/O error. For exampe if it wasn't possible to open the file stream on local machine.
+		 *
+		 * @property SECURITY_ERROR
+		 * @final
+		 */
+		SECURITY_ERROR : -400,
+
+		/**
+		 * Initialization error. Will be triggered if no runtime was initialized.
+		 *
+		 * @property INIT_ERROR
+		 * @final
+		 */
+		INIT_ERROR : -500,
+
+		/**
+		 * File size error. If the user selects a file that is to large it will be blocked and an error of this type will be triggered.
+		 *
+		 * @property FILE_SIZE_ERROR
+		 * @final
+		 */
+		FILE_SIZE_ERROR : -600,
+
+		/**
+		 * File extension error. If the user selects a file that isn't valid according to the filters setting.
+		 *
+		 * @property FILE_EXTENSION_ERROR
+		 * @final
+		 */
+		FILE_EXTENSION_ERROR : -700,
+
+		/**
+		 * Mime type lookup table.
+		 *
+		 * @property mimeTypes
+		 * @type Object
+		 * @final
+		 */
+		mimeTypes : mimes,
+
+		/**
+		 * Extends the specified object with another object.
+		 *
+		 * @method extend
+		 * @param {Object} target Object to extend.
+		 * @param {Object..} obj Multiple objects to extend with.
+		 * @return {Object} Same as target, the extended object.
+		 */
+		extend : function(target) {
+			plupload.each(arguments, function(arg, i) {
+				if (i > 0) {
+					plupload.each(arg, function(value, key) {
+						target[key] = value;
+					});
+				}
+			});
+
+			return target;
+		},
+
+		/**
+		 * Cleans the specified name from national characters (diacritics). The result will be a name with only a-z, 0-9 and _.
+		 *
+		 * @method cleanName
+		 * @param {String} s String to clean up.
+		 * @return {String} Cleaned string.
+		 */
+		cleanName : function(name) {
+			var i, lookup;
+
+			// Replace diacritics
+			lookup = [
+				/[\300-\306]/g, 'A', /[\340-\346]/g, 'a',
+				/\307/g, 'C', /\347/g, 'c',
+				/[\310-\313]/g, 'E', /[\350-\353]/g, 'e',
+				/[\314-\317]/g, 'I', /[\354-\357]/g, 'i',
+				/\321/g, 'N', /\361/g, 'n',
+				/[\322-\330]/g, 'O', /[\362-\370]/g, 'o',
+				/[\331-\334]/g, 'U', /[\371-\374]/g, 'u'
+			];
+
+			for (i = 0; i < lookup.length; i += 2) {
+				name = name.replace(lookup[i], lookup[i + 1]);
+			}
+
+			// Replace whitespace
+			name = name.replace(/\s+/g, '_');
+
+			// Remove anything else
+			name = name.replace(/[^a-z0-9_\-\.]+/gi, '');
+
+			return name;
+		},
+
+		/**
+		 * Adds a specific upload runtime like for example flash or gears.
+		 *
+		 * @method addRuntime
+		 * @param {String} name Runtime name for example flash.
+		 * @param {Object} obj Object containing init/destroy method.
+		 */
+		addRuntime : function(name, runtime) {
+			runtime.name = name;
+			runtimes[name] = runtime;
+			runtimes.push(runtime);
+
+			return runtime;
+		},
+
+		/**
+		 * Generates an unique ID. This is 99.99% unique since it takes the current time and 5 random numbers.
+		 * The only way a user would be able to get the same ID is if the two persons at the same exact milisecond manages
+		 * to get 5 the same random numbers between 0-65535 it also uses a counter so each call will be guaranteed to be page unique.
+		 * It's more probable for the earth to be hit with an ansteriod. You can also if you want to be 100% sure set the plupload.guidPrefix property
+		 * to an user unique key.
+		 *
+		 * @method guid
+		 * @return {String} Virtually unique id.
+		 */
+		guid : function() {
+			var guid = new Date().getTime().toString(32), i;
+
+			for (i = 0; i < 5; i++) {
+				guid += Math.floor(Math.random() * 65535).toString(32);
+			}
+
+			return (plupload.guidPrefix || 'p') + guid + (count++).toString(32);
+		},
+
+		/**
+		 * Builds a full url out of a base URL and an object with items to append as query string items.
+		 *
+		 * @param {String} url Base URL to append query string items to.
+		 * @param {Object} items Name/value object to serialize as a querystring.
+		 * @return {String} String with url + serialized query string items.
+		 */
+		buildUrl : function(url, items) {
+			var query = '';
+
+			plupload.each(items, function(value, name) {
+				query += (query ? '&' : '') + encodeURIComponent(name) + '=' + encodeURIComponent(value);
+			});
+
+			if (query) {
+				url += (url.indexOf('?') > 0 ? '&' : '?') + query;
+			}
+
+			return url;
+		},
+
+		/**
+		 * Executes the callback function for each item in array/object. If you return false in the
+		 * callback it will break the loop.
+		 *
+		 * @param {Object} obj Object to iterate.
+		 * @param {function} callback Callback function to execute for each item.
+		 */
+		each : function(obj, callback) {
+			var length, key, i;
+
+			if (obj) {
+				length = obj.length;
+
+				if (length === undef) {
+					// Loop object items
+					for (key in obj) {
+						if (obj.hasOwnProperty(key)) {
+							if (callback(obj[key], key) === false) {
+								return;
+							}
+						}
+					}
+				} else {
+					// Loop array items
+					for (i = 0; i < length; i++) {
+						if (callback(obj[i], i) === false) {
+							return;
+						}
+					}
+				}
+			}
+		},
+
+		/**
+		 * Formats the specified number as a size string for example 1024 becomes 1 KB.
+		 *
+		 * @method formatSize
+		 * @param {Number} size Size to format as string.
+		 * @return {String} Formatted size string.
+		 */
+		formatSize : function(size) {
+			if (size === undef) {
+				return plupload.translate('N/A');
+			}
+
+			// MB
+			if (size > 1048576) {
+				return Math.round(size / 1048576, 1) + " MB";
+			}
+
+			// KB
+			if (size > 1024) {
+				return Math.round(size / 1024, 1) + " KB";
+			}
+
+			return size + " b";
+		},
+
+		/**
+		 * Returns the absolute x, y position of an Element. The position will be returned in a object with x, y fields.
+		 *
+		 * @method getPos
+		 * @param {Element} node HTML element or element id to get x, y position from.
+		 * @param {Element} root Optional root element to stop calculations at.
+		 * @return {object} Absolute position of the specified element object with x, y fields.
+		 */
+		 getPos : function(node, root) {
+			var x = 0, y = 0, parent, doc = document, nodeRect, rootRect;
+
+			node = node;
+			root = root || doc.body;
+
+			// Returns the x, y cordinate for an element on IE 6 and IE 7
+			function getIEPos(node) {
+				var bodyElm, rect, x = 0, y = 0;
+
+				if (node) {
+					rect = node.getBoundingClientRect();
+					bodyElm = doc.compatMode === "CSS1Compat" ? doc.documentElement : doc.body;
+					x = rect.left + bodyElm.scrollLeft;
+					y = rect.top + bodyElm.scrollTop;
+				}
+
+				return {
+					x : x,
+					y : y
+				};
+			}
+
+			// Use getBoundingClientRect on IE 6 and IE 7 but not on IE 8 in standards mode
+			if (node.getBoundingClientRect && (navigator.userAgent.indexOf('MSIE') > 0 && doc.documentMode !== 8)) {
+				nodeRect = getIEPos(node);
+				rootRect = getIEPos(root);
+
+				return {
+					x : nodeRect.x - rootRect.x,
+					y : nodeRect.y - rootRect.y
+				};
+			}
+
+			parent = node;
+			while (parent && parent != root && parent.nodeType) {
+				x += parent.offsetLeft || 0;
+				y += parent.offsetTop || 0;
+				parent = parent.offsetParent;
+			}
+
+			parent = node.parentNode;
+			while (parent && parent != root && parent.nodeType) {
+				x -= parent.scrollLeft || 0;
+				y -= parent.scrollTop || 0;
+				parent = parent.parentNode;
+			}
+
+			return {
+				x : x,
+				y : y
+			};
+		},
+
+		/**
+		 * Returns the size of the specified node in pixels.
+		 *
+		 * @param {Node} node Node to get the size of.
+		 * @return {Object} Object with a w and h property.
+		 */
+		getSize : function(node) {
+			return {
+				w : node.clientWidth || node.offsetWidth,
+				h : node.clientHeight || node.offsetHeight
+			};
+		},
+
+		/**
+		 * Parses the specified size string into a byte value. For example 10kb becomes 10240.
+		 *
+		 * @method parseSize
+		 * @param {String/Number} size String to parse or number to just pass through.
+		 * @return {Number} Size in bytes.
+		 */
+		parseSize : function(size) {
+			var mul;
+
+			if (typeof(size) == 'string') {
+				size = /^([0-9]+)([mgk]+)$/.exec(size.toLowerCase().replace(/[^0-9mkg]/g, ''));
+				mul = size[2];
+				size = +size[1];
+
+				if (mul == 'g') {
+					size *= 1073741824;
+				}
+
+				if (mul == 'm') {
+					size *= 1048576;
+				}
+
+				if (mul == 'k') {
+					size *= 1024;
+				}
+			}
+
+			return size;
+		},
+
+		/**
+		 * Encodes the specified string.
+		 *
+		 * @method xmlEncode
+		 * @param {String} s String to encode.
+		 * @return {String} Encoded string.
+		 */
+		xmlEncode : function(str) {
+			return str ? ('' + str).replace(xmlEncodeRegExp, function(chr) {
+				return xmlEncodeChars[chr] ? '&' + xmlEncodeChars[chr] + ';' : chr;
+			}) : str;
+		},
+
+		/**
+		 * Forces anything into an array.
+		 *
+		 * @method toArray
+		 * @param {Object} obj Object with length field.
+		 * @return {Array} Array object containing all items.
+		 */
+		toArray : function(obj) {
+			var i, arr = [];
+
+			for (i = 0; i < obj.length; i++) {
+				arr[i] = obj[i];
+			}
+
+			return arr;
+		},
+
+		/**
+		 * Extends the language pack object with new items.
+		 *
+		 * @param {Object} pack Language pack items to add.
+		 * @return {Object} Extended language pack object.
+		 */
+		addI18n : function(pack) {
+			return plupload.extend(i18n, pack);
+		},
+
+		/**
+		 * Translates the specified string by checking for the english string in the language pack lookup.
+		 *
+		 * @param {String} str String to look for.
+		 * @reutrn {String} Translated string or the input string if it wasn't found.
+		 */
+		translate : function(str) {
+			return i18n[str] || str;
+		},
+
+		/**
+		 * Adds an event handler to the specified object.
+		 *
+		 * @param {Object} obj DOM element like object to add handler to.
+		 * @param {String} name Name to add event listener to.
+		 * @param {function} callback Function to call when event occurs.
+		 */
+		addEvent : function(obj, name, callback) {
+			if (obj.attachEvent) {
+				obj.attachEvent('on' + name, function() {
+					var evt = window.event;
+
+					if (!evt.target) {
+						evt.target = evt.srcElement;
+					}
+
+					evt.preventDefault = preventDefault;
+					evt.stopPropagation = stopPropagation;
+
+					callback(evt);
+				});
+			} else if (obj.addEventListener) {
+				obj.addEventListener(name, callback, false);
+			}
+		}
+	};
+
+	/**
+	 * Uploader class, an instance of this class will be created for each upload field.
+	 *
+	 * @example
+	 * var uploader = new plupload.Uploader({
+	 *     runtimes : 'gears,html5,flash',
+	 *     browse_button : 'button_id'
+	 * });
+	 *
+	 * uploader.bind('Init', function(up) {
+	 *     alert('Supports drag/drop: ' + (!!up.features.dragdrop));
+	 * });
+	 *
+	 * uploader.bind('FilesAdded', function(up, files) {
+	 *     alert('Selected files: ' + files.length);
+	 * });
+	 *
+	 * uploader.bind('QueueChanged', function(up) {
+	 *     alert('Queued files: ' + uploader.files.length);
+	 * });
+	 *
+	 * uploader.init();
+	 *
+	 * @class plupload.Uploader
+	 */
+
+	/**
+	 * Constructs a new uploader instance.
+	 *
+	 * @constructor
+	 * @method Uploader
+	 * @param {Object} settings Initialization settings, to be used by the uploader instance and runtimes.
+	 */
+	plupload.Uploader = function(settings) {
+		var events = {}, total, files = [], fileIndex, startTime;
+
+		// Inital total state
+		total = new plupload.QueueProgress();
+
+		// Default settings
+		settings = plupload.extend({
+			chunk_size : 0,
+			multipart : true,
+			multi_selection : true,
+			file_data_name : 'file',
+			filters : []
+		}, settings);
+
+		// Private methods
+		function uploadNext() {
+			var file;
+
+			if (this.state == plupload.STARTED && fileIndex < files.length) {
+				file = files[fileIndex++];
+
+				if (file.status == plupload.QUEUED) {
+					this.trigger('BeforeUpload', file);
+					this.trigger("UploadFile", file);
+				} else {
+					uploadNext.call(this);
+				}
+			} else {
+				this.stop();
+			}
+		}
+
+		function calc() {
+			var i, file;
+
+			// Reset stats
+			total.reset();
+
+			// Check status, size, loaded etc on all files
+			for (i = 0; i < files.length; i++) {
+				file = files[i];
+
+				if (file.size !== undef) {
+					total.size += file.size;
+					total.loaded += file.loaded;
+				} else {
+					total.size = undef;
+				}
+
+				if (file.status == plupload.DONE) {
+					total.uploaded++;
+				} else if (file.status == plupload.FAILED) {
+					total.failed++;
+				} else {
+					total.queued++;
+				}
+			}
+
+			// If we couldn't calculate a total file size then use the number of files to calc percent
+			if (total.size === undef) {
+				total.percent = files.length > 0 ? Math.ceil(total.uploaded / files.length * 100) : 0;
+			} else {
+				total.bytesPerSec = Math.ceil(total.loaded / ((+new Date() - startTime || 1) / 1000.0));
+				total.percent = total.size > 0 ? Math.ceil(total.loaded / total.size * 100) : 0;
+			}
+		}
+
+		// Add public methods
+		plupload.extend(this, {
+			/**
+			 * Current state of the total uploading progress. This one can either be plupload.STARTED or plupload.STOPPED.
+			 * These states are controlled by the stop/start methods. The default value is STOPPED.
+			 *
+			 * @property state
+			 * @type Number
+			 */
+			state : plupload.STOPPED,
+
+			/**
+			 * Map of features that are available for the uploader runtime. Features will be filled
+			 * before the init event is called, these features can then be used to alter the UI for the end user.
+			 * Some of the current features that might be in this map is: dragdrop, chunks, jpgresize, pngresize.
+			 *
+			 * @property features
+			 * @type Object
+			 */
+			features : {},
+
+			/**
+			 * Current upload queue, an array of File instances.
+			 *
+			 * @property files
+			 * @type Array
+			 * @see plupload.File
+			 */
+			files : files,
+
+			/**
+			 * Object with name/value settings.
+			 *
+			 * @property settings
+			 * @type Object
+			 */
+			settings : settings,
+
+			/**
+			 * Total progess information. How many files has been uploaded, total percent etc.
+			 *
+			 * @property total
+			 * @type plupload.QueueProgress
+			 */
+			total : total,
+
+			/**
+			 * Unique id for the Uploader instance.
+			 *
+			 * @property id
+			 * @type String
+			 */
+			id : plupload.guid(),
+
+			/**
+			 * Initializes the Uploader instance and adds internal event listeners.
+			 *
+			 * @method init
+			 */
+			init : function() {
+				var self = this, i, runtimeList, a, runTimeIndex = 0, items;
+
+				if (typeof(settings.preinit) == "function") {
+					settings.preinit(self);
+				} else {
+					plupload.each(settings.preinit, function(func, name) {
+						self.bind(name, func);
+					});
+				}
+
+				settings.page_url = settings.page_url || document.location.pathname.replace(/\/[^\/]+$/g, '/');
+
+				// If url is relative force it absolute to the current page
+				if (!/^(\w+:\/\/|\/)/.test(settings.url)) {
+					settings.url = settings.page_url + settings.url;
+				}
+
+				// Convert settings
+				settings.chunk_size = plupload.parseSize(settings.chunk_size);
+				settings.max_file_size = plupload.parseSize(settings.max_file_size);
+
+				// Add files to queue
+				self.bind('FilesAdded', function(up, selected_files) {
+					var i, file, count = 0, extensionsRegExp, filters = settings.filters;
+
+					// Convert extensions to regexp
+					if (filters && filters.length) {
+						extensionsRegExp = [];
+
+						plupload.each(filters, function(filter) {
+							plupload.each(filter.extensions.split(/,/), function(ext) {
+								extensionsRegExp.push('\\.' + ext.replace(new RegExp('[' + ('/^$.*+?|()[]{}\\'.replace(/./g, '\\$&')) + ']', 'g'), '\\$&'));
+							});
+						});
+
+						extensionsRegExp = new RegExp(extensionsRegExp.join('|') + '$', 'i');
+					}
+
+					for (i = 0; i < selected_files.length; i++) {
+						file = selected_files[i];
+						file.loaded = 0;
+						file.percent = 0;
+						file.status = plupload.QUEUED;
+
+						// Invalid file extension
+						if (extensionsRegExp && !extensionsRegExp.test(file.name)) {
+							up.trigger('Error', {
+								code : plupload.FILE_EXTENSION_ERROR,
+								message : 'File extension error.',
+								file : file
+							});
+
+							continue;
+						}
+
+						// Invalid file size
+						if (file.size !== undef && file.size > settings.max_file_size) {
+							up.trigger('Error', {
+								code : plupload.FILE_SIZE_ERROR,
+								message : 'File size error.',
+								file : file
+							});
+
+							continue;
+						}
+
+						// Add valid file to list
+						files.push(file);
+						count++;
+					}
+
+					// Only trigger QueueChanged event if any files where added
+					if (count) {
+						delay(function() {
+							self.trigger("QueueChanged");
+							self.refresh();
+						});
+					} else {
+						return false; // Stop the FilesAdded event from immediate propagation
+					}
+				});
+
+				// Generate unique target filenames
+				if (settings.unique_names) {
+					self.bind("UploadFile", function(up, file) {
+						var matches = file.name.match(/\.([^.]+)$/), ext = "tmp";
+
+						if (matches) {
+							ext = matches[1];
+						}
+
+						file.target_name = file.id + '.' + ext;
+					});
+				}
+
+				self.bind('UploadProgress', function(up, file) {
+					if (file.status == plupload.QUEUED) {
+						file.status = plupload.UPLOADING;
+					}
+
+					file.percent = file.size > 0 ? Math.ceil(file.loaded / file.size * 100) : 100;
+					calc();
+				});
+
+				self.bind('StateChanged', function(up) {
+					if (up.state == plupload.STARTED) {
+						// Get start time to calculate bps
+						startTime = (+new Date());
+					}
+				});
+
+				self.bind('QueueChanged', calc);
+
+				self.bind("Error", function(up, err) {
+					// Set failed status if an error occured on a file
+					if (err.file) {
+						err.file.status = plupload.FAILED;
+						calc();
+
+						// Upload next file but detach it from the error event
+						// since other custom listeners might want to stop the queue
+						delay(function() {
+							uploadNext.call(self);
+						});
+					}
+				});
+
+				self.bind("FileUploaded", function(up, file) {
+					file.status = plupload.DONE;
+					file.loaded = file.size;
+					up.trigger('UploadProgress', file);
+
+					// Upload next file but detach it from the error event
+					// since other custom listeners might want to stop the queue
+					delay(function() {
+						uploadNext.call(self);
+					});
+				});
+
+				// Setup runtimeList
+				if (settings.runtimes) {
+					runtimeList = [];
+					items = settings.runtimes.split(/\s?,\s?/);
+
+					for (i = 0; i < items.length; i++) {
+						if (runtimes[items[i]]) {
+							runtimeList.push(runtimes[items[i]]);
+						}
+					}
+				} else {
+					runtimeList = runtimes;
+				}
+
+				// Call init on each runtime in sequence
+				function callNextInit() {
+					var runtime = runtimeList[runTimeIndex++], features, requiredFeatures, i;
+
+					if (runtime) {
+						features = runtime.getFeatures();
+
+						// Check if runtime supports required features
+						requiredFeatures = self.settings.required_features;
+						if (requiredFeatures) {
+							requiredFeatures = requiredFeatures.split(',');
+
+							for (i = 0; i < requiredFeatures.length; i++) {
+								// Specified feature doesn't exist
+								if (!features[requiredFeatures[i]]) {
+									callNextInit();
+									return;
+								}
+							}
+						}
+
+						// Try initializing the runtime
+						runtime.init(self, function(res) {
+							if (res && res.success) {
+								// Successful initialization
+								self.features = features;
+								self.trigger('Init', {runtime : runtime.name});
+								self.trigger('PostInit');
+								self.refresh();
+							} else {
+								callNextInit();
+							}
+						});
+					} else {
+						// Trigger an init error if we run out of runtimes
+						self.trigger('Error', {
+							code : plupload.INIT_ERROR,
+							message : 'Init error.'
+						});
+					}
+				}
+
+				callNextInit();
+
+				if (typeof(settings.init) == "function") {
+					settings.init(self);
+				} else {
+					plupload.each(settings.init, function(func, name) {
+						self.bind(name, func);
+					});
+				}
+			},
+
+			/**
+			 * Refreshes the upload instance by dispatching out a refresh event to all runtimes.
+			 * This would for example reposition flash/silverlight shims on the page.
+			 *
+			 * @method refresh
+			 */
+			refresh : function() {
+				this.trigger("Refresh");
+			},
+
+			/**
+			 * Starts uploading the queued files.
+			 *
+			 * @method start
+			 */
+			start : function() {
+				if (this.state != plupload.STARTED) {
+					fileIndex = 0;
+
+					this.state = plupload.STARTED;
+					this.trigger("StateChanged");
+
+					uploadNext.call(this);
+				}
+			},
+
+			/**
+			 * Stops the upload of the queued files.
+			 *
+			 * @method stop
+			 */
+			stop : function() {
+				if (this.state != plupload.STOPPED) {
+					this.state = plupload.STOPPED;
+					this.trigger("StateChanged");
+				}
+			},
+
+			/**
+			 * Returns the specified file object by id.
+			 *
+			 * @method getFile
+			 * @param {String} id File id to look for.
+			 * @return {plupload.File} File object or undefined if it wasn't found;
+			 */
+			getFile : function(id) {
+				var i;
+
+				for (i = files.length - 1; i >= 0; i--) {
+					if (files[i].id === id) {
+						return files[i];
+					}
+				}
+			},
+
+			/**
+			 * Removes a specific file.
+			 *
+			 * @method removeFile
+			 * @param {plupload.File} file File to remove from queue.
+			 */
+			removeFile : function(file) {
+				var i;
+
+				for (i = files.length - 1; i >= 0; i--) {
+					if (files[i].id === file.id) {
+						return this.splice(i, 1)[0];
+					}
+				}
+			},
+
+			/**
+			 * Removes part of the queue and returns the files removed. This will also trigger the FilesRemoved and QueueChanged events.
+			 *
+			 * @method splice
+			 * @param {Number} start (Optional) Start index to remove from.
+			 * @param {Number} length (Optional) Lengh of items to remove.
+			 * @return {Array} Array of files that was removed.
+			 */
+			splice : function(start, length) {
+				var removed;
+
+				// Splice and trigger events
+				removed = files.splice(start === undef ? 0 : start, length === undef ? files.length : length);
+
+				this.trigger("FilesRemoved", removed);
+				this.trigger("QueueChanged");
+
+				return removed;
+			},
+
+			/**
+			 * Dispatches the specified event name and it's arguments to all listeners.
+			 *
+			 *
+			 * @method trigger
+			 * @param {String} name Event name to fire.
+			 * @param {Object..} Multiple arguments to pass along to the listener functions.
+			 */
+			trigger : function(name) {
+				var list = events[name.toLowerCase()], i, args;
+
+				// console.log(name, arguments);
+
+				if (list) {
+					// Replace name with sender in args
+					args = Array.prototype.slice.call(arguments);
+					args[0] = this;
+
+					// Dispatch event to all listeners
+					for (i = 0; i < list.length; i++) {
+						// Fire event, break chain if false is returned
+						if (list[i].func.apply(list[i].scope, args) === false) {
+							return false;
+						}
+					}
+				}
+
+				return true;
+			},
+
+			/**
+			 * Adds an event listener by name.
+			 *
+			 * @method bind
+			 * @param {String} name Event name to listen for.
+			 * @param {function} func Function to call ones the event gets fired.
+			 * @param {Object} scope Optional scope to execute the specified function in.
+			 */
+			bind : function(name, func, scope) {
+				var list;
+
+				name = name.toLowerCase();
+				list = events[name] || [];
+				list.push({func : func, scope : scope || this});
+				events[name] = list;
+			},
+
+			/**
+			 * Removes the specified event listener.
+			 *
+			 * @method unbind
+			 * @param {String} name Name of event to remove.
+			 * @param {function} func Function to remove from listener.
+			 */
+			unbind : function(name, func) {
+				var list = events[name.toLowerCase()], i;
+
+				if (list) {
+					for (i = list.length - 1; i >= 0; i--) {
+						if (list[i].func === func) {
+							list.splice(i, 1);
+						}
+					}
+				}
+			}
+
+			/**
+			 * Fires when the current RunTime has been initialized.
+			 *
+			 * @event Init
+			 * @param {plupload.Uploader} uploader Uploader instance sending the event.
+			 */
+
+			/**
+			 * Fires after the init event incase you need to perform actions there.
+			 *
+			 * @event PostInit
+			 * @param {plupload.Uploader} uploader Uploader instance sending the event.
+			 */
+
+			/**
+			 * Fires when the silverlight/flash or other shim needs to move.
+			 *
+			 * @event Refresh
+			 * @param {plupload.Uploader} uploader Uploader instance sending the event.
+			 */
+
+			/**
+			 * Fires when the overall state is being changed for the upload queue.
+			 *
+			 * @event StateChanged
+			 * @param {plupload.Uploader} uploader Uploader instance sending the event.
+			 */
+
+			/**
+			 * Fires when a file is to be uploaded by the runtime.
+			 *
+			 * @event UploadFile
+			 * @param {plupload.Uploader} uploader Uploader instance sending the event.
+			 * @param {plupload.File} file File to be uploaded.
+			 */
+
+			/**
+			 * Fires when just before a file is uploaded. This event enables you to override settings
+			 * on the uploader instance before the file is uploaded.
+			 *
+			 * @event BeforeUpload
+			 * @param {plupload.Uploader} uploader Uploader instance sending the event.
+			 * @param {plupload.File} file File to be uploaded.
+			 */
+
+			/**
+			 * Fires when the file queue is changed. In other words when files are added/removed to the files array of the uploader instance.
+			 *
+			 * @event QueueChanged
+			 * @param {plupload.Uploader} uploader Uploader instance sending the event.
+			 */
+
+			/**
+			 * Fires while a file is being uploaded. Use this event to update the current file upload progress.
+			 *
+			 * @event UploadProgress
+			 * @param {plupload.Uploader} uploader Uploader instance sending the event.
+			 * @param {plupload.File} file File that is currently being uploaded.
+			 */
+
+			/**
+			 * Fires while a file was removed from queue.
+			 *
+			 * @event FilesRemoved
+			 * @param {plupload.Uploader} uploader Uploader instance sending the event.
+			 * @param {Array} files Array of files that got removed.
+			 */
+
+			/**
+			 * Fires while when the user selects files to upload.
+			 *
+			 * @event FilesAdded
+			 * @param {plupload.Uploader} uploader Uploader instance sending the event.
+			 * @param {Array} files Array of file objects that was added to queue/selected by the user.
+			 */
+
+			/**
+			 * Fires when a file is successfully uploaded.
+			 *
+			 * @event FileUploaded
+			 * @param {plupload.Uploader} uploader Uploader instance sending the event.
+			 * @param {plupload.File} file File that was uploaded.
+			 * @param {Object} response Object with response properties.
+			 */
+
+			/**
+			 * Fires when file chunk is uploaded.
+			 *
+			 * @event ChunkUploaded
+			 * @param {plupload.Uploader} uploader Uploader instance sending the event.
+			 * @param {plupload.File} file File that the chunk was uploaded for.
+			 * @param {Object} response Object with response properties.
+			 */
+
+			/**
+			 * Fires when a error occurs.
+			 *
+			 * @event Error
+			 * @param {plupload.Uploader} uploader Uploader instance sending the event.
+			 * @param {Object} error Contains code, message and sometimes file and other details.
+			 */
+		});
+	};
+
+	/**
+	 * File instance.
+	 *
+	 * @class plupload.File
+	 * @param {String} name Name of the file.
+	 * @param {Number} size File size.
+	 */
+
+	/**
+	 * Constructs a new file instance.
+	 *
+	 * @constructor
+	 * @method File
+	 * @param {String} id Unique file id.
+	 * @param {String} name File name.
+	 * @param {Number} size File size in bytes.
+	 */
+	plupload.File = function(id, name, size) {
+		var self = this; // Setup alias for self to reduce code size when it's compressed
+
+		/**
+		 * File id this is a globally unique id for the specific file.
+		 *
+		 * @property id
+		 * @type String
+		 */
+		self.id = id;
+
+		/**
+		 * File name for example "myfile.gif".
+		 *
+		 * @property name
+		 * @type String
+		 */
+		self.name = name;
+
+		/**
+		 * File size in bytes.
+		 *
+		 * @property size
+		 * @type Number
+		 */
+		self.size = size;
+
+		/**
+		 * Number of bytes uploaded of the files total size.
+		 *
+		 * @property loaded
+		 * @type Number
+		 */
+		self.loaded = 0;
+
+		/**
+		 * Number of percentage uploaded of the file.
+		 *
+		 * @property percent
+		 * @type Number
+		 */
+		self.percent = 0;
+
+		/**
+		 * Status constant matching the plupload states QUEUED, UPLOADING, FAILED, DONE.
+		 *
+		 * @property status
+		 * @type Number
+		 * @see plupload
+		 */
+		self.status = 0;
+	};
+
+	/**
+	 * Runtime class gets implemented by each upload runtime.
+	 *
+	 * @class plupload.Runtime
+	 * @static
+	 */
+	plupload.Runtime = function() {
+		/**
+		 * Returns a list of supported features for the runtime.
+		 *
+		 * @return {Object} Name/value object with supported features.
+		 */
+		this.getFeatures = function() {
+		};
+
+		/**
+		 * Initializes the upload runtime. This method should add necessary items to the DOM and register events needed for operation.
+		 *
+		 * @method init
+		 * @param {plupload.Uploader} uploader Uploader instance that needs to be initialized.
+		 * @param {function} callback Callback function to execute when the runtime initializes or fails to initialize. If it succeeds an object with a parameter name success will be set to true.
+		 */
+		this.init = function(uploader, callback) {
+		};
+	};
+
+	/**
+	 * Runtime class gets implemented by each upload runtime.
+	 *
+	 * @class plupload.QueueProgress
+	 */
+
+	/**
+	 * Constructs a queue progress.
+	 *
+	 * @constructor
+	 * @method QueueProgress
+	 */
+	 plupload.QueueProgress = function() {
+		var self = this; // Setup alias for self to reduce code size when it's compressed
+
+		/**
+		 * Total queue file size.
+		 *
+		 * @property size
+		 * @type Number
+		 */
+		self.size = 0;
+
+		/**
+		 * Total bytes uploaded.
+		 *
+		 * @property loaded
+		 * @type Number
+		 */
+		self.loaded = 0;
+
+		/**
+		 * Number of files uploaded.
+		 *
+		 * @property uploaded
+		 * @type Number
+		 */
+		self.uploaded = 0;
+
+		/**
+		 * Number of files failed to upload.
+		 *
+		 * @property failed
+		 * @type Number
+		 */
+		self.failed = 0;
+
+		/**
+		 * Number of files yet to be uploaded.
+		 *
+		 * @property queued
+		 * @type Number
+		 */
+		self.queued = 0;
+
+		/**
+		 * Total percent of the uploaded bytes.
+		 *
+		 * @property percent
+		 * @type Number
+		 */
+		self.percent = 0;
+
+		/**
+		 * Bytes uploaded per second.
+		 *
+		 * @property bytesPerSec
+		 * @type Number
+		 */
+		self.bytesPerSec = 0;
+
+		/**
+		 * Resets the progress to it's initial values.
+		 *
+		 * @method reset
+		 */
+		self.reset = function() {
+			self.size = self.loaded = self.uploaded = self.failed = self.queued = self.percent = self.bytesPerSec = 0;
+		};
+	};
+
+	// Create runtimes namespace
+	plupload.runtimes = {};
+
+	// Expose plupload namespace
+	window.plupload = plupload;
+})();
+/**
+ * plupload.gears.js
+ *
+ * Copyright 2009, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+// JSLint defined globals
+/*global plupload:false, google:false, window:false */
+
+(function(plupload) {
+	var blobs = {};
+
+	function scaleImage(image_blob, width, height, quality, mime) {
+		var percentage, canvas, context, scale;
+
+		// Setup canvas and scale
+		canvas = google.gears.factory.create('beta.canvas');
+		canvas.decode(image_blob);
+		scale = Math.min(width / canvas.width, height / canvas.height);
+
+		if (scale < 1) {
+			width = Math.round(canvas.width * scale);
+			height = Math.round(canvas.height * scale);
+		} else {
+			width = canvas.width;
+			height = canvas.height;
+		}
+
+		canvas.resize(width, height);
+
+		return canvas.encode(mime, {quality : quality / 100});
+	}
+
+	/**
+	 * Gears implementation. This runtime supports these features: dragdrop, jpgresize, pngresize, chunks.
+	 *
+	 * @static
+	 * @class plupload.runtimes.Gears
+	 * @extends plupload.Runtime
+	 */
+	plupload.runtimes.Gears = plupload.addRuntime("gears", {
+		/**
+		 * Returns a list of supported features for the runtime.
+		 *
+		 * @return {Object} Name/value object with supported features.
+		 */
+		getFeatures : function() {
+			return {
+				dragdrop: true,
+				jpgresize: true,
+				pngresize: true,
+				chunks: true,
+				progress: true,
+				multipart: true
+			};
+		},
+
+		/**
+		 * Initializes the upload runtime.
+		 *
+		 * @method init
+		 * @param {plupload.Uploader} uploader Uploader instance that needs to be initialized.
+		 * @param {function} callback Callback to execute when the runtime initializes or fails to initialize. If it succeeds an object with a parameter name success will be set to true.
+		 */
+		init : function(uploader, callback) {
+			var desktop;
+
+			// Check for gears support
+			if (!window.google || !google.gears) {
+				return callback({success : false});
+			}
+
+			try {
+				desktop = google.gears.factory.create('beta.desktop');
+			} catch (e) {
+				// Might fail on the latest Gecko build for some odd reason
+				return callback({success : false});
+			}
+
+			function addSelectedFiles(selected_files) {
+				var file, i, files = [], id;
+
+				// Add the selected files to the file queue
+				for (i = 0; i < selected_files.length; i++) {
+					file = selected_files[i];
+
+					// Store away gears blob internally
+					id = plupload.guid();
+					blobs[id] = file.blob;
+
+					files.push(new plupload.File(id, file.name, file.blob.length));
+				}
+
+				// Fire FilesAdded event
+				uploader.trigger("FilesAdded", files);
+			}
+
+			// Add drop handler
+			uploader.bind("PostInit", function() {
+				var settings = uploader.settings, dropElm = document.getElementById(settings.drop_element);
+
+				if (dropElm) {
+					// Block browser default drag over
+					plupload.addEvent(dropElm, 'dragover', function(e) {
+						desktop.setDropEffect(e, 'copy');
+						e.preventDefault();
+					});
+
+					// Attach drop handler and grab files from Gears
+					plupload.addEvent(dropElm, 'drop', function(e) {
+						var dragData = desktop.getDragData(e, 'application/x-gears-files');
+
+						if (dragData) {
+							addSelectedFiles(dragData.files);
+						}
+
+						e.preventDefault();
+					});
+
+					// Prevent IE leak
+					dropElm = 0;
+				}
+
+				// Add browse button
+				plupload.addEvent(document.getElementById(settings.browse_button), 'click', function(e) {
+					var filters = [], i, a, ext;
+
+					e.preventDefault();
+
+					for (i = 0; i < settings.filters.length; i++) {
+						ext = settings.filters[i].extensions.split(',');
+
+						for (a = 0; a < ext.length; a++) {
+							filters.push('.' + ext[a]);
+						}
+					}
+
+					desktop.openFiles(addSelectedFiles, {singleFile : !settings.multi_selection, filter : filters});
+				});
+			});
+
+			uploader.bind("UploadFile", function(up, file) {
+				var chunk = 0, chunks, chunkSize, loaded = 0, resize = up.settings.resize, chunking;
+
+				chunkSize = up.settings.chunk_size;
+				chunking = chunkSize > 0;
+				chunks = Math.ceil(file.size / chunkSize);
+
+				// If chunking is disabled then upload the whole file in one huge chunk
+				if (!chunking) {
+					chunkSize = file.size;
+					chunks = 1;
+				}
+
+				// If file is png or jpeg and resize is configured then resize it
+				if (resize && /\.(png|jpg|jpeg)$/i.test(file.name)) {
+					blobs[file.id] = scaleImage(blobs[file.id], resize.width, resize.height, resize.quality || 90, /\.png$/i.test(file.name) ? 'image/png' : 'image/jpeg');
+				}
+
+				file.size = blobs[file.id].length;
+
+				function uploadNextChunk() {
+					var req, curChunkSize, multipart = up.settings.multipart, multipartLength = 0, reqArgs = {name : file.target_name || file.name}, url = up.settings.url;
+
+					// Sends the binary blob multipart encoded or raw depending on config
+					function sendBinaryBlob(blob) {
+						var builder, boundary = '----pluploadboundary' + plupload.guid(), dashdash = '--', crlf = '\r\n', multipartBlob, mimeType;
+
+						// Build multipart request
+						if (multipart) {
+							req.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary);
+							builder = google.gears.factory.create('beta.blobbuilder');
+
+							// Append mutlipart parameters
+							plupload.each(plupload.extend(reqArgs, up.settings.multipart_params), function(value, name) {
+								builder.append(
+									dashdash + boundary + crlf +
+									'Content-Disposition: form-data; name="' + name + '"' + crlf + crlf
+								);
+
+								builder.append(value + crlf);
+							});
+
+							mimeType = plupload.mimeTypes[file.name.replace(/^.+\.([^.]+)/, '$1')] || 'application/octet-stream';
+
+							// Add file header
+							builder.append(
+								dashdash + boundary + crlf +
+								'Content-Disposition: form-data; name="' + up.settings.file_data_name + '"; filename="' + file.name + '"' + crlf +
+								'Content-Type: ' + mimeType + crlf + crlf
+							);
+
+							// Add file data
+							builder.append(blob);
+
+							// Add footer
+							builder.append(crlf + dashdash + boundary + dashdash + crlf);
+							multipartBlob = builder.getAsBlob();
+							multipartLength = multipartBlob.length - blob.length;
+							blob = multipartBlob;
+						}
+
+						// Send blob or multipart blob depending on config
+						req.send(blob);
+					}
+
+					// File upload finished
+					if (file.status == plupload.DONE || file.status == plupload.FAILED || up.state == plupload.STOPPED) {
+						return;
+					}
+
+					// Only add chunking args if needed
+					if (chunking) {
+						reqArgs.chunk = chunk;
+						reqArgs.chunks = chunks;
+					}
+
+					// Setup current chunk size
+					curChunkSize = Math.min(chunkSize, file.size - (chunk  * chunkSize));
+
+					if (!multipart) {
+						url = plupload.buildUrl(up.settings.url, reqArgs);
+					}
+
+					req = google.gears.factory.create('beta.httprequest');
+					req.open('POST', url);
+
+					// Add disposition and type if multipart is disabled
+					if (!multipart) {
+						req.setRequestHeader('Content-Disposition', 'attachment; filename="' + file.name + '"');
+						req.setRequestHeader('Content-Type', 'application/octet-stream');
+					}
+
+					// Set custom headers
+					plupload.each(up.settings.headers, function(value, name) {
+						req.setRequestHeader(name, value);
+					});
+
+					req.upload.onprogress = function(progress) {
+						file.loaded = loaded + progress.loaded - multipartLength;
+						up.trigger('UploadProgress', file);
+					};
+
+					req.onreadystatechange = function() {
+						var chunkArgs;
+
+						if (req.readyState == 4) {
+							if (req.status == 200) {
+								chunkArgs = {
+									chunk : chunk,
+									chunks : chunks,
+									response : req.responseText,
+									status : req.status
+								};
+
+								up.trigger('ChunkUploaded', file, chunkArgs);
+
+								// Stop upload
+								if (chunkArgs.cancelled) {
+									file.status = plupload.FAILED;
+									return;
+								}
+
+								loaded += curChunkSize;
+
+								if (++chunk >= chunks) {
+									file.status = plupload.DONE;
+									up.trigger('FileUploaded', file, {
+										response : req.responseText,
+										status : req.status
+									});
+								} else {
+									uploadNextChunk();
+								}
+							} else {
+								up.trigger('Error', {
+									code : plupload.HTTP_ERROR,
+									message : 'HTTP Error.',
+									file : file,
+									chunk : chunk,
+									chunks : chunks,
+									status : req.status
+								});
+							}
+						}
+					};
+
+					if (chunk < chunks) {
+						sendBinaryBlob(blobs[file.id].slice(chunk * chunkSize, curChunkSize));
+					}
+				}
+
+				// Start uploading chunks
+				uploadNextChunk();
+			});
+
+			callback({success : true});
+		}
+	});
+})(plupload);
+/**
+ * plupload.silverlight.js
+ *
+ * Copyright 2009, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+// JSLint defined globals
+/*global plupload:false, ActiveXObject:false, window:false */
+
+(function(plupload) {
+	var uploadInstances = {};
+
+	function jsonSerialize(obj) {
+		var value, type = typeof obj, undef, isArray, i, key;
+
+		// Encode strings
+		if (type === 'string') {
+			value = '\bb\tt\nn\ff\rr\""\'\'\\\\';
+
+			return '"' + obj.replace(/([\u0080-\uFFFF\x00-\x1f\"])/g, function(a, b) {
+				var idx = value.indexOf(b);
+
+				if (idx + 1) {
+					return '\\' + value.charAt(idx + 1);
+				}
+
+				a = b.charCodeAt().toString(16);
+
+				return '\\u' + '0000'.substring(a.length) + a;
+			}) + '"';
+		}
+
+		// Loop objects/arrays
+		if (type == 'object') {
+			isArray = obj.length !== undef;
+			value = '';
+
+			if (isArray) {
+				for (i = 0; i < obj.length; i++) {
+					if (value) {
+						value += ',';
+					}
+
+					value += jsonSerialize(obj[i]);
+				}
+
+				value = '[' + value + ']';
+			} else {
+				for (key in obj) {
+					if (obj.hasOwnProperty(key)) {
+						if (value) {
+							value += ',';
+						}
+
+						value += jsonSerialize(key) + ':' + jsonSerialize(obj[key]);
+					}
+				}
+
+				value = '{' + value + '}';
+			}
+
+			return value;
+		}
+
+		// Treat undefined as null
+		if (obj === undef) {
+			return 'null';
+		}
+
+		// Convert all other types to string
+		return '' + obj;
+	}
+
+	function isInstalled(version) {
+		var isVersionSupported = false, container = null, control = null, actualVer,
+			actualVerArray, reqVerArray, requiredVersionPart, actualVersionPart, index = 0;
+
+		try {
+			try {
+				control = new ActiveXObject('AgControl.AgControl');
+
+				if (control.IsVersionSupported(version)) {
+					isVersionSupported = true;
+				}
+
+				control = null;
+			} catch (e) {
+				var plugin = navigator.plugins["Silverlight Plug-In"];
+
+				if (plugin) {
+					actualVer = plugin.description;
+
+					if (actualVer === "1.0.30226.2") {
+						actualVer = "2.0.30226.2";
+					}
+
+					actualVerArray = actualVer.split(".");
+
+					while (actualVerArray.length > 3) {
+						actualVerArray.pop();
+					}
+
+					while ( actualVerArray.length < 4) {
+						actualVerArray.push(0);
+					}
+
+					reqVerArray = version.split(".");
+
+					while (reqVerArray.length > 4) {
+						reqVerArray.pop();
+					}
+
+					do {
+						requiredVersionPart = parseInt(reqVerArray[index], 10);
+						actualVersionPart = parseInt(actualVerArray[index], 10);
+						index++;
+					} while (index < reqVerArray.length && requiredVersionPart === actualVersionPart);
+
+					if (requiredVersionPart <= actualVersionPart && !isNaN(requiredVersionPart)) {
+						isVersionSupported = true;
+					}
+				}
+			}
+		} catch (e2) {
+			isVersionSupported = false;
+		}
+
+		return isVersionSupported;
+	}
+
+	plupload.silverlight = {
+		trigger : function(id, name) {
+			var uploader = uploadInstances[id], i, args;
+
+			if (uploader) {
+				args = plupload.toArray(arguments).slice(1);
+				args[0] = 'Silverlight:' + name;
+
+				// Detach the call so that error handling in the browser is presented correctly
+				setTimeout(function() {
+					uploader.trigger.apply(uploader, args);
+				}, 0);
+			}
+		}
+	};
+
+	/**
+	 * Silverlight implementation. This runtime supports these features: jpgresize, pngresize, chunks.
+	 *
+	 * @static
+	 * @class plupload.runtimes.Silverlight
+	 * @extends plupload.Runtime
+	 */
+	plupload.runtimes.Silverlight = plupload.addRuntime("silverlight", {
+		/**
+		 * Returns a list of supported features for the runtime.
+		 *
+		 * @return {Object} Name/value object with supported features.
+		 */
+		getFeatures : function() {
+			return {
+				jpgresize: true,
+				pngresize: true,
+				chunks: true,
+				progress: true,
+				multipart: true
+			};
+		},
+
+		/**
+		 * Initializes the upload runtime. This runtime supports these features: jpgresize, pngresize, chunks.
+		 *
+		 * @method init
+		 * @param {plupload.Uploader} uploader Uploader instance that needs to be initialized.
+		 * @param {function} callback Callback to execute when the runtime initializes or fails to initialize. If it succeeds an object with a parameter name success will be set to true.
+		 */
+		init : function(uploader, callback) {
+			var silverlightContainer, filter = '', filters = uploader.settings.filters, i, container = document.body;
+
+			// Check if Silverlight is installed, Silverlight windowless parameter doesn't work correctly on Opera so we disable it for now
+			if (!isInstalled('2.0.31005.0') || (window.opera && window.opera.buildNumber)) {
+				callback({success : false});
+				return;
+			}
+
+			uploadInstances[uploader.id] = uploader;
+
+			// Create silverlight container and insert it at an absolute position within the browse button
+			silverlightContainer = document.createElement('div');
+			silverlightContainer.id = uploader.id + '_silverlight_container';
+
+			plupload.extend(silverlightContainer.style, {
+				position : 'absolute',
+				top : '0px',
+				background : uploader.settings.shim_bgcolor || 'transparent',
+				zIndex : 99999,
+				width : '100px',
+				height : '100px',
+				overflow : 'hidden',
+				opacity : uploader.settings.shim_bgcolor || document.documentMode > 8 ? '' : 0.01 // Force transparent if bgcolor is undefined
+			});
+
+			silverlightContainer.className = 'plupload silverlight';
+
+			if (uploader.settings.container) {
+				container = document.getElementById(uploader.settings.container);
+				container.style.position = 'relative';
+			}
+
+			container.appendChild(silverlightContainer);
+
+			for (i = 0; i < filters.length; i++) {
+				filter += (filter != '' ? '|' : '') + filters[i].title + " | *." + filters[i].extensions.replace(/,/g, ';*.');
+			}
+
+			// Insert the Silverlight object inide the Silverlight container
+			silverlightContainer.innerHTML = '<object id="' + uploader.id + '_silverlight" data="data:application/x-silverlight," type="application/x-silverlight-2" style="outline:none;" width="1024" height="1024">' +
+				'<param name="source" value="' + uploader.settings.silverlight_xap_url + '"/>' +
+				'<param name="background" value="Transparent"/>' +
+				'<param name="windowless" value="true"/>' +
+				'<param name="enablehtmlaccess" value="true"/>' +
+				'<param name="initParams" value="id=' + uploader.id + ',filter=' + filter + '"/>' +
+				'</object>';
+
+			function getSilverlightObj() {
+				return document.getElementById(uploader.id + '_silverlight').content.Upload;
+			}
+
+			uploader.bind("Silverlight:Init", function() {
+				var selectedFiles, lookup = {};
+
+				uploader.bind("Silverlight:StartSelectFiles", function(up) {
+					selectedFiles = [];
+				});
+
+				uploader.bind("Silverlight:SelectFile", function(up, sl_id, name, size) {
+					var id;
+
+					// Store away silverlight ids
+					id = plupload.guid();
+					lookup[id] = sl_id;
+					lookup[sl_id] = id;
+
+					// Expose id, name and size
+					selectedFiles.push(new plupload.File(id, name, size));
+				});
+
+				uploader.bind("Silverlight:SelectSuccessful", function() {
+					// Trigger FilesAdded event if we added any
+					if (selectedFiles.length) {
+						uploader.trigger("FilesAdded", selectedFiles);
+					}
+				});
+
+				uploader.bind("Silverlight:UploadChunkError", function(up, file_id, chunk, chunks, message) {
+					uploader.trigger("Error", {
+						code : plupload.IO_ERROR,
+						message : 'IO Error.',
+						details : message,
+						file : up.getFile(lookup[file_id])
+					});
+				});
+
+				uploader.bind("Silverlight:UploadFileProgress", function(up, sl_id, loaded, total) {
+					var file = up.getFile(lookup[sl_id]);
+
+					if (file.status != plupload.FAILED) {
+						file.size = total;
+						file.loaded = loaded;
+
+						up.trigger('UploadProgress', file);
+					}
+				});
+
+				uploader.bind("Refresh", function(up) {
+					var browseButton, browsePos, browseSize;
+
+					browseButton = document.getElementById(up.settings.browse_button);
+					browsePos = plupload.getPos(browseButton, document.getElementById(up.settings.container));
+					browseSize = plupload.getSize(browseButton);
+
+					plupload.extend(document.getElementById(up.id + '_silverlight_container').style, {
+						top : browsePos.y + 'px',
+						left : browsePos.x + 'px',
+						width : browseSize.w + 'px',
+						height : browseSize.h + 'px'
+					});
+				});
+
+				uploader.bind("Silverlight:UploadChunkSuccessful", function(up, sl_id, chunk, chunks, text) {
+					var chunkArgs, file = up.getFile(lookup[sl_id]);
+
+					chunkArgs = {
+						chunk : chunk,
+						chunks : chunks,
+						response : text
+					};
+
+					up.trigger('ChunkUploaded', file, chunkArgs);
+
+					// Stop upload if file is maked as failed
+					if (file.status != plupload.FAILED) {
+						getSilverlightObj().UploadNextChunk();
+					}
+
+					// Last chunk then dispatch FileUploaded event
+					if (chunk == chunks - 1) {
+						file.status = plupload.DONE;
+
+						up.trigger('FileUploaded', file, {
+							response : text
+						});
+					}
+				});
+
+				uploader.bind("Silverlight:UploadSuccessful", function(up, sl_id, response) {
+					var file = up.getFile(lookup[sl_id]);
+
+					file.status = plupload.DONE;
+
+					up.trigger('FileUploaded', file, {
+						response : response
+					});
+				});
+
+				uploader.bind("FilesRemoved", function(up, files) {
+					var i;
+
+					for (i = 0; i < files.length; i++) {
+						getSilverlightObj().RemoveFile(lookup[files[i].id]);
+					}
+				});
+
+				uploader.bind("UploadFile", function(up, file) {
+					var settings = up.settings, resize = settings.resize || {};
+
+					getSilverlightObj().UploadFile(
+						lookup[file.id],
+						up.settings.url,
+						jsonSerialize({
+							name : file.target_name || file.name,
+							mime : plupload.mimeTypes[file.name.replace(/^.+\.([^.]+)/, '$1')] || 'application/octet-stream',
+							chunk_size : settings.chunk_size,
+							image_width : resize.width,
+							image_height : resize.height,
+							image_quality : resize.quality || 90,
+							multipart : !!settings.multipart,
+							multipart_params : settings.multipart_params || {},
+							headers : settings.headers
+						})
+					);
+				});
+
+				callback({success : true});
+			});
+		}
+	});
+})(plupload);
+/**
+ * plupload.flash.js
+ *
+ * Copyright 2009, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+// JSLint defined globals
+/*global plupload:false, ActiveXObject:false, escape:false */
+
+(function(plupload) {
+	var uploadInstances = {};
+
+	function getFlashVersion() {
+		var version;
+
+		try {
+			version = navigator.plugins['Shockwave Flash'];
+			version = version.description;
+		} catch (e1) {
+			try {
+				version = new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version');
+			} catch (e2) {
+				version = '0.0';
+			}
+		}
+
+		version = version.match(/\d+/g);
+
+		return parseFloat(version[0] + '.' + version[1]);
+	}
+
+	plupload.flash = {
+		/**
+		 * Will be executed by the Flash runtime when it sends out events.
+		 *
+		 * @param {String} id If for the upload instance.
+		 * @param {String} name Event name to trigger.
+		 * @param {Object} obj Parameters to be passed with event.
+		 */
+		trigger : function(id, name, obj) {
+			// Detach the call so that error handling in the browser is presented correctly
+			setTimeout(function() {
+				var uploader = uploadInstances[id], i, args;
+
+				if (uploader) {
+					uploader.trigger('Flash:' + name, obj);
+				}
+			}, 0);
+		}
+	};
+
+	/**
+	 * FlashRuntime implementation. This runtime supports these features: jpgresize, pngresize, chunks.
+	 *
+	 * @static
+	 * @class plupload.runtimes.Flash
+	 * @extends plupload.Runtime
+	 */
+	plupload.runtimes.Flash = plupload.addRuntime("flash", {
+		/**
+		 * Returns a list of supported features for the runtime.
+		 *
+		 * @return {Object} Name/value object with supported features.
+		 */
+		getFeatures : function() {
+			return {
+				jpgresize: true,
+				pngresize: true,
+				chunks: true,
+				progress: true,
+				multipart: true
+			};
+		},
+
+		/**
+		 * Initializes the upload runtime. This method should add necessary items to the DOM and register events needed for operation.
+		 *
+		 * @method init
+		 * @param {plupload.Uploader} uploader Uploader instance that needs to be initialized.
+		 * @param {function} callback Callback to execute when the runtime initializes or fails to initialize. If it succeeds an object with a parameter name success will be set to true.
+		 */
+		init : function(uploader, callback) {
+			var browseButton, flashContainer, flashVars, initialized, waitCount = 0, container = document.body;
+
+			if (getFlashVersion() < 10) {
+				callback({success : false});
+				return;
+			}
+
+			uploadInstances[uploader.id] = uploader;
+
+			// Find browse button and set to to be relative
+			browseButton = document.getElementById(uploader.settings.browse_button);
+
+			// Create flash container and insert it at an absolute position within the browse button
+			flashContainer = document.createElement('div');
+			flashContainer.id = uploader.id + '_flash_container';
+
+			plupload.extend(flashContainer.style, {
+				position : 'absolute',
+				top : '0px',
+				background : uploader.settings.shim_bgcolor || 'transparent',
+				zIndex : 99999,
+				width : '100%',
+				height : '100%'
+			});
+
+			flashContainer.className = 'plupload flash';
+
+			if (uploader.settings.container) {
+				container = document.getElementById(uploader.settings.container);
+				container.style.position = 'relative';
+			}
+
+			container.appendChild(flashContainer);
+
+			flashVars = 'id=' + escape(uploader.id);
+
+			// Insert the Flash inide the flash container
+			flashContainer.innerHTML = '<object id="' + uploader.id + '_flash" width="100%" height="100%" style="outline:0" type="application/x-shockwave-flash" data="' + uploader.settings.flash_swf_url + '">' +
+				'<param name="movie" value="' + uploader.settings.flash_swf_url + '" />' +
+				'<param name="flashvars" value="' + flashVars + '" />' +
+				'<param name="wmode" value="transparent" />' +
+				'<param name="allowscriptaccess" value="always" /></object>';
+
+			function getFlashObj() {
+				return document.getElementById(uploader.id + '_flash');
+			}
+
+			function waitLoad() {
+				// Wait for 5 sec
+				if (waitCount++ > 5000) {
+					callback({success : false});
+					return;
+				}
+
+				if (!initialized) {
+					setTimeout(waitLoad, 1);
+				}
+			}
+
+			waitLoad();
+
+			// Fix IE memory leaks
+			browseButton = flashContainer = null;
+
+			// Wait for Flash to send init event
+			uploader.bind("Flash:Init", function() {
+				var lookup = {}, i, resize = uploader.settings.resize || {};
+
+				initialized = true;
+				getFlashObj().setFileFilters(uploader.settings.filters, uploader.settings.multi_selection);
+
+				uploader.bind("UploadFile", function(up, file) {
+					var settings = up.settings;
+
+					getFlashObj().uploadFile(lookup[file.id], settings.url, {
+						name : file.target_name || file.name,
+						mime : plupload.mimeTypes[file.name.replace(/^.+\.([^.]+)/, '$1')] || 'application/octet-stream',
+						chunk_size : settings.chunk_size,
+						width : resize.width,
+						height : resize.height,
+						quality : resize.quality || 90,
+						multipart : settings.multipart,
+						multipart_params : settings.multipart_params || {},
+						file_data_name : settings.file_data_name,
+						format : /\.(jpg|jpeg)$/i.test(file.name) ? 'jpg' : 'png',
+						headers : settings.headers,
+						urlstream_upload : settings.urlstream_upload
+					});
+				});
+
+				uploader.bind("Flash:UploadProcess", function(up, flash_file) {
+					var file = up.getFile(lookup[flash_file.id]);
+
+					if (file.status != plupload.FAILED) {
+						file.loaded = flash_file.loaded;
+						file.size = flash_file.size;
+
+						up.trigger('UploadProgress', file);
+					}
+				});
+
+				uploader.bind("Flash:UploadChunkComplete", function(up, info) {
+					var chunkArgs, file = up.getFile(lookup[info.id]);
+
+					chunkArgs = {
+						chunk : info.chunk,
+						chunks : info.chunks,
+						response : info.text
+					};
+
+					up.trigger('ChunkUploaded', file, chunkArgs);
+
+					// Stop upload if file is maked as failed
+					if (file.status != plupload.FAILED) {
+						getFlashObj().uploadNextChunk();
+					}
+
+					// Last chunk then dispatch FileUploaded event
+					if (info.chunk == info.chunks - 1) {
+						file.status = plupload.DONE;
+
+						up.trigger('FileUploaded', file, {
+							response : info.text
+						});
+					}
+				});
+
+				uploader.bind("Flash:SelectFiles", function(up, selected_files) {
+					var file, i, files = [], id;
+
+					// Add the selected files to the file queue
+					for (i = 0; i < selected_files.length; i++) {
+						file = selected_files[i];
+
+						// Store away flash ref internally
+						id = plupload.guid();
+						lookup[id] = file.id;
+						lookup[file.id] = id;
+
+						files.push(new plupload.File(id, file.name, file.size));
+					}
+
+					// Trigger FilesAdded event if we added any
+					if (files.length) {
+						uploader.trigger("FilesAdded", files);
+					}
+				});
+
+				uploader.bind("Flash:SecurityError", function(up, err) {
+					uploader.trigger('Error', {
+						code : plupload.SECURITY_ERROR,
+						message : 'Security error.',
+						details : err.message,
+						file : uploader.getFile(lookup[err.id])
+					});
+				});
+
+				uploader.bind("Flash:GenericError", function(up, err) {
+					uploader.trigger('Error', {
+						code : plupload.GENERIC_ERROR,
+						message : 'Generic error.',
+						details : err.message,
+						file : uploader.getFile(lookup[err.id])
+					});
+				});
+
+				uploader.bind("Flash:IOError", function(up, err) {
+					uploader.trigger('Error', {
+						code : plupload.IO_ERROR,
+						message : 'IO error.',
+						details : err.message,
+						file : uploader.getFile(lookup[err.id])
+					});
+				});
+
+				uploader.bind("QueueChanged", function(up) {
+					uploader.refresh();
+				});
+
+				uploader.bind("FilesRemoved", function(up, files) {
+					var i;
+
+					for (i = 0; i < files.length; i++) {
+						getFlashObj().removeFile(lookup[files[i].id]);
+					}
+				});
+
+				uploader.bind("StateChanged", function(up) {
+					uploader.refresh();
+				});
+
+				uploader.bind("Refresh", function(up) {
+					var browseButton, browsePos, browseSize;
+
+					// Set file filters incase it has been changed dynamically
+					getFlashObj().setFileFilters(uploader.settings.filters, uploader.settings.multi_selection);
+
+					browseButton = document.getElementById(up.settings.browse_button);
+					browsePos = plupload.getPos(browseButton, document.getElementById(up.settings.container));
+					browseSize = plupload.getSize(browseButton);
+
+					plupload.extend(document.getElementById(up.id + '_flash_container').style, {
+						top : browsePos.y + 'px',
+						left : browsePos.x + 'px',
+						width : browseSize.w + 'px',
+						height : browseSize.h + 'px'
+					});
+				});
+
+				callback({success : true});
+			});
+		}
+	});
+})(plupload);
+/**
+ * plupload.browserplus.js
+ *
+ * Copyright 2009, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+// JSLint defined globals
+/*global plupload:false, BrowserPlus:false, window:false */
+
+(function(plupload) {
+	/**
+	 * Yahoo BrowserPlus implementation. This runtime supports these features: dragdrop, jpgresize, pngresize.
+	 *
+	 * @static
+	 * @class plupload.runtimes.BrowserPlus
+	 * @extends plupload.Runtime
+	 */
+	plupload.runtimes.BrowserPlus = plupload.addRuntime("browserplus", {
+		/**
+		 * Returns a list of supported features for the runtime.
+		 *
+		 * @return {Object} Name/value object with supported features.
+		 */
+		getFeatures : function() {
+			return {
+				dragdrop : true,
+				jpgresize : true,
+				pngresize : true,
+				chunks : true,
+				progress: true,
+				multipart: true
+			};
+		},
+
+		/**
+		 * Initializes the browserplus runtime.
+		 *
+		 * @method init
+		 * @param {plupload.Uploader} uploader Uploader instance that needs to be initialized.
+		 * @param {function} callback Callback to execute when the runtime initializes or fails to initialize. If it succeeds an object with a parameter name success will be set to true.
+		 */
+		init : function(uploader, callback) {
+			var browserPlus = window.BrowserPlus, browserPlusFiles = {}, settings = uploader.settings, resize = settings.resize;
+
+			function addSelectedFiles(native_files) {
+				var files, i, selectedFiles = [], file, id;
+
+				// Add the native files and setup plupload files
+				for (i = 0; i < native_files.length; i++) {
+					file = native_files[i];
+					id = plupload.guid();
+					browserPlusFiles[id] = file;
+
+					selectedFiles.push(new plupload.File(id, file.name, file.size));
+				}
+
+				// Any files selected fire event
+				if (i) {
+					uploader.trigger("FilesAdded", selectedFiles);
+				}
+			}
+
+			// Setup event listeners if browserplus was initialized
+			function setup() {
+				// Add drop handler
+				uploader.bind("PostInit", function() {
+					var dropTargetElm, dropElmId = settings.drop_element,
+						dropTargetId = uploader.id + '_droptarget',
+						dropElm = document.getElementById(dropElmId),
+						lastState;
+
+					// Enable/disable drop support for the drop target
+					// this is needed to resolve IE bubbeling issues and make it possible to drag/drop
+					// files into gears runtimes on the same page
+					function addDropHandler(id, end_callback) {
+						// Add drop target and listener
+						browserPlus.DragAndDrop.AddDropTarget({id : id}, function(res) {
+							browserPlus.DragAndDrop.AttachCallbacks({
+								id : id,
+								hover : function(res) {
+									if (!res && end_callback) {
+										end_callback();
+									}
+								},
+								drop : function(res) {
+									if (end_callback) {
+										end_callback();
+									}
+
+									addSelectedFiles(res);
+								}
+							}, function() {
+							});
+						});
+					}
+
+					function hide() {
+						document.getElementById(dropTargetId).style.top = '-1000px';
+					}
+
+					if (dropElm) {
+						// Since IE has issues with bubbeling when it comes to the drop of files
+						// we need to do this hack where we show a drop target div element while dropping
+						if (document.attachEvent && (/MSIE/gi).test(navigator.userAgent)) {
+							// Create drop target
+							dropTargetElm = document.createElement('div');
+							dropTargetElm.setAttribute('id', dropTargetId);
+							plupload.extend(dropTargetElm.style, {
+								position : 'absolute',
+								top : '-1000px',
+								background : 'red',
+								filter : 'alpha(opacity=0)',
+								opacity : 0
+							});
+
+							document.body.appendChild(dropTargetElm);
+
+							plupload.addEvent(dropElm, 'dragenter', function(e) {
+								var dropElm, dropElmPos;
+
+								dropElm = document.getElementById(dropElmId);
+								dropElmPos = plupload.getPos(dropElm);
+
+								plupload.extend(document.getElementById(dropTargetId).style, {
+									top : dropElmPos.y + 'px',
+									left : dropElmPos.x + 'px',
+									width : dropElm.offsetWidth + 'px',
+									height : dropElm.offsetHeight + 'px'
+								});
+							});
+
+							addDropHandler(dropTargetId, hide);
+						} else {
+							addDropHandler(dropElmId);
+						}
+					}
+
+					plupload.addEvent(document.getElementById(settings.browse_button), 'click', function(e) {
+						var mimeTypes = [], i, a, filters = settings.filters, ext;
+
+						e.preventDefault();
+
+						// Convert extensions to mimetypes
+						for (i = 0; i < filters.length; i++) {
+							ext = filters[i].extensions.split(',');
+
+							for (a = 0; a < ext.length; a++) {
+								mimeTypes.push(plupload.mimeTypes[ext[a]]);
+							}
+						}
+
+						browserPlus.FileBrowse.OpenBrowseDialog({
+							mimeTypes : mimeTypes
+						}, function(res) {
+							if (res.success) {
+								addSelectedFiles(res.value);
+							}
+						});
+					});
+
+					// Prevent IE leaks
+					dropElm = dropTargetElm = null;
+				});
+
+				uploader.bind("UploadFile", function(up, file) {
+					var nativeFile = browserPlusFiles[file.id], reqParams = {},
+					    chunkSize = up.settings.chunk_size, loadProgress, chunkStack = [];
+
+					function uploadFile(chunk, chunks) {
+						var chunkFile;
+
+						// Stop upload if file is maked as failed
+						if (file.status == plupload.FAILED) {
+							return;
+						}
+
+						reqParams.name = file.target_name || file.name;
+
+						// Only send chunk parameters if chunk size is defined
+						if (chunkSize) {
+							reqParams.chunk = "" + chunk;
+							reqParams.chunks = "" + chunks;
+						}
+
+					    chunkFile = chunkStack.shift();
+
+						browserPlus.Uploader.upload({
+							url : up.settings.url,
+							files : {file : chunkFile},
+							cookies : document.cookies,
+							postvars : plupload.extend(reqParams, up.settings.multipart_params),
+							progressCallback : function(res) {
+								var i, loaded = 0;
+
+								// since more than 1 chunk can be sent at a time, keep track of how many bytes
+								// of each chunk was sent
+								loadProgress[chunk] = parseInt(res.filePercent * chunkFile.size / 100, 10);
+								for (i = 0; i < loadProgress.length; i++) {
+									loaded += loadProgress[i];
+								}
+
+								file.loaded = loaded;
+								up.trigger('UploadProgress', file);
+							}
+						}, function(res) {
+							var httpStatus, chunkArgs;
+
+							if (res.success) {
+								httpStatus = res.value.statusCode;
+
+								if (chunkSize) {
+									up.trigger('ChunkUploaded', file, {
+										chunk : chunk,
+										chunks : chunks,
+										response : res.value.body,
+										status : httpStatus
+									});
+								}
+
+							    if (chunkStack.length > 0) {
+									// More chunks to be uploaded
+									uploadFile(++chunk, chunks);
+							    } else {
+									file.status = plupload.DONE;
+
+									up.trigger('FileUploaded', file, {
+										response : res.value.body,
+										status : httpStatus
+									});
+
+									// Is error status
+									if (httpStatus >= 400) {
+										up.trigger('Error', {
+											code : plupload.HTTP_ERROR,
+											message : 'HTTP Error.',
+											file : file,
+											status : httpStatus
+										});
+									}
+							    }
+							} else {
+								up.trigger('Error', {
+									code : plupload.GENERIC_ERROR,
+									message : 'Generic Error.',
+									file : file,
+									details : res.error
+								});
+							}
+						});
+					}
+
+					function chunkAndUploadFile(native_file) {
+						file.size = native_file.size;
+						if (chunkSize) {
+							browserPlus.FileAccess.chunk({file : native_file, chunkSize : chunkSize}, function(cr) {
+								if (cr.success) {
+									var chunks = cr.value, len = chunks.length;
+
+									loadProgress = Array(len);
+
+									for (var i = 0; i < len; i++) {
+										loadProgress[i] = 0;
+										chunkStack.push(chunks[i]);
+									}
+
+									uploadFile(0, len);
+								}
+							});
+						} else {
+							loadProgress = Array(1);
+							chunkStack.push(native_file);
+							uploadFile(0, 1);
+						}
+					}
+
+					// Resize image if it's a supported format and resize is enabled
+					if (resize && /\.(png|jpg|jpeg)$/i.test(file.name)) {
+						BrowserPlus.ImageAlter.transform({
+							file : nativeFile,
+							quality : resize.quality || 90,
+							actions : [{
+								scale : {
+									maxwidth : resize.width,
+									maxheight : resize.height
+								}
+							}]
+						}, function(res) {
+							if (res.success) {
+								chunkAndUploadFile(res.value.file);
+							}
+						});
+					} else {
+						chunkAndUploadFile(nativeFile);
+					}
+				});
+
+				callback({success : true});
+			}
+
+			// Check for browserplus object
+			if (browserPlus) {
+				browserPlus.init(function(res) {
+					var services = [
+						{service: "Uploader", version: "3"},
+						{service: "DragAndDrop", version: "1"},
+						{service: "FileBrowse", version: "1"},
+						{service: "FileAccess", version: "2"}
+					];
+
+					if (resize) {
+						services.push({service : 'ImageAlter', version : "4"});
+					}
+
+					if (res.success) {
+						browserPlus.require({
+							services : services
+						}, function(sres) {
+							if (sres.success) {
+								setup();
+							} else {
+								callback();
+							}
+						});
+					} else {
+						callback();
+					}
+				});
+			} else {
+				callback();
+			}
+		}
+	});
+})(plupload);
+/**
+ * plupload.html5.js
+ *
+ * Copyright 2009, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+// JSLint defined globals
+/*global plupload:false, File:false, window:false, atob:false, FormData:false, FileReader:false */
+
+(function(plupload) {
+	var fakeSafariDragDrop;
+
+	function readFile(file, callback) {
+		var reader;
+
+		// Use FileReader if it's available
+		if ("FileReader" in window) {
+			reader = new FileReader();
+			reader.readAsDataURL(file);
+			reader.onload = function() {
+				callback(reader.result);
+			};
+		} else {
+			return callback(file.getAsDataURL());
+		}
+	}
+
+	function scaleImage(image_file, max_width, max_height, mime, callback) {
+		var canvas, context, img, data, scale;
+
+		readFile(image_file, function(data) {
+			// Setup canvas and context
+			canvas = document.createElement("canvas");
+			canvas.style.display = 'none';
+			document.body.appendChild(canvas);
+			context = canvas.getContext('2d');
+
+			// Load image
+			img = new Image();
+			img.onload = function() {
+				var width, height, percentage;
+
+				scale = Math.min(max_width / img.width, max_height / img.height);
+
+				if (scale < 1) {
+					width = Math.round(img.width * scale);
+					height = Math.round(img.height * scale);
+				} else {
+					width = img.width;
+					height = img.height;
+				}
+
+				// Scale image and canvas
+				canvas.width = width;
+				canvas.height = height;
+				context.drawImage(img, 0, 0, width, height);
+
+				// Remove data prefix information and grab the base64 encoded data and decode it
+				data = canvas.toDataURL(mime);
+				data = data.substring(data.indexOf('base64,') + 7);
+				data = atob(data);
+
+				// Remove canvas and execute callback with decoded image data
+				canvas.parentNode.removeChild(canvas);
+				callback({success : true, data : data});
+			};
+
+			img.src = data;
+		});
+	}
+
+	/**
+	 * HMTL5 implementation. This runtime supports these features: dragdrop, jpgresize, pngresize.
+	 *
+	 * @static
+	 * @class plupload.runtimes.Html5
+	 * @extends plupload.Runtime
+	 */
+	plupload.runtimes.Html5 = plupload.addRuntime("html5", {
+		/**
+		 * Returns a list of supported features for the runtime.
+		 *
+		 * @return {Object} Name/value object with supported features.
+		 */
+		getFeatures : function() {
+			var xhr, hasXhrSupport, hasProgress, dataAccessSupport, sliceSupport, win = window;
+
+			hasXhrSupport = hasProgress = dataAccessSupport = sliceSupport = false;
+
+			if (win.XMLHttpRequest) {
+				xhr = new XMLHttpRequest();
+				hasProgress = !!xhr.upload;
+				hasXhrSupport = !!(xhr.sendAsBinary || xhr.upload);
+			}
+
+			// Check for support for various features
+			if (hasXhrSupport) {
+				// Set dataAccessSupport only for Gecko since BlobBuilder and XHR doesn't handle binary data correctly
+				dataAccessSupport = !!(File && (File.prototype.getAsDataURL || win.FileReader) && xhr.sendAsBinary);
+				sliceSupport = !!(File && File.prototype.slice);
+			}
+
+			// Sniff for Safari and fake drag/drop
+			fakeSafariDragDrop = navigator.userAgent.indexOf('Safari') > 0;
+
+			return {
+				// Detect drag/drop file support by sniffing, will try to find a better way
+				html5: hasXhrSupport, // This is a special one that we check inside the init call
+				dragdrop: win.mozInnerScreenX !== undefined || sliceSupport || fakeSafariDragDrop,
+				jpgresize: dataAccessSupport,
+				pngresize: dataAccessSupport,
+				multipart: dataAccessSupport || !!win.FileReader || !!win.FormData,
+				progress: hasProgress,
+				chunking: sliceSupport || dataAccessSupport
+			};
+		},
+
+		/**
+		 * Initializes the upload runtime.
+		 *
+		 * @method init
+		 * @param {plupload.Uploader} uploader Uploader instance that needs to be initialized.
+		 * @param {function} callback Callback to execute when the runtime initializes or fails to initialize. If it succeeds an object with a parameter name success will be set to true.
+		 */
+		init : function(uploader, callback) {
+			var html5files = {}, features;
+
+			function addSelectedFiles(native_files) {
+				var file, i, files = [], id;
+
+				// Add the selected files to the file queue
+				for (i = 0; i < native_files.length; i++) {
+					file = native_files[i];
+
+					// Store away gears blob internally
+					id = plupload.guid();
+					html5files[id] = file;
+
+					// Expose id, name and size
+					files.push(new plupload.File(id, file.fileName, file.fileSize));
+				}
+
+				// Trigger FilesAdded event if we added any
+				if (files.length) {
+					uploader.trigger("FilesAdded", files);
+				}
+			}
+
+			// No HTML5 upload support
+			features = this.getFeatures();
+			if (!features.html5) {
+				callback({success : false});
+				return;
+			}
+
+			uploader.bind("Init", function(up) {
+				var inputContainer, mimes = [], i, y, filters = up.settings.filters, ext, type, container = document.body;
+
+				// Create input container and insert it at an absolute position within the browse button
+				inputContainer = document.createElement('div');
+				inputContainer.id = up.id + '_html5_container';
+
+				// Convert extensions to mime types list
+				for (i = 0; i < filters.length; i++) {
+					ext = filters[i].extensions.split(/,/);
+
+					for (y = 0; y < ext.length; y++) {
+						type = plupload.mimeTypes[ext[y]];
+
+						if (type) {
+							mimes.push(type);
+						}
+					}
+				}
+
+				plupload.extend(inputContainer.style, {
+					position : 'absolute',
+					background : uploader.settings.shim_bgcolor || 'transparent',
+					width : '100px',
+					height : '100px',
+					overflow : 'hidden',
+					zIndex : 99999,
+					opacity : uploader.settings.shim_bgcolor ? '' : 0 // Force transparent if bgcolor is undefined
+				});
+
+				inputContainer.className = 'plupload html5';
+
+				if (uploader.settings.container) {
+					container = document.getElementById(uploader.settings.container);
+					container.style.position = 'relative';
+				}
+
+				container.appendChild(inputContainer);
+
+				// Insert the input inide the input container
+				inputContainer.innerHTML = '<input id="' + uploader.id + '_html5" ' +
+											'style="width:100%;" type="file" accept="' + mimes.join(',') + '" ' +
+											(uploader.settings.multi_selection ? 'multiple="multiple"' : '') + ' />';
+
+				document.getElementById(uploader.id + '_html5').onchange = function() {
+					// Add the selected files from file input
+					addSelectedFiles(this.files);
+
+					// Clearing the value enables the user to select the same file again if they want to
+					this.value = '';
+				};
+			});
+
+			// Add drop handler
+			uploader.bind("PostInit", function() {
+				var dropElm = document.getElementById(uploader.settings.drop_element);
+
+				if (dropElm) {
+					// Lets fake drag/drop on Safari by moving a inpit type file in front of the mouse pointer when we drag into the drop zone
+					// TODO: Remove this logic once Safari has official drag/drop support
+					if (fakeSafariDragDrop) {
+						plupload.addEvent(dropElm, 'dragenter', function(e) {
+							var dropInputElm, dropPos, dropSize;
+
+							// Get or create drop zone
+							dropInputElm = document.getElementById(uploader.id + "_drop");
+							if (!dropInputElm) {
+								dropInputElm = document.createElement("input");
+								dropInputElm.setAttribute('type', "file");
+								dropInputElm.setAttribute('id', uploader.id + "_drop");
+								dropInputElm.setAttribute('multiple', 'multiple');
+
+								dropInputElm.onchange = function() {
+									// Add the selected files from file input
+									addSelectedFiles(this.files);
+
+									// Clearing the value enables the user to select the same file again if they want to
+									this.value = '';
+								};
+							}
+
+							dropPos = plupload.getPos(dropElm, document.getElementById(uploader.settings.container));
+							dropSize = plupload.getSize(dropElm);
+
+							plupload.extend(dropInputElm.style, {
+								position : 'absolute',
+								display : 'block',
+								top : dropPos.y + 'px',
+								left : dropPos.x + 'px',
+								width : dropSize.w + 'px',
+								height : dropSize.h + 'px',
+								opacity : 0
+							});
+
+							dropElm.appendChild(dropInputElm);
+						});
+
+						return;
+					}
+
+					// Block browser default drag over
+					plupload.addEvent(dropElm, 'dragover', function(e) {
+						e.preventDefault();
+					});
+
+					// Attach drop handler and grab files
+					plupload.addEvent(dropElm, 'drop', function(e) {
+						var dataTransfer = e.dataTransfer;
+
+						// Add dropped files
+						if (dataTransfer && dataTransfer.files) {
+							addSelectedFiles(dataTransfer.files);
+						}
+
+						e.preventDefault();
+					});
+				}
+			});
+
+			uploader.bind("Refresh", function(up) {
+				var browseButton, browsePos, browseSize;
+
+				browseButton = document.getElementById(uploader.settings.browse_button);
+				browsePos = plupload.getPos(browseButton, document.getElementById(up.settings.container));
+				browseSize = plupload.getSize(browseButton);
+
+				plupload.extend(document.getElementById(uploader.id + '_html5_container').style, {
+					top : browsePos.y + 'px',
+					left : browsePos.x + 'px',
+					width : browseSize.w + 'px',
+					height : browseSize.h + 'px'
+				});
+			});
+
+			uploader.bind("UploadFile", function(up, file) {
+				var settings = up.settings, nativeFile, resize;
+
+				function sendBinaryBlob(blob) {
+					var chunk = 0, loaded = 0;
+
+					function uploadNextChunk() {
+						var chunkBlob = blob, xhr, upload, chunks, args, multipartDeltaSize = 0,
+							boundary = '----pluploadboundary' + plupload.guid(), chunkSize, curChunkSize,
+							dashdash = '--', crlf = '\r\n', multipartBlob = '', mimeType, url = up.settings.url;
+
+						// File upload finished
+						if (file.status == plupload.DONE || file.status == plupload.FAILED || up.state == plupload.STOPPED) {
+							return;
+						}
+
+						// Standard arguments
+						args = {name : file.target_name || file.name};
+
+						// Only add chunking args if needed
+						if (settings.chunk_size && features.chunking) {
+							chunkSize = settings.chunk_size;
+							chunks = Math.ceil(file.size / chunkSize);
+							curChunkSize = Math.min(chunkSize, file.size - (chunk  * chunkSize));
+
+							// Blob is string so we need to fake chunking, this is not
+							// ideal since the whole file is loaded into memory
+							if (typeof(blob) == 'string') {
+								chunkBlob = blob.substring(chunk * chunkSize, chunk * chunkSize + curChunkSize);
+							} else {
+								// Slice the chunk
+								chunkBlob = blob.slice(chunk * chunkSize, curChunkSize);
+							}
+
+							// Setup query string arguments
+							args.chunk = chunk;
+							args.chunks = chunks;
+						} else {
+							curChunkSize = file.size;
+						}
+
+						// Setup XHR object
+						xhr = new XMLHttpRequest();
+						upload = xhr.upload;
+
+						// Do we have upload progress support
+						if (upload) {
+							upload.onprogress = function(e) {
+								file.loaded = Math.min(file.size, loaded + e.loaded - multipartDeltaSize); // Loaded can be larger than file size due to multipart encoding
+								up.trigger('UploadProgress', file);
+							};
+						}
+
+						// Add name, chunk and chunks to query string on direct streaming
+						if (!up.settings.multipart || !features.multipart) {
+							url = plupload.buildUrl(up.settings.url, args);
+						} else {
+							args.name = file.target_name || file.name;
+						}
+
+						xhr.open("post", url, true);
+
+						xhr.onreadystatechange = function() {
+							var httpStatus, chunkArgs;
+
+							if (xhr.readyState == 4) {
+								// Getting the HTTP status might fail on some Gecko versions
+								try {
+									httpStatus = xhr.status;
+								} catch (ex) {
+									httpStatus = 0;
+								}
+
+								// Is error status
+								if (httpStatus >= 400) {
+									up.trigger('Error', {
+										code : plupload.HTTP_ERROR,
+										message : 'HTTP Error.',
+										file : file,
+										status : httpStatus
+									});
+								} else {
+									// Handle chunk response
+									if (chunks) {
+										chunkArgs = {
+											chunk : chunk,
+											chunks : chunks,
+											response : xhr.responseText,
+											status : httpStatus
+										};
+
+										up.trigger('ChunkUploaded', file, chunkArgs);
+										loaded += curChunkSize;
+
+										// Stop upload
+										if (chunkArgs.cancelled) {
+											file.status = plupload.FAILED;
+											return;
+										}
+
+										file.loaded = Math.min(file.size, (chunk + 1) * chunkSize);
+									} else {
+										file.loaded = file.size;
+									}
+
+									up.trigger('UploadProgress', file);
+
+									// Check if file is uploaded
+									if (!chunks || ++chunk >= chunks) {
+										file.status = plupload.DONE;
+										up.trigger('FileUploaded', file, {
+											response : xhr.responseText,
+											status : httpStatus
+										});
+									} else {
+										// Still chunks left
+										uploadNextChunk();
+									}
+								}
+							}
+						};
+
+						// Set custom headers
+						plupload.each(up.settings.headers, function(value, name) {
+							xhr.setRequestHeader(name, value);
+						});
+
+						// Build multipart request
+						if (up.settings.multipart && features.multipart) {
+							// Has FormData support like Chrome 6+, Safari 5+, Firefox 4
+							if (!xhr.sendAsBinary) {
+								var data = new FormData();
+
+								// Add multipart params
+								plupload.each(plupload.extend(args, up.settings.multipart_params), function(value, name) {
+									data.append(name, value);
+								});
+
+								// Add file and send it
+								data.append(up.settings.file_data_name, chunkBlob);
+								xhr.send(data);
+
+								return;
+							}
+
+							// Gecko multipart request
+							xhr.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary);
+
+							// Append multipart parameters
+							plupload.each(plupload.extend(args, up.settings.multipart_params), function(value, name) {
+								multipartBlob += dashdash + boundary + crlf +
+									'Content-Disposition: form-data; name="' + name + '"' + crlf + crlf;
+
+								multipartBlob += value + crlf;
+							});
+
+							mimeType = plupload.mimeTypes[file.name.replace(/^.+\.([^.]+)/, '$1')] || 'application/octet-stream';
+
+							// Build RFC2388 blob
+							multipartBlob += dashdash + boundary + crlf +
+								'Content-Disposition: form-data; name="' + up.settings.file_data_name + '"; filename="' + file.name + '"' + crlf +
+								'Content-Type: ' + mimeType + crlf + crlf +
+								chunkBlob + crlf +
+								dashdash + boundary + dashdash + crlf;
+
+							multipartDeltaSize = multipartBlob.length - chunkBlob.length;
+							chunkBlob = multipartBlob;
+						} else {
+							// Binary stream header
+							xhr.setRequestHeader('Content-Type', 'application/octet-stream');
+						}
+
+						if (xhr.sendAsBinary) {
+							xhr.sendAsBinary(chunkBlob); // Gecko
+						} else {
+							xhr.send(chunkBlob); // WebKit
+						}
+					}
+
+					// Start uploading chunks
+					uploadNextChunk();
+				}
+
+				nativeFile = html5files[file.id];
+				resize = up.settings.resize;
+
+				if (features.jpgresize) {
+					// Resize image if it's a supported format and resize is enabled
+					if (resize && /\.(png|jpg|jpeg)$/i.test(file.name)) {
+						scaleImage(nativeFile, resize.width, resize.height, /\.png$/i.test(file.name) ? 'image/png' : 'image/jpeg', function(res) {
+							// If it was scaled send the scaled image if it failed then
+							// send the raw image and let the server do the scaling
+							if (res.success) {
+								file.size = res.data.length;
+								sendBinaryBlob(res.data);
+							} else {
+								sendBinaryBlob(nativeFile.getAsBinary());
+							}
+						});
+					} else {
+						sendBinaryBlob(nativeFile.getAsBinary());
+					}
+				} else {
+					sendBinaryBlob(nativeFile);
+				}
+			});
+
+			callback({success : true});
+		}
+	});
+})(plupload);
+/**
+ * plupload.html4.js
+ *
+ * Copyright 2010, Ryan Demmer
+ * Copyright 2009, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+// JSLint defined globals
+/*global plupload:false, window:false */
+
+(function(plupload) {
+	function getById(id) {
+		return document.getElementById(id);
+	}
+
+	/**
+	 * HTML4 implementation. This runtime has no special features it uses an form that posts files into an hidden iframe.
+	 *
+	 * @static
+	 * @class plupload.runtimes.Html4
+	 * @extends plupload.Runtime
+	 */
+	plupload.runtimes.Html4 = plupload.addRuntime("html4", {
+		/**
+		 * Returns a list of supported features for the runtime.
+		 *
+		 * @return {Object} Name/value object with supported features.
+		 */
+		getFeatures : function() {
+			// Only multipart feature
+			return {
+				multipart: true
+			};
+		},
+
+		/**
+		 * Initializes the upload runtime.
+		 *
+		 * @method init
+		 * @param {plupload.Uploader} uploader Uploader instance that needs to be initialized.
+		 * @param {function} callback Callback to execute when the runtime initializes or fails to initialize. If it succeeds an object with a parameter name success will be set to true.
+		 */
+		init : function(uploader, callback) {
+			uploader.bind("Init", function(up) {
+				var container = document.body, iframe, url = "javascript", currentFile,
+					input, currentFileId, IE = /MSIE/.test(navigator.userAgent), mimes = [],
+					filters = up.settings.filters, i, ext, type, y;
+
+				// Convert extensions to mime types list
+				for (i = 0; i < filters.length; i++) {
+					ext = filters[i].extensions.split(/,/);
+
+					for (y = 0; y < ext.length; y++) {
+						type = plupload.mimeTypes[ext[y]];
+
+						if (type) {
+							mimes.push(type);
+						}
+					}
+				}
+
+				mimes = mimes.join(',');
+
+				function createForm() {
+					var form, input, bgcolor;
+
+					// Setup unique id for form
+					currentFileId = plupload.guid();
+
+					// Create form
+					form = document.createElement('form');
+					form.setAttribute('id', 'form_' + currentFileId);
+					form.setAttribute('method', 'post');
+					form.setAttribute('enctype', 'multipart/form-data');
+					form.setAttribute('encoding', 'multipart/form-data');
+					form.setAttribute("target", up.id + '_iframe');
+					form.style.position = 'absolute';
+
+					// Create input and set attributes
+					input = document.createElement('input');
+					input.setAttribute('id', 'input_' + currentFileId);
+					input.setAttribute('type', 'file');
+					input.setAttribute('accept', mimes);
+					input.setAttribute('size', 1);
+
+					// Set input styles
+					plupload.extend(input.style, {
+						width : '100%',
+						height : '100%',
+						opacity : 0
+					});
+
+					// Show the container if shim_bgcolor is specified
+					bgcolor = up.settings.shim_bgcolor;
+					if (bgcolor) {
+						form.style.background = bgcolor;
+					}
+
+					// no opacity in IE
+					if (IE) {
+						plupload.extend(input.style, {
+							filter : "alpha(opacity=0)"
+						});
+					}
+
+					// add change event
+					plupload.addEvent(input, 'change', function(e) {
+						var element = e.target, name, files = [];
+
+						if (element.value) {
+							getById('form_' + currentFileId).style.top = -0xFFFFF + "px";
+
+							// Get file name
+							name = element.value.replace(/\\/g, '/');
+							name = name.substring(name.length, name.lastIndexOf('/') + 1);
+
+							// Push files
+							files.push(new plupload.File(currentFileId, name));
+
+							// Create and position next form
+							createForm();
+
+							// Fire FilesAdded event
+							if (files.length) {
+								uploader.trigger("FilesAdded", files);
+							}
+						}
+					});
+
+					// append to container
+					form.appendChild(input);
+					container.appendChild(form);
+
+					up.refresh();
+				}
+
+
+				function createIframe() {
+					// Create iframe and add it to the container
+					iframe = document.createElement('iframe');
+					iframe.setAttribute('src', url + ':""'); // javascript:"" for HTTPS issue on IE6, uses a variable to make an ignore for jslint
+					iframe.setAttribute('id', up.id + '_iframe');
+					iframe.setAttribute('name', up.id + '_iframe');
+					iframe.style.display = 'none';
+
+					container.appendChild(iframe);
+
+					// Add IFrame onload event
+					plupload.addEvent(iframe, 'load', function(e) {
+						var n = e.target, el, result;
+
+						// Ignore load event if there is no file
+						if (!currentFile) {
+							return;
+						}
+
+						try {
+							el = n.contentWindow.document || n.contentDocument || window.frames[n.id].document;
+						} catch (ex) {
+							// Probably a permission denied error
+							up.trigger('Error', {
+								code : plupload.SECURITY_ERROR,
+								message : 'Security error.',
+								file : currentFile
+							});
+
+							return;
+						}
+
+						// Get result
+						result = el.documentElement.innerText || el.documentElement.textContent;
+
+						// Assume no error
+						if (result) {
+							currentFile.status = plupload.DONE;
+							currentFile.loaded = 1025;
+							currentFile.percent = 100;
+
+							up.trigger('UploadProgress', currentFile);
+							up.trigger('FileUploaded', currentFile, {
+								response : result
+							});
+						}
+					});
+
+					// Upload file
+					up.bind("UploadFile", function(up, file) {
+						var form, input;
+
+						// File upload finished
+						if (file.status == plupload.DONE || file.status == plupload.FAILED || up.state == plupload.STOPPED) {
+							return;
+						}
+
+						// Get the form and input elements
+						form = getById('form_' + file.id);
+						input = getById('input_' + file.id);
+
+						// Set input element name attribute which allows it to be submitted
+						input.setAttribute('name', up.settings.file_data_name);
+
+						// Store action
+						form.setAttribute("action", up.settings.url);
+
+						// Append multipart parameters
+						plupload.each(plupload.extend({name : file.target_name || file.name}, up.settings.multipart_params), function(value, name) {
+							var input = document.createElement('input');
+
+							plupload.extend(input, {
+								type : 'hidden',
+								name : name,
+								value : value
+							});
+
+							form.insertBefore(input, form.firstChild);
+						});
+
+						currentFile = file;
+
+						// Hide the current form
+						getById('form_' + currentFileId).style.top = -0xFFFFF + "px";
+
+						form.submit();
+						form.parentNode.removeChild(form);
+					});
+				}
+
+				if (up.settings.container) {
+					container = getById(up.settings.container);
+					container.style.position = 'relative';
+				}
+
+				up.bind('StateChanged', function(up) {
+					if (up.state == plupload.STARTED) {
+						createIframe();
+					}
+
+					if (up.state == plupload.STOPPED) {
+						window.setTimeout(function() {
+							iframe.parentNode.removeChild(iframe);
+						}, 0);
+					}
+				});
+
+				// Refresh button, will reposition the input form
+				up.bind("Refresh", function(up) {
+					var browseButton, browsePos, browseSize;
+
+					browseButton = getById(up.settings.browse_button);
+					browsePos = plupload.getPos(browseButton, getById(up.settings.container));
+					browseSize = plupload.getSize(browseButton);
+
+					plupload.extend(getById('form_' + currentFileId).style, {
+						top : browsePos.y + 'px',
+						left : browsePos.x + 'px',
+						width : browseSize.w + 'px',
+						height : browseSize.h + 'px'
+					});
+				});
+
+				// Remove files
+				uploader.bind("FilesRemoved", function(up, files) {
+					var i, n;
+
+					for (i = 0; i < files.length; i++) {
+						n = getById('form_' + files[i].id);
+						n.parentNode.removeChild(n);
+					}
+				});
+
+				// Create initial form
+				createForm();
+			});
+
+			callback({success : true});
+		}
+	});
+})(plupload);
Index: typo3/sysext/t3skin/stylesheets/structure/module_file_upload.css
===================================================================
--- typo3/sysext/t3skin/stylesheets/structure/module_file_upload.css	(revision 7906)
+++ typo3/sysext/t3skin/stylesheets/structure/module_file_upload.css	(revision )
@@ -21,4 +21,73 @@
 .t3-upload-window-infopanel input {
 	margin-right: 3px;
 	vertical-align: text-bottom;
-}
\ No newline at end of file
+}
+
+.x-plupload-body {
+    overflow-x: hidden;
+    overflow-y: auto;
+}
+
+.x-plupload-body dl {
+    padding: 5px;
+    border-bottom: 1px solid #D0D0D0;
+    font: normal 11px arial,tahoma,verdana,helvetica;
+    width: 100%;
+}
+
+.x-plupload-body dt {
+    float: left;
+    cursor: pointer;
+    display: block;
+    overflow: hidden;
+    white-space: nowrap;
+}
+
+.t3-plupload-remove {
+	visibility: hidden;
+}
+
+.plupload_over {
+	filter: alpha(opacity=50);
+	opacity: 0.5;
+	-moz-opacity: 0.5;
+}
+
+.plupload_over .t3-plupload-remove {
+	visibility: visible;
+}
+
+
+.plupload_selected {
+    background-color: #EFF5FB;
+}
+
+.plupload_emptytext {
+    font: 11px Arial,Helvetica,sans-serif;
+    vertical-align: middle;
+    text-align: center;
+}
+
+.plupload_emptytext span {
+    line-height: 100px;
+}
+
+.silk-accept {
+	background-image: url(../../images/icons/status/dialog-ok.png) !important; background-repeat: no-repeat;
+}
+
+.silk-add {
+	background-image: url(../../images/icons/actions/edit-add.png) !important; background-repeat: no-repeat;
+}
+
+.silk-cross {
+	background-image: url(../../images/icons/status/status-icon-missing.png) !important; background-repeat: no-repeat;
+}
+
+.silk-stop {
+	background-image: url(../../images/icons/status/status-permission-denied.png) !important; background-repeat: no-repeat;
+}
+
+.silk-arrow-up {
+	background-image: url(../../images/icons/actions/edit-upload.png) !important; background-repeat: no-repeat;
+}
\ No newline at end of file
Index: typo3/contrib/plupload/js/jquery.plupload.queue.min.js
===================================================================
--- typo3/contrib/plupload/js/jquery.plupload.queue.min.js	(revision )
+++ typo3/contrib/plupload/js/jquery.plupload.queue.min.js	(revision )
@@ -0,0 +1,1 @@
+(function(c){var d={};function a(e){return plupload.translate(e)||e}function b(f,e){e.contents().each(function(g,h){h=c(h);if(!h.is(".plupload")){h.remove()}});e.prepend('<div class="plupload_wrapper plupload_scroll"><div id="'+f+'_container" class="plupload_container"><div class="plupload"><div class="plupload_header"><div class="plupload_header_content"><div class="plupload_header_title">'+a("Select files")+'</div><div class="plupload_header_text">'+a("Add files to the upload queue and click the start button.")+'</div></div></div><div class="plupload_content"><div class="plupload_filelist_header"><div class="plupload_file_name">'+a("Filename")+'</div><div class="plupload_file_action">&nbsp;</div><div class="plupload_file_status"><span>'+a("Status")+'</span></div><div class="plupload_file_size">'+a("Size")+'</div><div class="plupload_clearer">&nbsp;</div></div><ul id="'+f+'_filelist" class="plupload_filelist"></ul><div class="plupload_filelist_footer"><div class="plupload_file_name"><div class="plupload_buttons"><a href="#" class="plupload_button plupload_add">'+a("Add files")+'</a><a href="#" class="plupload_button plupload_start">'+a("Start upload")+'</a></div><span class="plupload_upload_status"></span></div><div class="plupload_file_action"></div><div class="plupload_file_status"><span class="plupload_total_status">0%</span></div><div class="plupload_file_size"><span class="plupload_total_file_size">0 b</span></div><div class="plupload_progress"><div class="plupload_progress_container"><div class="plupload_progress_bar"></div></div></div><div class="plupload_clearer">&nbsp;</div></div></div></div></div><input type="hidden" id="'+f+'_count" name="'+f+'_count" value="0" /></div>')}c.fn.pluploadQueue=function(e){if(e){this.each(function(){var j,i,k;i=c(this);k=i.attr("id");if(!k){k=plupload.guid();i.attr("id",k)}j=new plupload.Uploader(c.extend({dragdrop:true,container:k},e));if(e.preinit){e.preinit(j)}d[k]=j;function h(l){var m;if(l.status==plupload.DONE){m="plupload_done"}if(l.status==plupload.FAILED){m="plupload_failed"}if(l.status==plupload.QUEUED){m="plupload_delete"}if(l.status==plupload.UPLOADING){m="plupload_uploading"}c("#"+l.id).attr("class",m).find("a").css("display","block")}function f(){c("span.plupload_total_status",i).html(j.total.percent+"%");c("div.plupload_progress_bar",i).css("width",j.total.percent+"%");c("span.plupload_upload_status",i).text("Uploaded "+j.total.uploaded+"/"+j.files.length+" files");if(j.total.uploaded==j.files.length){j.stop()}}function g(){var m=c("ul.plupload_filelist",i).html(""),n=0,l;c.each(j.files,function(p,o){l="";if(o.status==plupload.DONE){if(o.target_name){l+='<input type="hidden" name="'+k+"_"+n+'_tmpname" value="'+plupload.xmlEncode(o.target_name)+'" />'}l+='<input type="hidden" name="'+k+"_"+n+'_name" value="'+plupload.xmlEncode(o.name)+'" />';l+='<input type="hidden" name="'+k+"_"+n+'_status" value="'+(o.status==plupload.DONE?"done":"failed")+'" />';n++;c("#"+k+"_count").val(n)}m.append('<li id="'+o.id+'"><div class="plupload_file_name"><span>'+o.name+'</span></div><div class="plupload_file_action"><a href="#"></a></div><div class="plupload_file_status">'+o.percent+'%</div><div class="plupload_file_size">'+plupload.formatSize(o.size)+'</div><div class="plupload_clearer">&nbsp;</div>'+l+"</li>");h(o);c("#"+o.id+".plupload_delete a").click(function(q){c("#"+o.id).remove();j.removeFile(o);q.preventDefault()})});c("span.plupload_total_file_size",i).html(plupload.formatSize(j.total.size));if(j.total.queued===0){c("span.plupload_add_text",i).text(a("Add files."))}else{c("span.plupload_add_text",i).text(j.total.queued+" files queued.")}c("a.plupload_start",i).toggleClass("plupload_disabled",j.files.length===0);m[0].scrollTop=m[0].scrollHeight;f();if(!j.files.length&&j.features.dragdrop&&j.settings.dragdrop){c("#"+k+"_filelist").append('<li class="plupload_droptext">'+a("Drag files here.")+"</li>")}}j.bind("UploadFile",function(l,m){c("#"+m.id).addClass("plupload_current_file")});j.bind("Init",function(l,m){b(k,i);if(!e.unique_names&&e.rename){c("#"+k+"_filelist div.plupload_file_name span",i).live("click",function(s){var q=c(s.target),o,r,n,p="";o=l.getFile(q.parents("li")[0].id);n=o.name;r=/^(.+)(\.[^.]+)$/.exec(n);if(r){n=r[1];p=r[2]}q.hide().after('<input type="text" />');q.next().val(n).focus().blur(function(){q.show().next().remove()}).keydown(function(u){var t=c(this);if(u.keyCode==13){u.preventDefault();o.name=t.val()+p;q.text(o.name);t.blur()}})})}c("a.plupload_add",i).attr("id",k+"_browse");l.settings.browse_button=k+"_browse";if(l.features.dragdrop&&l.settings.dragdrop){l.settings.drop_element=k+"_filelist";c("#"+k+"_filelist").append('<li class="plupload_droptext">'+a("Drag files here.")+"</li>")}c("#"+k+"_container").attr("title","Using runtime: "+m.runtime);c("a.plupload_start",i).click(function(n){if(!c(this).hasClass("plupload_disabled")){j.start()}n.preventDefault()});c("a.plupload_stop",i).click(function(n){j.stop();n.preventDefault()});c("a.plupload_start",i).addClass("plupload_disabled")});j.init();j.bind("Error",function(l,o){var m=o.file,n;if(m){n=o.message;if(o.details){n+=" ("+o.details+")"}if(o.code==plupload.FILE_SIZE_ERROR){alert(a("Error: File to large: ")+m.name)}if(o.code==plupload.FILE_EXTENSION_ERROR){alert(a("Error: Invalid file extension: ")+m.name)}c("#"+m.id).attr("class","plupload_failed").find("a").css("display","block").attr("title",n)}});j.bind("StateChanged",function(){if(j.state===plupload.STARTED){c("li.plupload_delete a,div.plupload_buttons",i).hide();c("span.plupload_upload_status,div.plupload_progress,a.plupload_stop",i).css("display","block");c("span.plupload_upload_status",i).text("Uploaded 0/"+j.files.length+" files")}else{c("a.plupload_stop,div.plupload_progress",i).hide();c("a.plupload_delete",i).css("display","block")}});j.bind("QueueChanged",g);j.bind("StateChanged",function(l){if(l.state==plupload.STOPPED){g()}});j.bind("FileUploaded",function(l,m){h(m)});j.bind("UploadProgress",function(l,m){c("#"+m.id+" div.plupload_file_status",i).html(m.percent+"%");h(m);f()});if(e.setup){e.setup(j)}});return this}else{return d[c(this[0]).attr("id")]}}})(jQuery);
Index: typo3/js/extjs/PluploadWindow.js
===================================================================
--- typo3/js/extjs/PluploadWindow.js	(revision )
+++ typo3/js/extjs/PluploadWindow.js	(revision )
@@ -0,0 +1,104 @@
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2011 Christian M?ller <christian@kitsunet.de>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *  A copy is found in the textfile GPL.txt and important notices to the license
+ *  from the author is found in LICENSE.txt distributed with these scripts.
+ *
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+Ext.onReady(function() {
+	/**
+	 * Upload Window based on plupload.
+	 *
+	 * @author	Christian Müller <christian@kitsunet.de>
+	 */
+
+	TYPO3.PluploadWindow = new Ext.Window({
+			reloadWindow: false,
+			width: 600,
+			height: 350,
+			center: true,
+			modal: true,
+			id: 't3-plupload-window',
+			layout: 'fit',
+			title: String.format(top.TYPO3.LLL.fileUpload.windowTitle),
+			shadow: false,
+			hideBorders: true,
+			closeAction: 'hide',
+			items:[{
+				xtype: 'pluploadpanel',
+				id: 't3-plupload-panel',
+				layout:'fit',
+				url: top.TYPO3.configuration.PATH_typo3 + 'ajax.php',
+				runtimes: 'html5,flash,gears,html4',
+				multipart: true,
+				multipart_params: { },
+				file_data_name: 'upload_1',
+				max_file_size: '1mb',
+				flash_swf_url : top.TYPO3.configuration.PATH_typo3 + 'contrib/plupload/js/plupload.flash.swf',
+				runtime_visible: false,
+				addButtonText: top.TYPO3.LLL.fileUpload.buttonSelectFiles,
+				uploadButtonText: top.TYPO3.LLL.fileUpload.buttonStartUpload,
+				cancelButtonText: top.TYPO3.LLL.fileUpload.buttonCancelAll,
+				progressText: top.TYPO3.LLL.fileUpload.progressText,
+				emptyText: top.TYPO3.LLL.fileUpload.infoFileQueueEmpty,
+				statusQueuedText: top.TYPO3.LLL.fileUpload.infoFileQueued,
+				statusUploadingText: top.TYPO3.LLL.fileUpload.infoFileUploading,
+				statusFailedText: top.TYPO3.LLL.fileUpload.errorUploadFailed,
+				statusDoneText: top.TYPO3.LLL.fileUpload.infoFileFinished,
+				listeners: {
+					uploadfile: function(uploadpanel, uploader, file) {
+						var parameters = {
+							'file[upload][1][name]': file.name,
+							'file[upload][1][target]': top.TYPO3.configuration.FileUpload.targetDirectory,
+							'file[upload][1][data]': 1,
+							'file[upload][1][charset]': 'utf-8',
+							'ajaxID': 'TYPO3_tcefile::process',
+							'uploaderType': 'plupload',
+							"vC": top.TYPO3.configuration.veriCode
+						};
+						uploader.settings.max_file_size = top.TYPO3.configuration.FileUpload.maxFileSize+'b';
+						uploader.settings.multipart_params = parameters;
+					}
+				}
+			}],
+			listeners:{
+				hide: function(uploadwindow) {
+					Ext.getCmp('t3-plupload-panel').onCancel();
+					Ext.getCmp('t3-plupload-panel').onDeleteAll();
+				},
+				afterrender: function(uploadwindow) {
+					Ext.getCmp('t3-plupload-panel').uploader.settings.max_file_size = top.TYPO3.configuration.FileUpload.maxFileSize+'b';
+					Ext.getCmp('t3-plupload-panel').on('uploadcomplete', this.onUploadComplete);
+				}
+			},
+			onUploadComplete: function(uploadPanel, success, failed) {
+				if (failed.length == 0) {
+					var windowComponent = Ext.getCmp('t3-plupload-window');
+					windowComponent.hide();
+					if (windowComponent.reloadWindow) {
+						windowComponent.reloadWindow.location.reload();
+					}
+				}
+			}
+	});
+
+});
Index: typo3/contrib/plupload/js/plupload.browserplus.min.js
===================================================================
--- typo3/contrib/plupload/js/plupload.browserplus.min.js	(revision )
+++ typo3/contrib/plupload/js/plupload.browserplus.min.js	(revision )
@@ -0,0 +1,1 @@
+(function(a){a.runtimes.BrowserPlus=a.addRuntime("browserplus",{getFeatures:function(){return{dragdrop:true,jpgresize:true,pngresize:true,chunks:true,progress:true,multipart:true}},init:function(g,i){var e=window.BrowserPlus,h={},d=g.settings,c=d.resize;function f(n){var m,l,j=[],k,o;for(l=0;l<n.length;l++){k=n[l];o=a.guid();h[o]=k;j.push(new a.File(o,k.name,k.size))}if(l){g.trigger("FilesAdded",j)}}function b(){g.bind("PostInit",function(){var m,k=d.drop_element,o=g.id+"_droptarget",j=document.getElementById(k),l;function p(r,q){e.DragAndDrop.AddDropTarget({id:r},function(s){e.DragAndDrop.AttachCallbacks({id:r,hover:function(t){if(!t&&q){q()}},drop:function(t){if(q){q()}f(t)}},function(){})})}function n(){document.getElementById(o).style.top="-1000px"}if(j){if(document.attachEvent&&(/MSIE/gi).test(navigator.userAgent)){m=document.createElement("div");m.setAttribute("id",o);a.extend(m.style,{position:"absolute",top:"-1000px",background:"red",filter:"alpha(opacity=0)",opacity:0});document.body.appendChild(m);a.addEvent(j,"dragenter",function(r){var q,s;q=document.getElementById(k);s=a.getPos(q);a.extend(document.getElementById(o).style,{top:s.y+"px",left:s.x+"px",width:q.offsetWidth+"px",height:q.offsetHeight+"px"})});p(o,n)}else{p(k)}}a.addEvent(document.getElementById(d.browse_button),"click",function(v){var t=[],r,q,u=d.filters,s;v.preventDefault();for(r=0;r<u.length;r++){s=u[r].extensions.split(",");for(q=0;q<s.length;q++){t.push(a.mimeTypes[s[q]])}}e.FileBrowse.OpenBrowseDialog({mimeTypes:t},function(w){if(w.success){f(w.value)}})});j=m=null});g.bind("UploadFile",function(n,k){var m=h[k.id],j={},l=n.settings.chunk_size,o,p=[];function r(s,u){var t;if(k.status==a.FAILED){return}j.name=k.target_name||k.name;if(l){j.chunk=s;j.chunks=u}t=p.shift();e.Uploader.upload({url:a.buildUrl(n.settings.url,j),files:{file:t},cookies:document.cookies,postvars:n.settings.multipart_params,progressCallback:function(x){var w,v=0;o[s]=parseInt(x.filePercent*t.size/100,10);for(w=0;w<o.length;w++){v+=o[w]}k.loaded=v;n.trigger("UploadProgress",k)}},function(w){var v,x;if(w.success){v=w.value.statusCode;if(l){n.trigger("ChunkUploaded",k,{chunk:s,chunks:u,response:w.value.body,status:v})}if(p.length>0){r(++s,u)}else{k.status=a.DONE;n.trigger("FileUploaded",k,{response:w.value.body,status:v});if(v>=400){n.trigger("Error",{code:a.HTTP_ERROR,message:"HTTP Error.",file:k,status:v})}}}else{n.trigger("Error",{code:a.GENERIC_ERROR,message:"Generic Error.",file:k,details:w.error})}})}function q(s){k.size=s.size;if(l){e.FileAccess.chunk({file:s,chunkSize:l},function(v){if(v.success){var w=v.value,t=w.length;o=Array(t);for(var u=0;u<t;u++){o[u]=0;p.push(w[u])}r(0,t)}})}else{o=Array(1);p.push(s);r(0,1)}}if(c&&/\.(png|jpg|jpeg)$/i.test(k.name)){BrowserPlus.ImageAlter.transform({file:m,quality:c.quality||90,actions:[{scale:{maxwidth:c.width,maxheight:c.height}}]},function(s){if(s.success){q(s.value.file)}})}else{q(m)}});i({success:true})}if(e){e.init(function(k){var j=[{service:"Uploader",version:"3"},{service:"DragAndDrop",version:"1"},{service:"FileBrowse",version:"1"},{service:"FileAccess",version:"2"}];if(c){j.push({service:"ImageAlter",version:"4"})}if(k.success){e.require({services:j},function(l){if(l.success){b()}else{i()}})}else{i()}})}else{i()}}})})(plupload);
Index: typo3/backend.php
===================================================================
--- typo3/backend.php	(revision 9844)
+++ typo3/backend.php	(revision )
@@ -125,12 +125,15 @@
 			'swfupload.swfobject'   => 'contrib/swfupload/plugins/swfupload.swfobject.js',
 			'swfupload.cookies'     => 'contrib/swfupload/plugins/swfupload.cookies.js',
 			'swfupload.queue'       => 'contrib/swfupload/plugins/swfupload.queue.js',
+			'plupload'              => 'contrib/plupload/js/plupload.full.min.js',
 			'md5'                   => 'md5.js',
 			'common'                => 'js/common.js',
 			'toolbarmanager'        => 'js/toolbarmanager.js',
 			'modulemenu'            => 'js/modulemenu.js',
 			'iecompatibility'       => 'js/iecompatibility.js',
 			'flashupload'           => 'js/flashupload.js',
+			'pluploadPanel'         => 'js/extjs/ext.ux.plupload.js',
+			'pluploadWindow'        => 'js/extjs/PluploadWindow.js',
 			'evalfield'             => '../t3lib/jsfunc.evalfield.js',
 			'flashmessages'         => '../t3lib/js/extjs/ux/flashmessages.js',
 			'tabclosemenu'          => '../t3lib/js/extjs/ux/ext.ux.tabclosemenu.js',
@@ -458,6 +461,9 @@
 			'ContextHelpWindows' => array(
 				'width' => 600,
 				'height' => 400
+			),
+			'FileUpload' => array(
+				'maxFileSize' => t3lib_div::getMaxUploadFileSize()
 			)
 		);
 		$t3LLLcore = array(
@@ -493,11 +499,17 @@
 		$t3LLLfileUpload = array(
 			'windowTitle' => $GLOBALS['LANG']->getLL('fileUpload_windowTitle'),
 			'buttonSelectFiles' => $GLOBALS['LANG']->getLL('fileUpload_buttonSelectFiles'),
+			'buttonStartUpload' => $GLOBALS['LANG']->getLL('fileUpload_buttonStartUpload'),
 			'buttonCancelAll' => $GLOBALS['LANG']->getLL('fileUpload_buttonCancelAll'),
+			'progressText' => $GLOBALS['LANG']->getLL('fileUpload_progressText'),
 			'infoComponentMaxFileSize' => $GLOBALS['LANG']->getLL('fileUpload_infoComponentMaxFileSize'),
 			'infoComponentFileUploadLimit' => $GLOBALS['LANG']->getLL('fileUpload_infoComponentFileUploadLimit'),
 			'infoComponentFileTypeLimit' => $GLOBALS['LANG']->getLL('fileUpload_infoComponentFileTypeLimit'),
 			'infoComponentOverrideFiles' => $GLOBALS['LANG']->getLL('fileUpload_infoComponentOverrideFiles'),
+			'infoFileQueueEmpty' => $GLOBALS['LANG']->getLL('fileUpload_infoFileQueueEmpty'),
+			'infoFileQueued' => $GLOBALS['LANG']->getLL('fileUpload_infoFileQueued'),
+			'infoFileFinished' => $GLOBALS['LANG']->getLL('fileUpload_infoFileFinished'),
+			'infoFileUploading' => $GLOBALS['LANG']->getLL('fileUpload_infoFileQueued'),
 	 		'processRunning' => $GLOBALS['LANG']->getLL('fileUpload_processRunning'),
 			'uploadWait' => $GLOBALS['LANG']->getLL('fileUpload_uploadWait'),
 			'uploadStarting' => $GLOBALS['LANG']->getLL('fileUpload_uploadStarting'),
Index: typo3/contrib/plupload/js/plupload.gears.min.js
===================================================================
--- typo3/contrib/plupload/js/plupload.gears.min.js	(revision )
+++ typo3/contrib/plupload/js/plupload.gears.min.js	(revision )
@@ -0,0 +1,1 @@
+(function(b){var c={};function a(i,e,k,j,d){var l,g,f,h;g=google.gears.factory.create("beta.canvas");g.decode(i);h=Math.min(e/g.width,k/g.height);if(h<1){e=Math.round(g.width*h);k=Math.round(g.height*h)}else{e=g.width;k=g.height}g.resize(e,k);return g.encode(d,{quality:j/100})}b.runtimes.Gears=b.addRuntime("gears",{getFeatures:function(){return{dragdrop:true,jpgresize:true,pngresize:true,chunks:true,progress:true,multipart:true}},init:function(g,i){var h;if(!window.google||!google.gears){return i({success:false})}try{h=google.gears.factory.create("beta.desktop")}catch(f){return i({success:false})}function d(k){var j,e,l=[],m;for(e=0;e<k.length;e++){j=k[e];m=b.guid();c[m]=j.blob;l.push(new b.File(m,j.name,j.blob.length))}g.trigger("FilesAdded",l)}g.bind("PostInit",function(){var j=g.settings,e=document.getElementById(j.drop_element);if(e){b.addEvent(e,"dragover",function(k){h.setDropEffect(k,"copy");k.preventDefault()});b.addEvent(e,"drop",function(l){var k=h.getDragData(l,"application/x-gears-files");if(k){d(k.files)}l.preventDefault()});e=0}b.addEvent(document.getElementById(j.browse_button),"click",function(o){var n=[],l,k,m;o.preventDefault();for(l=0;l<j.filters.length;l++){m=j.filters[l].extensions.split(",");for(k=0;k<m.length;k++){n.push("."+m[k])}}h.openFiles(d,{singleFile:!j.multi_selection,filter:n})})});g.bind("UploadFile",function(o,l){var q=0,p,m,n=0,k=o.settings.resize,e;m=o.settings.chunk_size;e=m>0;p=Math.ceil(l.size/m);if(!e){m=l.size;p=1}if(k&&/\.(png|jpg|jpeg)$/i.test(l.name)){c[l.id]=a(c[l.id],k.width,k.height,k.quality||90,/\.png$/i.test(l.name)?"image/png":"image/jpeg")}l.size=c[l.id].length;function j(){var u,w,s=o.settings.multipart,r=0,v={name:l.target_name||l.name};function t(y){var x,C="----pluploadboundary"+b.guid(),A="--",B="\r\n",z;if(s){u.setRequestHeader("Content-Type","multipart/form-data; boundary="+C);x=google.gears.factory.create("beta.blobbuilder");b.each(o.settings.multipart_params,function(E,D){x.append(A+C+B+'Content-Disposition: form-data; name="'+D+'"'+B+B);x.append(E+B)});x.append(A+C+B+'Content-Disposition: form-data; name="'+o.settings.file_data_name+'"; filename="'+l.name+'"'+B+"Content-Type: application/octet-stream"+B+B);x.append(y);x.append(B+A+C+A+B);z=x.getAsBlob();r=z.length-y.length;y=z}u.send(y)}if(l.status==b.DONE||l.status==b.FAILED||o.state==b.STOPPED){return}if(e){v.chunk=q;v.chunks=p}w=Math.min(m,l.size-(q*m));u=google.gears.factory.create("beta.httprequest");u.open("POST",b.buildUrl(o.settings.url,v));if(!s){u.setRequestHeader("Content-Disposition",'attachment; filename="'+l.name+'"');u.setRequestHeader("Content-Type","application/octet-stream")}b.each(o.settings.headers,function(y,x){u.setRequestHeader(x,y)});u.upload.onprogress=function(x){l.loaded=n+x.loaded-r;o.trigger("UploadProgress",l)};u.onreadystatechange=function(){var x;if(u.readyState==4){if(u.status==200){x={chunk:q,chunks:p,response:u.responseText,status:u.status};o.trigger("ChunkUploaded",l,x);if(x.cancelled){l.status=b.FAILED;return}n+=w;if(++q>=p){l.status=b.DONE;o.trigger("FileUploaded",l,{response:u.responseText,status:u.status})}else{j()}}else{o.trigger("Error",{code:b.HTTP_ERROR,message:"HTTP Error.",file:l,chunk:q,chunks:p,status:u.status})}}};if(q<p){t(c[l.id].slice(q*m,w))}}j()});i({success:true})}})})(plupload);
Index: typo3/contrib/plupload/license.txt
===================================================================
--- typo3/contrib/plupload/license.txt	(revision )
+++ typo3/contrib/plupload/license.txt	(revision )
@@ -0,0 +1,339 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
Index: typo3/contrib/plupload/js/plupload.flash.min.js
===================================================================
--- typo3/contrib/plupload/js/plupload.flash.min.js	(revision )
+++ typo3/contrib/plupload/js/plupload.flash.min.js	(revision )
@@ -0,0 +1,1 @@
+(function(c){var a={};function b(){var d;try{d=navigator.plugins["Shockwave Flash"];d=d.description}catch(f){try{d=new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable("$version")}catch(e){d="0.0"}}d=d.match(/\d+/g);return parseFloat(d[0]+"."+d[1])}c.flash={trigger:function(f,d,e){setTimeout(function(){var j=a[f],h,g;if(j){j.trigger("Flash:"+d,e)}},0)}};c.runtimes.Flash=c.addRuntime("flash",{getFeatures:function(){return{jpgresize:true,pngresize:true,chunks:true,progress:true,multipart:true}},init:function(g,l){var k,f,h,e,m=0,d=document.body;if(b()<10){l({success:false});return}a[g.id]=g;k=document.getElementById(g.settings.browse_button);f=document.createElement("div");f.id=g.id+"_flash_container";c.extend(f.style,{position:"absolute",top:"0px",background:g.settings.shim_bgcolor||"transparent",zIndex:99999,width:"100%",height:"100%"});f.className="plupload flash";if(g.settings.container){d=document.getElementById(g.settings.container);d.style.position="relative"}d.appendChild(f);h="id="+escape(g.id);f.innerHTML='<object id="'+g.id+'_flash" width="100%" height="100%" style="outline:0" type="application/x-shockwave-flash" data="'+g.settings.flash_swf_url+'"><param name="movie" value="'+g.settings.flash_swf_url+'" /><param name="flashvars" value="'+h+'" /><param name="wmode" value="transparent" /><param name="allowscriptaccess" value="always" /></object>';function j(){return document.getElementById(g.id+"_flash")}function i(){if(m++>5000){l({success:false});return}if(!e){setTimeout(i,1)}}i();k=f=null;g.bind("Flash:Init",function(){var p={},o,n=g.settings.resize||{};e=true;j().setFileFilters(g.settings.filters,g.settings.multi_selection);g.bind("UploadFile",function(q,r){var s=q.settings;j().uploadFile(p[r.id],c.buildUrl(s.url,{name:r.target_name||r.name}),{chunk_size:s.chunk_size,width:n.width,height:n.height,quality:n.quality||90,multipart:s.multipart,multipart_params:s.multipart_params,file_data_name:s.file_data_name,format:/\.(jpg|jpeg)$/i.test(r.name)?"jpg":"png",headers:s.headers,urlstream_upload:s.urlstream_upload})});g.bind("Flash:UploadProcess",function(r,q){var s=r.getFile(p[q.id]);if(s.status!=c.FAILED){s.loaded=q.loaded;s.size=q.size;r.trigger("UploadProgress",s)}});g.bind("Flash:UploadChunkComplete",function(q,s){var t,r=q.getFile(p[s.id]);t={chunk:s.chunk,chunks:s.chunks,response:s.text};q.trigger("ChunkUploaded",r,t);if(r.status!=c.FAILED){j().uploadNextChunk()}if(s.chunk==s.chunks-1){r.status=c.DONE;q.trigger("FileUploaded",r,{response:s.text})}});g.bind("Flash:SelectFiles",function(q,t){var s,r,u=[],v;for(r=0;r<t.length;r++){s=t[r];v=c.guid();p[v]=s.id;p[s.id]=v;u.push(new c.File(v,s.name,s.size))}if(u.length){g.trigger("FilesAdded",u)}});g.bind("Flash:SecurityError",function(q,r){g.trigger("Error",{code:c.SECURITY_ERROR,message:"Security error.",details:r.message,file:g.getFile(p[r.id])})});g.bind("Flash:GenericError",function(q,r){g.trigger("Error",{code:c.GENERIC_ERROR,message:"Generic error.",details:r.message,file:g.getFile(p[r.id])})});g.bind("Flash:IOError",function(q,r){g.trigger("Error",{code:c.IO_ERROR,message:"IO error.",details:r.message,file:g.getFile(p[r.id])})});g.bind("QueueChanged",function(q){g.refresh()});g.bind("FilesRemoved",function(q,s){var r;for(r=0;r<s.length;r++){j().removeFile(p[s[r].id])}});g.bind("StateChanged",function(q){g.refresh()});g.bind("Refresh",function(q){var r,s,t;j().setFileFilters(g.settings.filters,g.settings.multi_selection);r=document.getElementById(q.settings.browse_button);s=c.getPos(r,document.getElementById(q.settings.container));t=c.getSize(r);c.extend(document.getElementById(q.id+"_flash_container").style,{top:s.y+"px",left:s.x+"px",width:t.w+"px",height:t.h+"px"})});l({success:true})})}})})(plupload);
