0&&navigator.vendor.indexOf("Apple")!==-1;return{html5:k,dragdrop:m.mozInnerScreenX!==c||j||d,jpgresize:l,pngresize:l,multipart:l||!!m.FileReader||!!m.FormData,progress:n,chunking:j||l,canOpenDialog:navigator.userAgent.indexOf("WebKit")!==-1}},init:function(m,n){var j={},k;function l(s){var q,p,r=[],t,o={};for(p=0;p";A=g.getElementById(m.id+"_html5");A.onchange=function(){l(this.files);this.value=""};B=g.getElementById(s.settings.browse_button);if(B){var u=s.settings.browse_button_hover,v=s.settings.browse_button_active,t=s.features.canOpenDialog?B:C;if(u){f.addEvent(t,"mouseover",function(){f.addClass(B,u)},s.id);f.addEvent(t,"mouseout",function(){f.removeClass(B,u)},s.id)}if(v){f.addEvent(t,"mousedown",function(){f.addClass(B,v)},s.id);f.addEvent(g.body,"mouseup",function(){f.removeClass(B,v)},s.id)}if(s.features.canOpenDialog){f.addEvent(B,"click",function(y){g.getElementById(s.id+"_html5").click();y.preventDefault()},s.id)}}});m.bind("PostInit",function(){var o=g.getElementById(m.settings.drop_element);if(o){if(d){f.addEvent(o,"dragenter",function(s){var r,p,q;r=g.getElementById(m.id+"_drop");if(!r){r=g.createElement("input");r.setAttribute("type","file");r.setAttribute("id",m.id+"_drop");r.setAttribute("multiple","multiple");f.addEvent(r,"change",function(){l(this.files);f.removeEvent(r,"change",m.id);r.parentNode.removeChild(r)},m.id);o.appendChild(r)}p=f.getPos(o,g.getElementById(m.settings.container));q=f.getSize(o);f.extend(o.style,{position:"relative"});f.extend(r.style,{position:"absolute",display:"block",top:0,left:0,width:q.w+"px",height:q.h+"px",opacity:0})},m.id);return}f.addEvent(o,"dragover",function(p){p.preventDefault()},m.id);f.addEvent(o,"drop",function(q){var p=q.dataTransfer;if(p&&p.files){l(p.files)}q.preventDefault()},m.id)}});m.bind("Refresh",function(o){var p,r,s,t,q;p=g.getElementById(m.settings.browse_button);if(p){r=f.getPos(p,g.getElementById(o.settings.container));s=f.getSize(p);t=g.getElementById(m.id+"_html5_container");f.extend(t.style,{top:r.y+"px",left:r.x+"px",width:s.w+"px",height:s.h+"px"});if(m.features.canOpenDialog){q=parseInt(p.parentNode.style.zIndex,10);if(isNaN(q)){q=0}f.extend(p.style,{position:"relative",zIndex:q});f.extend(t.style,{zIndex:q-1})}}});m.bind("UploadFile",function(o,q){var r=o.settings,t,p;function s(u){var x=0,w=0;function v(){var E=u,L,M,H,I,J=0,A="----pluploadboundary"+f.guid(),D,F,B,C="--",K="\r\n",G="",z,y=o.settings.url;if(q.status==f.DONE||q.status==f.FAILED||o.state==f.STOPPED){return}I={name:q.target_name||q.name};if(r.chunk_size&&k.chunking){D=r.chunk_size;H=Math.ceil(q.size/D);F=Math.min(D,q.size-(x*D));if(typeof(u)=="string"){E=u.substring(x*D,x*D+F)}else{E=u.slice(x*D,F)}I.chunk=x;I.chunks=H}else{F=q.size}L=new XMLHttpRequest();M=L.upload;if(M){M.onprogress=function(N){q.loaded=Math.min(q.size,w+N.loaded-J);o.trigger("UploadProgress",q)}}if(!o.settings.multipart||!k.multipart){y=f.buildUrl(o.settings.url,I)}else{I.name=q.target_name||q.name}L.open("post",y,true);L.onreadystatechange=function(){var N,P;if(L.readyState==4){try{N=L.status}catch(O){N=0}if(N>=400){o.trigger("Error",{code:f.HTTP_ERROR,message:f.translate("HTTP Error."),file:q,status:N})}else{if(H){P={chunk:x,chunks:H,response:L.responseText,status:N};o.trigger("ChunkUploaded",q,P);w+=F;if(P.cancelled){q.status=f.FAILED;return}q.loaded=Math.min(q.size,(x+1)*D)}else{q.loaded=q.size}o.trigger("UploadProgress",q);if(!H||++x>=H){q.status=f.DONE;o.trigger("FileUploaded",q,{response:L.responseText,status:N});t=u=j[q.id]=null}else{v()}}L=E=B=G=null}};f.each(o.settings.headers,function(O,N){L.setRequestHeader(N,O)});if(o.settings.multipart&&k.multipart){if(!L.sendAsBinary){B=new FormData();f.each(f.extend(I,o.settings.multipart_params),function(O,N){B.append(N,O)});B.append(o.settings.file_data_name,E);L.send(B);return}L.setRequestHeader("Content-Type","multipart/form-data; boundary="+A);f.each(f.extend(I,o.settings.multipart_params),function(O,N){G+=C+A+K+'Content-Disposition: form-data; name="'+N+'"'+K+K;G+=unescape(encodeURIComponent(O))+K});z=f.mimeTypes[q.name.replace(/^.+\.([^.]+)/,"$1")]||"application/octet-stream";G+=C+A+K+'Content-Disposition: form-data; name="'+o.settings.file_data_name+'"; filename="'+unescape(encodeURIComponent(q.name))+'"'+K+"Content-Type: "+z+K+K+E+K+C+A+C+K;J=G.length-E.length;E=G}else{L.setRequestHeader("Content-Type","application/octet-stream")}if(L.sendAsBinary){L.sendAsBinary(E)}else{L.send(E)}}v()}t=j[q.id];p=o.settings.resize;if(k.jpgresize){if(p&&/\.(png|jpg|jpeg)$/i.test(q.name)){b(t,p.width,p.height,/\.png$/i.test(q.name)?"image/png":"image/jpeg",function(u){if(u.success){q.size=u.data.length;s(u.data)}else{h(t,s)}})}else{h(t,s)}}else{s(t)}});m.bind("Destroy",function(o){var q,r,p=g.body,s={inputContainer:o.id+"_html5_container",inputFile:o.id+"_html5",browseButton:o.settings.browse_button,dropElm:o.settings.drop_element};for(q in s){r=g.getElementById(s[q]);if(r){f.removeAllEvents(r,o.id)}}f.removeAllEvents(g.body,o.id);if(o.settings.container){p=g.getElementById(o.settings.container)}p.removeChild(g.getElementById(s.inputContainer))});n({success:true})}});a=function(){var l,m,B,v,w,q,u,x,G,s,D,z,n,F,j,E,C,o,k;function r(){var K=false,I;function L(N,P){var M=K?0:-8*(P-1),Q=0,O;for(O=0;O>Math.abs(M+P*8))&255)}H(N,R,true)}return{II:function(M){if(M===j){return K}else{K=M}},init:function(M){I=M},SEGMENT:function(M,O,N){if(!arguments.length){return I}if(typeof O=="number"){return I.substr(parseInt(M,10),O)}H(M,O,N)},BYTE:function(M){return L(M,1)},SHORT:function(M){return L(M,2)},LONG:function(M,N){if(N===j){return L(M,4)}else{J(M,N,4)}},SLONG:function(M){var N=L(M,4);return(N>2147483647?N-4294967296:N)},STRING:function(M,N){var O="";for(N+=M;M4){K=G.LONG(K)+F}for(R=0;R4){K=G.LONG(K)+F}S[T]=G.STRING(K,M-1);continue;case 3:if(M>2){K=G.LONG(K)+F}for(R=0;R1){K=G.LONG(K)+F}for(R=0;R';n=i.firstChild;j.appendChild(n);b.addEvent(n,"load",function(C){var D=C.target,B,y;if(!k){return}try{B=D.contentWindow.document||D.contentDocument||d.frames[D.id].document}catch(A){p.trigger("Error",{code:b.SECURITY_ERROR,message:b.translate("Security error."),file:k});return}y=B.documentElement.innerText||B.documentElement.textContent;if(y){k.status=b.DONE;k.loaded=1025;k.percent=100;p.trigger("UploadProgress",k);p.trigger("FileUploaded",k,{response:y})}},p.id)}if(p.settings.container){j=e(p.settings.container);j.style.position="relative"}p.bind("UploadFile",function(i,A){var B,y;if(A.status==b.DONE||A.status==b.FAILED||i.state==b.STOPPED){return}B=e("form_"+A.id);y=e("input_"+A.id);y.setAttribute("name",i.settings.file_data_name);B.setAttribute("action",i.settings.url);b.each(b.extend({name:A.target_name||A.name},i.settings.multipart_params),function(E,C){var D=a.createElement("input");b.extend(D,{type:"hidden",name:C,value:E});B.insertBefore(D,B.firstChild)});k=A;e("form_"+q).style.top=-1048575+"px";B.submit();B.parentNode.removeChild(B)});p.bind("FileUploaded",function(i){i.refresh()});p.bind("StateChanged",function(i){if(i.state==b.STARTED){u()}if(i.state==b.STOPPED){d.setTimeout(function(){b.removeEvent(n,"load",i.id);n.parentNode.removeChild(n)},0)}});p.bind("Refresh",function(A){var F,B,C,D,i,G,H,E,y;F=e(A.settings.browse_button);if(F){i=b.getPos(F,e(A.settings.container));G=b.getSize(F);H=e("form_"+q);E=e("input_"+q);b.extend(H.style,{top:i.y+"px",left:i.x+"px",width:G.w+"px",height:G.h+"px"});if(A.features.canOpenDialog){y=parseInt(F.parentNode.style.zIndex,10);if(isNaN(y)){y=0}b.extend(F.style,{position:"relative",zIndex:y});b.extend(H.style,{zIndex:y-1})}C=A.settings.browse_button_hover;D=A.settings.browse_button_active;B=A.features.canOpenDialog?F:H;if(C){b.addEvent(B,"mouseover",function(){b.addClass(F,C)},A.id);b.addEvent(B,"mouseout",function(){b.removeClass(F,C)},A.id)}if(D){b.addEvent(B,"mousedown",function(){b.addClass(F,D)},A.id);b.addEvent(a.body,"mouseup",function(){b.removeClass(F,D)},A.id)}}});f.bind("FilesRemoved",function(y,B){var A,C;for(A=0;A0;s=Math.ceil(o.size/p);if(!l){p=o.size;s=1}function m(){var y,A,v=r.settings.multipart,u=0,z={name:o.target_name||o.name},w=r.settings.url;function x(C){var B,H="----pluploadboundary"+c.guid(),E="--",G="\r\n",D,F;if(v){y.setRequestHeader("Content-Type","multipart/form-data; boundary="+H);B=google.gears.factory.create("beta.blobbuilder");c.each(c.extend(z,r.settings.multipart_params),function(J,I){B.append(E+H+G+'Content-Disposition: form-data; name="'+I+'"'+G+G);B.append(J+G)});F=c.mimeTypes[o.name.replace(/^.+\.([^.]+)/,"$1")]||"application/octet-stream";B.append(E+H+G+'Content-Disposition: form-data; name="'+r.settings.file_data_name+'"; filename="'+o.name+'"'+G+"Content-Type: "+F+G+G);B.append(C);B.append(G+E+H+E+G);D=B.getAsBlob();u=D.length-C.length;C=D}y.send(C)}if(o.status==c.DONE||o.status==c.FAILED||r.state==c.STOPPED){return}if(l){z.chunk=t;z.chunks=s}A=Math.min(p,o.size-(t*p));if(!v){w=c.buildUrl(r.settings.url,z)}y=google.gears.factory.create("beta.httprequest");y.open("POST",w);if(!v){y.setRequestHeader("Content-Disposition",'attachment; filename="'+o.name+'"');y.setRequestHeader("Content-Type","application/octet-stream")}c.each(r.settings.headers,function(C,B){y.setRequestHeader(B,C)});y.upload.onprogress=function(B){o.loaded=q+B.loaded-u;r.trigger("UploadProgress",o)};y.onreadystatechange=function(){var B;if(y.readyState==4){if(y.status==200){B={chunk:t,chunks:s,response:y.responseText,status:y.status};r.trigger("ChunkUploaded",o,B);if(B.cancelled){o.status=c.FAILED;return}q+=A;if(++t>=s){o.status=c.DONE;r.trigger("FileUploaded",o,{response:y.responseText,status:y.status})}else{m()}}else{r.trigger("Error",{code:c.HTTP_ERROR,message:c.translate("HTTP Error."),file:o,chunk:t,chunks:s,status:y.status})}}};if(t';n=i.firstChild;j.appendChild(n);b.addEvent(n,"load",function(C){var D=C.target,B,y;if(!k){return}try{B=D.contentWindow.document||D.contentDocument||d.frames[D.id].document}catch(A){p.trigger("Error",{code:b.SECURITY_ERROR,message:b.translate("Security error."),file:k});return}y=B.documentElement.innerText||B.documentElement.textContent;if(y){k.status=b.DONE;k.loaded=1025;k.percent=100;p.trigger("UploadProgress",k);p.trigger("FileUploaded",k,{response:y})}},p.id)}if(p.settings.container){j=e(p.settings.container);j.style.position="relative"}p.bind("UploadFile",function(i,A){var B,y;if(A.status==b.DONE||A.status==b.FAILED||i.state==b.STOPPED){return}B=e("form_"+A.id);y=e("input_"+A.id);y.setAttribute("name",i.settings.file_data_name);B.setAttribute("action",i.settings.url);b.each(b.extend({name:A.target_name||A.name},i.settings.multipart_params),function(E,C){var D=a.createElement("input");b.extend(D,{type:"hidden",name:C,value:E});B.insertBefore(D,B.firstChild)});k=A;e("form_"+q).style.top=-1048575+"px";B.submit();B.parentNode.removeChild(B)});p.bind("FileUploaded",function(i){i.refresh()});p.bind("StateChanged",function(i){if(i.state==b.STARTED){u()}if(i.state==b.STOPPED){d.setTimeout(function(){b.removeEvent(n,"load",i.id);n.parentNode.removeChild(n)},0)}});p.bind("Refresh",function(A){var F,B,C,D,i,G,H,E,y;F=e(A.settings.browse_button);if(F){i=b.getPos(F,e(A.settings.container));G=b.getSize(F);H=e("form_"+q);E=e("input_"+q);b.extend(H.style,{top:i.y+"px",left:i.x+"px",width:G.w+"px",height:G.h+"px"});if(A.features.canOpenDialog){y=parseInt(F.parentNode.style.zIndex,10);if(isNaN(y)){y=0}b.extend(F.style,{position:"relative",zIndex:y});b.extend(H.style,{zIndex:y-1})}C=A.settings.browse_button_hover;D=A.settings.browse_button_active;B=A.features.canOpenDialog?F:H;if(C){b.addEvent(B,"mouseover",function(){b.addClass(F,C)},A.id);b.addEvent(B,"mouseout",function(){b.removeClass(F,C)},A.id)}if(D){b.addEvent(B,"mousedown",function(){b.addClass(F,D)},A.id);b.addEvent(a.body,"mouseup",function(){b.removeClass(F,D)},A.id)}}});f.bind("FilesRemoved",function(y,B){var A,C;for(A=0;A0&&navigator.vendor.indexOf("Apple")!==-1;return{html5:k,dragdrop:m.mozInnerScreenX!==c||j||d,jpgresize:l,pngresize:l,multipart:l||!!m.FileReader||!!m.FormData,progress:n,chunking:j||l,canOpenDialog:navigator.userAgent.indexOf("WebKit")!==-1}},init:function(m,n){var j={},k;function l(s){var q,p,r=[],t,o={};for(p=0;p";A=g.getElementById(m.id+"_html5");A.onchange=function(){l(this.files);this.value=""};B=g.getElementById(s.settings.browse_button);if(B){var u=s.settings.browse_button_hover,v=s.settings.browse_button_active,t=s.features.canOpenDialog?B:C;if(u){f.addEvent(t,"mouseover",function(){f.addClass(B,u)},s.id);f.addEvent(t,"mouseout",function(){f.removeClass(B,u)},s.id)}if(v){f.addEvent(t,"mousedown",function(){f.addClass(B,v)},s.id);f.addEvent(g.body,"mouseup",function(){f.removeClass(B,v)},s.id)}if(s.features.canOpenDialog){f.addEvent(B,"click",function(y){g.getElementById(s.id+"_html5").click();y.preventDefault()},s.id)}}});m.bind("PostInit",function(){var o=g.getElementById(m.settings.drop_element);if(o){if(d){f.addEvent(o,"dragenter",function(s){var r,p,q;r=g.getElementById(m.id+"_drop");if(!r){r=g.createElement("input");r.setAttribute("type","file");r.setAttribute("id",m.id+"_drop");r.setAttribute("multiple","multiple");f.addEvent(r,"change",function(){l(this.files);f.removeEvent(r,"change",m.id);r.parentNode.removeChild(r)},m.id);o.appendChild(r)}p=f.getPos(o,g.getElementById(m.settings.container));q=f.getSize(o);f.extend(o.style,{position:"relative"});f.extend(r.style,{position:"absolute",display:"block",top:0,left:0,width:q.w+"px",height:q.h+"px",opacity:0})},m.id);return}f.addEvent(o,"dragover",function(p){p.preventDefault()},m.id);f.addEvent(o,"drop",function(q){var p=q.dataTransfer;if(p&&p.files){l(p.files)}q.preventDefault()},m.id)}});m.bind("Refresh",function(o){var p,r,s,t,q;p=g.getElementById(m.settings.browse_button);if(p){r=f.getPos(p,g.getElementById(o.settings.container));s=f.getSize(p);t=g.getElementById(m.id+"_html5_container");f.extend(t.style,{top:r.y+"px",left:r.x+"px",width:s.w+"px",height:s.h+"px"});if(m.features.canOpenDialog){q=parseInt(p.parentNode.style.zIndex,10);if(isNaN(q)){q=0}f.extend(p.style,{position:"relative",zIndex:q});f.extend(t.style,{zIndex:q-1})}}});m.bind("UploadFile",function(o,q){var r=o.settings,t,p;function s(u){var x=0,w=0;function v(){var E=u,L,M,H,I,J=0,A="----pluploadboundary"+f.guid(),D,F,B,C="--",K="\r\n",G="",z,y=o.settings.url;if(q.status==f.DONE||q.status==f.FAILED||o.state==f.STOPPED){return}I={name:q.target_name||q.name};if(r.chunk_size&&k.chunking){D=r.chunk_size;H=Math.ceil(q.size/D);F=Math.min(D,q.size-(x*D));if(typeof(u)=="string"){E=u.substring(x*D,x*D+F)}else{E=u.slice(x*D,F)}I.chunk=x;I.chunks=H}else{F=q.size}L=new XMLHttpRequest();M=L.upload;if(M){M.onprogress=function(N){q.loaded=Math.min(q.size,w+N.loaded-J);o.trigger("UploadProgress",q)}}if(!o.settings.multipart||!k.multipart){y=f.buildUrl(o.settings.url,I)}else{I.name=q.target_name||q.name}L.open("post",y,true);L.onreadystatechange=function(){var N,P;if(L.readyState==4){try{N=L.status}catch(O){N=0}if(N>=400){o.trigger("Error",{code:f.HTTP_ERROR,message:f.translate("HTTP Error."),file:q,status:N})}else{if(H){P={chunk:x,chunks:H,response:L.responseText,status:N};o.trigger("ChunkUploaded",q,P);w+=F;if(P.cancelled){q.status=f.FAILED;return}q.loaded=Math.min(q.size,(x+1)*D)}else{q.loaded=q.size}o.trigger("UploadProgress",q);if(!H||++x>=H){q.status=f.DONE;o.trigger("FileUploaded",q,{response:L.responseText,status:N});t=u=j[q.id]=null}else{v()}}L=E=B=G=null}};f.each(o.settings.headers,function(O,N){L.setRequestHeader(N,O)});if(o.settings.multipart&&k.multipart){if(!L.sendAsBinary){B=new FormData();f.each(f.extend(I,o.settings.multipart_params),function(O,N){B.append(N,O)});B.append(o.settings.file_data_name,E);L.send(B);return}L.setRequestHeader("Content-Type","multipart/form-data; boundary="+A);f.each(f.extend(I,o.settings.multipart_params),function(O,N){G+=C+A+K+'Content-Disposition: form-data; name="'+N+'"'+K+K;G+=unescape(encodeURIComponent(O))+K});z=f.mimeTypes[q.name.replace(/^.+\.([^.]+)/,"$1")]||"application/octet-stream";G+=C+A+K+'Content-Disposition: form-data; name="'+o.settings.file_data_name+'"; filename="'+unescape(encodeURIComponent(q.name))+'"'+K+"Content-Type: "+z+K+K+E+K+C+A+C+K;J=G.length-E.length;E=G}else{L.setRequestHeader("Content-Type","application/octet-stream")}if(L.sendAsBinary){L.sendAsBinary(E)}else{L.send(E)}}v()}t=j[q.id];p=o.settings.resize;if(k.jpgresize){if(p&&/\.(png|jpg|jpeg)$/i.test(q.name)){b(t,p.width,p.height,/\.png$/i.test(q.name)?"image/png":"image/jpeg",function(u){if(u.success){q.size=u.data.length;s(u.data)}else{h(t,s)}})}else{h(t,s)}}else{s(t)}});m.bind("Destroy",function(o){var q,r,p=g.body,s={inputContainer:o.id+"_html5_container",inputFile:o.id+"_html5",browseButton:o.settings.browse_button,dropElm:o.settings.drop_element};for(q in s){r=g.getElementById(s[q]);if(r){f.removeAllEvents(r,o.id)}}f.removeAllEvents(g.body,o.id);if(o.settings.container){p=g.getElementById(o.settings.container)}p.removeChild(g.getElementById(s.inputContainer))});n({success:true})}});a=function(){var l,m,B,v,w,q,u,x,G,s,D,z,n,F,j,E,C,o,k;function r(){var K=false,I;function L(N,P){var M=K?0:-8*(P-1),Q=0,O;for(O=0;O>Math.abs(M+P*8))&255)}H(N,R,true)}return{II:function(M){if(M===j){return K}else{K=M}},init:function(M){I=M},SEGMENT:function(M,O,N){if(!arguments.length){return I}if(typeof O=="number"){return I.substr(parseInt(M,10),O)}H(M,O,N)},BYTE:function(M){return L(M,1)},SHORT:function(M){return L(M,2)},LONG:function(M,N){if(N===j){return L(M,4)}else{J(M,N,4)}},SLONG:function(M){var N=L(M,4);return(N>2147483647?N-4294967296:N)},STRING:function(M,N){var O="";for(N+=M;M4){K=G.LONG(K)+F}for(R=0;R4){K=G.LONG(K)+F}S[T]=G.STRING(K,M-1);continue;case 3:if(M>2){K=G.LONG(K)+F}for(R=0;R1){K=G.LONG(K)+F}for(R=0;R":"gt","&":"amp",'"':"quot","'":"#39"},l=/[<>&\"\']/g,b,c=window.setTimeout,d={},e;function h(){this.returnValue=false}function j(){this.cancelBubble=true}(function(n){var o=n.split(/,/),p,r,q;for(p=0;p0){g.each(o,function(r,q){n[q]=r})}});return n},cleanName:function(n){var o,p;p=[/[\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(o=0;o0?"&":"?")+p}return o},each:function(q,r){var p,o,n;if(q){p=q.length;if(p===b){for(o in q){if(q.hasOwnProperty(o)){if(r(q[o],o)===false){return}}}}else{for(n=0;n1073741824){return Math.round(n/1073741824,1)+" GB"}if(n>1048576){return Math.round(n/1048576,1)+" MB"}if(n>1024){return Math.round(n/1024,1)+" KB"}return n+" b"},getPos:function(o,s){var t=0,r=0,v,u=document,p,q;o=o;s=s||u.body;function n(B){var z,A,w=0,C=0;if(B){A=B.getBoundingClientRect();z=u.compatMode==="CSS1Compat"?u.documentElement:u.body;w=A.left+z.scrollLeft;C=A.top+z.scrollTop}return{x:w,y:C}}if(o&&o.getBoundingClientRect&&(navigator.userAgent.indexOf("MSIE")>0&&u.documentMode!==8)){p=n(o);q=n(s);return{x:p.x-q.x,y:p.y-q.y}}v=o;while(v&&v!=s&&v.nodeType){t+=v.offsetLeft||0;r+=v.offsetTop||0;v=v.offsetParent}v=o.parentNode;while(v&&v!=s&&v.nodeType){t-=v.scrollLeft||0;r-=v.scrollTop||0;v=v.parentNode}return{x:t,y:r}},getSize:function(n){return{w:n.offsetWidth||n.clientWidth,h:n.offsetHeight||n.clientHeight}},parseSize:function(n){var o;if(typeof(n)=="string"){n=/^([0-9]+)([mgk]+)$/.exec(n.toLowerCase().replace(/[^0-9mkg]/g,""));o=n[2];n=+n[1];if(o=="g"){n*=1073741824}if(o=="m"){n*=1048576}if(o=="k"){n*=1024}}return n},xmlEncode:function(n){return n?(""+n).replace(l,function(o){return a[o]?"&"+a[o]+";":o}):n},toArray:function(p){var o,n=[];for(o=0;o
=0;p--){if(r[p].key===q||r[p].orig===u){if(t.detachEvent){t.detachEvent("on"+o,r[p].func)}else{if(t.removeEventListener){t.removeEventListener(o,r[p].func,false)}}r[p].orig=null;r[p].func=null;r.splice(p,1);if(u!==b){break}}}if(!r.length){delete d[t[e]][o]}if(n(d[t[e]])){delete d[t[e]];try{delete t[e]}catch(s){t[e]=b}}},removeAllEvents:function(o){var n=arguments[1];if(o[e]===b||!o[e]){return}g.each(d[o[e]],function(q,p){g.removeEvent(o,p,n)})}};g.Uploader=function(q){var o={},t,s=[],p;t=new g.QueueProgress();q=g.extend({chunk_size:0,multipart:true,multi_selection:true,file_data_name:"file",filters:[]},q);function r(){var v,w=0,u;if(this.state==g.STARTED){for(u=0;u0?Math.ceil(t.uploaded/s.length*100):0}else{t.bytesPerSec=Math.ceil(t.loaded/((+new Date()-p||1)/1000));t.percent=t.size>0?Math.ceil(t.loaded/t.size*100):0}}g.extend(this,{state:g.STOPPED,runtime:"",features:{},files:s,settings:q,total:t,id:g.guid(),init:function(){var z=this,A,w,v,y=0,x;if(typeof(q.preinit)=="function"){q.preinit(z)}else{g.each(q.preinit,function(C,B){z.bind(B,C)})}q.page_url=q.page_url||document.location.pathname.replace(/\/[^\/]+$/g,"/");if(!/^(\w+:\/\/|\/)/.test(q.url)){q.url=q.page_url+q.url}q.chunk_size=g.parseSize(q.chunk_size);q.max_file_size=g.parseSize(q.max_file_size);z.bind("FilesAdded",function(B,E){var D,C,G=0,H,F=q.filters;if(F&&F.length){H=[];g.each(F,function(I){g.each(I.extensions.split(/,/),function(J){H.push("\\."+J.replace(new RegExp("["+("/^$.*+?|()[]{}\\".replace(/./g,"\\$&"))+"]","g"),"\\$&"))})});H=new RegExp(H.join("|")+"$","i")}for(D=0;Dq.max_file_size){B.trigger("Error",{code:g.FILE_SIZE_ERROR,message:g.translate("File size error."),file:C});continue}s.push(C);G++}if(G){c(function(){z.trigger("QueueChanged");z.refresh()},1)}else{return false}});if(q.unique_names){z.bind("UploadFile",function(B,C){var E=C.name.match(/\.([^.]+)$/),D="tmp";if(E){D=E[1]}C.target_name=C.id+"."+D})}z.bind("UploadProgress",function(B,C){C.percent=C.size>0?Math.ceil(C.loaded/C.size*100):100;n()});z.bind("StateChanged",function(B){if(B.state==g.STARTED){p=(+new Date())}});z.bind("QueueChanged",n);z.bind("Error",function(B,C){if(C.file){C.file.status=g.FAILED;n();if(B.state==g.STARTED){c(function(){r.call(z)},1)}}});z.bind("FileUploaded",function(B,C){C.status=g.DONE;C.loaded=C.size;B.trigger("UploadProgress",C);c(function(){r.call(z)},1)});if(q.runtimes){w=[];x=q.runtimes.split(/\s?,\s?/);for(A=0;A=0;u--){if(s[u].id===v){return s[u]}}},removeFile:function(v){var u;for(u=s.length-1;u>=0;u--){if(s[u].id===v.id){return this.splice(u,1)[0]}}},splice:function(w,u){var v;v=s.splice(w===b?0:w,u===b?s.length:u);this.trigger("FilesRemoved",v);this.trigger("QueueChanged");return v},trigger:function(v){var x=o[v.toLowerCase()],w,u;if(x){u=Array.prototype.slice.call(arguments);u[0]=this;for(w=0;w=0;v--){if(x[v].func===w){x.splice(v,1);break}}}else{x=[]}if(!x.length){delete o[u]}}},unbindAll:function(){var u=this;g.each(o,function(w,v){u.unbind(v)})},destroy:function(){this.trigger("Destroy");this.unbindAll()}})};g.File=function(q,o,p){var n=this;n.id=q;n.name=o;n.size=p;n.loaded=0;n.percent=0;n.status=0};g.Runtime=function(){this.getFeatures=function(){};this.init=function(n,o){}};g.QueueProgress=function(){var n=this;n.size=0;n.loaded=0;n.uploaded=0;n.failed=0;n.queued=0;n.percent=0;n.bytesPerSec=0;n.reset=function(){n.size=n.loaded=n.uploaded=n.failed=n.queued=n.percent=n.bytesPerSec=0}};g.runtimes={};window.plupload=g})();
\ No newline at end of file
diff --git a/assets/javascripts/plupload/plupload.silverlight.min.js b/assets/javascripts/plupload/plupload.silverlight.min.js
new file mode 100644
index 00000000..7e520f5e
--- /dev/null
+++ b/assets/javascripts/plupload/plupload.silverlight.min.js
@@ -0,0 +1 @@
+(function(g,b,d,e){var a={},h={};function c(o){var n,m=typeof o,j,l,k;if(m==="string"){n="\bb\tt\nn\ff\rr\"\"''\\\\";return'"'+o.replace(/([\u0080-\uFFFF\x00-\x1f\"])/g,function(q,p){var i=n.indexOf(p);if(i+1){return"\\"+n.charAt(i+1)}q=p.charCodeAt().toString(16);return"\\u"+"0000".substring(q.length)+q})+'"'}if(m=="object"){j=o.length!==e;n="";if(j){for(l=0;l3){k.pop()}while(k.length<4){k.push(0)}l=r.split(".");while(l.length>4){l.pop()}do{t=parseInt(l[p],10);m=parseInt(k[p],10);p++}while(p8?"":0.01});o.className="plupload silverlight";if(p.settings.container){k=b.getElementById(p.settings.container);k.style.position="relative"}k.appendChild(o);for(l=0;l';function j(){return b.getElementById(p.id+"_silverlight").content.Upload}p.bind("Silverlight:Init",function(){var i,r={};if(h[p.id]){return}h[p.id]=true;p.bind("Silverlight:StartSelectFiles",function(s){i=[]});p.bind("Silverlight:SelectFile",function(s,v,t,u){var w;w=d.guid();r[w]=v;r[v]=w;i.push(new d.File(w,t,u))});p.bind("Silverlight:SelectSuccessful",function(){if(i.length){p.trigger("FilesAdded",i)}});p.bind("Silverlight:UploadChunkError",function(s,v,t,w,u){p.trigger("Error",{code:d.IO_ERROR,message:"IO Error.",details:u,file:s.getFile(r[v])})});p.bind("Silverlight:UploadFileProgress",function(s,w,t,v){var u=s.getFile(r[w]);if(u.status!=d.FAILED){u.size=v;u.loaded=t;s.trigger("UploadProgress",u)}});p.bind("Refresh",function(s){var t,u,v;t=b.getElementById(s.settings.browse_button);if(t){u=d.getPos(t,b.getElementById(s.settings.container));v=d.getSize(t);d.extend(b.getElementById(s.id+"_silverlight_container").style,{top:u.y+"px",left:u.x+"px",width:v.w+"px",height:v.h+"px"})}});p.bind("Silverlight:UploadChunkSuccessful",function(s,v,t,y,x){var w,u=s.getFile(r[v]);w={chunk:t,chunks:y,response:x};s.trigger("ChunkUploaded",u,w);if(u.status!=d.FAILED){j().UploadNextChunk()}if(t==y-1){u.status=d.DONE;s.trigger("FileUploaded",u,{response:x})}});p.bind("Silverlight:UploadSuccessful",function(s,v,t){var u=s.getFile(r[v]);u.status=d.DONE;s.trigger("FileUploaded",u,{response:t})});p.bind("FilesRemoved",function(s,u){var t;for(t=0;t false
+ t.text :description
+ t.references :project, :null => false
+ t.references :dmsf_folder
+
+ t.boolean :notification, :default => false, :null => false
+
+ t.references :user, :null => false
+ t.timestamps
+ end
+
+ create_table :dmsf_files do |t|
+ t.string :name, :null => false
+ t.references :project, :null => false
+ t.references :dmsf_folder
+
+ t.boolean :notification, :default => false, :null => false
+
+ t.boolean :deleted, :default => false, :null => false
+ t.integer :deleted_by_user_id
+
+ t.timestamps
+ end
+
+ create_table :dmsf_file_revisions do |t|
+ t.references :dmsf_file, :null => false
+ t.string :disk_filename, :null => false
+
+ t.string :name, :null => false
+ t.references :dmsf_folder
+
+ t.integer :size
+ t.string :mime_type
+ t.string :title
+ t.text :description
+ t.references :user, :null => false
+
+ t.integer :workflow
+
+ t.text :comment
+ t.integer :major_version, :null => false
+ t.integer :minor_version, :null => false
+
+ t.integer :source_dmsf_file_revision_id
+
+ t.boolean :deleted, :default => false, :null => false
+ t.integer :deleted_by_user_id
+
+ t.timestamps
+ end
+
+ create_table :dmsf_file_locks do |t|
+ t.references :dmsf_file, :null => false
+ t.boolean :locked, :default => false, :null => false
+ t.references :user, :null => false
+ t.timestamps
+ end
+
+ create_table :dmsf_user_prefs do |t|
+ t.references :project, :null => false
+ t.references :user, :null => false
+
+ t.boolean :email_notify
+
+ t.timestamps
+ end
+
+ end
+
+ def self.down
+ drop_table :dmsf_file_revisions
+ drop_table :dmsf_files
+ drop_table :dmsf_folders
+ end
+end
diff --git a/init.rb b/init.rb
new file mode 100644
index 00000000..e9bd1c7e
--- /dev/null
+++ b/init.rb
@@ -0,0 +1,60 @@
+require 'redmine'
+
+Redmine::Plugin.register :redmine_dmsf do
+ name "DMSF"
+ author "Vít Jonáš"
+ description "Document Management System Features for Redmine"
+ version "0.5.0"
+ url "https://code.google.com/p/redmine-dmsf/"
+ author_url "mailto:vit.jonas@kontron-czech.com"
+
+ settings :partial => 'settings/dmsf_settings',
+ :default => {
+ "dmsf_max_file_download" => "0",
+ "dmsf_storage_directory" => "#{RAILS_ROOT}/files/dmsf",
+ "dmsf_index_database" => "#{RAILS_ROOT}/files/dmsf_index",
+ "dmsf_stemming_lang" => "english",
+ "dmsf_stemming_strategy" => "STEM_NONE"
+ }
+
+ menu :project_menu, :dmsf, { :controller => 'dmsf', :action => 'index' }, :caption => 'DMSF', :after => :activity, :param => :id
+ #delete_menu_item :project_menu, :documents
+
+ activity_provider :dmsf_files, :class_name => "DmsfFileRevision", :default => true
+
+ project_module :dmsf do
+ permission :browse_documents, {:dmsf => [:index]}
+ permission :user_preferences, {:dmsf_state => [:user_pref]}
+ permission :view_dmsf_files, {:dmsf => [:download_file, :download_revision, :entries_operation, :email_entries_send],
+ :dmsf_detail => [:file_detail]}
+ permission :folder_manipulation, {:dmsf_detail => [:create_folder, :delete_folder, :folder_detail, :save_folder]}
+ permission :file_manipulation, {:dmsf_detail => [:upload_files, :upload_file, :commit_files, :save_file, :delete_file],
+ :dmsf_state => [:lock_file, :unlock_file]}
+ permission :file_approval, {:dmsf_detail => [:approve_file, :delete_revision],
+ :dmsf_state => [:file_notify_activate, :file_notify_deactivate, :folder_notify_activate, :folder_notify_deactivate]}
+ permission :force_file_unlock, {:dmsf_state => [:force_file_unlock]}
+ end
+
+ Redmine::WikiFormatting::Macros.register do
+ desc "Wiki link to DMSF content:\n\n" +
+ " File: !{{dmsf(file_id)}}\n\n" +
+ "_file_id_ can be found in link for file download"
+
+ macro :dmsf do |obj, args|
+ return nil if args.length < 1 # require file id
+ return nil if @project == nil
+ entry_id = args[0].strip
+ file = DmsfFile.find(entry_id)
+ unless file.nil? || file.deleted
+ return nil if file.project != @project
+ return link_to "#{file.last_revision.title}", :controller => "dmsf", :action => "download_file", :id => @project, :file_id => file
+ end
+ nil
+ end
+ end
+
+end
+
+Redmine::Search.map do |search|
+ search.register :dmsf_files
+end
diff --git a/lib/tasks/dmsf_convert_documents.rake b/lib/tasks/dmsf_convert_documents.rake
new file mode 100644
index 00000000..23dc01ce
--- /dev/null
+++ b/lib/tasks/dmsf_convert_documents.rake
@@ -0,0 +1,127 @@
+desc <<-END_DESC
+Convert project documents to DMSF folder/file structure.
+
+Converted project must have documents and may not have DMSF active!
+
+Available options:
+ * project => id or identifier of project (defaults to all projects)
+
+Example:
+ rake redmine:dmsf_convert_documents project=test RAILS_ENV="production"
+END_DESC
+require File.expand_path(File.dirname(__FILE__) + "/../../../../../config/environment")
+
+class DmsfConvertDocuments
+
+ def self.convert(options={})
+ projects = options[:project] ? [Project.find(options[:project])] : Project.find(:all)
+
+ projects.reject! {|project| !project.enabled_modules.index{|mod| mod.name == "dmsf"}.nil? }
+ projects.reject! {|project| project.enabled_modules.index{|mod| mod.name == "documents"}.nil? }
+
+ unless projects.nil? || projects.empty?
+ projects.each do |project|
+ puts "Processing project: " + project.identifier
+
+ project.enabled_module_names = (project.enabled_module_names << "dmsf").uniq
+ project.save!
+
+ folders = []
+ project.documents.each do |document|
+ folder = DmsfFolder.new
+
+ folder.project = project
+ folder.user = (a = document.attachments.find(:first, :order => "created_on ASC")) ? a.author : User.find(:first)
+
+ folder.name = document.title
+
+ i = 1
+ suffix = ""
+ while folders.index{|f| f.name == (folder.name + suffix)}
+ i+=1
+ suffix = "_#{i}"
+ end
+
+ folder.name = folder.name + suffix
+
+ folder.description = document.description
+
+ folder.save!
+ folders << folder;
+
+ puts "Created folder: " + folder.name
+
+ files = []
+ document.attachments.each do |attachment|
+ begin
+ file = DmsfFile.new
+ file.project = project
+ file.folder = folder
+
+ file.name = attachment.filename
+ i = 1
+ suffix = ""
+ while files.index{|f| f.name == (DmsfFileRevision.remove_extension(file.name) + suffix + File.extname(file.name))}
+ i+=1
+ suffix = "_#{i}"
+ end
+
+ file.name = DmsfFileRevision.remove_extension(file.name) + suffix + File.extname(file.name)
+
+ revision = DmsfFileRevision.new
+ revision.file = file
+ revision.name = file.name
+ revision.folder = file.folder
+ revision.title = DmsfFileRevision.filename_to_title(attachment.filename)
+ revision.description = attachment.description
+ revision.user = attachment.author
+ revision.created_at = attachment.created_on
+ revision.updated_at = attachment.created_on
+ revision.major_version = 0
+ revision.minor_version = 1
+ revision.comment = "Converted from documents"
+ revision.mime_type = attachment.content_type
+
+ revision.disk_filename = file.new_storage_filename
+ attachment_file = File.open(attachment.diskfile, "rb")
+ File.open(revision.disk_file, "wb") do |f|
+ while (buffer = attachment_file.read(8192))
+ f.write(buffer)
+ end
+ end
+ attachment_file.close
+
+ revision.size = File.size(revision.disk_file)
+
+ file.save!
+ revision.save!
+
+ files << file
+
+ attachment.destroy
+
+ puts "Created file: " + file.name
+ rescue Exception => e
+ puts "Creating file: " + attachment.filename + " failed"
+ end
+ end
+
+ document.destroy
+
+ end
+ project.enabled_module_names = project.enabled_module_names.reject {|mod| mod == "documents"}
+ project.save!
+ end
+ end
+
+ end
+end
+
+namespace :redmine do
+ task :dmsf_convert_documents => :environment do
+ options = {}
+ options[:project] = ENV['project'] if ENV['project']
+
+ DmsfConvertDocuments.convert(options)
+ end
+end
diff --git a/test/fixtures/dmsf_folders.yml b/test/fixtures/dmsf_folders.yml
new file mode 100644
index 00000000..2ada52fd
--- /dev/null
+++ b/test/fixtures/dmsf_folders.yml
@@ -0,0 +1,24 @@
+# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
+# It is possible to use ERb template markup
+one:
+ id: 1
+
+ name: folder1
+
+ project_id: 1
+
+ dmsf_folder_id:
+
+ user_id: 1
+
+two:
+ id: 2
+
+ name: folder2
+
+ project_id: 1
+
+ dmsf_folder_id: 1
+
+ user_id: 1
+
diff --git a/test/functional/dmsf_controller_test.rb b/test/functional/dmsf_controller_test.rb
new file mode 100644
index 00000000..6433ddc0
--- /dev/null
+++ b/test/functional/dmsf_controller_test.rb
@@ -0,0 +1,8 @@
+require File.dirname(__FILE__) + '/../test_helper'
+
+class DmsfControllerTest < ActionController::TestCase
+ # Replace this with your real tests.
+ def test_truth
+ assert true
+ end
+end
diff --git a/test/test_helper.rb b/test/test_helper.rb
new file mode 100644
index 00000000..7cc962ff
--- /dev/null
+++ b/test/test_helper.rb
@@ -0,0 +1,5 @@
+# Load the normal Rails helper
+require File.expand_path(File.dirname(__FILE__) + '/../../../../test/test_helper')
+
+# Ensure that we are using the temporary fixture path
+Engines::Testing.set_fixture_path
diff --git a/test/unit/dmsf_folder_test.rb b/test/unit/dmsf_folder_test.rb
new file mode 100644
index 00000000..f50b73ad
--- /dev/null
+++ b/test/unit/dmsf_folder_test.rb
@@ -0,0 +1,11 @@
+require File.dirname(__FILE__) + '/../test_helper'
+
+class DmsfFolderTest < ActiveSupport::TestCase
+ fixtures :projects, :users, :dmsf_folders, :dmsf_files, :dmsf_file_revisions,
+ :roles, :members, :member_roles, :enabled_modules, :enumerations
+
+ def test_folder_creating
+ assert_not_nil(dmsf_folders(:one))
+ end
+
+end