Merge branch 'master' into wip_leon_T7094_logo_image_upload_in_boilerplate
authorleon <leon@roojs.com>
Tue, 12 Jul 2022 04:57:25 +0000 (12:57 +0800)
committerleon <leon@roojs.com>
Tue, 12 Jul 2022 04:57:25 +0000 (12:57 +0800)
1  2 
roojs-all.js
roojs-debug.js
roojs-ui-debug.js
roojs-ui.js

diff --combined roojs-all.js
@@@ -1893,8 -1893,8 +1893,8 @@@ this.push({type:'endparagraph',pos:this
  Roo.htmleditor={};
  // Roo/htmleditor/Filter.js
  Roo.htmleditor.Filter=function(A){Roo.apply(this.cfg);};Roo.htmleditor.Filter.prototype={node:false,tag:false,replaceComment:false,replaceTag:false,walk:function(A){Roo.each(Array.from(A.childNodes),function(e){switch(true){case e.nodeType==8&&this.replaceComment!==false:this.replaceComment(e);
- return;case e.nodeType!=1:return;case this.tag===true:case typeof(this.tag)=='object'&&this.tag.indexOf(e.tagName)>-1:case typeof(this.tag)=='string'&&this.tag==e.tagName:if(this.replaceTag&&false===this.replaceTag(e)){return;}if(e.hasChildNodes()){this.walk(e);
- }return;default:if(e.hasChildNodes()){this.walk(e);}}},this);}};
+ return;case e.nodeType!=1:return;case this.tag===true:case e.tagName.indexOf(":")>-1&&typeof(this.tag)=='object'&&this.tag.indexOf(":")>-1:case e.tagName.indexOf(":")>-1&&typeof(this.tag)=='string'&&this.tag==":":case typeof(this.tag)=='object'&&this.tag.indexOf(e.tagName)>-1:case typeof(this.tag)=='string'&&this.tag==e.tagName:if(this.replaceTag&&false===this.replaceTag(e)){return;
+ }if(e.hasChildNodes()){this.walk(e);}return;default:if(e.hasChildNodes()){this.walk(e);}}},this);}};
  // Roo/htmleditor/FilterAttributes.js
  Roo.htmleditor.FilterAttributes=function(A){Roo.apply(this,A);this.attrib_black=this.attrib_black||[];this.attrib_white=this.attrib_white||[];this.attrib_clean=this.attrib_clean||[];this.style_white=this.style_white||[];this.style_black=this.style_black||[];
  this.walk(A.node);};Roo.extend(Roo.htmleditor.FilterAttributes,Roo.htmleditor.Filter,{tag:true,attrib_black:false,attrib_clean:false,attrib_white:false,style_white:false,style_black:false,replaceTag:function(A){if(!A.attributes||!A.attributes.length){return true;
@@@ -1930,11 -1930,12 +1930,12 @@@ return false;}if(A.tagName.toLowerCase(
  A.removeChild(cn);A.parentNode.insertBefore(cn,A);if(cn.nodeType==1){this.replaceTag(cn);}}A.parentNode.removeChild(A);return false;}if(A.className.length){var cn=A.className.split(/\W+/);var C=[];Roo.each(cn,function(F){if(F.match(/Mso[a-zA-Z]+/)){return;
  }C.push(F);});A.className=C.length?C.join(' '):'';if(!C.length){A.removeAttribute("class");}}if(A.hasAttribute("lang")){A.removeAttribute("lang");}if(A.hasAttribute("style")){var D=A.getAttribute("style").split(";");var E=[];Roo.each(D,function(s){if(!s.match(/:/)){return;
  }var kv=s.split(":");if(kv[0].match(/^(mso-|line|font|background|margin|padding|color)/)){return;}E.push(s);});A.setAttribute("style",E.length?E.join(';'):'');if(!E.length){A.removeAttribute('style');}}return true;},styleToObject:function(A){var B=(A.getAttribute("style")||'').split(";");
- var C={};Roo.each(B,function(s){if(!s.match(/:/)){return;}var kv=s.split(":");C[kv[0].trim()]=kv[1];});return C;},replaceDocBullets:function(A){var B=A.getElementsByClassName('ql-indent-1');while(B.length){this.replaceDocBullet(B.item(0));}var B=A.getElementsByClassName('MsoListParagraph');
+ var C={};Roo.each(B,function(s){if(!s.match(/:/)){return;}var kv=s.split(":");C[kv[0].trim()]=kv[1];});return C;},replaceDocBullets:function(A){var B=A.getElementsByClassName('MsoListParagraphCxSpFirst');for(var i=0;i<B.length;i++){B.item(i).className="MsoListParagraph";
+ }var C=A.getElementsByTagName('h2');for(var i=0;i<C.length;i++){if(C.item(i).getAttribute('style').match(/mso-list:/)){C.item(i).className="MsoListParagraph";}}B=A.getElementsByClassName('ql-indent-1');while(B.length){this.replaceDocBullet(B.item(0));}B=A.getElementsByClassName('MsoListParagraph');
  while(B.length){this.replaceDocBullet(B.item(0));}},replaceDocBullet:function(p){var ns=p,A=p.parentNode,B=A.ownerDocument,C=[];while(ns){if(ns.nodeType!=1){ns=ns.nextSibling;continue;}if(!ns.className.match(/(MsoListParagraph|ql-indent-1)/i)){break;}C.push(ns);
  ns=ns.nextSibling;}var ul=A.ownerDocument.createElement('ul');A.insertBefore(ul,p);var D=0;var E=[ul];var F=false;C.forEach(function(n,G){var H=n.getElementsByTagName('span');if(!H.length){A.removeChild(n);return;}var I={};for(var i=0;i<H.length;i++){I=this.styleToObject(H[i]);
  if(typeof(I['mso-list'])=='undefined'){continue;}H[i].parentNode.removeChild(H[i]);break;}I=this.styleToObject(n);if(typeof(I['mso-list'])=='undefined'){A.removeChild(n);return;}var J=(I['mso-list'].split(' ')[1].replace(/level/,'')*1)-1;if(J>D){var K=B.createElement('ul');
- F.appendChild(K);E[J]=K;}D=J;var L=E[J].appendChild(B.createElement('li'));F=L;L.innerHTML=n.innerHTML;A.removeChild(n);},this);}});
if(!F){F=B.createElement('li');E[D].appendChild(F);}F.appendChild(K);E[J]=K;}D=J;var L=E[J].appendChild(B.createElement('li'));F=L;L.innerHTML=n.innerHTML;A.removeChild(n);},this);}});
  // Roo/htmleditor/FilterStyleToTag.js
  Roo.htmleditor.FilterStyleToTag=function(A){this.tags={B:['fontWeight','bold'],I:['fontStyle','italic'],SUP:['verticalAlign','super'],SUB:['verticalAlign','sub']};Roo.apply(this,A);this.walk(A.node);};Roo.extend(Roo.htmleditor.FilterStyleToTag,Roo.htmleditor.Filter,{tag:true,tags:false,replaceTag:function(A){if(A.getAttribute("style")===null){return true;
  }var B=[];for(var k in this.tags){if(A.style[this.tags[k][0]]==this.tags[k][1]){B.push(k);A.style.removeProperty(this.tags[k][0]);}}if(!B.length){return true;}var cn=Array.from(A.childNodes);var nn=A;Roo.each(B,function(t){var nc=A.ownerDocument.createElement(t);
@@@ -1979,10 -1980,10 +1980,10 @@@ C=C||this.namedEntities;return A.replac
  while(i--){C[A[i]]={};}return C;}};Roo.htmleditor.TidyEntities.init();
  // Roo/htmleditor/KeyEnter.js
  Roo.htmleditor.KeyEnter=function(A){Roo.apply(this,A);Roo.get(this.core.doc.body).on('keypress',this.keypress,this);};Roo.htmleditor.KeyEnter.prototype={core:false,keypress:function(e){if(e.charCode!=13&&e.charCode!=10){Roo.log([e.charCode,e]);return true;
- }e.preventDefault();var A=this.core.doc;var B=this.core.getSelection();var C=B.getRangeAt(0);var n=C.commonAncestorContainer;var pc=C.closest(['ol','ul']);var D=C.closest('li');if(!pc||e.ctrlKey){B.insertNode('br','after');this.core.undoManager.addEvent();
this.core.fireEditorEvent(e);return false;}if(D.innerText.trim()==''&&D.previousSibling&&D.previousSibling.nodeName=='LI'&&D.previousSibling.innerText.trim()==''){D.parentNode.removeChild(D.previousSibling);B.cursorAfter(pc);this.core.undoManager.addEvent();
this.core.fireEditorEvent(e);return false;}var li=A.createElement('LI');li.innerHTML='&nbsp;';if(!D||!D.firstSibling){pc.appendChild(li);}else{D.parentNode.insertBefore(li,D.firstSibling);}B.cursorText(li.firstChild);this.core.undoManager.addEvent();this.core.fireEditorEvent(e);
- return false;}};
+ }e.preventDefault();var A=this.core.doc;var B=this.core.getSelection();var C=B.getRangeAt(0);var n=C.commonAncestorContainer;var pc=C.closest(['ol','ul']);var D=C.closest('li');if(!pc||e.ctrlKey){if(!e.ctrlKey){B.insertNode('br','after');}else{var br=A.createElement('br');
br.className='clear';br.setAttribute('style','clear: both');B.insertNode(br,'after');}this.core.undoManager.addEvent();this.core.fireEditorEvent(e);return false;}if(D.innerText.trim()==''&&D.previousSibling&&D.previousSibling.nodeName=='LI'&&D.previousSibling.innerText.trim()==''){D.parentNode.removeChild(D.previousSibling);
B.cursorAfter(pc);this.core.undoManager.addEvent();this.core.fireEditorEvent(e);return false;}var li=A.createElement('LI');li.innerHTML='&nbsp;';if(!D||!D.firstSibling){pc.appendChild(li);}else{D.parentNode.insertBefore(li,D.firstSibling);}B.cursorText(li.firstChild);
this.core.undoManager.addEvent();this.core.fireEditorEvent(e);return false;}};
  // Roo/htmleditor/Block.js
  Roo.htmleditor.Block=function(A){};Roo.htmleditor.Block.factory=function(A){var cc=Roo.htmleditor.Block.cache;var id=Roo.get(A).id;if(typeof(cc[id])!='undefined'&&(!cc[id].node||cc[id].node.closest('body'))){Roo.htmleditor.Block.cache[id].readElement(A);return Roo.htmleditor.Block.cache[id];
  }var db=A.getAttribute('data-block');if(!db){db=A.nodeName.toLowerCase().toUpperCaseFirst();}var B=Roo.htmleditor['Block'+db];if(typeof(B)=='undefined'){Roo.log("OOps missing block : "+'Block'+db);return false;}Roo.htmleditor.Block.cache[id]=new B({node:A}
@@@ -1996,7 -1997,7 +1997,7 @@@ Roo.htmleditor.BlockFigure=function(A){
  }b.image_src=I;b.updateElement();D();A.editorcore.onEditorEvent();},minWidth:250,prompt:true,modal:true,value:b.image_src});}},xns:C.Toolbar},{xtype:'Button',text:'Change Link URL',listeners:{click:function(F,G){var b=B();Roo.MessageBox.show({title:"Link URL",msg:"Enter the url for the link - leave blank to have no link",buttons:Roo.MessageBox.OKCANCEL,fn:function(H,I){if(H!='ok'){return;
  }b.href=I;b.updateElement();D();A.editorcore.onEditorEvent();},minWidth:250,prompt:true,modal:true,value:b.href});}},xns:C.Toolbar},{xtype:'Button',text:'Show Video URL',listeners:{click:function(F,G){Roo.MessageBox.alert("Video URL",B().video_url==''?'This image is not linked ot a video':'The image is linked to: <a target="_new" href="'+B().video_url+'">'+B().video_url+'</a>');
  }},xns:C.Toolbar},{xtype:'TextItem',text:"Width: ",xns:C.Toolbar},{xtype:'ComboBox',allowBlank:false,displayField:'val',editable:true,listWidth:100,triggerAction:'all',typeAhead:true,valueField:'val',width:70,name:'width',listeners:{select:function(F,r,G){A.editorcore.selectNode(A.tb.selectedNode);
- var b=B();b.width=r.get('val');b.updateElement();D();A.editorcore.onEditorEvent();}},xns:C.form,store:{xtype:'SimpleStore',data:[['50%'],['80%'],['100%']],fields:['val'],xns:Roo.data}},{xtype:'TextItem',text:"Align: ",xns:C.Toolbar},{xtype:'ComboBox',allowBlank:false,displayField:'val',editable:true,listWidth:100,triggerAction:'all',typeAhead:true,valueField:'val',width:70,name:'align',listeners:{select:function(F,r,G){A.editorcore.selectNode(A.tb.selectedNode);
+ var b=B();b.width=r.get('val');b.updateElement();D();A.editorcore.onEditorEvent();}},xns:C.form,store:{xtype:'SimpleStore',data:[['100%'],['80%'],['50%'],['20%'],['10%']],fields:['val'],xns:Roo.data}},{xtype:'TextItem',text:"Align: ",xns:C.Toolbar},{xtype:'ComboBox',allowBlank:false,displayField:'val',editable:true,listWidth:100,triggerAction:'all',typeAhead:true,valueField:'val',width:70,name:'align',listeners:{select:function(F,r,G){A.editorcore.selectNode(A.tb.selectedNode);
  var b=B();b.align=r.get('val');b.updateElement();D();A.editorcore.onEditorEvent();}},xns:C.form,store:{xtype:'SimpleStore',data:[['left'],['right'],['center']],fields:['val'],xns:Roo.data}},{xtype:'Button',text:'Hide Caption',name:'caption_display',pressed:false,enableToggle:true,setValue:function(v){this.setText(v?"Hide Caption":"Show Caption");
  this.setPressed(v!='block');},listeners:{toggle:function(F,G){var b=B();b.caption_display=b.caption_display=='block'?'none':'block';this.setText(b.caption_display=='block'?"Hide Caption":"Show Caption");b.updateElement();D();A.editorcore.selectNode(A.tb.selectedNode);
  A.editorcore.onEditorEvent();}},xns:C.Toolbar}];},toObject:function(){var d=document.createElement('div');d.innerHTML=this.caption;var m=this.width!='100%'&&this.align=='center'?'0 auto':0;var iw=this.align=='center'?this.width:'100%';var A={tag:'img',contenteditable:'false',src:this.image_src,alt:d.innerText.replace(/\n/g," ").replace(/\s+/g,' ').trim(),style:{width:iw,maxWidth:iw+' !important',margin:m}
@@@ -2083,7 -2084,7 +2084,7 @@@ this.insertAtCursor('<img src=" + url 
  }C=C.filter(function(g){return !g.path.match(/^rtf\/(head|pgdsctbl|listtable|footerf)/);}).map(function(g){return g.toDataURL();}).filter(function(g){return g!='about:blank';});D=this.cleanWordChars(D);var d=(new DOMParser().parseFromString(D,'text/html')).body;
  var sn=this.getParentElement();if(d.getElementsByTagName('table').length&&sn&&sn.closest('table')){e.preventDefault();this.insertAtCursor("You can not nest tables");return false;}if(C.length>0){Roo.each(d.getElementsByTagName('img'),function(F,i){F.setAttribute('src',C[i]);
  });}if(this.autoClean){new Roo.htmleditor.FilterWord({node:d});new Roo.htmleditor.FilterStyleToTag({node:d});new Roo.htmleditor.FilterAttributes({node:d,attrib_white:['href','src','name','align','colspan','rowspan','data-display','data-width'],attrib_clean:['href','src']}
- );new Roo.htmleditor.FilterBlack({node:d,tag:this.black});new Roo.htmleditor.FilterKeepChildren({node:d,tag:['FONT','O:P']});new Roo.htmleditor.FilterParagraph({node:d});new Roo.htmleditor.FilterSpan({node:d});new Roo.htmleditor.FilterLongBr({node:d});new Roo.htmleditor.FilterComment({node:d}
+ );new Roo.htmleditor.FilterBlack({node:d,tag:this.black});new Roo.htmleditor.FilterKeepChildren({node:d,tag:['FONT',':']});new Roo.htmleditor.FilterParagraph({node:d});new Roo.htmleditor.FilterSpan({node:d});new Roo.htmleditor.FilterLongBr({node:d});new Roo.htmleditor.FilterComment({node:d}
  );}if(this.enableBlocks){Array.from(d.getElementsByTagName('img')).forEach(function(F){if(F.closest('figure')){return;}var G=new Roo.htmleditor.BlockFigure({image_src:F.src});G.updateElement(F);});}this.insertAtCursor(d.innerHTML.replace(/&nbsp;/g,' '));if(this.enableBlocks){Roo.htmleditor.Block.initAll(this.doc.body);
  }e.preventDefault();return false;},onDestroy:function(){if(this.rendered){}},onFirstFocus:function(){this.assignDocWin();this.undoManager=new Roo.lib.UndoManager(100,(this.doc.body||this.doc.documentElement));this.activated=true;if(Roo.isGecko){this.win.focus();
  var s=this.win.getSelection();if(!s.focusNode||s.focusNode.nodeType!=3){var r=s.getRangeAt(0);r.selectNodeContents((this.doc.body||this.doc.documentElement));r.collapse(true);this.deferFocus();}try{this.execCmd('useCSS',true);this.execCmd('styleWithCSS',false);
@@@ -2112,12 -2113,12 +2113,12 @@@ F.collapse(true);var G=C.cloneRange();G
  }catch(e){C.selectNodeContents(B);}A.collapse(true);C.collapse(true);var ss=A.compareBoundaryPoints(Range.START_TO_START,C);var ee=A.compareBoundaryPoints(Range.END_TO_END,C);var D=ss==1;var E=ee==-1;if(D&&E){return 0;}if(!D&&E){return 1;}if(D&&!E){return 2;
  }return 3;},cleanWordChars:function(A){var B=[[8211,"&#8211;"],[8212,"&#8212;"],[8216,"'"],[8217,"'"],[8220,'"'],[8221,'"'],[8226,"*"],[8230,"..."]];var C=A;Roo.each(B,function(sw){var D=new RegExp("\\u"+sw[0].toString(16),"g");C=C.replace(D,sw[1]);});return C;
  },cleanUpChild:function(A){new Roo.htmleditor.FilterComment({node:A});new Roo.htmleditor.FilterAttributes({node:A,attrib_black:this.ablack,attrib_clean:this.aclean,style_white:this.cwhite,style_black:this.cblack});new Roo.htmleditor.FilterBlack({node:A,tag:this.black}
- );new Roo.htmleditor.FilterKeepChildren({node:A,tag:this.tag_remove});},cleanWord:function(A){new Roo.htmleditor.FilterWord({node:A?A:this.doc.body});},cleanTableWidths:function(A){new Roo.htmleditor.FilterTableWidth({node:A?A:this.doc.body});},applyBlacklists:function(){var w=typeof(this.owner.white)!='undefined'&&this.owner.white?this.owner.white:[];
var b=typeof(this.owner.black)!='undefined'&&this.owner.black?this.owner.black:[];this.aclean=typeof(this.owner.aclean)!='undefined'&&this.owner.aclean?this.owner.aclean:Roo.HtmlEditorCore.aclean;this.ablack=typeof(this.owner.ablack)!='undefined'&&this.owner.ablack?this.owner.ablack:Roo.HtmlEditorCore.ablack;
- this.tag_remove=typeof(this.owner.tag_remove)!='undefined'&&this.owner.tag_remove?this.owner.tag_remove:Roo.HtmlEditorCore.tag_remove;this.white=[];this.black=[];Roo.each(Roo.HtmlEditorCore.white,function(A){if(b.indexOf(A)>-1){return;}this.white.push(A);
},this);Roo.each(w,function(A){if(b.indexOf(A)>-1){return;}if(this.white.indexOf(A)>-1){return;}this.white.push(A);},this);Roo.each(Roo.HtmlEditorCore.black,function(A){if(w.indexOf(A)>-1){return;}this.black.push(A);},this);Roo.each(b,function(A){if(w.indexOf(A)>-1){return;
- }if(this.black.indexOf(A)>-1){return;}this.black.push(A);},this);w=typeof(this.owner.cwhite)!='undefined'&&this.owner.cwhite?this.owner.cwhite:[];b=typeof(this.owner.cblack)!='undefined'&&this.owner.cblack?this.owner.cblack:[];this.cwhite=[];this.cblack=[];
- Roo.each(Roo.HtmlEditorCore.cwhite,function(A){if(b.indexOf(A)>-1){return;}this.cwhite.push(A);},this);Roo.each(w,function(A){if(b.indexOf(A)>-1){return;}if(this.cwhite.indexOf(A)>-1){return;}this.cwhite.push(A);},this);Roo.each(Roo.HtmlEditorCore.cblack,function(A){if(w.indexOf(A)>-1){return;
+ );new Roo.htmleditor.FilterKeepChildren({node:A,tag:this.tag_remove});},cleanWord:function(A){new Roo.htmleditor.FilterWord({node:A?A:this.doc.body});new Roo.htmleditor.FilterKeepChildren({node:A?A:this.doc.body,tag:['FONT',':']});},cleanTableWidths:function(A){new Roo.htmleditor.FilterTableWidth({node:A?A:this.doc.body}
);},applyBlacklists:function(){var w=typeof(this.owner.white)!='undefined'&&this.owner.white?this.owner.white:[];var b=typeof(this.owner.black)!='undefined'&&this.owner.black?this.owner.black:[];this.aclean=typeof(this.owner.aclean)!='undefined'&&this.owner.aclean?this.owner.aclean:Roo.HtmlEditorCore.aclean;
+ this.ablack=typeof(this.owner.ablack)!='undefined'&&this.owner.ablack?this.owner.ablack:Roo.HtmlEditorCore.ablack;this.tag_remove=typeof(this.owner.tag_remove)!='undefined'&&this.owner.tag_remove?this.owner.tag_remove:Roo.HtmlEditorCore.tag_remove;this.white=[];
this.black=[];Roo.each(Roo.HtmlEditorCore.white,function(A){if(b.indexOf(A)>-1){return;}this.white.push(A);},this);Roo.each(w,function(A){if(b.indexOf(A)>-1){return;}if(this.white.indexOf(A)>-1){return;}this.white.push(A);},this);Roo.each(Roo.HtmlEditorCore.black,function(A){if(w.indexOf(A)>-1){return;
+ }this.black.push(A);},this);Roo.each(b,function(A){if(w.indexOf(A)>-1){return;}if(this.black.indexOf(A)>-1){return;}this.black.push(A);},this);w=typeof(this.owner.cwhite)!='undefined'&&this.owner.cwhite?this.owner.cwhite:[];b=typeof(this.owner.cblack)!='undefined'&&this.owner.cblack?this.owner.cblack:[];
this.cwhite=[];this.cblack=[];Roo.each(Roo.HtmlEditorCore.cwhite,function(A){if(b.indexOf(A)>-1){return;}this.cwhite.push(A);},this);Roo.each(w,function(A){if(b.indexOf(A)>-1){return;}if(this.cwhite.indexOf(A)>-1){return;}this.cwhite.push(A);},this);Roo.each(Roo.HtmlEditorCore.cblack,function(A){if(w.indexOf(A)>-1){return;
  }this.cblack.push(A);},this);Roo.each(b,function(A){if(w.indexOf(A)>-1){return;}if(this.cblack.indexOf(A)>-1){return;}this.cblack.push(A);},this);},setStylesheets:function(A){if(typeof(A)=='string'){Roo.get(this.iframe.contentDocument.head).createChild({tag:'link',rel:'stylesheet',type:'text/css',href:A}
  );return;}var B=this;Roo.each(A,function(s){if(!s.length){return;}Roo.get(B.iframe.contentDocument.head).createChild({tag:'link',rel:'stylesheet',type:'text/css',href:s});});},updateLanguage:function(){if(!this.iframe||!this.iframe.contentDocument){return;
  }Roo.get(this.iframe.contentDocument.body).attr("lang",this.language);},removeStylesheets:function(){var A=this;Roo.each(Roo.get(A.iframe.contentDocument.head).select('link[rel=stylesheet]',true).elements,function(s){s.remove();});},setStyle:function(A){Roo.get(this.iframe.contentDocument.head).createChild({tag:'style',type:'text/css',html:A}
@@@ -2544,9 -2545,9 +2545,9 @@@ return this.el.getUpdateManager();},_ha
  te.setWidth(A);}if(this.adjustments){A+=this.adjustments[0];B+=this.adjustments[1];}return {"width":A,"height":B};},setSize:function(A,B){if(this.fitToFrame&&!this.ignoreResize(A,B)){if(this.fitContainer&&this.resizeEl!=this.el){this.el.setSize(A,B);}var C=this.adjustForComponents(A,B);
  this.resizeEl.setSize(this.autoWidth?"auto":C.width,this.autoHeight?"auto":C.height);this.fireEvent('resize',this,C.width,C.height);}},getTitle:function(){return this.title;},setTitle:function(A){this.title=A;if(this.region){this.region.updatePanelTitle(this,A);
  }},isClosable:function(){return this.closable;},beforeSlide:function(){this.el.clip();this.resizeEl.clip();},afterSlide:function(){this.el.unclip();this.resizeEl.unclip();},refresh:function(){if(this.refreshDelegate){this.loaded=false;this.refreshDelegate();
 -}},destroy:function(){this.el.removeAllListeners();var A=document.createElement("span");A.appendChild(this.el.dom);A.innerHTML="";this.el.remove();this.el=null;},form:false,view:false,addxtype:function(A){if(A.xtype.match(/^Form$/)){var el;el=this.el.createChild();
 -this.form=new Roo.form.Form(A);if(this.form.allItems.length){this.form.render(el.dom);}return this.form;}if(['View','JsonView','DatePicker'].indexOf(A.xtype)>-1){A.el=this.el.appendChild(document.createElement("div"));var B=new Roo.factory(A);B.render&&B.render(false,'');
 -this.view=B;return B;}return false;}});
 +}},destroy:function(){this.el.removeAllListeners();var A=document.createElement("span");A.appendChild(this.el.dom);A.innerHTML="";this.el.remove();this.el=null;},form:false,view:false,addxtype:function(A){if(A.xtype.match(/^UploadCropbox$/)){this.cropbox=new Roo.factory(A);
 +this.cropbox.render(this.el);return this.cropbox;}if(A.xtype.match(/^Form$/)){var el;el=this.el.createChild();this.form=new Roo.form.Form(A);if(this.form.allItems.length){this.form.render(el.dom);}return this.form;}if(['View','JsonView','DatePicker'].indexOf(A.xtype)>-1){A.el=this.el.appendChild(document.createElement("div"));
 +var B=new Roo.factory(A);B.render&&B.render(false,'');this.view=B;return B;}return false;}});
  // Roo/GridPanel.js
  Roo.GridPanel=function(A,B){if(typeof(A.grid)!='undefined'){B=A;A=B.grid;}this.wrapper=Roo.DomHelper.append(document.body,{tag:"div",cls:"x-layout-grid-wrapper x-layout-inactive-content"},true);this.wrapper.dom.appendChild(A.getGridEl().dom);Roo.GridPanel.superclass.constructor.call(this,this.wrapper,B);
  if(this.toolbar){this.toolbar.el.insertBefore(this.wrapper.dom.firstChild);}if(this.footer&&!this.footer.el&&this.footer.xtype){this.footer.container=this.grid.getView().getFooterPanel(true);this.footer.dataSource=this.grid.dataSource;this.footer=Roo.factory(this.footer,Roo);
@@@ -2875,104 -2876,3 +2876,104 @@@ F.push("(typeof("+G+") == 'undefined')"
  }return "'"+A+H+C+")"+A+"'";};var B;if(Roo.isGecko){B="tpl.compiled = function(values, parent){  with(values) { return '"+tpl.body.replace(/(\r\n|\n)/g,'\\n').replace(/'/g,"\\'").replace(this.re,fn)+"';};};";}else{B=["tpl.compiled = function(values, parent){  with (values) { return ['"];
  B.push(tpl.body.replace(/(\r\n|\n)/g,'\\n').replace(/'/g,"\\'").replace(this.re,fn));B.push("'].join('');};};");B=B.join('');}Roo.debug&&Roo.log(B.replace(/\\n/,'\n'));eval(B);return this;},applyTemplate:function(A){return this.master.compiled.call(this,A,{}
  );},apply:function(){return this.applyTemplate.apply(this,arguments);}});Roo.XTemplate.from=function(el){el=Roo.getDom(el);return new Roo.XTemplate(el.value||el.innerHTML);};
 +// Roo/dialog/namespace.js
 +Roo.dialog={};
 +// Roo/dialog/UploadCropbox.js
 +Roo.dialog.UploadCropbox=function(A){Roo.dialog.UploadCropbox.superclass.constructor.call(this,A);this.addEvents({"beforeselectfile":true,"initial":true,"crop":true,"prepare":true,"exception":true,"beforeloadcanvas":true,"trash":true,"download":true,"footerbuttonclick":true,"resize":true,"rotate":true,"inspect":true,"upload":true,"arrange":true,"loadcanvas":true}
 +);this.buttons=this.buttons||Roo.dialog.UploadCropbox.footer.STANDARD;};Roo.extend(Roo.dialog.UploadCropbox,Roo.Component,{emptyText:'Click to upload image',rotateNotify:'Image is too small to rotate',errorTimeout:3000,scale:0,baseScale:1,rotate:0,dragable:false,pinching:false,mouseX:0,mouseY:0,cropData:false,minWidth:300,minHeight:300,outputMaxWidth:1200,file:false,exif:{}
 +,baseRotate:1,cropType:'image/jpeg',buttons:false,canvasLoaded:false,isDocument:false,method:'POST',paramName:'imageUpload',loadMask:true,loadingText:'Loading...',maskEl:false,getAutoCreate:function(){var A={tag:'div',cls:'roo-upload-cropbox',cn:[{tag:'input',cls:'roo-upload-cropbox-selector',type:'file'}
 +,{tag:'div',cls:'roo-upload-cropbox-body',style:'cursor:pointer',cn:[{tag:'div',cls:'roo-upload-cropbox-preview'},{tag:'div',cls:'roo-upload-cropbox-thumb'},{tag:'div',cls:'roo-upload-cropbox-empty-notify',html:this.emptyText},{tag:'div',cls:'roo-upload-cropbox-error-notify alert alert-danger',html:this.rotateNotify}
 +]},{tag:'div',cls:'roo-upload-cropbox-footer',cn:{tag:'div',cls:'btn-group btn-group-justified roo-upload-cropbox-btn-group',cn:[]}}]};return A;},onRender:function(ct,A){Roo.dialog.UploadCropbox.superclass.onRender.call(this,ct,A);if(this.el){if(this.el.attr('xtype')){this.el.attr('xtypex',this.el.attr('xtype'));
 +this.el.dom.removeAttribute('xtype');this.initEvents();}}else{var B=Roo.apply({},this.getAutoCreate());B.id=this.id||Roo.id();if(this.cls){B.cls=(typeof(B.cls)=='undefined'?this.cls:B.cls)+' '+this.cls;}if(this.style){B.style=(typeof(B.style)=='undefined'?this.style:B.style)+'; '+this.style;
 +}this.el=ct.createChild(B,A);this.initEvents();}if(this.buttons.length){Roo.each(this.buttons,function(bb){var C=this.el.select('.roo-upload-cropbox-footer div.roo-upload-cropbox-btn-group').first().createChild(bb);C.on('click',this.onFooterButtonClick.createDelegate(this,[bb.action],true));
 +},this);}if(this.loadMask){this.maskEl=this.el;}},initEvents:function(){this.urlAPI=(window.createObjectURL&&window)||(window.URL&&URL.revokeObjectURL&&URL)||(window.webkitURL&&webkitURL);this.bodyEl=this.el.select('.roo-upload-cropbox-body',true).first();
 +this.bodyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';this.selectorEl=this.el.select('.roo-upload-cropbox-selector',true).first();this.selectorEl.hide();this.previewEl=this.el.select('.roo-upload-cropbox-preview',true).first();this.previewEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';
 +this.thumbEl=this.el.select('.roo-upload-cropbox-thumb',true).first();this.thumbEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';this.thumbEl.hide();this.notifyEl=this.el.select('.roo-upload-cropbox-empty-notify',true).first();this.notifyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';
 +this.errorEl=this.el.select('.roo-upload-cropbox-error-notify',true).first();this.errorEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';this.errorEl.hide();this.footerEl=this.el.select('.roo-upload-cropbox-footer',true).first();this.footerEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';
 +this.footerEl.hide();this.setThumbBoxSize();this.bind();this.resize();this.fireEvent('initial',this);},bind:function(){var A=this;window.addEventListener("resize",function(){A.resize();});this.bodyEl.on('click',this.beforeSelectFile,this);if(Roo.isTouch){this.bodyEl.on('touchstart',this.onTouchStart,this);
 +this.bodyEl.on('touchmove',this.onTouchMove,this);this.bodyEl.on('touchend',this.onTouchEnd,this);}if(!Roo.isTouch){this.bodyEl.on('mousedown',this.onMouseDown,this);this.bodyEl.on('mousemove',this.onMouseMove,this);var B=(/Firefox/i.test(navigator.userAgent))?'DOMMouseScroll':'mousewheel';
 +this.bodyEl.on(B,this.onMouseWheel,this);Roo.get(document).on('mouseup',this.onMouseUp,this);}this.selectorEl.on('change',this.onFileSelected,this);},reset:function(){this.scale=0;this.baseScale=1;this.rotate=0;this.baseRotate=1;this.dragable=false;this.pinching=false;
 +this.mouseX=0;this.mouseY=0;this.cropData=false;this.notifyEl.dom.innerHTML=this.emptyText;},resize:function(){if(this.fireEvent('resize',this)!=false){this.setThumbBoxPosition();this.setCanvasPosition();}},onFooterButtonClick:function(e,el,o,A){switch(A){case 'rotate-left':this.onRotateLeft(e);
 +break;case 'rotate-right':this.onRotateRight(e);break;case 'picture':this.beforeSelectFile(e);break;case 'trash':this.trash(e);break;case 'crop':this.crop(e);break;case 'download':this.download(e);break;default:break;}this.fireEvent('footerbuttonclick',this,A);
 +},beforeSelectFile:function(e){e.preventDefault();if(this.fireEvent('beforeselectfile',this)!=false){this.selectorEl.dom.click();}},onFileSelected:function(e){e.preventDefault();if(typeof(this.selectorEl.dom.files)=='undefined'||!this.selectorEl.dom.files.length){return;
 +}var A=this.selectorEl.dom.files[0];if(this.fireEvent('inspect',this,A)!=false){this.prepare(A);}},trash:function(e){this.fireEvent('trash',this);},download:function(e){this.fireEvent('download',this);},loadCanvas:function(A){if(this.fireEvent('beforeloadcanvas',this,A)!=false){this.reset();
 +this.imageEl=document.createElement('img');var B=this;this.imageEl.addEventListener("load",function(){B.onLoadCanvas();});this.imageEl.src=A;}},onLoadCanvas:function(){this.imageEl.OriginWidth=this.imageEl.naturalWidth||this.imageEl.width;this.imageEl.OriginHeight=this.imageEl.naturalHeight||this.imageEl.height;
 +if(this.fireEvent('loadcanvas',this,this.imageEl)!=false){this.bodyEl.un('click',this.beforeSelectFile,this);this.notifyEl.hide();this.thumbEl.show();this.footerEl.show();this.baseRotateLevel();if(this.isDocument){this.setThumbBoxSize();}this.setThumbBoxPosition();
 +this.baseScaleLevel();this.draw();this.resize();this.canvasLoaded=true;}if(this.loadMask){this.maskEl.unmask();}},setCanvasPosition:function(){if(!this.canvasEl){return;}var pw=Math.ceil((this.bodyEl.getWidth()-this.canvasEl.width)/2);var ph=Math.ceil((this.bodyEl.getHeight()-this.canvasEl.height)/2);
 +this.previewEl.setLeft(pw);this.previewEl.setTop(ph);},onMouseDown:function(e){e.stopEvent();this.dragable=true;this.pinching=false;if(this.isDocument&&(this.canvasEl.width<this.thumbEl.getWidth()||this.canvasEl.height<this.thumbEl.getHeight())){this.dragable=false;
 +return;}this.mouseX=Roo.isTouch?e.browserEvent.touches[0].pageX:e.getPageX();this.mouseY=Roo.isTouch?e.browserEvent.touches[0].pageY:e.getPageY();},onMouseMove:function(e){e.stopEvent();if(!this.canvasLoaded){return;}if(!this.dragable){return;}var A=Math.ceil(this.thumbEl.getLeft(true));
 +var B=Math.ceil(this.thumbEl.getTop(true));var C=Math.ceil(A+this.thumbEl.getWidth()-this.canvasEl.width);var D=Math.ceil(B+this.thumbEl.getHeight()-this.canvasEl.height);if(A>C){var E=A;A=C;C=E;}if(B>D){var F=B;B=D;D=F;}var x=Roo.isTouch?e.browserEvent.touches[0].pageX:e.getPageX();
 +var y=Roo.isTouch?e.browserEvent.touches[0].pageY:e.getPageY();x=x-this.mouseX;y=y-this.mouseY;var G=Math.ceil(x+this.previewEl.getLeft(true));var H=Math.ceil(y+this.previewEl.getTop(true));G=(G<A)?A:((G>C)?C:G);H=(H<B)?B:((H>D)?D:H);this.previewEl.setLeft(G);
 +this.previewEl.setTop(H);this.mouseX=Roo.isTouch?e.browserEvent.touches[0].pageX:e.getPageX();this.mouseY=Roo.isTouch?e.browserEvent.touches[0].pageY:e.getPageY();},onMouseUp:function(e){e.stopEvent();this.dragable=false;},onMouseWheel:function(e){e.stopEvent();
 +this.startScale=this.scale;this.scale=(e.getWheelDelta()==1)?(this.scale+1):(this.scale-1);if(!this.zoomable()){this.scale=this.startScale;return;}this.draw();return;},zoomable:function(){var A=this.thumbEl.getWidth()/this.minWidth;if(this.minWidth<this.minHeight){A=this.thumbEl.getHeight()/this.minHeight;
 +}var B=Math.ceil(this.imageEl.OriginWidth*this.getScaleLevel()/A);var C=Math.ceil(this.imageEl.OriginHeight*this.getScaleLevel()/A);var D=this.imageEl.OriginWidth;var E=this.imageEl.OriginHeight;if(this.isDocument&&(this.rotate==0||this.rotate==180)&&(B>this.imageEl.OriginWidth||C>this.imageEl.OriginHeight||(B<this.minWidth&&C<this.minHeight))){return false;
 +}if(this.isDocument&&(this.rotate==90||this.rotate==270)&&(B>this.imageEl.OriginWidth||C>this.imageEl.OriginHeight||(B<this.minHeight&&C<this.minWidth))){return false;}if(!this.isDocument&&(this.rotate==0||this.rotate==180)&&((this.imageEl.OriginWidth>=this.minWidth)&&B<this.minWidth||(this.imageEl.OriginHeight>=this.minHeight)&&C<this.minHeight||B>D||C>E)){return false;
 +}if(!this.isDocument&&(this.rotate==90||this.rotate==270)&&(B<this.minHeight||B>this.imageEl.OriginWidth||C<this.minWidth||C>this.imageEl.OriginHeight)){return false;}return true;},onRotateLeft:function(e){if(!this.isDocument&&(this.canvasEl.height<this.thumbEl.getWidth()||this.canvasEl.width<this.thumbEl.getHeight())){var A=this.thumbEl.getWidth()/this.minWidth;
 +var bw=Math.ceil(this.canvasEl.width/this.getScaleLevel());var bh=Math.ceil(this.canvasEl.height/this.getScaleLevel());this.startScale=this.scale;while(this.getScaleLevel()<A){this.scale=this.scale+1;if(!this.zoomable()){break;}if(Math.ceil(bw*this.getScaleLevel())<this.thumbEl.getHeight()||Math.ceil(bh*this.getScaleLevel())<this.thumbEl.getWidth()){continue;
 +}this.rotate=(this.rotate<90)?270:this.rotate-90;this.draw();return;}this.scale=this.startScale;this.onRotateFail();return false;}this.rotate=(this.rotate<90)?270:this.rotate-90;if(this.isDocument){this.setThumbBoxSize();this.setThumbBoxPosition();this.setCanvasPosition();
 +}this.draw();this.fireEvent('rotate',this,'left');},onRotateRight:function(e){if(!this.isDocument&&(this.canvasEl.height<this.thumbEl.getWidth()||this.canvasEl.width<this.thumbEl.getHeight())){var A=this.thumbEl.getWidth()/this.minWidth;var bw=Math.ceil(this.canvasEl.width/this.getScaleLevel());
 +var bh=Math.ceil(this.canvasEl.height/this.getScaleLevel());this.startScale=this.scale;while(this.getScaleLevel()<A){this.scale=this.scale+1;if(!this.zoomable()){break;}if(Math.ceil(bw*this.getScaleLevel())<this.thumbEl.getHeight()||Math.ceil(bh*this.getScaleLevel())<this.thumbEl.getWidth()){continue;
 +}this.rotate=(this.rotate>180)?0:this.rotate+90;this.draw();return;}this.scale=this.startScale;this.onRotateFail();return false;}this.rotate=(this.rotate>180)?0:this.rotate+90;if(this.isDocument){this.setThumbBoxSize();this.setThumbBoxPosition();this.setCanvasPosition();
 +}this.draw();this.fireEvent('rotate',this,'right');},onRotateFail:function(){this.errorEl.show(true);var A=this;(function(){A.errorEl.hide(true);}).defer(this.errorTimeout);},draw:function(){this.previewEl.dom.innerHTML='';var A=document.createElement("canvas");
 +var B=A.getContext("2d");A.width=this.imageEl.OriginWidth*this.getScaleLevel();A.height=this.imageEl.OriginWidth*this.getScaleLevel();var C=this.imageEl.OriginWidth/2;if(this.imageEl.OriginWidth<this.imageEl.OriginHeight){A.width=this.imageEl.OriginHeight*this.getScaleLevel();
 +A.height=this.imageEl.OriginHeight*this.getScaleLevel();C=this.imageEl.OriginHeight/2;}B.scale(this.getScaleLevel(),this.getScaleLevel());B.translate(C,C);B.rotate(this.rotate*Math.PI/180);B.drawImage(this.imageEl,0,0,this.imageEl.OriginWidth,this.imageEl.OriginHeight,C*-1,C*-1,this.imageEl.OriginWidth,this.imageEl.OriginHeight);
 +this.canvasEl=document.createElement("canvas");this.contextEl=this.canvasEl.getContext("2d");switch(this.rotate){case 0:this.canvasEl.width=this.imageEl.OriginWidth*this.getScaleLevel();this.canvasEl.height=this.imageEl.OriginHeight*this.getScaleLevel();this.contextEl.drawImage(A,0,0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);
 +break;case 90:this.canvasEl.width=this.imageEl.OriginHeight*this.getScaleLevel();this.canvasEl.height=this.imageEl.OriginWidth*this.getScaleLevel();if(this.imageEl.OriginWidth>this.imageEl.OriginHeight){this.contextEl.drawImage(A,Math.abs(this.canvasEl.width-this.canvasEl.height),0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);
 +break;}this.contextEl.drawImage(A,0,0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);break;case 180:this.canvasEl.width=this.imageEl.OriginWidth*this.getScaleLevel();this.canvasEl.height=this.imageEl.OriginHeight*this.getScaleLevel();
 +if(this.imageEl.OriginWidth>this.imageEl.OriginHeight){this.contextEl.drawImage(A,0,Math.abs(this.canvasEl.width-this.canvasEl.height),this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);break;}this.contextEl.drawImage(A,Math.abs(this.canvasEl.width-this.canvasEl.height),0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);
 +break;case 270:this.canvasEl.width=this.imageEl.OriginHeight*this.getScaleLevel();this.canvasEl.height=this.imageEl.OriginWidth*this.getScaleLevel();if(this.imageEl.OriginWidth>this.imageEl.OriginHeight){this.contextEl.drawImage(A,0,0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);
 +break;}this.contextEl.drawImage(A,0,Math.abs(this.canvasEl.width-this.canvasEl.height),this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);break;default:break;}this.previewEl.appendChild(this.canvasEl);this.setCanvasPosition();
 +},crop:function(){if(!this.canvasLoaded){return;}var A=document.createElement("canvas");var B=A.getContext("2d");A.width=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?this.imageEl.OriginWidth:this.imageEl.OriginHeight;A.height=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?this.imageEl.OriginWidth:this.imageEl.OriginHeight;
 +var C=A.width/2;B.translate(C,C);B.rotate(this.rotate*Math.PI/180);B.drawImage(this.imageEl,0,0,this.imageEl.OriginWidth,this.imageEl.OriginHeight,C*-1,C*-1,this.imageEl.OriginWidth,this.imageEl.OriginHeight);var D=document.createElement("canvas");var E=D.getContext("2d");
 +D.width=this.thumbEl.getWidth()/this.getScaleLevel();D.height=this.thumbEl.getHeight()/this.getScaleLevel();switch(this.rotate){case 0:var F=(this.thumbEl.getWidth()/this.getScaleLevel()>this.imageEl.OriginWidth)?this.imageEl.OriginWidth:(this.thumbEl.getWidth()/this.getScaleLevel());
 +var G=(this.thumbEl.getHeight()/this.getScaleLevel()>this.imageEl.OriginHeight)?this.imageEl.OriginHeight:(this.thumbEl.getHeight()/this.getScaleLevel());var x=(this.thumbEl.getLeft(true)>this.previewEl.getLeft(true))?0:((this.previewEl.getLeft(true)-this.thumbEl.getLeft(true))/this.getScaleLevel());
 +var y=(this.thumbEl.getTop(true)>this.previewEl.getTop(true))?0:((this.previewEl.getTop(true)-this.thumbEl.getTop(true))/this.getScaleLevel());var sx=this.thumbEl.getLeft(true)-this.previewEl.getLeft(true);var sy=this.thumbEl.getTop(true)-this.previewEl.getTop(true);
 +sx=sx<0?0:(sx/this.getScaleLevel());sy=sy<0?0:(sy/this.getScaleLevel());if(D.width>this.outputMaxWidth){var H=this.outputMaxWidth/D.width;D.width=D.width*H;D.height=D.height*H;E.scale(H,H);}E.drawImage(A,sx,sy,F,G,x,y,F,G);break;case 90:var F=(this.thumbEl.getWidth()/this.getScaleLevel()>this.imageEl.OriginHeight)?this.imageEl.OriginHeight:(this.thumbEl.getWidth()/this.getScaleLevel());
 +var G=(this.thumbEl.getHeight()/this.getScaleLevel()>this.imageEl.OriginWidth)?this.imageEl.OriginWidth:(this.thumbEl.getHeight()/this.getScaleLevel());var x=(this.thumbEl.getLeft(true)>this.previewEl.getLeft(true))?0:((this.previewEl.getLeft(true)-this.thumbEl.getLeft(true))/this.getScaleLevel());
 +var y=(this.thumbEl.getTop(true)>this.previewEl.getTop(true))?0:((this.previewEl.getTop(true)-this.thumbEl.getTop(true))/this.getScaleLevel());var I=this.minWidth-2*x;var J=this.minHeight-2*y;var H=1;if((x==0&&y==0)||(x==0&&y>0)){H=I/F;}if(x>0&&y==0){H=J/G;
 +}if(x>0&&y>0){H=I/F;if(F<G){H=J/G;}}E.scale(H,H);var sx=Math.min(this.canvasEl.width-this.thumbEl.getWidth(),this.thumbEl.getLeft(true)-this.previewEl.getLeft(true));var sy=Math.min(this.canvasEl.height-this.thumbEl.getHeight(),this.thumbEl.getTop(true)-this.previewEl.getTop(true));
 +sx=sx<0?0:(sx/this.getScaleLevel());sy=sy<0?0:(sy/this.getScaleLevel());sx+=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?Math.abs(this.imageEl.OriginWidth-this.imageEl.OriginHeight):0;E.drawImage(A,sx,sy,F,G,x,y,F,G);break;case 180:var F=(this.thumbEl.getWidth()/this.getScaleLevel()>this.imageEl.OriginWidth)?this.imageEl.OriginWidth:(this.thumbEl.getWidth()/this.getScaleLevel());
 +var G=(this.thumbEl.getHeight()/this.getScaleLevel()>this.imageEl.OriginHeight)?this.imageEl.OriginHeight:(this.thumbEl.getHeight()/this.getScaleLevel());var x=(this.thumbEl.getLeft(true)>this.previewEl.getLeft(true))?0:((this.previewEl.getLeft(true)-this.thumbEl.getLeft(true))/this.getScaleLevel());
 +var y=(this.thumbEl.getTop(true)>this.previewEl.getTop(true))?0:((this.previewEl.getTop(true)-this.thumbEl.getTop(true))/this.getScaleLevel());var I=this.minWidth-2*x;var J=this.minHeight-2*y;var H=1;if((x==0&&y==0)||(x==0&&y>0)){H=I/F;}if(x>0&&y==0){H=J/G;
 +}if(x>0&&y>0){H=I/F;if(F<G){H=J/G;}}E.scale(H,H);var sx=Math.min(this.canvasEl.width-this.thumbEl.getWidth(),this.thumbEl.getLeft(true)-this.previewEl.getLeft(true));var sy=Math.min(this.canvasEl.height-this.thumbEl.getHeight(),this.thumbEl.getTop(true)-this.previewEl.getTop(true));
 +sx=sx<0?0:(sx/this.getScaleLevel());sy=sy<0?0:(sy/this.getScaleLevel());sx+=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?0:Math.abs(this.imageEl.OriginWidth-this.imageEl.OriginHeight);sy+=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?Math.abs(this.imageEl.OriginWidth-this.imageEl.OriginHeight):0;
 +E.drawImage(A,sx,sy,F,G,x,y,F,G);break;case 270:var F=(this.thumbEl.getWidth()/this.getScaleLevel()>this.imageEl.OriginHeight)?this.imageEl.OriginHeight:(this.thumbEl.getWidth()/this.getScaleLevel());var G=(this.thumbEl.getHeight()/this.getScaleLevel()>this.imageEl.OriginWidth)?this.imageEl.OriginWidth:(this.thumbEl.getHeight()/this.getScaleLevel());
 +var x=(this.thumbEl.getLeft(true)>this.previewEl.getLeft(true))?0:((this.previewEl.getLeft(true)-this.thumbEl.getLeft(true))/this.getScaleLevel());var y=(this.thumbEl.getTop(true)>this.previewEl.getTop(true))?0:((this.previewEl.getTop(true)-this.thumbEl.getTop(true))/this.getScaleLevel());
 +var I=this.minWidth-2*x;var J=this.minHeight-2*y;var H=1;if((x==0&&y==0)||(x==0&&y>0)){H=I/F;}if(x>0&&y==0){H=J/G;}if(x>0&&y>0){H=I/F;if(F<G){H=J/G;}}E.scale(H,H);var sx=Math.min(this.canvasEl.width-this.thumbEl.getWidth(),this.thumbEl.getLeft(true)-this.previewEl.getLeft(true));
 +var sy=Math.min(this.canvasEl.height-this.thumbEl.getHeight(),this.thumbEl.getTop(true)-this.previewEl.getTop(true));sx=sx<0?0:(sx/this.getScaleLevel());sy=sy<0?0:(sy/this.getScaleLevel());sy+=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?0:Math.abs(this.imageEl.OriginWidth-this.imageEl.OriginHeight);
 +E.drawImage(A,sx,sy,F,G,x,y,F,G);break;default:break;}this.cropData=D.toDataURL(this.cropType);if(this.fireEvent('crop',this,this.cropData)!==false){this.process(this.file,this.cropData);}return;},setThumbBoxSize:function(){var A,B;if(this.isDocument&&typeof(this.imageEl)!='undefined'){A=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?Math.max(this.minWidth,this.minHeight):Math.min(this.minWidth,this.minHeight);
 +B=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?Math.min(this.minWidth,this.minHeight):Math.max(this.minWidth,this.minHeight);this.minWidth=A;this.minHeight=B;if(this.rotate==90||this.rotate==270){this.minWidth=B;this.minHeight=A;}}B=300;A=Math.ceil(this.minWidth*B/this.minHeight);
 +if(this.minWidth>this.minHeight){A=300;B=Math.ceil(this.minHeight*A/this.minWidth);}this.thumbEl.setStyle({width:A+'px',height:B+'px'});return;},setThumbBoxPosition:function(){var x=Math.ceil((this.bodyEl.getWidth()-this.thumbEl.getWidth())/2);var y=Math.ceil((this.bodyEl.getHeight()-this.thumbEl.getHeight())/2);
 +this.thumbEl.setLeft(x);this.thumbEl.setTop(y);},baseRotateLevel:function(){this.baseRotate=1;if(typeof(this.exif)!='undefined'&&typeof(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']])!='undefined'&&[1,3,6,8].indexOf(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']])!=-1){this.baseRotate=this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']];
 +}this.rotate=Roo.dialog.UploadCropbox['Orientation'][this.baseRotate];},baseScaleLevel:function(){var A,B;if(this.isDocument){if(this.baseRotate==6||this.baseRotate==8){B=this.thumbEl.getHeight();this.baseScale=B/this.imageEl.OriginWidth;if(this.imageEl.OriginHeight*this.baseScale>this.thumbEl.getWidth()){A=this.thumbEl.getWidth();
 +this.baseScale=A/this.imageEl.OriginHeight;}return;}B=this.thumbEl.getHeight();this.baseScale=B/this.imageEl.OriginHeight;if(this.imageEl.OriginWidth*this.baseScale>this.thumbEl.getWidth()){A=this.thumbEl.getWidth();this.baseScale=A/this.imageEl.OriginWidth;
 +}return;}if(this.baseRotate==6||this.baseRotate==8){A=this.thumbEl.getHeight();this.baseScale=A/this.imageEl.OriginHeight;if(this.imageEl.OriginHeight*this.baseScale<this.thumbEl.getWidth()){B=this.thumbEl.getWidth();this.baseScale=B/this.imageEl.OriginHeight;
 +}if(this.imageEl.OriginWidth>this.imageEl.OriginHeight){B=this.thumbEl.getWidth();this.baseScale=B/this.imageEl.OriginHeight;if(this.imageEl.OriginWidth*this.baseScale<this.thumbEl.getHeight()){A=this.thumbEl.getHeight();this.baseScale=A/this.imageEl.OriginWidth;
 +}}return;}A=this.thumbEl.getWidth();this.baseScale=A/this.imageEl.OriginWidth;if(this.imageEl.OriginHeight*this.baseScale<this.thumbEl.getHeight()){B=this.thumbEl.getHeight();this.baseScale=B/this.imageEl.OriginHeight;}if(this.imageEl.OriginWidth>this.imageEl.OriginHeight){B=this.thumbEl.getHeight();
 +this.baseScale=B/this.imageEl.OriginHeight;if(this.imageEl.OriginWidth*this.baseScale<this.thumbEl.getWidth()){A=this.thumbEl.getWidth();this.baseScale=A/this.imageEl.OriginWidth;}}if(this.imageEl.OriginWidth<this.minWidth||this.imageEl.OriginHeight<this.minHeight){this.baseScale=A/this.minWidth;
 +}return;},getScaleLevel:function(){return this.baseScale*Math.pow(1.02,this.scale);},onTouchStart:function(e){if(!this.canvasLoaded){this.beforeSelectFile(e);return;}var A=e.browserEvent.touches;if(!A){return;}if(A.length==1){this.onMouseDown(e);return;}if(A.length!=2){return;
 +}var B=[];for(var i=0,C;C=A[i];i++){B.push(C.pageX,C.pageY);}var x=Math.pow(B[0]-B[2],2);var y=Math.pow(B[1]-B[3],2);this.startDistance=Math.sqrt(x+y);this.startScale=this.scale;this.pinching=true;this.dragable=false;},onTouchMove:function(e){if(!this.pinching&&!this.dragable){return;
 +}var A=e.browserEvent.touches;if(!A){return;}if(this.dragable){this.onMouseMove(e);return;}var B=[];for(var i=0,C;C=A[i];i++){B.push(C.pageX,C.pageY);}var x=Math.pow(B[0]-B[2],2);var y=Math.pow(B[1]-B[3],2);this.endDistance=Math.sqrt(x+y);this.scale=this.startScale+Math.floor(Math.log(this.endDistance/this.startDistance)/Math.log(1.1));
 +if(!this.zoomable()){this.scale=this.startScale;return;}this.draw();},onTouchEnd:function(e){this.pinching=false;this.dragable=false;},process:function(A,B){if(this.loadMask){this.maskEl.mask(this.loadingText);}this.xhr=new XMLHttpRequest();A.xhr=this.xhr;
 +this.xhr.open(this.method,this.url,true);var C={"Accept":"application/json","Cache-Control":"no-cache","X-Requested-With":"XMLHttpRequest"};for(var D in C){var E=C[D];if(E){this.xhr.setRequestHeader(D,E);}}var F=this;this.xhr.onload=function(){F.xhrOnLoad(F.xhr);
 +};this.xhr.onerror=function(){F.xhrOnError(F.xhr);};var G=new FormData();G.append('returnHTML','NO');if(B){G.append('crop',B);var H=atob(B.split(',')[1]);var I=[];for(var i=0;i<H.length;i++){I.push(H.charCodeAt(i));}var J=new Blob([new Uint8Array(I)],{type:this.cropType}
 +);G.append(this.paramName,J,A.name);}if(typeof(A.filename)!='undefined'){G.append('filename',A.filename);}if(typeof(A.mimetype)!='undefined'){G.append('mimetype',A.mimetype);}if(this.fireEvent('arrange',this,G)!=false){this.xhr.send(G);};},xhrOnLoad:function(A){if(this.loadMask){this.maskEl.unmask();
 +}if(A.readyState!==4){this.fireEvent('exception',this,A);return;}var B=Roo.decode(A.responseText);if(!B.success){this.fireEvent('exception',this,A);return;}var B=Roo.decode(A.responseText);this.fireEvent('upload',this,B);},xhrOnError:function(){if(this.loadMask){this.maskEl.unmask();
 +}Roo.log('xhr on error');var A=Roo.decode(xhr.responseText);Roo.log(A);},prepare:function(A){if(this.loadMask){this.maskEl.mask(this.loadingText);}this.file=false;this.exif={};if(typeof(A)==='string'){this.loadCanvas(A);return;}if(!A||!this.urlAPI){return;
 +}this.file=A;if(typeof(A.type)!='undefined'&&A.type.length!=0){this.cropType=A.type;}var B=this;if(this.fireEvent('prepare',this,this.file)!=false){var C=new FileReader();C.onload=function(e){if(e.target.error){Roo.log(e.target.error);return;}var D=e.target.result,E=new DataView(D),F=2,G=E.byteLength-4,H,I;
 +if(E.getUint16(0)===0xffd8){while(F<G){H=E.getUint16(F);if((H>=0xffe0&&H<=0xffef)||H===0xfffe){I=E.getUint16(F+2)+2;if(F+I>E.byteLength){Roo.log('Invalid meta data: Invalid segment size.');break;}if(H==0xffe1){B.parseExifData(E,F,I);}F+=I;continue;}break;
 +}}var J=B.urlAPI.createObjectURL(B.file);B.loadCanvas(J);return;};C.readAsArrayBuffer(this.file);}},parseExifData:function(A,B,C){var D=B+10,E,F;if(A.getUint32(B+4)!==0x45786966){return;}if(A.getUint32(B+4)!==0x45786966){return;}if(D+8>A.byteLength){Roo.log('Invalid Exif data: Invalid segment size.');
 +return;}if(A.getUint16(B+8)!==0x0000){Roo.log('Invalid Exif data: Missing byte alignment offset.');return;}switch(A.getUint16(D)){case 0x4949:E=true;break;case 0x4D4D:E=false;break;default:Roo.log('Invalid Exif data: Invalid byte alignment marker.');return;
 +}if(A.getUint16(D+2,E)!==0x002A){Roo.log('Invalid Exif data: Missing TIFF marker.');return;}F=A.getUint32(D+4,E);this.parseExifTags(A,D,D+F,E);},parseExifTags:function(A,B,C,D){var E,F,i;if(C+6>A.byteLength){Roo.log('Invalid Exif data: Invalid directory offset.');
 +return;}E=A.getUint16(C,D);F=C+2+12*E;if(F+4>A.byteLength){Roo.log('Invalid Exif data: Invalid directory size.');return;}for(i=0;i<E;i+=1){this.parseExifTag(A,B,C+2+12*i,D);}return A.getUint32(F,D);},parseExifTag:function(A,B,C,D){var E=A.getUint16(C,D);this.exif[E]=this.getExifValue(A,B,C,A.getUint16(C+2,D),A.getUint32(C+4,D),D);
 +},getExifValue:function(A,B,C,D,E,F){var G=Roo.dialog.UploadCropbox.exifTagTypes[D],H,I,J,i,K,c;if(!G){Roo.log('Invalid Exif data: Invalid tag type.');return;}H=G.size*E;I=H>4?B+A.getUint32(C+8,F):(C+8);if(I+H>A.byteLength){Roo.log('Invalid Exif data: Invalid data offset.');
 +return;}if(E===1){return G.getValue(A,I,F);}J=[];for(i=0;i<E;i+=1){J[i]=G.getValue(A,I+i*G.size,F);}if(G.ascii){K='';for(i=0;i<J.length;i+=1){c=J[i];if(c==='\u0000'){break;}K+=c;}return K;}return J;}});Roo.apply(Roo.dialog.UploadCropbox,{tags:{'Orientation':0x0112
 +}
 +,Orientation:{1:0,3:180,6:90,8:270},exifTagTypes:{1:{getValue:function(A,B){return A.getUint8(B);},size:1},2:{getValue:function(A,B){return String.fromCharCode(A.getUint8(B));},size:1,ascii:true},3:{getValue:function(A,B,C){return A.getUint16(B,C);},size:2}
 +,4:{getValue:function(A,B,C){return A.getUint32(B,C);},size:4},5:{getValue:function(A,B,C){return A.getUint32(B,C)/A.getUint32(B+4,C);},size:8},9:{getValue:function(A,B,C){return A.getInt32(B,C);},size:4},10:{getValue:function(A,B,C){return A.getInt32(B,C)/A.getInt32(B+4,C);
 +},size:8}},footer:{STANDARD:[{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-left',action:'rotate-left',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-undo"></i>'}]},{tag:'div',cls:'btn-group roo-upload-cropbox-picture',action:'picture',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-picture-o"></i>'}
 +]},{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-right',action:'rotate-right',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-repeat"></i>'}]}],DOCUMENT:[{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-left',action:'rotate-left',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-undo"></i>'}
 +]},{tag:'div',cls:'btn-group roo-upload-cropbox-download',action:'download',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-download"></i>'}]},{tag:'div',cls:'btn-group roo-upload-cropbox-crop',action:'crop',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-crop"></i>'}
 +]},{tag:'div',cls:'btn-group roo-upload-cropbox-trash',action:'trash',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-trash"></i>'}]},{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-right',action:'rotate-right',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-repeat"></i>'}
 +]}],ROTATOR:[{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-left',action:'rotate-left',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-undo"></i>'}]},{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-right',action:'rotate-right',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-repeat"></i>'}
 +]}]}});
diff --combined roojs-debug.js
@@@ -45652,6 -45652,8 +45652,8 @@@ Roo.htmleditor.Filter.prototype = 
                      return;
                  
                  case this.tag === true: // everything
+                 case e.tagName.indexOf(":") > -1 && typeof(this.tag) == 'object' && this.tag.indexOf(":") > -1:
+                 case e.tagName.indexOf(":") > -1 && typeof(this.tag) == 'string' && this.tag == ":":
                  case typeof(this.tag) == 'object' && this.tag.indexOf(e.tagName) > -1: // array and it matches.
                  case typeof(this.tag) == 'string' && this.tag == e.tagName: // array and it matches.
                      if (this.replaceTag && false === this.replaceTag(e)) {
@@@ -46079,6 -46081,7 +46081,7 @@@ Roo.htmleditor.FilterWord = function(cf
      // no need to apply config.
      this.replaceDocBullets(cfg.node);
      
+     // this is disabled as the removal is done by other filters;
     // this.walk(cfg.node);
      
      
@@@ -46208,16 -46211,29 +46211,29 @@@ Roo.extend(Roo.htmleditor.FilterWord, R
      replaceDocBullets : function(doc)
      {
          // this is a bit odd - but it appears some indents use ql-indent-1
+         //Roo.log(doc.innerHTML);
          
-         var listpara = doc.getElementsByClassName('ql-indent-1');
+         var listpara = doc.getElementsByClassName('MsoListParagraphCxSpFirst');
+         for( var i = 0; i < listpara.length; i ++) {
+             listpara.item(i).className = "MsoListParagraph";
+         }
+         // this is a bit hacky - we had one word document where h2 had a miso-list attribute.
+         var htwo = doc.getElementsByTagName('h2');
+         for( var i = 0; i < htwo.length; i ++) {
+             if (htwo.item(i).getAttribute('style').match(/mso-list:/)) {
+                 htwo.item(i).className = "MsoListParagraph";
+             }
+         }
+         
+         listpara = doc.getElementsByClassName('ql-indent-1');
          while(listpara.length) {
              this.replaceDocBullet(listpara.item(0));
          }
-         
-         var listpara = doc.getElementsByClassName('MsoListParagraph');
+         listpara = doc.getElementsByClassName('MsoListParagraph');
          while(listpara.length) {
              this.replaceDocBullet(listpara.item(0));
          }
+       
      },
      
      replaceDocBullet : function(p)
              if (nlvl > lvl) {
                  //new indent
                  var nul = doc.createElement('ul'); // what about number lists...
+                 if (!last_li) {
+                     last_li = doc.createElement('li');
+                     stack[lvl].appendChild(last_li);
+                 }
                  last_li.appendChild(nul);
                  stack[nlvl] = nul;
                  
@@@ -47808,7 -47828,17 +47828,17 @@@ Roo.htmleditor.KeyEnter.prototype = 
          var pc = range.closest([ 'ol', 'ul']);
          var pli = range.closest('li');
          if (!pc || e.ctrlKey) {
-             sel.insertNode('br', 'after'); 
+             // on it list, or ctrl pressed.
+             if (!e.ctrlKey) {
+                 sel.insertNode('br', 'after'); 
+             } else {
+                 // only do this if we have ctrl key..
+                 var br = doc.createElement('br');
+                 br.className = 'clear';
+                 br.setAttribute('style', 'clear: both');
+                 sel.insertNode(br, 'after'); 
+             }
+             
           
              this.core.undoManager.addEvent();
              this.core.fireEditorEvent(e);
@@@ -48172,9 -48202,11 +48202,11 @@@ Roo.extend(Roo.htmleditor.BlockFigure, 
                  store : {
                      xtype : 'SimpleStore',
                      data : [
-                         ['50%'],
+                         ['100%'],
                          ['80%'],
-                         ['100%']
+                         ['50%'],
+                         ['20%'],
+                         ['10%']
                      ],
                      fields : [ 'val'],
                      xns : Roo.data
@@@ -50283,7 -50315,7 +50315,7 @@@ Roo.extend(Roo.HtmlEditorCore, Roo.Comp
              });
              new Roo.htmleditor.FilterBlack({ node : d, tag : this.black});
              // should be fonts..
-             new Roo.htmleditor.FilterKeepChildren({node : d, tag : [ 'FONT', 'O:P' ]} );
+             new Roo.htmleditor.FilterKeepChildren({node : d, tag : [ 'FONT', ':' ]} );
              new Roo.htmleditor.FilterParagraph({ node : d });
              new Roo.htmleditor.FilterSpan({ node : d });
              new Roo.htmleditor.FilterLongBr({ node : d });
      cleanWord : function(node)
      {
          new Roo.htmleditor.FilterWord({ node : node ? node : this.doc.body });
+         new Roo.htmleditor.FilterKeepChildren({node : node ? node : this.doc.body, tag : [ 'FONT', ':' ]} );
          
      },
     
@@@ -60414,6 -60447,7 +60447,6 @@@ Roo.LayoutStateManager.prototype = 
   */
  Roo.ContentPanel = function(el, config, content){
      
 -     
      /*
      if(el.autoCreate || el.xtype){ // xtype is available if this is called from factory
          config = el;
@@@ -60797,14 -60831,6 +60830,14 @@@ layout.addxtype(
       */
      
      addxtype : function(cfg) {
 +        if(cfg.xtype.match(/^UploadCropbox$/)) {
 +
 +            this.cropbox = new Roo.factory(cfg);
 +
 +            this.cropbox.render(this.el);
 +
 +            return this.cropbox;
 +        }
          // add form..
          if (cfg.xtype.match(/^Form$/)) {
              
@@@ -68057,1803 -68083,4 +68090,1803 @@@ Roo.extend(Roo.XTemplate, Roo.Template
  Roo.XTemplate.from = function(el){
      el = Roo.getDom(el);
      return new Roo.XTemplate(el.value || el.innerHTML);
 -};
 +};Roo.dialog = {};
 +/*
 +* Licence: LGPL
 +*/
 +
 +/**
 + * @class Roo.dialog.UploadCropbox
 + * @extends Roo.BoxComponent
 + * Dialog UploadCropbox class
 + * @cfg {String} emptyText show when image has been loaded
 + * @cfg {String} rotateNotify show when image too small to rotate
 + * @cfg {Number} errorTimeout default 3000
 + * @cfg {Number} minWidth default 300
 + * @cfg {Number} minHeight default 300
 + * @cfg {Number} outputMaxWidth default 1200
 + * @cfg {Array} buttons default ['rotateLeft', 'pictureBtn', 'rotateRight']
 + * @cfg {Boolean} isDocument (true|false) default false
 + * @cfg {String} url action url
 + * @cfg {String} paramName default 'imageUpload'
 + * @cfg {String} method default POST
 + * @cfg {Boolean} loadMask (true|false) default true
 + * @cfg {Boolean} loadingText default 'Loading...'
 + * 
 + * @constructor
 + * Create a new UploadCropbox
 + * @param {Object} config The config object
 + */
 +
 + Roo.dialog.UploadCropbox = function(config){
 +    Roo.dialog.UploadCropbox.superclass.constructor.call(this, config);
 +    
 +    this.addEvents({
 +        /**
 +         * @event beforeselectfile
 +         * Fire before select file
 +         * @param {Roo.dialog.UploadCropbox} this
 +         */
 +        "beforeselectfile" : true,
 +        /**
 +         * @event initial
 +         * Fire after initEvent
 +         * @param {Roo.dialog.UploadCropbox} this
 +         */
 +        "initial" : true,
 +        /**
 +         * @event crop
 +         * Fire after initEvent
 +         * @param {Roo.dialog.UploadCropbox} this
 +         * @param {String} data
 +         */
 +        "crop" : true,
 +        /**
 +         * @event prepare
 +         * Fire when preparing the file data
 +         * @param {Roo.dialog.UploadCropbox} this
 +         * @param {Object} file
 +         */
 +        "prepare" : true,
 +        /**
 +         * @event exception
 +         * Fire when get exception
 +         * @param {Roo.dialog.UploadCropbox} this
 +         * @param {XMLHttpRequest} xhr
 +         */
 +        "exception" : true,
 +        /**
 +         * @event beforeloadcanvas
 +         * Fire before load the canvas
 +         * @param {Roo.dialog.UploadCropbox} this
 +         * @param {String} src
 +         */
 +        "beforeloadcanvas" : true,
 +        /**
 +         * @event trash
 +         * Fire when trash image
 +         * @param {Roo.dialog.UploadCropbox} this
 +         */
 +        "trash" : true,
 +        /**
 +         * @event download
 +         * Fire when download the image
 +         * @param {Roo.dialog.UploadCropbox} this
 +         */
 +        "download" : true,
 +        /**
 +         * @event footerbuttonclick
 +         * Fire when footerbuttonclick
 +         * @param {Roo.dialog.UploadCropbox} this
 +         * @param {String} type
 +         */
 +        "footerbuttonclick" : true,
 +        /**
 +         * @event resize
 +         * Fire when resize
 +         * @param {Roo.dialog.UploadCropbox} this
 +         */
 +        "resize" : true,
 +        /**
 +         * @event rotate
 +         * Fire when rotate the image
 +         * @param {Roo.dialog.UploadCropbox} this
 +         * @param {String} pos
 +         */
 +        "rotate" : true,
 +        /**
 +         * @event inspect
 +         * Fire when inspect the file
 +         * @param {Roo.dialog.UploadCropbox} this
 +         * @param {Object} file
 +         */
 +        "inspect" : true,
 +        /**
 +         * @event upload
 +         * Fire when xhr upload the file
 +         * @param {Roo.dialog.UploadCropbox} this
 +         * @param {Object} data
 +         */
 +        "upload" : true,
 +        /**
 +         * @event arrange
 +         * Fire when arrange the file data
 +         * @param {Roo.dialog.UploadCropbox} this
 +         * @param {Object} formData
 +         */
 +        "arrange" : true,
 +        /**
 +         * @event loadcanvas
 +         * Fire after load the canvas
 +         * @param {Roo.dialog.UploadCropbox}
 +         * @param {Object} imgEl
 +         */
 +        "loadcanvas" : true
 +    });
 +    
 +    this.buttons = this.buttons || Roo.dialog.UploadCropbox.footer.STANDARD;
 +};
 +
 +Roo.extend(Roo.dialog.UploadCropbox, Roo.Component,  {
 +    
 +    emptyText : 'Click to upload image',
 +    rotateNotify : 'Image is too small to rotate',
 +    errorTimeout : 3000,
 +    scale : 0,
 +    baseScale : 1,
 +    rotate : 0,
 +    dragable : false,
 +    pinching : false,
 +    mouseX : 0,
 +    mouseY : 0,
 +    cropData : false,
 +    minWidth : 300,
 +    minHeight : 300,
 +    outputMaxWidth : 1200,
 +    file : false,
 +    exif : {},
 +    baseRotate : 1,
 +    cropType : 'image/jpeg',
 +    buttons : false,
 +    canvasLoaded : false,
 +    isDocument : false,
 +    method : 'POST',
 +    paramName : 'imageUpload',
 +    loadMask : true,
 +    loadingText : 'Loading...',
 +    maskEl : false,
 +    
 +    getAutoCreate : function()
 +    {
 +        var cfg = {
 +            tag : 'div',
 +            cls : 'roo-upload-cropbox',
 +            cn : [
 +                {
 +                    tag : 'input',
 +                    cls : 'roo-upload-cropbox-selector',
 +                    type : 'file'
 +                },
 +                {
 +                    tag : 'div',
 +                    cls : 'roo-upload-cropbox-body',
 +                    style : 'cursor:pointer',
 +                    cn : [
 +                        {
 +                            tag : 'div',
 +                            cls : 'roo-upload-cropbox-preview'
 +                        },
 +                        {
 +                            tag : 'div',
 +                            cls : 'roo-upload-cropbox-thumb'
 +                        },
 +                        {
 +                            tag : 'div',
 +                            cls : 'roo-upload-cropbox-empty-notify',
 +                            html : this.emptyText
 +                        },
 +                        {
 +                            tag : 'div',
 +                            cls : 'roo-upload-cropbox-error-notify alert alert-danger',
 +                            html : this.rotateNotify
 +                        }
 +                    ]
 +                },
 +                {
 +                    tag : 'div',
 +                    cls : 'roo-upload-cropbox-footer',
 +                    cn : {
 +                        tag : 'div',
 +                        cls : 'btn-group btn-group-justified roo-upload-cropbox-btn-group',
 +                        cn : []
 +                    }
 +                }
 +            ]
 +        };
 +        
 +        return cfg;
 +    },
 +    
 +    onRender : function(ct, position)
 +    {
 +        Roo.dialog.UploadCropbox.superclass.onRender.call(this, ct, position);
 +
 +        if(this.el){
 +            if (this.el.attr('xtype')) {
 +                this.el.attr('xtypex', this.el.attr('xtype'));
 +                this.el.dom.removeAttribute('xtype');
 +                
 +                this.initEvents();
 +            }
 +        }
 +        else {
 +            var cfg = Roo.apply({},  this.getAutoCreate());
 +        
 +            cfg.id = this.id || Roo.id();
 +            
 +            if (this.cls) {
 +                cfg.cls = (typeof(cfg.cls) == 'undefined' ? this.cls : cfg.cls) + ' ' + this.cls;
 +            }
 +            
 +            if (this.style) { // fixme needs to support more complex style data.
 +                cfg.style = (typeof(cfg.style) == 'undefined' ? this.style : cfg.style) + '; ' + this.style;
 +            }
 +            
 +            this.el = ct.createChild(cfg, position);
 +            
 +            this.initEvents();
 +        }
 +        
 +        if (this.buttons.length) {
 +            
 +            Roo.each(this.buttons, function(bb) {
 +                
 +                var btn = this.el.select('.roo-upload-cropbox-footer div.roo-upload-cropbox-btn-group').first().createChild(bb);
 +                
 +                btn.on('click', this.onFooterButtonClick.createDelegate(this, [bb.action], true));
 +                
 +            }, this);
 +        }
 +        
 +        if(this.loadMask){
 +            this.maskEl = this.el;
 +        }
 +    },
 +    
 +    initEvents : function()
 +    {
 +        this.urlAPI = (window.createObjectURL && window) || 
 +                                (window.URL && URL.revokeObjectURL && URL) || 
 +                                (window.webkitURL && webkitURL);
 +                        
 +        this.bodyEl = this.el.select('.roo-upload-cropbox-body', true).first();
 +        this.bodyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
 +        
 +        this.selectorEl = this.el.select('.roo-upload-cropbox-selector', true).first();
 +        this.selectorEl.hide();
 +        
 +        this.previewEl = this.el.select('.roo-upload-cropbox-preview', true).first();
 +        this.previewEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
 +        
 +        this.thumbEl = this.el.select('.roo-upload-cropbox-thumb', true).first();
 +        this.thumbEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
 +        this.thumbEl.hide();
 +        
 +        this.notifyEl = this.el.select('.roo-upload-cropbox-empty-notify', true).first();
 +        this.notifyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
 +        
 +        this.errorEl = this.el.select('.roo-upload-cropbox-error-notify', true).first();
 +        this.errorEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
 +        this.errorEl.hide();
 +        
 +        this.footerEl = this.el.select('.roo-upload-cropbox-footer', true).first();
 +        this.footerEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
 +        this.footerEl.hide();
 +        
 +        this.setThumbBoxSize();
 +        
 +        this.bind();
 +        
 +        this.resize();
 +        
 +        this.fireEvent('initial', this);
 +    },
 +
 +    bind : function()
 +    {
 +        var _this = this;
 +        
 +        window.addEventListener("resize", function() { _this.resize(); } );
 +        
 +        this.bodyEl.on('click', this.beforeSelectFile, this);
 +        
 +        if(Roo.isTouch){
 +            this.bodyEl.on('touchstart', this.onTouchStart, this);
 +            this.bodyEl.on('touchmove', this.onTouchMove, this);
 +            this.bodyEl.on('touchend', this.onTouchEnd, this);
 +        }
 +        
 +        if(!Roo.isTouch){
 +            this.bodyEl.on('mousedown', this.onMouseDown, this);
 +            this.bodyEl.on('mousemove', this.onMouseMove, this);
 +            var mousewheel = (/Firefox/i.test(navigator.userAgent))? 'DOMMouseScroll' : 'mousewheel';
 +            this.bodyEl.on(mousewheel, this.onMouseWheel, this);
 +            Roo.get(document).on('mouseup', this.onMouseUp, this);
 +        }
 +        
 +        this.selectorEl.on('change', this.onFileSelected, this);
 +    },
 +    
 +    reset : function()
 +    {    
 +        this.scale = 0;
 +        this.baseScale = 1;
 +        this.rotate = 0;
 +        this.baseRotate = 1;
 +        this.dragable = false;
 +        this.pinching = false;
 +        this.mouseX = 0;
 +        this.mouseY = 0;
 +        this.cropData = false;
 +        this.notifyEl.dom.innerHTML = this.emptyText;
 +        
 +        // this.selectorEl.dom.value = '';
 +        
 +    },
 +    
 +    resize : function()
 +    {
 +        if(this.fireEvent('resize', this) != false){
 +            this.setThumbBoxPosition();
 +            this.setCanvasPosition();
 +        }
 +    },
 +    
 +    onFooterButtonClick : function(e, el, o, type)
 +    {
 +        switch (type) {
 +            case 'rotate-left' :
 +                this.onRotateLeft(e);
 +                break;
 +            case 'rotate-right' :
 +                this.onRotateRight(e);
 +                break;
 +            case 'picture' :
 +                this.beforeSelectFile(e);
 +                break;
 +            case 'trash' :
 +                this.trash(e);
 +                break;
 +            case 'crop' :
 +                this.crop(e);
 +                break;
 +            case 'download' :
 +                this.download(e);
 +                break;
 +            default :
 +                break;
 +        }
 +        
 +        this.fireEvent('footerbuttonclick', this, type);
 +    },
 +    
 +    beforeSelectFile : function(e)
 +    {
 +        e.preventDefault();
 +        
 +        if(this.fireEvent('beforeselectfile', this) != false){
 +            this.selectorEl.dom.click();
 +        }
 +    },
 +    
 +    onFileSelected : function(e)
 +    {
 +        e.preventDefault();
 +        
 +        if(typeof(this.selectorEl.dom.files) == 'undefined' || !this.selectorEl.dom.files.length){
 +            return;
 +        }
 +        
 +        var file = this.selectorEl.dom.files[0];
 +        
 +        if(this.fireEvent('inspect', this, file) != false){
 +            this.prepare(file);
 +        }
 +        
 +    },
 +    
 +    trash : function(e)
 +    {
 +        this.fireEvent('trash', this);
 +    },
 +    
 +    download : function(e)
 +    {
 +        this.fireEvent('download', this);
 +    },
 +    
 +    loadCanvas : function(src)
 +    {   
 +        if(this.fireEvent('beforeloadcanvas', this, src) != false){
 +            
 +            this.reset();
 +            
 +            this.imageEl = document.createElement('img');
 +            
 +            var _this = this;
 +            
 +            this.imageEl.addEventListener("load", function(){ _this.onLoadCanvas(); });
 +            
 +            this.imageEl.src = src;
 +        }
 +    },
 +    
 +    onLoadCanvas : function()
 +    {   
 +        this.imageEl.OriginWidth = this.imageEl.naturalWidth || this.imageEl.width;
 +        this.imageEl.OriginHeight = this.imageEl.naturalHeight || this.imageEl.height;
 +
 +        if(this.fireEvent('loadcanvas', this, this.imageEl) != false){
 +        
 +            this.bodyEl.un('click', this.beforeSelectFile, this);
 +            
 +            this.notifyEl.hide();
 +            this.thumbEl.show();
 +            this.footerEl.show();
 +            
 +            this.baseRotateLevel();
 +            
 +            if(this.isDocument){
 +                this.setThumbBoxSize();
 +            }
 +            
 +            this.setThumbBoxPosition();
 +            
 +            this.baseScaleLevel();
 +            
 +            this.draw();
 +            
 +            this.resize();
 +            
 +            this.canvasLoaded = true;
 +        
 +        }
 +        
 +        if(this.loadMask){
 +            this.maskEl.unmask();
 +        }
 +        
 +    },
 +    
 +    setCanvasPosition : function()
 +    {   
 +        if(!this.canvasEl){
 +            return;
 +        }
 +        
 +        var pw = Math.ceil((this.bodyEl.getWidth() - this.canvasEl.width) / 2);
 +        var ph = Math.ceil((this.bodyEl.getHeight() - this.canvasEl.height) / 2);
 +        
 +        this.previewEl.setLeft(pw);
 +        this.previewEl.setTop(ph);
 +        
 +    },
 +    
 +    onMouseDown : function(e)
 +    {   
 +        e.stopEvent();
 +        
 +        this.dragable = true;
 +        this.pinching = false;
 +        
 +        if(this.isDocument && (this.canvasEl.width < this.thumbEl.getWidth() || this.canvasEl.height < this.thumbEl.getHeight())){
 +            this.dragable = false;
 +            return;
 +        }
 +        
 +        this.mouseX = Roo.isTouch ? e.browserEvent.touches[0].pageX : e.getPageX();
 +        this.mouseY = Roo.isTouch ? e.browserEvent.touches[0].pageY : e.getPageY();
 +        
 +    },
 +    
 +    onMouseMove : function(e)
 +    {   
 +        e.stopEvent();
 +        
 +        if(!this.canvasLoaded){
 +            return;
 +        }
 +        
 +        if (!this.dragable){
 +            return;
 +        }
 +        
 +        var minX = Math.ceil(this.thumbEl.getLeft(true));
 +        var minY = Math.ceil(this.thumbEl.getTop(true));
 +        
 +        var maxX = Math.ceil(minX + this.thumbEl.getWidth() - this.canvasEl.width);
 +        var maxY = Math.ceil(minY + this.thumbEl.getHeight() - this.canvasEl.height);
 +
 +        if(minX > maxX) {
 +            var tempX = minX;
 +            minX = maxX;
 +            maxX = tempX;
 +        }
 +
 +        if(minY > maxY) {
 +            var tempY = minY;
 +            minY = maxY;
 +            maxY = tempY;
 +        }
 +
 +        var x = Roo.isTouch ? e.browserEvent.touches[0].pageX : e.getPageX();
 +        var y = Roo.isTouch ? e.browserEvent.touches[0].pageY : e.getPageY();
 +        
 +        x = x - this.mouseX;
 +        y = y - this.mouseY;
 +
 +        var bgX = Math.ceil(x + this.previewEl.getLeft(true));
 +        var bgY = Math.ceil(y + this.previewEl.getTop(true));
 +        
 +        bgX = (bgX < minX) ? minX : ((bgX > maxX) ? maxX : bgX);
 +        bgY = (bgY < minY) ? minY : ((bgY > maxY) ? maxY : bgY);
 +        
 +        this.previewEl.setLeft(bgX);
 +        this.previewEl.setTop(bgY);
 +        
 +        this.mouseX = Roo.isTouch ? e.browserEvent.touches[0].pageX : e.getPageX();
 +        this.mouseY = Roo.isTouch ? e.browserEvent.touches[0].pageY : e.getPageY();
 +    },
 +    
 +    onMouseUp : function(e)
 +    {   
 +        e.stopEvent();
 +        
 +        this.dragable = false;
 +    },
 +    
 +    onMouseWheel : function(e)
 +    {   
 +        e.stopEvent();
 +        
 +        this.startScale = this.scale;
 +        this.scale = (e.getWheelDelta() == 1) ? (this.scale + 1) : (this.scale - 1);
 +        
 +        if(!this.zoomable()){
 +            this.scale = this.startScale;
 +            return;
 +        }
 +
 +        
 +        this.draw();
 +        
 +        return;
 +    },
 +    
 +    zoomable : function()
 +    {
 +        var minScale = this.thumbEl.getWidth() / this.minWidth;
 +        
 +        if(this.minWidth < this.minHeight){
 +            minScale = this.thumbEl.getHeight() / this.minHeight;
 +        }
 +        
 +        var width = Math.ceil(this.imageEl.OriginWidth * this.getScaleLevel() / minScale);
 +        var height = Math.ceil(this.imageEl.OriginHeight * this.getScaleLevel() / minScale);
 +
 +
 +        var maxWidth = this.imageEl.OriginWidth;
 +        var maxHeight = this.imageEl.OriginHeight;
 +        
 +        if(
 +                this.isDocument &&
 +                (this.rotate == 0 || this.rotate == 180) && 
 +                (
 +                    width > this.imageEl.OriginWidth || 
 +                    height > this.imageEl.OriginHeight ||
 +                    (width < this.minWidth && height < this.minHeight)
 +                )
 +        ){
 +            return false;
 +        }
 +        
 +        if(
 +                this.isDocument &&
 +                (this.rotate == 90 || this.rotate == 270) && 
 +                (
 +                    width > this.imageEl.OriginWidth || 
 +                    height > this.imageEl.OriginHeight ||
 +                    (width < this.minHeight && height < this.minWidth)
 +                )
 +        ){
 +            return false;
 +        }
 +        
 +        if(
 +                !this.isDocument &&
 +                (this.rotate == 0 || this.rotate == 180) && 
 +                (
 +                    (this.imageEl.OriginWidth >= this.minWidth) && width < this.minWidth ||
 +                    (this.imageEl.OriginHeight >= this.minHeight) && height < this.minHeight ||
 +                    width > maxWidth ||
 +                    height > maxHeight
 +                )
 +        ){
 +            return false;
 +        }
 +        
 +        if(
 +                !this.isDocument &&
 +                (this.rotate == 90 || this.rotate == 270) && 
 +                (
 +                    width < this.minHeight || 
 +                    width > this.imageEl.OriginWidth || 
 +                    height < this.minWidth || 
 +                    height > this.imageEl.OriginHeight
 +                )
 +        ){
 +            return false;
 +        }
 +        
 +        return true;
 +        
 +    },
 +    
 +    onRotateLeft : function(e)
 +    {   
 +        if(!this.isDocument && (this.canvasEl.height < this.thumbEl.getWidth() || this.canvasEl.width < this.thumbEl.getHeight())){
 +            
 +            var minScale = this.thumbEl.getWidth() / this.minWidth;
 +            
 +            var bw = Math.ceil(this.canvasEl.width / this.getScaleLevel());
 +            var bh = Math.ceil(this.canvasEl.height / this.getScaleLevel());
 +            
 +            this.startScale = this.scale;
 +            
 +            while (this.getScaleLevel() < minScale){
 +            
 +                this.scale = this.scale + 1;
 +                
 +                if(!this.zoomable()){
 +                    break;
 +                }
 +                
 +                if(
 +                        Math.ceil(bw * this.getScaleLevel()) < this.thumbEl.getHeight() ||
 +                        Math.ceil(bh * this.getScaleLevel()) < this.thumbEl.getWidth()
 +                ){
 +                    continue;
 +                }
 +                
 +                this.rotate = (this.rotate < 90) ? 270 : this.rotate - 90;
 +
 +                this.draw();
 +                
 +                return;
 +            }
 +            
 +            this.scale = this.startScale;
 +            
 +            this.onRotateFail();
 +            
 +            return false;
 +        }
 +        
 +        this.rotate = (this.rotate < 90) ? 270 : this.rotate - 90;
 +
 +        if(this.isDocument){
 +            this.setThumbBoxSize();
 +            this.setThumbBoxPosition();
 +            this.setCanvasPosition();
 +        }
 +        
 +        this.draw();
 +        
 +        this.fireEvent('rotate', this, 'left');
 +        
 +    },
 +    
 +    onRotateRight : function(e)
 +    {
 +        if(!this.isDocument && (this.canvasEl.height < this.thumbEl.getWidth() || this.canvasEl.width < this.thumbEl.getHeight())){
 +            
 +            var minScale = this.thumbEl.getWidth() / this.minWidth;
 +        
 +            var bw = Math.ceil(this.canvasEl.width / this.getScaleLevel());
 +            var bh = Math.ceil(this.canvasEl.height / this.getScaleLevel());
 +            
 +            this.startScale = this.scale;
 +            
 +            while (this.getScaleLevel() < minScale){
 +            
 +                this.scale = this.scale + 1;
 +                
 +                if(!this.zoomable()){
 +                    break;
 +                }
 +                
 +                if(
 +                        Math.ceil(bw * this.getScaleLevel()) < this.thumbEl.getHeight() ||
 +                        Math.ceil(bh * this.getScaleLevel()) < this.thumbEl.getWidth()
 +                ){
 +                    continue;
 +                }
 +                
 +                this.rotate = (this.rotate > 180) ? 0 : this.rotate + 90;
 +
 +                this.draw();
 +                
 +                return;
 +            }
 +            
 +            this.scale = this.startScale;
 +            
 +            this.onRotateFail();
 +            
 +            return false;
 +        }
 +        
 +        this.rotate = (this.rotate > 180) ? 0 : this.rotate + 90;
 +
 +        if(this.isDocument){
 +            this.setThumbBoxSize();
 +            this.setThumbBoxPosition();
 +            this.setCanvasPosition();
 +        }
 +        
 +        this.draw();
 +        
 +        this.fireEvent('rotate', this, 'right');
 +    },
 +    
 +    onRotateFail : function()
 +    {
 +        this.errorEl.show(true);
 +        
 +        var _this = this;
 +        
 +        (function() { _this.errorEl.hide(true); }).defer(this.errorTimeout);
 +    },
 +    
 +    draw : function()
 +    {
 +        this.previewEl.dom.innerHTML = '';
 +        
 +        var canvasEl = document.createElement("canvas");
 +        
 +        var contextEl = canvasEl.getContext("2d");
 +        
 +        canvasEl.width = this.imageEl.OriginWidth * this.getScaleLevel();
 +        canvasEl.height = this.imageEl.OriginWidth * this.getScaleLevel();
 +        var center = this.imageEl.OriginWidth / 2;
 +        
 +        if(this.imageEl.OriginWidth < this.imageEl.OriginHeight){
 +            canvasEl.width = this.imageEl.OriginHeight * this.getScaleLevel();
 +            canvasEl.height = this.imageEl.OriginHeight * this.getScaleLevel();
 +            center = this.imageEl.OriginHeight / 2;
 +        }
 +        
 +        contextEl.scale(this.getScaleLevel(), this.getScaleLevel());
 +        
 +        contextEl.translate(center, center);
 +        contextEl.rotate(this.rotate * Math.PI / 180);
 +
 +        contextEl.drawImage(this.imageEl, 0, 0, this.imageEl.OriginWidth, this.imageEl.OriginHeight, center * -1, center * -1, this.imageEl.OriginWidth, this.imageEl.OriginHeight);
 +        
 +        this.canvasEl = document.createElement("canvas");
 +        
 +        this.contextEl = this.canvasEl.getContext("2d");
 +        
 +        switch (this.rotate) {
 +            case 0 :
 +                
 +                this.canvasEl.width = this.imageEl.OriginWidth * this.getScaleLevel();
 +                this.canvasEl.height = this.imageEl.OriginHeight * this.getScaleLevel();
 +                
 +                this.contextEl.drawImage(canvasEl, 0, 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
 +                
 +                break;
 +            case 90 : 
 +                
 +                this.canvasEl.width = this.imageEl.OriginHeight * this.getScaleLevel();
 +                this.canvasEl.height = this.imageEl.OriginWidth * this.getScaleLevel();
 +                
 +                if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){
 +                    this.contextEl.drawImage(canvasEl, Math.abs(this.canvasEl.width - this.canvasEl.height), 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
 +                    break;
 +                }
 +                
 +                this.contextEl.drawImage(canvasEl, 0, 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
 +                
 +                break;
 +            case 180 :
 +                
 +                this.canvasEl.width = this.imageEl.OriginWidth * this.getScaleLevel();
 +                this.canvasEl.height = this.imageEl.OriginHeight * this.getScaleLevel();
 +                
 +                if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){
 +                    this.contextEl.drawImage(canvasEl, 0, Math.abs(this.canvasEl.width - this.canvasEl.height), this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
 +                    break;
 +                }
 +                
 +                this.contextEl.drawImage(canvasEl, Math.abs(this.canvasEl.width - this.canvasEl.height), 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
 +                
 +                break;
 +            case 270 :
 +                
 +                this.canvasEl.width = this.imageEl.OriginHeight * this.getScaleLevel();
 +                this.canvasEl.height = this.imageEl.OriginWidth * this.getScaleLevel();
 +        
 +                if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){
 +                    this.contextEl.drawImage(canvasEl, 0, 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
 +                    break;
 +                }
 +                
 +                this.contextEl.drawImage(canvasEl, 0, Math.abs(this.canvasEl.width - this.canvasEl.height), this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
 +                
 +                break;
 +            default : 
 +                break;
 +        }
 +        
 +        this.previewEl.appendChild(this.canvasEl);
 +        
 +        this.setCanvasPosition();
 +    },
 +    
 +    crop : function()
 +    {
 +        if(!this.canvasLoaded){
 +            return;
 +        }
 +        
 +        var imageCanvas = document.createElement("canvas");
 +        
 +        var imageContext = imageCanvas.getContext("2d");
 +        
 +        imageCanvas.width = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? this.imageEl.OriginWidth : this.imageEl.OriginHeight;
 +        imageCanvas.height = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? this.imageEl.OriginWidth : this.imageEl.OriginHeight;
 +        
 +        var center = imageCanvas.width / 2;
 +        
 +        imageContext.translate(center, center);
 +        
 +        imageContext.rotate(this.rotate * Math.PI / 180);
 +        
 +        imageContext.drawImage(this.imageEl, 0, 0, this.imageEl.OriginWidth, this.imageEl.OriginHeight, center * -1, center * -1, this.imageEl.OriginWidth, this.imageEl.OriginHeight);
 +        
 +        var canvas = document.createElement("canvas");
 +        
 +        var context = canvas.getContext("2d");
 +
 +        canvas.width = this.thumbEl.getWidth() / this.getScaleLevel();
 +        
 +        canvas.height = this.thumbEl.getHeight() / this.getScaleLevel();
 +
 +        switch (this.rotate) {
 +            case 0 :
 +                
 +                var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getWidth() / this.getScaleLevel());
 +                var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getHeight() / this.getScaleLevel());
 +                
 +                var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel());
 +                var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel());
 +                
 +                var sx = this.thumbEl.getLeft(true) - this.previewEl.getLeft(true);
 +                var sy = this.thumbEl.getTop(true) - this.previewEl.getTop(true);
 +
 +                sx = sx < 0 ? 0 : (sx / this.getScaleLevel());
 +                sy = sy < 0 ? 0 : (sy / this.getScaleLevel());
 +
 +                if(canvas.width > this.outputMaxWidth) {
 +                    var scale = this.outputMaxWidth / canvas.width;
 +                    canvas.width = canvas.width * scale;
 +                    canvas.height = canvas.height * scale;
 +                    context.scale(scale, scale);
 +                }
 +
 +                context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height);
 +                
 +                break;
 +            case 90 : 
 +                
 +                var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getWidth() / this.getScaleLevel());
 +                var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getHeight() / this.getScaleLevel());
 +                
 +                var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel());
 +                var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel());
 +                
 +                var targetWidth = this.minWidth - 2 * x;
 +                var targetHeight = this.minHeight - 2 * y;
 +                
 +                var scale = 1;
 +                
 +                if((x == 0 && y == 0) || (x == 0 && y > 0)){
 +                    scale = targetWidth / width;
 +                }
 +                
 +                if(x > 0 && y == 0){
 +                    scale = targetHeight / height;
 +                }
 +                
 +                if(x > 0 && y > 0){
 +                    scale = targetWidth / width;
 +                    
 +                    if(width < height){
 +                        scale = targetHeight / height;
 +                    }
 +                }
 +                
 +                context.scale(scale, scale);
 +                
 +                var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true));
 +                var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true));
 +
 +                sx = sx < 0 ? 0 : (sx / this.getScaleLevel());
 +                sy = sy < 0 ? 0 : (sy / this.getScaleLevel());
 +                
 +                sx += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight) : 0;
 +                
 +                context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height);
 +                
 +                break;
 +            case 180 :
 +                
 +                var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getWidth() / this.getScaleLevel());
 +                var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getHeight() / this.getScaleLevel());
 +                
 +                var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel());
 +                var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel());
 +                
 +                var targetWidth = this.minWidth - 2 * x;
 +                var targetHeight = this.minHeight - 2 * y;
 +                
 +                var scale = 1;
 +                
 +                if((x == 0 && y == 0) || (x == 0 && y > 0)){
 +                    scale = targetWidth / width;
 +                }
 +                
 +                if(x > 0 && y == 0){
 +                    scale = targetHeight / height;
 +                }
 +                
 +                if(x > 0 && y > 0){
 +                    scale = targetWidth / width;
 +                    
 +                    if(width < height){
 +                        scale = targetHeight / height;
 +                    }
 +                }
 +                
 +                context.scale(scale, scale);
 +                
 +                var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true));
 +                var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true));
 +
 +                sx = sx < 0 ? 0 : (sx / this.getScaleLevel());
 +                sy = sy < 0 ? 0 : (sy / this.getScaleLevel());
 +
 +                sx += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? 0 : Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight);
 +                sy += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight) : 0;
 +                
 +                context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height);
 +                
 +                break;
 +            case 270 :
 +                
 +                var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getWidth() / this.getScaleLevel());
 +                var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getHeight() / this.getScaleLevel());
 +                
 +                var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel());
 +                var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel());
 +                
 +                var targetWidth = this.minWidth - 2 * x;
 +                var targetHeight = this.minHeight - 2 * y;
 +                
 +                var scale = 1;
 +                
 +                if((x == 0 && y == 0) || (x == 0 && y > 0)){
 +                    scale = targetWidth / width;
 +                }
 +                
 +                if(x > 0 && y == 0){
 +                    scale = targetHeight / height;
 +                }
 +                
 +                if(x > 0 && y > 0){
 +                    scale = targetWidth / width;
 +                    
 +                    if(width < height){
 +                        scale = targetHeight / height;
 +                    }
 +                }
 +                
 +                context.scale(scale, scale);
 +                var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true));
 +                var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true));
 +
 +                sx = sx < 0 ? 0 : (sx / this.getScaleLevel());
 +                sy = sy < 0 ? 0 : (sy / this.getScaleLevel());
 +                
 +                sy += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? 0 : Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight);
 +                
 +                context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height);
 +                
 +                break;
 +            default : 
 +                break;
 +        }
 +        
 +        this.cropData = canvas.toDataURL(this.cropType);
 +        
 +        if(this.fireEvent('crop', this, this.cropData) !== false){
 +            this.process(this.file, this.cropData);
 +        }
 +        
 +        return;
 +        
 +    },
 +    
 +    setThumbBoxSize : function()
 +    {
 +        var width, height;
 +        
 +        if(this.isDocument && typeof(this.imageEl) != 'undefined'){
 +            width = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.max(this.minWidth, this.minHeight) : Math.min(this.minWidth, this.minHeight);
 +            height = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.min(this.minWidth, this.minHeight) : Math.max(this.minWidth, this.minHeight);
 +            
 +            this.minWidth = width;
 +            this.minHeight = height;
 +            
 +            if(this.rotate == 90 || this.rotate == 270){
 +                this.minWidth = height;
 +                this.minHeight = width;
 +            }
 +        }
 +        
 +        height = 300;
 +        width = Math.ceil(this.minWidth * height / this.minHeight);
 +        
 +        if(this.minWidth > this.minHeight){
 +            width = 300;
 +            height = Math.ceil(this.minHeight * width / this.minWidth);
 +        }
 +        
 +        this.thumbEl.setStyle({
 +            width : width + 'px',
 +            height : height + 'px'
 +        });
 +
 +        return;
 +            
 +    },
 +    
 +    setThumbBoxPosition : function()
 +    {
 +        var x = Math.ceil((this.bodyEl.getWidth() - this.thumbEl.getWidth()) / 2 );
 +        var y = Math.ceil((this.bodyEl.getHeight() - this.thumbEl.getHeight()) / 2);
 +        
 +        this.thumbEl.setLeft(x);
 +        this.thumbEl.setTop(y);
 +        
 +    },
 +    
 +    baseRotateLevel : function()
 +    {
 +        this.baseRotate = 1;
 +        
 +        if(
 +                typeof(this.exif) != 'undefined' &&
 +                typeof(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']]) != 'undefined' &&
 +                [1, 3, 6, 8].indexOf(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']]) != -1
 +        ){
 +            this.baseRotate = this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']];
 +        }
 +        
 +        this.rotate = Roo.dialog.UploadCropbox['Orientation'][this.baseRotate];
 +        
 +    },
 +    
 +    baseScaleLevel : function()
 +    {
 +        var width, height;
 +        
 +        if(this.isDocument){
 +            
 +            if(this.baseRotate == 6 || this.baseRotate == 8){
 +            
 +                height = this.thumbEl.getHeight();
 +                this.baseScale = height / this.imageEl.OriginWidth;
 +
 +                if(this.imageEl.OriginHeight * this.baseScale > this.thumbEl.getWidth()){
 +                    width = this.thumbEl.getWidth();
 +                    this.baseScale = width / this.imageEl.OriginHeight;
 +                }
 +
 +                return;
 +            }
 +
 +            height = this.thumbEl.getHeight();
 +            this.baseScale = height / this.imageEl.OriginHeight;
 +
 +            if(this.imageEl.OriginWidth * this.baseScale > this.thumbEl.getWidth()){
 +                width = this.thumbEl.getWidth();
 +                this.baseScale = width / this.imageEl.OriginWidth;
 +            }
 +
 +            return;
 +        }
 +        
 +        if(this.baseRotate == 6 || this.baseRotate == 8){
 +            
 +            width = this.thumbEl.getHeight();
 +            this.baseScale = width / this.imageEl.OriginHeight;
 +            
 +            if(this.imageEl.OriginHeight * this.baseScale < this.thumbEl.getWidth()){
 +                height = this.thumbEl.getWidth();
 +                this.baseScale = height / this.imageEl.OriginHeight;
 +            }
 +            
 +            if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){
 +                height = this.thumbEl.getWidth();
 +                this.baseScale = height / this.imageEl.OriginHeight;
 +                
 +                if(this.imageEl.OriginWidth * this.baseScale < this.thumbEl.getHeight()){
 +                    width = this.thumbEl.getHeight();
 +                    this.baseScale = width / this.imageEl.OriginWidth;
 +                }
 +            }
 +            
 +            return;
 +        }
 +        
 +        width = this.thumbEl.getWidth();
 +        this.baseScale = width / this.imageEl.OriginWidth;
 +        
 +        if(this.imageEl.OriginHeight * this.baseScale < this.thumbEl.getHeight()){
 +            height = this.thumbEl.getHeight();
 +            this.baseScale = height / this.imageEl.OriginHeight;
 +        }
 +        
 +        if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){
 +            
 +            height = this.thumbEl.getHeight();
 +            this.baseScale = height / this.imageEl.OriginHeight;
 +            
 +            if(this.imageEl.OriginWidth * this.baseScale < this.thumbEl.getWidth()){
 +                width = this.thumbEl.getWidth();
 +                this.baseScale = width / this.imageEl.OriginWidth;
 +            }
 +            
 +        }
 +
 +        if(this.imageEl.OriginWidth < this.minWidth || this.imageEl.OriginHeight < this.minHeight) {
 +            this.baseScale = width / this.minWidth;
 +        }
 +
 +        return;
 +    },
 +    
 +    getScaleLevel : function()
 +    {
 +        return this.baseScale * Math.pow(1.02, this.scale);
 +    },
 +    
 +    onTouchStart : function(e)
 +    {
 +        if(!this.canvasLoaded){
 +            this.beforeSelectFile(e);
 +            return;
 +        }
 +        
 +        var touches = e.browserEvent.touches;
 +        
 +        if(!touches){
 +            return;
 +        }
 +        
 +        if(touches.length == 1){
 +            this.onMouseDown(e);
 +            return;
 +        }
 +        
 +        if(touches.length != 2){
 +            return;
 +        }
 +        
 +        var coords = [];
 +        
 +        for(var i = 0, finger; finger = touches[i]; i++){
 +            coords.push(finger.pageX, finger.pageY);
 +        }
 +        
 +        var x = Math.pow(coords[0] - coords[2], 2);
 +        var y = Math.pow(coords[1] - coords[3], 2);
 +        
 +        this.startDistance = Math.sqrt(x + y);
 +        
 +        this.startScale = this.scale;
 +        
 +        this.pinching = true;
 +        this.dragable = false;
 +        
 +    },
 +    
 +    onTouchMove : function(e)
 +    {
 +        if(!this.pinching && !this.dragable){
 +            return;
 +        }
 +        
 +        var touches = e.browserEvent.touches;
 +        
 +        if(!touches){
 +            return;
 +        }
 +        
 +        if(this.dragable){
 +            this.onMouseMove(e);
 +            return;
 +        }
 +        
 +        var coords = [];
 +        
 +        for(var i = 0, finger; finger = touches[i]; i++){
 +            coords.push(finger.pageX, finger.pageY);
 +        }
 +        
 +        var x = Math.pow(coords[0] - coords[2], 2);
 +        var y = Math.pow(coords[1] - coords[3], 2);
 +        
 +        this.endDistance = Math.sqrt(x + y);
 +        
 +        this.scale = this.startScale + Math.floor(Math.log(this.endDistance / this.startDistance) / Math.log(1.1));
 +        
 +        if(!this.zoomable()){
 +            this.scale = this.startScale;
 +            return;
 +        }
 +        
 +        this.draw();
 +        
 +    },
 +    
 +    onTouchEnd : function(e)
 +    {
 +        this.pinching = false;
 +        this.dragable = false;
 +        
 +    },
 +    
 +    process : function(file, crop)
 +    {
 +        if(this.loadMask){
 +            this.maskEl.mask(this.loadingText);
 +        }
 +        
 +        this.xhr = new XMLHttpRequest();
 +        
 +        file.xhr = this.xhr;
 +
 +        this.xhr.open(this.method, this.url, true);
 +        
 +        var headers = {
 +            "Accept": "application/json",
 +            "Cache-Control": "no-cache",
 +            "X-Requested-With": "XMLHttpRequest"
 +        };
 +        
 +        for (var headerName in headers) {
 +            var headerValue = headers[headerName];
 +            if (headerValue) {
 +                this.xhr.setRequestHeader(headerName, headerValue);
 +            }
 +        }
 +        
 +        var _this = this;
 +        
 +        this.xhr.onload = function()
 +        {
 +            _this.xhrOnLoad(_this.xhr);
 +        }
 +        
 +        this.xhr.onerror = function()
 +        {
 +            _this.xhrOnError(_this.xhr);
 +        }
 +        
 +        var formData = new FormData();
 +
 +        formData.append('returnHTML', 'NO');
 +
 +        if(crop){
 +            formData.append('crop', crop);
 +            var blobBin = atob(crop.split(',')[1]);
 +            var array = [];
 +            for(var i = 0; i < blobBin.length; i++) {
 +                array.push(blobBin.charCodeAt(i));
 +            }
 +            var croppedFile =new Blob([new Uint8Array(array)], {type: this.cropType});
 +            formData.append(this.paramName, croppedFile, file.name);
 +        }
 +        
 +        if(typeof(file.filename) != 'undefined'){
 +            formData.append('filename', file.filename);
 +        }
 +        
 +        if(typeof(file.mimetype) != 'undefined'){
 +            formData.append('mimetype', file.mimetype);
 +        }
 +
 +        if(this.fireEvent('arrange', this, formData) != false){
 +            this.xhr.send(formData);
 +        };
 +    },
 +    
 +    xhrOnLoad : function(xhr)
 +    {
 +        if(this.loadMask){
 +            this.maskEl.unmask();
 +        }
 +        
 +        if (xhr.readyState !== 4) {
 +            this.fireEvent('exception', this, xhr);
 +            return;
 +        }
 +
 +        var response = Roo.decode(xhr.responseText);
 +        
 +        if(!response.success){
 +            this.fireEvent('exception', this, xhr);
 +            return;
 +        }
 +        
 +        var response = Roo.decode(xhr.responseText);
 +        
 +        this.fireEvent('upload', this, response);
 +        
 +    },
 +    
 +    xhrOnError : function()
 +    {
 +        if(this.loadMask){
 +            this.maskEl.unmask();
 +        }
 +        
 +        Roo.log('xhr on error');
 +        
 +        var response = Roo.decode(xhr.responseText);
 +          
 +        Roo.log(response);
 +        
 +    },
 +    
 +    prepare : function(file)
 +    {   
 +        if(this.loadMask){
 +            this.maskEl.mask(this.loadingText);
 +        }
 +        
 +        this.file = false;
 +        this.exif = {};
 +        
 +        if(typeof(file) === 'string'){
 +            this.loadCanvas(file);
 +            return;
 +        }
 +        
 +        if(!file || !this.urlAPI){
 +            return;
 +        }
 +        
 +        this.file = file;
 +        if(typeof(file.type) != 'undefined' && file.type.length != 0) {
 +            this.cropType = file.type;
 +        }
 +        
 +        var _this = this;
 +        
 +        if(this.fireEvent('prepare', this, this.file) != false){
 +            
 +            var reader = new FileReader();
 +            
 +            reader.onload = function (e) {
 +                if (e.target.error) {
 +                    Roo.log(e.target.error);
 +                    return;
 +                }
 +                
 +                var buffer = e.target.result,
 +                    dataView = new DataView(buffer),
 +                    offset = 2,
 +                    maxOffset = dataView.byteLength - 4,
 +                    markerBytes,
 +                    markerLength;
 +                
 +                if (dataView.getUint16(0) === 0xffd8) {
 +                    while (offset < maxOffset) {
 +                        markerBytes = dataView.getUint16(offset);
 +                        
 +                        if ((markerBytes >= 0xffe0 && markerBytes <= 0xffef) || markerBytes === 0xfffe) {
 +                            markerLength = dataView.getUint16(offset + 2) + 2;
 +                            if (offset + markerLength > dataView.byteLength) {
 +                                Roo.log('Invalid meta data: Invalid segment size.');
 +                                break;
 +                            }
 +                            
 +                            if(markerBytes == 0xffe1){
 +                                _this.parseExifData(
 +                                    dataView,
 +                                    offset,
 +                                    markerLength
 +                                );
 +                            }
 +                            
 +                            offset += markerLength;
 +                            
 +                            continue;
 +                        }
 +                        
 +                        break;
 +                    }
 +                    
 +                }
 +                
 +                var url = _this.urlAPI.createObjectURL(_this.file);
 +                
 +                _this.loadCanvas(url);
 +                
 +                return;
 +            }
 +            
 +            reader.readAsArrayBuffer(this.file);
 +            
 +        }
 +        
 +    },
 +    
 +    parseExifData : function(dataView, offset, length)
 +    {
 +        var tiffOffset = offset + 10,
 +            littleEndian,
 +            dirOffset;
 +    
 +        if (dataView.getUint32(offset + 4) !== 0x45786966) {
 +            // No Exif data, might be XMP data instead
 +            return;
 +        }
 +        
 +        // Check for the ASCII code for "Exif" (0x45786966):
 +        if (dataView.getUint32(offset + 4) !== 0x45786966) {
 +            // No Exif data, might be XMP data instead
 +            return;
 +        }
 +        if (tiffOffset + 8 > dataView.byteLength) {
 +            Roo.log('Invalid Exif data: Invalid segment size.');
 +            return;
 +        }
 +        // Check for the two null bytes:
 +        if (dataView.getUint16(offset + 8) !== 0x0000) {
 +            Roo.log('Invalid Exif data: Missing byte alignment offset.');
 +            return;
 +        }
 +        // Check the byte alignment:
 +        switch (dataView.getUint16(tiffOffset)) {
 +        case 0x4949:
 +            littleEndian = true;
 +            break;
 +        case 0x4D4D:
 +            littleEndian = false;
 +            break;
 +        default:
 +            Roo.log('Invalid Exif data: Invalid byte alignment marker.');
 +            return;
 +        }
 +        // Check for the TIFF tag marker (0x002A):
 +        if (dataView.getUint16(tiffOffset + 2, littleEndian) !== 0x002A) {
 +            Roo.log('Invalid Exif data: Missing TIFF marker.');
 +            return;
 +        }
 +        // Retrieve the directory offset bytes, usually 0x00000008 or 8 decimal:
 +        dirOffset = dataView.getUint32(tiffOffset + 4, littleEndian);
 +        
 +        this.parseExifTags(
 +            dataView,
 +            tiffOffset,
 +            tiffOffset + dirOffset,
 +            littleEndian
 +        );
 +    },
 +    
 +    parseExifTags : function(dataView, tiffOffset, dirOffset, littleEndian)
 +    {
 +        var tagsNumber,
 +            dirEndOffset,
 +            i;
 +        if (dirOffset + 6 > dataView.byteLength) {
 +            Roo.log('Invalid Exif data: Invalid directory offset.');
 +            return;
 +        }
 +        tagsNumber = dataView.getUint16(dirOffset, littleEndian);
 +        dirEndOffset = dirOffset + 2 + 12 * tagsNumber;
 +        if (dirEndOffset + 4 > dataView.byteLength) {
 +            Roo.log('Invalid Exif data: Invalid directory size.');
 +            return;
 +        }
 +        for (i = 0; i < tagsNumber; i += 1) {
 +            this.parseExifTag(
 +                dataView,
 +                tiffOffset,
 +                dirOffset + 2 + 12 * i, // tag offset
 +                littleEndian
 +            );
 +        }
 +        // Return the offset to the next directory:
 +        return dataView.getUint32(dirEndOffset, littleEndian);
 +    },
 +    
 +    parseExifTag : function (dataView, tiffOffset, offset, littleEndian) 
 +    {
 +        var tag = dataView.getUint16(offset, littleEndian);
 +        
 +        this.exif[tag] = this.getExifValue(
 +            dataView,
 +            tiffOffset,
 +            offset,
 +            dataView.getUint16(offset + 2, littleEndian), // tag type
 +            dataView.getUint32(offset + 4, littleEndian), // tag length
 +            littleEndian
 +        );
 +    },
 +    
 +    getExifValue : function (dataView, tiffOffset, offset, type, length, littleEndian)
 +    {
 +        var tagType = Roo.dialog.UploadCropbox.exifTagTypes[type],
 +            tagSize,
 +            dataOffset,
 +            values,
 +            i,
 +            str,
 +            c;
 +    
 +        if (!tagType) {
 +            Roo.log('Invalid Exif data: Invalid tag type.');
 +            return;
 +        }
 +        
 +        tagSize = tagType.size * length;
 +        // Determine if the value is contained in the dataOffset bytes,
 +        // or if the value at the dataOffset is a pointer to the actual data:
 +        dataOffset = tagSize > 4 ?
 +                tiffOffset + dataView.getUint32(offset + 8, littleEndian) : (offset + 8);
 +        if (dataOffset + tagSize > dataView.byteLength) {
 +            Roo.log('Invalid Exif data: Invalid data offset.');
 +            return;
 +        }
 +        if (length === 1) {
 +            return tagType.getValue(dataView, dataOffset, littleEndian);
 +        }
 +        values = [];
 +        for (i = 0; i < length; i += 1) {
 +            values[i] = tagType.getValue(dataView, dataOffset + i * tagType.size, littleEndian);
 +        }
 +        
 +        if (tagType.ascii) {
 +            str = '';
 +            // Concatenate the chars:
 +            for (i = 0; i < values.length; i += 1) {
 +                c = values[i];
 +                // Ignore the terminating NULL byte(s):
 +                if (c === '\u0000') {
 +                    break;
 +                }
 +                str += c;
 +            }
 +            return str;
 +        }
 +        return values;
 +    }
 +    
 +});
 +
 +Roo.apply(Roo.dialog.UploadCropbox, {
 +    tags : {
 +        'Orientation': 0x0112
 +    },
 +    
 +    Orientation: {
 +            1: 0, //'top-left',
 +//            2: 'top-right',
 +            3: 180, //'bottom-right',
 +//            4: 'bottom-left',
 +//            5: 'left-top',
 +            6: 90, //'right-top',
 +//            7: 'right-bottom',
 +            8: 270 //'left-bottom'
 +    },
 +    
 +    exifTagTypes : {
 +        // byte, 8-bit unsigned int:
 +        1: {
 +            getValue: function (dataView, dataOffset) {
 +                return dataView.getUint8(dataOffset);
 +            },
 +            size: 1
 +        },
 +        // ascii, 8-bit byte:
 +        2: {
 +            getValue: function (dataView, dataOffset) {
 +                return String.fromCharCode(dataView.getUint8(dataOffset));
 +            },
 +            size: 1,
 +            ascii: true
 +        },
 +        // short, 16 bit int:
 +        3: {
 +            getValue: function (dataView, dataOffset, littleEndian) {
 +                return dataView.getUint16(dataOffset, littleEndian);
 +            },
 +            size: 2
 +        },
 +        // long, 32 bit int:
 +        4: {
 +            getValue: function (dataView, dataOffset, littleEndian) {
 +                return dataView.getUint32(dataOffset, littleEndian);
 +            },
 +            size: 4
 +        },
 +        // rational = two long values, first is numerator, second is denominator:
 +        5: {
 +            getValue: function (dataView, dataOffset, littleEndian) {
 +                return dataView.getUint32(dataOffset, littleEndian) /
 +                    dataView.getUint32(dataOffset + 4, littleEndian);
 +            },
 +            size: 8
 +        },
 +        // slong, 32 bit signed int:
 +        9: {
 +            getValue: function (dataView, dataOffset, littleEndian) {
 +                return dataView.getInt32(dataOffset, littleEndian);
 +            },
 +            size: 4
 +        },
 +        // srational, two slongs, first is numerator, second is denominator:
 +        10: {
 +            getValue: function (dataView, dataOffset, littleEndian) {
 +                return dataView.getInt32(dataOffset, littleEndian) /
 +                    dataView.getInt32(dataOffset + 4, littleEndian);
 +            },
 +            size: 8
 +        }
 +    },
 +    
 +    footer : {
 +        STANDARD : [
 +            {
 +                tag : 'div',
 +                cls : 'btn-group roo-upload-cropbox-rotate-left',
 +                action : 'rotate-left',
 +                cn : [
 +                    {
 +                        tag : 'button',
 +                        cls : 'btn btn-default',
 +                        html : '<i class="fa fa-undo"></i>'
 +                    }
 +                ]
 +            },
 +            {
 +                tag : 'div',
 +                cls : 'btn-group roo-upload-cropbox-picture',
 +                action : 'picture',
 +                cn : [
 +                    {
 +                        tag : 'button',
 +                        cls : 'btn btn-default',
 +                        html : '<i class="fa fa-picture-o"></i>'
 +                    }
 +                ]
 +            },
 +            {
 +                tag : 'div',
 +                cls : 'btn-group roo-upload-cropbox-rotate-right',
 +                action : 'rotate-right',
 +                cn : [
 +                    {
 +                        tag : 'button',
 +                        cls : 'btn btn-default',
 +                        html : '<i class="fa fa-repeat"></i>'
 +                    }
 +                ]
 +            }
 +        ],
 +        DOCUMENT : [
 +            {
 +                tag : 'div',
 +                cls : 'btn-group roo-upload-cropbox-rotate-left',
 +                action : 'rotate-left',
 +                cn : [
 +                    {
 +                        tag : 'button',
 +                        cls : 'btn btn-default',
 +                        html : '<i class="fa fa-undo"></i>'
 +                    }
 +                ]
 +            },
 +            {
 +                tag : 'div',
 +                cls : 'btn-group roo-upload-cropbox-download',
 +                action : 'download',
 +                cn : [
 +                    {
 +                        tag : 'button',
 +                        cls : 'btn btn-default',
 +                        html : '<i class="fa fa-download"></i>'
 +                    }
 +                ]
 +            },
 +            {
 +                tag : 'div',
 +                cls : 'btn-group roo-upload-cropbox-crop',
 +                action : 'crop',
 +                cn : [
 +                    {
 +                        tag : 'button',
 +                        cls : 'btn btn-default',
 +                        html : '<i class="fa fa-crop"></i>'
 +                    }
 +                ]
 +            },
 +            {
 +                tag : 'div',
 +                cls : 'btn-group roo-upload-cropbox-trash',
 +                action : 'trash',
 +                cn : [
 +                    {
 +                        tag : 'button',
 +                        cls : 'btn btn-default',
 +                        html : '<i class="fa fa-trash"></i>'
 +                    }
 +                ]
 +            },
 +            {
 +                tag : 'div',
 +                cls : 'btn-group roo-upload-cropbox-rotate-right',
 +                action : 'rotate-right',
 +                cn : [
 +                    {
 +                        tag : 'button',
 +                        cls : 'btn btn-default',
 +                        html : '<i class="fa fa-repeat"></i>'
 +                    }
 +                ]
 +            }
 +        ],
 +        ROTATOR : [
 +            {
 +                tag : 'div',
 +                cls : 'btn-group roo-upload-cropbox-rotate-left',
 +                action : 'rotate-left',
 +                cn : [
 +                    {
 +                        tag : 'button',
 +                        cls : 'btn btn-default',
 +                        html : '<i class="fa fa-undo"></i>'
 +                    }
 +                ]
 +            },
 +            {
 +                tag : 'div',
 +                cls : 'btn-group roo-upload-cropbox-rotate-right',
 +                action : 'rotate-right',
 +                cn : [
 +                    {
 +                        tag : 'button',
 +                        cls : 'btn btn-default',
 +                        html : '<i class="fa fa-repeat"></i>'
 +                    }
 +                ]
 +            }
 +        ]
 +    }
 +});
diff --combined roojs-ui-debug.js
@@@ -21160,6 -21160,8 +21160,8 @@@ Roo.htmleditor.Filter.prototype = 
                      return;
                  
                  case this.tag === true: // everything
+                 case e.tagName.indexOf(":") > -1 && typeof(this.tag) == 'object' && this.tag.indexOf(":") > -1:
+                 case e.tagName.indexOf(":") > -1 && typeof(this.tag) == 'string' && this.tag == ":":
                  case typeof(this.tag) == 'object' && this.tag.indexOf(e.tagName) > -1: // array and it matches.
                  case typeof(this.tag) == 'string' && this.tag == e.tagName: // array and it matches.
                      if (this.replaceTag && false === this.replaceTag(e)) {
@@@ -21587,6 -21589,7 +21589,7 @@@ Roo.htmleditor.FilterWord = function(cf
      // no need to apply config.
      this.replaceDocBullets(cfg.node);
      
+     // this is disabled as the removal is done by other filters;
     // this.walk(cfg.node);
      
      
@@@ -21716,16 -21719,29 +21719,29 @@@ Roo.extend(Roo.htmleditor.FilterWord, R
      replaceDocBullets : function(doc)
      {
          // this is a bit odd - but it appears some indents use ql-indent-1
+         //Roo.log(doc.innerHTML);
          
-         var listpara = doc.getElementsByClassName('ql-indent-1');
+         var listpara = doc.getElementsByClassName('MsoListParagraphCxSpFirst');
+         for( var i = 0; i < listpara.length; i ++) {
+             listpara.item(i).className = "MsoListParagraph";
+         }
+         // this is a bit hacky - we had one word document where h2 had a miso-list attribute.
+         var htwo = doc.getElementsByTagName('h2');
+         for( var i = 0; i < htwo.length; i ++) {
+             if (htwo.item(i).getAttribute('style').match(/mso-list:/)) {
+                 htwo.item(i).className = "MsoListParagraph";
+             }
+         }
+         
+         listpara = doc.getElementsByClassName('ql-indent-1');
          while(listpara.length) {
              this.replaceDocBullet(listpara.item(0));
          }
-         
-         var listpara = doc.getElementsByClassName('MsoListParagraph');
+         listpara = doc.getElementsByClassName('MsoListParagraph');
          while(listpara.length) {
              this.replaceDocBullet(listpara.item(0));
          }
+       
      },
      
      replaceDocBullet : function(p)
              if (nlvl > lvl) {
                  //new indent
                  var nul = doc.createElement('ul'); // what about number lists...
+                 if (!last_li) {
+                     last_li = doc.createElement('li');
+                     stack[lvl].appendChild(last_li);
+                 }
                  last_li.appendChild(nul);
                  stack[nlvl] = nul;
                  
@@@ -23316,7 -23336,17 +23336,17 @@@ Roo.htmleditor.KeyEnter.prototype = 
          var pc = range.closest([ 'ol', 'ul']);
          var pli = range.closest('li');
          if (!pc || e.ctrlKey) {
-             sel.insertNode('br', 'after'); 
+             // on it list, or ctrl pressed.
+             if (!e.ctrlKey) {
+                 sel.insertNode('br', 'after'); 
+             } else {
+                 // only do this if we have ctrl key..
+                 var br = doc.createElement('br');
+                 br.className = 'clear';
+                 br.setAttribute('style', 'clear: both');
+                 sel.insertNode(br, 'after'); 
+             }
+             
           
              this.core.undoManager.addEvent();
              this.core.fireEditorEvent(e);
@@@ -23680,9 -23710,11 +23710,11 @@@ Roo.extend(Roo.htmleditor.BlockFigure, 
                  store : {
                      xtype : 'SimpleStore',
                      data : [
-                         ['50%'],
+                         ['100%'],
                          ['80%'],
-                         ['100%']
+                         ['50%'],
+                         ['20%'],
+                         ['10%']
                      ],
                      fields : [ 'val'],
                      xns : Roo.data
@@@ -25791,7 -25823,7 +25823,7 @@@ Roo.extend(Roo.HtmlEditorCore, Roo.Comp
              });
              new Roo.htmleditor.FilterBlack({ node : d, tag : this.black});
              // should be fonts..
-             new Roo.htmleditor.FilterKeepChildren({node : d, tag : [ 'FONT', 'O:P' ]} );
+             new Roo.htmleditor.FilterKeepChildren({node : d, tag : [ 'FONT', ':' ]} );
              new Roo.htmleditor.FilterParagraph({ node : d });
              new Roo.htmleditor.FilterSpan({ node : d });
              new Roo.htmleditor.FilterLongBr({ node : d });
      cleanWord : function(node)
      {
          new Roo.htmleditor.FilterWord({ node : node ? node : this.doc.body });
+         new Roo.htmleditor.FilterKeepChildren({node : node ? node : this.doc.body, tag : [ 'FONT', ':' ]} );
          
      },
     
@@@ -35922,6 -35955,7 +35955,6 @@@ Roo.LayoutStateManager.prototype = 
   */
  Roo.ContentPanel = function(el, config, content){
      
 -     
      /*
      if(el.autoCreate || el.xtype){ // xtype is available if this is called from factory
          config = el;
@@@ -36305,14 -36339,6 +36338,14 @@@ layout.addxtype(
       */
      
      addxtype : function(cfg) {
 +        if(cfg.xtype.match(/^UploadCropbox$/)) {
 +
 +            this.cropbox = new Roo.factory(cfg);
 +
 +            this.cropbox.render(this.el);
 +
 +            return this.cropbox;
 +        }
          // add form..
          if (cfg.xtype.match(/^Form$/)) {
              
@@@ -43565,1803 -43591,4 +43598,1803 @@@ Roo.extend(Roo.XTemplate, Roo.Template
  Roo.XTemplate.from = function(el){
      el = Roo.getDom(el);
      return new Roo.XTemplate(el.value || el.innerHTML);
 -};
 +};Roo.dialog = {};
 +/*
 +* Licence: LGPL
 +*/
 +
 +/**
 + * @class Roo.dialog.UploadCropbox
 + * @extends Roo.BoxComponent
 + * Dialog UploadCropbox class
 + * @cfg {String} emptyText show when image has been loaded
 + * @cfg {String} rotateNotify show when image too small to rotate
 + * @cfg {Number} errorTimeout default 3000
 + * @cfg {Number} minWidth default 300
 + * @cfg {Number} minHeight default 300
 + * @cfg {Number} outputMaxWidth default 1200
 + * @cfg {Array} buttons default ['rotateLeft', 'pictureBtn', 'rotateRight']
 + * @cfg {Boolean} isDocument (true|false) default false
 + * @cfg {String} url action url
 + * @cfg {String} paramName default 'imageUpload'
 + * @cfg {String} method default POST
 + * @cfg {Boolean} loadMask (true|false) default true
 + * @cfg {Boolean} loadingText default 'Loading...'
 + * 
 + * @constructor
 + * Create a new UploadCropbox
 + * @param {Object} config The config object
 + */
 +
 + Roo.dialog.UploadCropbox = function(config){
 +    Roo.dialog.UploadCropbox.superclass.constructor.call(this, config);
 +    
 +    this.addEvents({
 +        /**
 +         * @event beforeselectfile
 +         * Fire before select file
 +         * @param {Roo.dialog.UploadCropbox} this
 +         */
 +        "beforeselectfile" : true,
 +        /**
 +         * @event initial
 +         * Fire after initEvent
 +         * @param {Roo.dialog.UploadCropbox} this
 +         */
 +        "initial" : true,
 +        /**
 +         * @event crop
 +         * Fire after initEvent
 +         * @param {Roo.dialog.UploadCropbox} this
 +         * @param {String} data
 +         */
 +        "crop" : true,
 +        /**
 +         * @event prepare
 +         * Fire when preparing the file data
 +         * @param {Roo.dialog.UploadCropbox} this
 +         * @param {Object} file
 +         */
 +        "prepare" : true,
 +        /**
 +         * @event exception
 +         * Fire when get exception
 +         * @param {Roo.dialog.UploadCropbox} this
 +         * @param {XMLHttpRequest} xhr
 +         */
 +        "exception" : true,
 +        /**
 +         * @event beforeloadcanvas
 +         * Fire before load the canvas
 +         * @param {Roo.dialog.UploadCropbox} this
 +         * @param {String} src
 +         */
 +        "beforeloadcanvas" : true,
 +        /**
 +         * @event trash
 +         * Fire when trash image
 +         * @param {Roo.dialog.UploadCropbox} this
 +         */
 +        "trash" : true,
 +        /**
 +         * @event download
 +         * Fire when download the image
 +         * @param {Roo.dialog.UploadCropbox} this
 +         */
 +        "download" : true,
 +        /**
 +         * @event footerbuttonclick
 +         * Fire when footerbuttonclick
 +         * @param {Roo.dialog.UploadCropbox} this
 +         * @param {String} type
 +         */
 +        "footerbuttonclick" : true,
 +        /**
 +         * @event resize
 +         * Fire when resize
 +         * @param {Roo.dialog.UploadCropbox} this
 +         */
 +        "resize" : true,
 +        /**
 +         * @event rotate
 +         * Fire when rotate the image
 +         * @param {Roo.dialog.UploadCropbox} this
 +         * @param {String} pos
 +         */
 +        "rotate" : true,
 +        /**
 +         * @event inspect
 +         * Fire when inspect the file
 +         * @param {Roo.dialog.UploadCropbox} this
 +         * @param {Object} file
 +         */
 +        "inspect" : true,
 +        /**
 +         * @event upload
 +         * Fire when xhr upload the file
 +         * @param {Roo.dialog.UploadCropbox} this
 +         * @param {Object} data
 +         */
 +        "upload" : true,
 +        /**
 +         * @event arrange
 +         * Fire when arrange the file data
 +         * @param {Roo.dialog.UploadCropbox} this
 +         * @param {Object} formData
 +         */
 +        "arrange" : true,
 +        /**
 +         * @event loadcanvas
 +         * Fire after load the canvas
 +         * @param {Roo.dialog.UploadCropbox}
 +         * @param {Object} imgEl
 +         */
 +        "loadcanvas" : true
 +    });
 +    
 +    this.buttons = this.buttons || Roo.dialog.UploadCropbox.footer.STANDARD;
 +};
 +
 +Roo.extend(Roo.dialog.UploadCropbox, Roo.Component,  {
 +    
 +    emptyText : 'Click to upload image',
 +    rotateNotify : 'Image is too small to rotate',
 +    errorTimeout : 3000,
 +    scale : 0,
 +    baseScale : 1,
 +    rotate : 0,
 +    dragable : false,
 +    pinching : false,
 +    mouseX : 0,
 +    mouseY : 0,
 +    cropData : false,
 +    minWidth : 300,
 +    minHeight : 300,
 +    outputMaxWidth : 1200,
 +    file : false,
 +    exif : {},
 +    baseRotate : 1,
 +    cropType : 'image/jpeg',
 +    buttons : false,
 +    canvasLoaded : false,
 +    isDocument : false,
 +    method : 'POST',
 +    paramName : 'imageUpload',
 +    loadMask : true,
 +    loadingText : 'Loading...',
 +    maskEl : false,
 +    
 +    getAutoCreate : function()
 +    {
 +        var cfg = {
 +            tag : 'div',
 +            cls : 'roo-upload-cropbox',
 +            cn : [
 +                {
 +                    tag : 'input',
 +                    cls : 'roo-upload-cropbox-selector',
 +                    type : 'file'
 +                },
 +                {
 +                    tag : 'div',
 +                    cls : 'roo-upload-cropbox-body',
 +                    style : 'cursor:pointer',
 +                    cn : [
 +                        {
 +                            tag : 'div',
 +                            cls : 'roo-upload-cropbox-preview'
 +                        },
 +                        {
 +                            tag : 'div',
 +                            cls : 'roo-upload-cropbox-thumb'
 +                        },
 +                        {
 +                            tag : 'div',
 +                            cls : 'roo-upload-cropbox-empty-notify',
 +                            html : this.emptyText
 +                        },
 +                        {
 +                            tag : 'div',
 +                            cls : 'roo-upload-cropbox-error-notify alert alert-danger',
 +                            html : this.rotateNotify
 +                        }
 +                    ]
 +                },
 +                {
 +                    tag : 'div',
 +                    cls : 'roo-upload-cropbox-footer',
 +                    cn : {
 +                        tag : 'div',
 +                        cls : 'btn-group btn-group-justified roo-upload-cropbox-btn-group',
 +                        cn : []
 +                    }
 +                }
 +            ]
 +        };
 +        
 +        return cfg;
 +    },
 +    
 +    onRender : function(ct, position)
 +    {
 +        Roo.dialog.UploadCropbox.superclass.onRender.call(this, ct, position);
 +
 +        if(this.el){
 +            if (this.el.attr('xtype')) {
 +                this.el.attr('xtypex', this.el.attr('xtype'));
 +                this.el.dom.removeAttribute('xtype');
 +                
 +                this.initEvents();
 +            }
 +        }
 +        else {
 +            var cfg = Roo.apply({},  this.getAutoCreate());
 +        
 +            cfg.id = this.id || Roo.id();
 +            
 +            if (this.cls) {
 +                cfg.cls = (typeof(cfg.cls) == 'undefined' ? this.cls : cfg.cls) + ' ' + this.cls;
 +            }
 +            
 +            if (this.style) { // fixme needs to support more complex style data.
 +                cfg.style = (typeof(cfg.style) == 'undefined' ? this.style : cfg.style) + '; ' + this.style;
 +            }
 +            
 +            this.el = ct.createChild(cfg, position);
 +            
 +            this.initEvents();
 +        }
 +        
 +        if (this.buttons.length) {
 +            
 +            Roo.each(this.buttons, function(bb) {
 +                
 +                var btn = this.el.select('.roo-upload-cropbox-footer div.roo-upload-cropbox-btn-group').first().createChild(bb);
 +                
 +                btn.on('click', this.onFooterButtonClick.createDelegate(this, [bb.action], true));
 +                
 +            }, this);
 +        }
 +        
 +        if(this.loadMask){
 +            this.maskEl = this.el;
 +        }
 +    },
 +    
 +    initEvents : function()
 +    {
 +        this.urlAPI = (window.createObjectURL && window) || 
 +                                (window.URL && URL.revokeObjectURL && URL) || 
 +                                (window.webkitURL && webkitURL);
 +                        
 +        this.bodyEl = this.el.select('.roo-upload-cropbox-body', true).first();
 +        this.bodyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
 +        
 +        this.selectorEl = this.el.select('.roo-upload-cropbox-selector', true).first();
 +        this.selectorEl.hide();
 +        
 +        this.previewEl = this.el.select('.roo-upload-cropbox-preview', true).first();
 +        this.previewEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
 +        
 +        this.thumbEl = this.el.select('.roo-upload-cropbox-thumb', true).first();
 +        this.thumbEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
 +        this.thumbEl.hide();
 +        
 +        this.notifyEl = this.el.select('.roo-upload-cropbox-empty-notify', true).first();
 +        this.notifyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
 +        
 +        this.errorEl = this.el.select('.roo-upload-cropbox-error-notify', true).first();
 +        this.errorEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
 +        this.errorEl.hide();
 +        
 +        this.footerEl = this.el.select('.roo-upload-cropbox-footer', true).first();
 +        this.footerEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
 +        this.footerEl.hide();
 +        
 +        this.setThumbBoxSize();
 +        
 +        this.bind();
 +        
 +        this.resize();
 +        
 +        this.fireEvent('initial', this);
 +    },
 +
 +    bind : function()
 +    {
 +        var _this = this;
 +        
 +        window.addEventListener("resize", function() { _this.resize(); } );
 +        
 +        this.bodyEl.on('click', this.beforeSelectFile, this);
 +        
 +        if(Roo.isTouch){
 +            this.bodyEl.on('touchstart', this.onTouchStart, this);
 +            this.bodyEl.on('touchmove', this.onTouchMove, this);
 +            this.bodyEl.on('touchend', this.onTouchEnd, this);
 +        }
 +        
 +        if(!Roo.isTouch){
 +            this.bodyEl.on('mousedown', this.onMouseDown, this);
 +            this.bodyEl.on('mousemove', this.onMouseMove, this);
 +            var mousewheel = (/Firefox/i.test(navigator.userAgent))? 'DOMMouseScroll' : 'mousewheel';
 +            this.bodyEl.on(mousewheel, this.onMouseWheel, this);
 +            Roo.get(document).on('mouseup', this.onMouseUp, this);
 +        }
 +        
 +        this.selectorEl.on('change', this.onFileSelected, this);
 +    },
 +    
 +    reset : function()
 +    {    
 +        this.scale = 0;
 +        this.baseScale = 1;
 +        this.rotate = 0;
 +        this.baseRotate = 1;
 +        this.dragable = false;
 +        this.pinching = false;
 +        this.mouseX = 0;
 +        this.mouseY = 0;
 +        this.cropData = false;
 +        this.notifyEl.dom.innerHTML = this.emptyText;
 +        
 +        // this.selectorEl.dom.value = '';
 +        
 +    },
 +    
 +    resize : function()
 +    {
 +        if(this.fireEvent('resize', this) != false){
 +            this.setThumbBoxPosition();
 +            this.setCanvasPosition();
 +        }
 +    },
 +    
 +    onFooterButtonClick : function(e, el, o, type)
 +    {
 +        switch (type) {
 +            case 'rotate-left' :
 +                this.onRotateLeft(e);
 +                break;
 +            case 'rotate-right' :
 +                this.onRotateRight(e);
 +                break;
 +            case 'picture' :
 +                this.beforeSelectFile(e);
 +                break;
 +            case 'trash' :
 +                this.trash(e);
 +                break;
 +            case 'crop' :
 +                this.crop(e);
 +                break;
 +            case 'download' :
 +                this.download(e);
 +                break;
 +            default :
 +                break;
 +        }
 +        
 +        this.fireEvent('footerbuttonclick', this, type);
 +    },
 +    
 +    beforeSelectFile : function(e)
 +    {
 +        e.preventDefault();
 +        
 +        if(this.fireEvent('beforeselectfile', this) != false){
 +            this.selectorEl.dom.click();
 +        }
 +    },
 +    
 +    onFileSelected : function(e)
 +    {
 +        e.preventDefault();
 +        
 +        if(typeof(this.selectorEl.dom.files) == 'undefined' || !this.selectorEl.dom.files.length){
 +            return;
 +        }
 +        
 +        var file = this.selectorEl.dom.files[0];
 +        
 +        if(this.fireEvent('inspect', this, file) != false){
 +            this.prepare(file);
 +        }
 +        
 +    },
 +    
 +    trash : function(e)
 +    {
 +        this.fireEvent('trash', this);
 +    },
 +    
 +    download : function(e)
 +    {
 +        this.fireEvent('download', this);
 +    },
 +    
 +    loadCanvas : function(src)
 +    {   
 +        if(this.fireEvent('beforeloadcanvas', this, src) != false){
 +            
 +            this.reset();
 +            
 +            this.imageEl = document.createElement('img');
 +            
 +            var _this = this;
 +            
 +            this.imageEl.addEventListener("load", function(){ _this.onLoadCanvas(); });
 +            
 +            this.imageEl.src = src;
 +        }
 +    },
 +    
 +    onLoadCanvas : function()
 +    {   
 +        this.imageEl.OriginWidth = this.imageEl.naturalWidth || this.imageEl.width;
 +        this.imageEl.OriginHeight = this.imageEl.naturalHeight || this.imageEl.height;
 +
 +        if(this.fireEvent('loadcanvas', this, this.imageEl) != false){
 +        
 +            this.bodyEl.un('click', this.beforeSelectFile, this);
 +            
 +            this.notifyEl.hide();
 +            this.thumbEl.show();
 +            this.footerEl.show();
 +            
 +            this.baseRotateLevel();
 +            
 +            if(this.isDocument){
 +                this.setThumbBoxSize();
 +            }
 +            
 +            this.setThumbBoxPosition();
 +            
 +            this.baseScaleLevel();
 +            
 +            this.draw();
 +            
 +            this.resize();
 +            
 +            this.canvasLoaded = true;
 +        
 +        }
 +        
 +        if(this.loadMask){
 +            this.maskEl.unmask();
 +        }
 +        
 +    },
 +    
 +    setCanvasPosition : function()
 +    {   
 +        if(!this.canvasEl){
 +            return;
 +        }
 +        
 +        var pw = Math.ceil((this.bodyEl.getWidth() - this.canvasEl.width) / 2);
 +        var ph = Math.ceil((this.bodyEl.getHeight() - this.canvasEl.height) / 2);
 +        
 +        this.previewEl.setLeft(pw);
 +        this.previewEl.setTop(ph);
 +        
 +    },
 +    
 +    onMouseDown : function(e)
 +    {   
 +        e.stopEvent();
 +        
 +        this.dragable = true;
 +        this.pinching = false;
 +        
 +        if(this.isDocument && (this.canvasEl.width < this.thumbEl.getWidth() || this.canvasEl.height < this.thumbEl.getHeight())){
 +            this.dragable = false;
 +            return;
 +        }
 +        
 +        this.mouseX = Roo.isTouch ? e.browserEvent.touches[0].pageX : e.getPageX();
 +        this.mouseY = Roo.isTouch ? e.browserEvent.touches[0].pageY : e.getPageY();
 +        
 +    },
 +    
 +    onMouseMove : function(e)
 +    {   
 +        e.stopEvent();
 +        
 +        if(!this.canvasLoaded){
 +            return;
 +        }
 +        
 +        if (!this.dragable){
 +            return;
 +        }
 +        
 +        var minX = Math.ceil(this.thumbEl.getLeft(true));
 +        var minY = Math.ceil(this.thumbEl.getTop(true));
 +        
 +        var maxX = Math.ceil(minX + this.thumbEl.getWidth() - this.canvasEl.width);
 +        var maxY = Math.ceil(minY + this.thumbEl.getHeight() - this.canvasEl.height);
 +
 +        if(minX > maxX) {
 +            var tempX = minX;
 +            minX = maxX;
 +            maxX = tempX;
 +        }
 +
 +        if(minY > maxY) {
 +            var tempY = minY;
 +            minY = maxY;
 +            maxY = tempY;
 +        }
 +
 +        var x = Roo.isTouch ? e.browserEvent.touches[0].pageX : e.getPageX();
 +        var y = Roo.isTouch ? e.browserEvent.touches[0].pageY : e.getPageY();
 +        
 +        x = x - this.mouseX;
 +        y = y - this.mouseY;
 +
 +        var bgX = Math.ceil(x + this.previewEl.getLeft(true));
 +        var bgY = Math.ceil(y + this.previewEl.getTop(true));
 +        
 +        bgX = (bgX < minX) ? minX : ((bgX > maxX) ? maxX : bgX);
 +        bgY = (bgY < minY) ? minY : ((bgY > maxY) ? maxY : bgY);
 +        
 +        this.previewEl.setLeft(bgX);
 +        this.previewEl.setTop(bgY);
 +        
 +        this.mouseX = Roo.isTouch ? e.browserEvent.touches[0].pageX : e.getPageX();
 +        this.mouseY = Roo.isTouch ? e.browserEvent.touches[0].pageY : e.getPageY();
 +    },
 +    
 +    onMouseUp : function(e)
 +    {   
 +        e.stopEvent();
 +        
 +        this.dragable = false;
 +    },
 +    
 +    onMouseWheel : function(e)
 +    {   
 +        e.stopEvent();
 +        
 +        this.startScale = this.scale;
 +        this.scale = (e.getWheelDelta() == 1) ? (this.scale + 1) : (this.scale - 1);
 +        
 +        if(!this.zoomable()){
 +            this.scale = this.startScale;
 +            return;
 +        }
 +
 +        
 +        this.draw();
 +        
 +        return;
 +    },
 +    
 +    zoomable : function()
 +    {
 +        var minScale = this.thumbEl.getWidth() / this.minWidth;
 +        
 +        if(this.minWidth < this.minHeight){
 +            minScale = this.thumbEl.getHeight() / this.minHeight;
 +        }
 +        
 +        var width = Math.ceil(this.imageEl.OriginWidth * this.getScaleLevel() / minScale);
 +        var height = Math.ceil(this.imageEl.OriginHeight * this.getScaleLevel() / minScale);
 +
 +
 +        var maxWidth = this.imageEl.OriginWidth;
 +        var maxHeight = this.imageEl.OriginHeight;
 +        
 +        if(
 +                this.isDocument &&
 +                (this.rotate == 0 || this.rotate == 180) && 
 +                (
 +                    width > this.imageEl.OriginWidth || 
 +                    height > this.imageEl.OriginHeight ||
 +                    (width < this.minWidth && height < this.minHeight)
 +                )
 +        ){
 +            return false;
 +        }
 +        
 +        if(
 +                this.isDocument &&
 +                (this.rotate == 90 || this.rotate == 270) && 
 +                (
 +                    width > this.imageEl.OriginWidth || 
 +                    height > this.imageEl.OriginHeight ||
 +                    (width < this.minHeight && height < this.minWidth)
 +                )
 +        ){
 +            return false;
 +        }
 +        
 +        if(
 +                !this.isDocument &&
 +                (this.rotate == 0 || this.rotate == 180) && 
 +                (
 +                    (this.imageEl.OriginWidth >= this.minWidth) && width < this.minWidth ||
 +                    (this.imageEl.OriginHeight >= this.minHeight) && height < this.minHeight ||
 +                    width > maxWidth ||
 +                    height > maxHeight
 +                )
 +        ){
 +            return false;
 +        }
 +        
 +        if(
 +                !this.isDocument &&
 +                (this.rotate == 90 || this.rotate == 270) && 
 +                (
 +                    width < this.minHeight || 
 +                    width > this.imageEl.OriginWidth || 
 +                    height < this.minWidth || 
 +                    height > this.imageEl.OriginHeight
 +                )
 +        ){
 +            return false;
 +        }
 +        
 +        return true;
 +        
 +    },
 +    
 +    onRotateLeft : function(e)
 +    {   
 +        if(!this.isDocument && (this.canvasEl.height < this.thumbEl.getWidth() || this.canvasEl.width < this.thumbEl.getHeight())){
 +            
 +            var minScale = this.thumbEl.getWidth() / this.minWidth;
 +            
 +            var bw = Math.ceil(this.canvasEl.width / this.getScaleLevel());
 +            var bh = Math.ceil(this.canvasEl.height / this.getScaleLevel());
 +            
 +            this.startScale = this.scale;
 +            
 +            while (this.getScaleLevel() < minScale){
 +            
 +                this.scale = this.scale + 1;
 +                
 +                if(!this.zoomable()){
 +                    break;
 +                }
 +                
 +                if(
 +                        Math.ceil(bw * this.getScaleLevel()) < this.thumbEl.getHeight() ||
 +                        Math.ceil(bh * this.getScaleLevel()) < this.thumbEl.getWidth()
 +                ){
 +                    continue;
 +                }
 +                
 +                this.rotate = (this.rotate < 90) ? 270 : this.rotate - 90;
 +
 +                this.draw();
 +                
 +                return;
 +            }
 +            
 +            this.scale = this.startScale;
 +            
 +            this.onRotateFail();
 +            
 +            return false;
 +        }
 +        
 +        this.rotate = (this.rotate < 90) ? 270 : this.rotate - 90;
 +
 +        if(this.isDocument){
 +            this.setThumbBoxSize();
 +            this.setThumbBoxPosition();
 +            this.setCanvasPosition();
 +        }
 +        
 +        this.draw();
 +        
 +        this.fireEvent('rotate', this, 'left');
 +        
 +    },
 +    
 +    onRotateRight : function(e)
 +    {
 +        if(!this.isDocument && (this.canvasEl.height < this.thumbEl.getWidth() || this.canvasEl.width < this.thumbEl.getHeight())){
 +            
 +            var minScale = this.thumbEl.getWidth() / this.minWidth;
 +        
 +            var bw = Math.ceil(this.canvasEl.width / this.getScaleLevel());
 +            var bh = Math.ceil(this.canvasEl.height / this.getScaleLevel());
 +            
 +            this.startScale = this.scale;
 +            
 +            while (this.getScaleLevel() < minScale){
 +            
 +                this.scale = this.scale + 1;
 +                
 +                if(!this.zoomable()){
 +                    break;
 +                }
 +                
 +                if(
 +                        Math.ceil(bw * this.getScaleLevel()) < this.thumbEl.getHeight() ||
 +                        Math.ceil(bh * this.getScaleLevel()) < this.thumbEl.getWidth()
 +                ){
 +                    continue;
 +                }
 +                
 +                this.rotate = (this.rotate > 180) ? 0 : this.rotate + 90;
 +
 +                this.draw();
 +                
 +                return;
 +            }
 +            
 +            this.scale = this.startScale;
 +            
 +            this.onRotateFail();
 +            
 +            return false;
 +        }
 +        
 +        this.rotate = (this.rotate > 180) ? 0 : this.rotate + 90;
 +
 +        if(this.isDocument){
 +            this.setThumbBoxSize();
 +            this.setThumbBoxPosition();
 +            this.setCanvasPosition();
 +        }
 +        
 +        this.draw();
 +        
 +        this.fireEvent('rotate', this, 'right');
 +    },
 +    
 +    onRotateFail : function()
 +    {
 +        this.errorEl.show(true);
 +        
 +        var _this = this;
 +        
 +        (function() { _this.errorEl.hide(true); }).defer(this.errorTimeout);
 +    },
 +    
 +    draw : function()
 +    {
 +        this.previewEl.dom.innerHTML = '';
 +        
 +        var canvasEl = document.createElement("canvas");
 +        
 +        var contextEl = canvasEl.getContext("2d");
 +        
 +        canvasEl.width = this.imageEl.OriginWidth * this.getScaleLevel();
 +        canvasEl.height = this.imageEl.OriginWidth * this.getScaleLevel();
 +        var center = this.imageEl.OriginWidth / 2;
 +        
 +        if(this.imageEl.OriginWidth < this.imageEl.OriginHeight){
 +            canvasEl.width = this.imageEl.OriginHeight * this.getScaleLevel();
 +            canvasEl.height = this.imageEl.OriginHeight * this.getScaleLevel();
 +            center = this.imageEl.OriginHeight / 2;
 +        }
 +        
 +        contextEl.scale(this.getScaleLevel(), this.getScaleLevel());
 +        
 +        contextEl.translate(center, center);
 +        contextEl.rotate(this.rotate * Math.PI / 180);
 +
 +        contextEl.drawImage(this.imageEl, 0, 0, this.imageEl.OriginWidth, this.imageEl.OriginHeight, center * -1, center * -1, this.imageEl.OriginWidth, this.imageEl.OriginHeight);
 +        
 +        this.canvasEl = document.createElement("canvas");
 +        
 +        this.contextEl = this.canvasEl.getContext("2d");
 +        
 +        switch (this.rotate) {
 +            case 0 :
 +                
 +                this.canvasEl.width = this.imageEl.OriginWidth * this.getScaleLevel();
 +                this.canvasEl.height = this.imageEl.OriginHeight * this.getScaleLevel();
 +                
 +                this.contextEl.drawImage(canvasEl, 0, 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
 +                
 +                break;
 +            case 90 : 
 +                
 +                this.canvasEl.width = this.imageEl.OriginHeight * this.getScaleLevel();
 +                this.canvasEl.height = this.imageEl.OriginWidth * this.getScaleLevel();
 +                
 +                if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){
 +                    this.contextEl.drawImage(canvasEl, Math.abs(this.canvasEl.width - this.canvasEl.height), 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
 +                    break;
 +                }
 +                
 +                this.contextEl.drawImage(canvasEl, 0, 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
 +                
 +                break;
 +            case 180 :
 +                
 +                this.canvasEl.width = this.imageEl.OriginWidth * this.getScaleLevel();
 +                this.canvasEl.height = this.imageEl.OriginHeight * this.getScaleLevel();
 +                
 +                if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){
 +                    this.contextEl.drawImage(canvasEl, 0, Math.abs(this.canvasEl.width - this.canvasEl.height), this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
 +                    break;
 +                }
 +                
 +                this.contextEl.drawImage(canvasEl, Math.abs(this.canvasEl.width - this.canvasEl.height), 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
 +                
 +                break;
 +            case 270 :
 +                
 +                this.canvasEl.width = this.imageEl.OriginHeight * this.getScaleLevel();
 +                this.canvasEl.height = this.imageEl.OriginWidth * this.getScaleLevel();
 +        
 +                if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){
 +                    this.contextEl.drawImage(canvasEl, 0, 0, this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
 +                    break;
 +                }
 +                
 +                this.contextEl.drawImage(canvasEl, 0, Math.abs(this.canvasEl.width - this.canvasEl.height), this.canvasEl.width, this.canvasEl.height, 0, 0, this.canvasEl.width, this.canvasEl.height);
 +                
 +                break;
 +            default : 
 +                break;
 +        }
 +        
 +        this.previewEl.appendChild(this.canvasEl);
 +        
 +        this.setCanvasPosition();
 +    },
 +    
 +    crop : function()
 +    {
 +        if(!this.canvasLoaded){
 +            return;
 +        }
 +        
 +        var imageCanvas = document.createElement("canvas");
 +        
 +        var imageContext = imageCanvas.getContext("2d");
 +        
 +        imageCanvas.width = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? this.imageEl.OriginWidth : this.imageEl.OriginHeight;
 +        imageCanvas.height = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? this.imageEl.OriginWidth : this.imageEl.OriginHeight;
 +        
 +        var center = imageCanvas.width / 2;
 +        
 +        imageContext.translate(center, center);
 +        
 +        imageContext.rotate(this.rotate * Math.PI / 180);
 +        
 +        imageContext.drawImage(this.imageEl, 0, 0, this.imageEl.OriginWidth, this.imageEl.OriginHeight, center * -1, center * -1, this.imageEl.OriginWidth, this.imageEl.OriginHeight);
 +        
 +        var canvas = document.createElement("canvas");
 +        
 +        var context = canvas.getContext("2d");
 +
 +        canvas.width = this.thumbEl.getWidth() / this.getScaleLevel();
 +        
 +        canvas.height = this.thumbEl.getHeight() / this.getScaleLevel();
 +
 +        switch (this.rotate) {
 +            case 0 :
 +                
 +                var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getWidth() / this.getScaleLevel());
 +                var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getHeight() / this.getScaleLevel());
 +                
 +                var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel());
 +                var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel());
 +                
 +                var sx = this.thumbEl.getLeft(true) - this.previewEl.getLeft(true);
 +                var sy = this.thumbEl.getTop(true) - this.previewEl.getTop(true);
 +
 +                sx = sx < 0 ? 0 : (sx / this.getScaleLevel());
 +                sy = sy < 0 ? 0 : (sy / this.getScaleLevel());
 +
 +                if(canvas.width > this.outputMaxWidth) {
 +                    var scale = this.outputMaxWidth / canvas.width;
 +                    canvas.width = canvas.width * scale;
 +                    canvas.height = canvas.height * scale;
 +                    context.scale(scale, scale);
 +                }
 +
 +                context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height);
 +                
 +                break;
 +            case 90 : 
 +                
 +                var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getWidth() / this.getScaleLevel());
 +                var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getHeight() / this.getScaleLevel());
 +                
 +                var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel());
 +                var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel());
 +                
 +                var targetWidth = this.minWidth - 2 * x;
 +                var targetHeight = this.minHeight - 2 * y;
 +                
 +                var scale = 1;
 +                
 +                if((x == 0 && y == 0) || (x == 0 && y > 0)){
 +                    scale = targetWidth / width;
 +                }
 +                
 +                if(x > 0 && y == 0){
 +                    scale = targetHeight / height;
 +                }
 +                
 +                if(x > 0 && y > 0){
 +                    scale = targetWidth / width;
 +                    
 +                    if(width < height){
 +                        scale = targetHeight / height;
 +                    }
 +                }
 +                
 +                context.scale(scale, scale);
 +                
 +                var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true));
 +                var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true));
 +
 +                sx = sx < 0 ? 0 : (sx / this.getScaleLevel());
 +                sy = sy < 0 ? 0 : (sy / this.getScaleLevel());
 +                
 +                sx += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight) : 0;
 +                
 +                context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height);
 +                
 +                break;
 +            case 180 :
 +                
 +                var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getWidth() / this.getScaleLevel());
 +                var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getHeight() / this.getScaleLevel());
 +                
 +                var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel());
 +                var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel());
 +                
 +                var targetWidth = this.minWidth - 2 * x;
 +                var targetHeight = this.minHeight - 2 * y;
 +                
 +                var scale = 1;
 +                
 +                if((x == 0 && y == 0) || (x == 0 && y > 0)){
 +                    scale = targetWidth / width;
 +                }
 +                
 +                if(x > 0 && y == 0){
 +                    scale = targetHeight / height;
 +                }
 +                
 +                if(x > 0 && y > 0){
 +                    scale = targetWidth / width;
 +                    
 +                    if(width < height){
 +                        scale = targetHeight / height;
 +                    }
 +                }
 +                
 +                context.scale(scale, scale);
 +                
 +                var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true));
 +                var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true));
 +
 +                sx = sx < 0 ? 0 : (sx / this.getScaleLevel());
 +                sy = sy < 0 ? 0 : (sy / this.getScaleLevel());
 +
 +                sx += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? 0 : Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight);
 +                sy += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight) : 0;
 +                
 +                context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height);
 +                
 +                break;
 +            case 270 :
 +                
 +                var width = (this.thumbEl.getWidth() / this.getScaleLevel() > this.imageEl.OriginHeight) ? this.imageEl.OriginHeight : (this.thumbEl.getWidth() / this.getScaleLevel());
 +                var height = (this.thumbEl.getHeight() / this.getScaleLevel() > this.imageEl.OriginWidth) ? this.imageEl.OriginWidth : (this.thumbEl.getHeight() / this.getScaleLevel());
 +                
 +                var x = (this.thumbEl.getLeft(true) > this.previewEl.getLeft(true)) ? 0 : ((this.previewEl.getLeft(true) - this.thumbEl.getLeft(true)) / this.getScaleLevel());
 +                var y = (this.thumbEl.getTop(true) > this.previewEl.getTop(true)) ? 0 : ((this.previewEl.getTop(true) - this.thumbEl.getTop(true)) / this.getScaleLevel());
 +                
 +                var targetWidth = this.minWidth - 2 * x;
 +                var targetHeight = this.minHeight - 2 * y;
 +                
 +                var scale = 1;
 +                
 +                if((x == 0 && y == 0) || (x == 0 && y > 0)){
 +                    scale = targetWidth / width;
 +                }
 +                
 +                if(x > 0 && y == 0){
 +                    scale = targetHeight / height;
 +                }
 +                
 +                if(x > 0 && y > 0){
 +                    scale = targetWidth / width;
 +                    
 +                    if(width < height){
 +                        scale = targetHeight / height;
 +                    }
 +                }
 +                
 +                context.scale(scale, scale);
 +                var sx = Math.min(this.canvasEl.width - this.thumbEl.getWidth(), this.thumbEl.getLeft(true) - this.previewEl.getLeft(true));
 +                var sy = Math.min(this.canvasEl.height - this.thumbEl.getHeight(), this.thumbEl.getTop(true) - this.previewEl.getTop(true));
 +
 +                sx = sx < 0 ? 0 : (sx / this.getScaleLevel());
 +                sy = sy < 0 ? 0 : (sy / this.getScaleLevel());
 +                
 +                sy += (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? 0 : Math.abs(this.imageEl.OriginWidth - this.imageEl.OriginHeight);
 +                
 +                context.drawImage(imageCanvas, sx, sy, width, height, x, y, width, height);
 +                
 +                break;
 +            default : 
 +                break;
 +        }
 +        
 +        this.cropData = canvas.toDataURL(this.cropType);
 +        
 +        if(this.fireEvent('crop', this, this.cropData) !== false){
 +            this.process(this.file, this.cropData);
 +        }
 +        
 +        return;
 +        
 +    },
 +    
 +    setThumbBoxSize : function()
 +    {
 +        var width, height;
 +        
 +        if(this.isDocument && typeof(this.imageEl) != 'undefined'){
 +            width = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.max(this.minWidth, this.minHeight) : Math.min(this.minWidth, this.minHeight);
 +            height = (this.imageEl.OriginWidth > this.imageEl.OriginHeight) ? Math.min(this.minWidth, this.minHeight) : Math.max(this.minWidth, this.minHeight);
 +            
 +            this.minWidth = width;
 +            this.minHeight = height;
 +            
 +            if(this.rotate == 90 || this.rotate == 270){
 +                this.minWidth = height;
 +                this.minHeight = width;
 +            }
 +        }
 +        
 +        height = 300;
 +        width = Math.ceil(this.minWidth * height / this.minHeight);
 +        
 +        if(this.minWidth > this.minHeight){
 +            width = 300;
 +            height = Math.ceil(this.minHeight * width / this.minWidth);
 +        }
 +        
 +        this.thumbEl.setStyle({
 +            width : width + 'px',
 +            height : height + 'px'
 +        });
 +
 +        return;
 +            
 +    },
 +    
 +    setThumbBoxPosition : function()
 +    {
 +        var x = Math.ceil((this.bodyEl.getWidth() - this.thumbEl.getWidth()) / 2 );
 +        var y = Math.ceil((this.bodyEl.getHeight() - this.thumbEl.getHeight()) / 2);
 +        
 +        this.thumbEl.setLeft(x);
 +        this.thumbEl.setTop(y);
 +        
 +    },
 +    
 +    baseRotateLevel : function()
 +    {
 +        this.baseRotate = 1;
 +        
 +        if(
 +                typeof(this.exif) != 'undefined' &&
 +                typeof(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']]) != 'undefined' &&
 +                [1, 3, 6, 8].indexOf(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']]) != -1
 +        ){
 +            this.baseRotate = this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']];
 +        }
 +        
 +        this.rotate = Roo.dialog.UploadCropbox['Orientation'][this.baseRotate];
 +        
 +    },
 +    
 +    baseScaleLevel : function()
 +    {
 +        var width, height;
 +        
 +        if(this.isDocument){
 +            
 +            if(this.baseRotate == 6 || this.baseRotate == 8){
 +            
 +                height = this.thumbEl.getHeight();
 +                this.baseScale = height / this.imageEl.OriginWidth;
 +
 +                if(this.imageEl.OriginHeight * this.baseScale > this.thumbEl.getWidth()){
 +                    width = this.thumbEl.getWidth();
 +                    this.baseScale = width / this.imageEl.OriginHeight;
 +                }
 +
 +                return;
 +            }
 +
 +            height = this.thumbEl.getHeight();
 +            this.baseScale = height / this.imageEl.OriginHeight;
 +
 +            if(this.imageEl.OriginWidth * this.baseScale > this.thumbEl.getWidth()){
 +                width = this.thumbEl.getWidth();
 +                this.baseScale = width / this.imageEl.OriginWidth;
 +            }
 +
 +            return;
 +        }
 +        
 +        if(this.baseRotate == 6 || this.baseRotate == 8){
 +            
 +            width = this.thumbEl.getHeight();
 +            this.baseScale = width / this.imageEl.OriginHeight;
 +            
 +            if(this.imageEl.OriginHeight * this.baseScale < this.thumbEl.getWidth()){
 +                height = this.thumbEl.getWidth();
 +                this.baseScale = height / this.imageEl.OriginHeight;
 +            }
 +            
 +            if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){
 +                height = this.thumbEl.getWidth();
 +                this.baseScale = height / this.imageEl.OriginHeight;
 +                
 +                if(this.imageEl.OriginWidth * this.baseScale < this.thumbEl.getHeight()){
 +                    width = this.thumbEl.getHeight();
 +                    this.baseScale = width / this.imageEl.OriginWidth;
 +                }
 +            }
 +            
 +            return;
 +        }
 +        
 +        width = this.thumbEl.getWidth();
 +        this.baseScale = width / this.imageEl.OriginWidth;
 +        
 +        if(this.imageEl.OriginHeight * this.baseScale < this.thumbEl.getHeight()){
 +            height = this.thumbEl.getHeight();
 +            this.baseScale = height / this.imageEl.OriginHeight;
 +        }
 +        
 +        if(this.imageEl.OriginWidth > this.imageEl.OriginHeight){
 +            
 +            height = this.thumbEl.getHeight();
 +            this.baseScale = height / this.imageEl.OriginHeight;
 +            
 +            if(this.imageEl.OriginWidth * this.baseScale < this.thumbEl.getWidth()){
 +                width = this.thumbEl.getWidth();
 +                this.baseScale = width / this.imageEl.OriginWidth;
 +            }
 +            
 +        }
 +
 +        if(this.imageEl.OriginWidth < this.minWidth || this.imageEl.OriginHeight < this.minHeight) {
 +            this.baseScale = width / this.minWidth;
 +        }
 +
 +        return;
 +    },
 +    
 +    getScaleLevel : function()
 +    {
 +        return this.baseScale * Math.pow(1.02, this.scale);
 +    },
 +    
 +    onTouchStart : function(e)
 +    {
 +        if(!this.canvasLoaded){
 +            this.beforeSelectFile(e);
 +            return;
 +        }
 +        
 +        var touches = e.browserEvent.touches;
 +        
 +        if(!touches){
 +            return;
 +        }
 +        
 +        if(touches.length == 1){
 +            this.onMouseDown(e);
 +            return;
 +        }
 +        
 +        if(touches.length != 2){
 +            return;
 +        }
 +        
 +        var coords = [];
 +        
 +        for(var i = 0, finger; finger = touches[i]; i++){
 +            coords.push(finger.pageX, finger.pageY);
 +        }
 +        
 +        var x = Math.pow(coords[0] - coords[2], 2);
 +        var y = Math.pow(coords[1] - coords[3], 2);
 +        
 +        this.startDistance = Math.sqrt(x + y);
 +        
 +        this.startScale = this.scale;
 +        
 +        this.pinching = true;
 +        this.dragable = false;
 +        
 +    },
 +    
 +    onTouchMove : function(e)
 +    {
 +        if(!this.pinching && !this.dragable){
 +            return;
 +        }
 +        
 +        var touches = e.browserEvent.touches;
 +        
 +        if(!touches){
 +            return;
 +        }
 +        
 +        if(this.dragable){
 +            this.onMouseMove(e);
 +            return;
 +        }
 +        
 +        var coords = [];
 +        
 +        for(var i = 0, finger; finger = touches[i]; i++){
 +            coords.push(finger.pageX, finger.pageY);
 +        }
 +        
 +        var x = Math.pow(coords[0] - coords[2], 2);
 +        var y = Math.pow(coords[1] - coords[3], 2);
 +        
 +        this.endDistance = Math.sqrt(x + y);
 +        
 +        this.scale = this.startScale + Math.floor(Math.log(this.endDistance / this.startDistance) / Math.log(1.1));
 +        
 +        if(!this.zoomable()){
 +            this.scale = this.startScale;
 +            return;
 +        }
 +        
 +        this.draw();
 +        
 +    },
 +    
 +    onTouchEnd : function(e)
 +    {
 +        this.pinching = false;
 +        this.dragable = false;
 +        
 +    },
 +    
 +    process : function(file, crop)
 +    {
 +        if(this.loadMask){
 +            this.maskEl.mask(this.loadingText);
 +        }
 +        
 +        this.xhr = new XMLHttpRequest();
 +        
 +        file.xhr = this.xhr;
 +
 +        this.xhr.open(this.method, this.url, true);
 +        
 +        var headers = {
 +            "Accept": "application/json",
 +            "Cache-Control": "no-cache",
 +            "X-Requested-With": "XMLHttpRequest"
 +        };
 +        
 +        for (var headerName in headers) {
 +            var headerValue = headers[headerName];
 +            if (headerValue) {
 +                this.xhr.setRequestHeader(headerName, headerValue);
 +            }
 +        }
 +        
 +        var _this = this;
 +        
 +        this.xhr.onload = function()
 +        {
 +            _this.xhrOnLoad(_this.xhr);
 +        }
 +        
 +        this.xhr.onerror = function()
 +        {
 +            _this.xhrOnError(_this.xhr);
 +        }
 +        
 +        var formData = new FormData();
 +
 +        formData.append('returnHTML', 'NO');
 +
 +        if(crop){
 +            formData.append('crop', crop);
 +            var blobBin = atob(crop.split(',')[1]);
 +            var array = [];
 +            for(var i = 0; i < blobBin.length; i++) {
 +                array.push(blobBin.charCodeAt(i));
 +            }
 +            var croppedFile =new Blob([new Uint8Array(array)], {type: this.cropType});
 +            formData.append(this.paramName, croppedFile, file.name);
 +        }
 +        
 +        if(typeof(file.filename) != 'undefined'){
 +            formData.append('filename', file.filename);
 +        }
 +        
 +        if(typeof(file.mimetype) != 'undefined'){
 +            formData.append('mimetype', file.mimetype);
 +        }
 +
 +        if(this.fireEvent('arrange', this, formData) != false){
 +            this.xhr.send(formData);
 +        };
 +    },
 +    
 +    xhrOnLoad : function(xhr)
 +    {
 +        if(this.loadMask){
 +            this.maskEl.unmask();
 +        }
 +        
 +        if (xhr.readyState !== 4) {
 +            this.fireEvent('exception', this, xhr);
 +            return;
 +        }
 +
 +        var response = Roo.decode(xhr.responseText);
 +        
 +        if(!response.success){
 +            this.fireEvent('exception', this, xhr);
 +            return;
 +        }
 +        
 +        var response = Roo.decode(xhr.responseText);
 +        
 +        this.fireEvent('upload', this, response);
 +        
 +    },
 +    
 +    xhrOnError : function()
 +    {
 +        if(this.loadMask){
 +            this.maskEl.unmask();
 +        }
 +        
 +        Roo.log('xhr on error');
 +        
 +        var response = Roo.decode(xhr.responseText);
 +          
 +        Roo.log(response);
 +        
 +    },
 +    
 +    prepare : function(file)
 +    {   
 +        if(this.loadMask){
 +            this.maskEl.mask(this.loadingText);
 +        }
 +        
 +        this.file = false;
 +        this.exif = {};
 +        
 +        if(typeof(file) === 'string'){
 +            this.loadCanvas(file);
 +            return;
 +        }
 +        
 +        if(!file || !this.urlAPI){
 +            return;
 +        }
 +        
 +        this.file = file;
 +        if(typeof(file.type) != 'undefined' && file.type.length != 0) {
 +            this.cropType = file.type;
 +        }
 +        
 +        var _this = this;
 +        
 +        if(this.fireEvent('prepare', this, this.file) != false){
 +            
 +            var reader = new FileReader();
 +            
 +            reader.onload = function (e) {
 +                if (e.target.error) {
 +                    Roo.log(e.target.error);
 +                    return;
 +                }
 +                
 +                var buffer = e.target.result,
 +                    dataView = new DataView(buffer),
 +                    offset = 2,
 +                    maxOffset = dataView.byteLength - 4,
 +                    markerBytes,
 +                    markerLength;
 +                
 +                if (dataView.getUint16(0) === 0xffd8) {
 +                    while (offset < maxOffset) {
 +                        markerBytes = dataView.getUint16(offset);
 +                        
 +                        if ((markerBytes >= 0xffe0 && markerBytes <= 0xffef) || markerBytes === 0xfffe) {
 +                            markerLength = dataView.getUint16(offset + 2) + 2;
 +                            if (offset + markerLength > dataView.byteLength) {
 +                                Roo.log('Invalid meta data: Invalid segment size.');
 +                                break;
 +                            }
 +                            
 +                            if(markerBytes == 0xffe1){
 +                                _this.parseExifData(
 +                                    dataView,
 +                                    offset,
 +                                    markerLength
 +                                );
 +                            }
 +                            
 +                            offset += markerLength;
 +                            
 +                            continue;
 +                        }
 +                        
 +                        break;
 +                    }
 +                    
 +                }
 +                
 +                var url = _this.urlAPI.createObjectURL(_this.file);
 +                
 +                _this.loadCanvas(url);
 +                
 +                return;
 +            }
 +            
 +            reader.readAsArrayBuffer(this.file);
 +            
 +        }
 +        
 +    },
 +    
 +    parseExifData : function(dataView, offset, length)
 +    {
 +        var tiffOffset = offset + 10,
 +            littleEndian,
 +            dirOffset;
 +    
 +        if (dataView.getUint32(offset + 4) !== 0x45786966) {
 +            // No Exif data, might be XMP data instead
 +            return;
 +        }
 +        
 +        // Check for the ASCII code for "Exif" (0x45786966):
 +        if (dataView.getUint32(offset + 4) !== 0x45786966) {
 +            // No Exif data, might be XMP data instead
 +            return;
 +        }
 +        if (tiffOffset + 8 > dataView.byteLength) {
 +            Roo.log('Invalid Exif data: Invalid segment size.');
 +            return;
 +        }
 +        // Check for the two null bytes:
 +        if (dataView.getUint16(offset + 8) !== 0x0000) {
 +            Roo.log('Invalid Exif data: Missing byte alignment offset.');
 +            return;
 +        }
 +        // Check the byte alignment:
 +        switch (dataView.getUint16(tiffOffset)) {
 +        case 0x4949:
 +            littleEndian = true;
 +            break;
 +        case 0x4D4D:
 +            littleEndian = false;
 +            break;
 +        default:
 +            Roo.log('Invalid Exif data: Invalid byte alignment marker.');
 +            return;
 +        }
 +        // Check for the TIFF tag marker (0x002A):
 +        if (dataView.getUint16(tiffOffset + 2, littleEndian) !== 0x002A) {
 +            Roo.log('Invalid Exif data: Missing TIFF marker.');
 +            return;
 +        }
 +        // Retrieve the directory offset bytes, usually 0x00000008 or 8 decimal:
 +        dirOffset = dataView.getUint32(tiffOffset + 4, littleEndian);
 +        
 +        this.parseExifTags(
 +            dataView,
 +            tiffOffset,
 +            tiffOffset + dirOffset,
 +            littleEndian
 +        );
 +    },
 +    
 +    parseExifTags : function(dataView, tiffOffset, dirOffset, littleEndian)
 +    {
 +        var tagsNumber,
 +            dirEndOffset,
 +            i;
 +        if (dirOffset + 6 > dataView.byteLength) {
 +            Roo.log('Invalid Exif data: Invalid directory offset.');
 +            return;
 +        }
 +        tagsNumber = dataView.getUint16(dirOffset, littleEndian);
 +        dirEndOffset = dirOffset + 2 + 12 * tagsNumber;
 +        if (dirEndOffset + 4 > dataView.byteLength) {
 +            Roo.log('Invalid Exif data: Invalid directory size.');
 +            return;
 +        }
 +        for (i = 0; i < tagsNumber; i += 1) {
 +            this.parseExifTag(
 +                dataView,
 +                tiffOffset,
 +                dirOffset + 2 + 12 * i, // tag offset
 +                littleEndian
 +            );
 +        }
 +        // Return the offset to the next directory:
 +        return dataView.getUint32(dirEndOffset, littleEndian);
 +    },
 +    
 +    parseExifTag : function (dataView, tiffOffset, offset, littleEndian) 
 +    {
 +        var tag = dataView.getUint16(offset, littleEndian);
 +        
 +        this.exif[tag] = this.getExifValue(
 +            dataView,
 +            tiffOffset,
 +            offset,
 +            dataView.getUint16(offset + 2, littleEndian), // tag type
 +            dataView.getUint32(offset + 4, littleEndian), // tag length
 +            littleEndian
 +        );
 +    },
 +    
 +    getExifValue : function (dataView, tiffOffset, offset, type, length, littleEndian)
 +    {
 +        var tagType = Roo.dialog.UploadCropbox.exifTagTypes[type],
 +            tagSize,
 +            dataOffset,
 +            values,
 +            i,
 +            str,
 +            c;
 +    
 +        if (!tagType) {
 +            Roo.log('Invalid Exif data: Invalid tag type.');
 +            return;
 +        }
 +        
 +        tagSize = tagType.size * length;
 +        // Determine if the value is contained in the dataOffset bytes,
 +        // or if the value at the dataOffset is a pointer to the actual data:
 +        dataOffset = tagSize > 4 ?
 +                tiffOffset + dataView.getUint32(offset + 8, littleEndian) : (offset + 8);
 +        if (dataOffset + tagSize > dataView.byteLength) {
 +            Roo.log('Invalid Exif data: Invalid data offset.');
 +            return;
 +        }
 +        if (length === 1) {
 +            return tagType.getValue(dataView, dataOffset, littleEndian);
 +        }
 +        values = [];
 +        for (i = 0; i < length; i += 1) {
 +            values[i] = tagType.getValue(dataView, dataOffset + i * tagType.size, littleEndian);
 +        }
 +        
 +        if (tagType.ascii) {
 +            str = '';
 +            // Concatenate the chars:
 +            for (i = 0; i < values.length; i += 1) {
 +                c = values[i];
 +                // Ignore the terminating NULL byte(s):
 +                if (c === '\u0000') {
 +                    break;
 +                }
 +                str += c;
 +            }
 +            return str;
 +        }
 +        return values;
 +    }
 +    
 +});
 +
 +Roo.apply(Roo.dialog.UploadCropbox, {
 +    tags : {
 +        'Orientation': 0x0112
 +    },
 +    
 +    Orientation: {
 +            1: 0, //'top-left',
 +//            2: 'top-right',
 +            3: 180, //'bottom-right',
 +//            4: 'bottom-left',
 +//            5: 'left-top',
 +            6: 90, //'right-top',
 +//            7: 'right-bottom',
 +            8: 270 //'left-bottom'
 +    },
 +    
 +    exifTagTypes : {
 +        // byte, 8-bit unsigned int:
 +        1: {
 +            getValue: function (dataView, dataOffset) {
 +                return dataView.getUint8(dataOffset);
 +            },
 +            size: 1
 +        },
 +        // ascii, 8-bit byte:
 +        2: {
 +            getValue: function (dataView, dataOffset) {
 +                return String.fromCharCode(dataView.getUint8(dataOffset));
 +            },
 +            size: 1,
 +            ascii: true
 +        },
 +        // short, 16 bit int:
 +        3: {
 +            getValue: function (dataView, dataOffset, littleEndian) {
 +                return dataView.getUint16(dataOffset, littleEndian);
 +            },
 +            size: 2
 +        },
 +        // long, 32 bit int:
 +        4: {
 +            getValue: function (dataView, dataOffset, littleEndian) {
 +                return dataView.getUint32(dataOffset, littleEndian);
 +            },
 +            size: 4
 +        },
 +        // rational = two long values, first is numerator, second is denominator:
 +        5: {
 +            getValue: function (dataView, dataOffset, littleEndian) {
 +                return dataView.getUint32(dataOffset, littleEndian) /
 +                    dataView.getUint32(dataOffset + 4, littleEndian);
 +            },
 +            size: 8
 +        },
 +        // slong, 32 bit signed int:
 +        9: {
 +            getValue: function (dataView, dataOffset, littleEndian) {
 +                return dataView.getInt32(dataOffset, littleEndian);
 +            },
 +            size: 4
 +        },
 +        // srational, two slongs, first is numerator, second is denominator:
 +        10: {
 +            getValue: function (dataView, dataOffset, littleEndian) {
 +                return dataView.getInt32(dataOffset, littleEndian) /
 +                    dataView.getInt32(dataOffset + 4, littleEndian);
 +            },
 +            size: 8
 +        }
 +    },
 +    
 +    footer : {
 +        STANDARD : [
 +            {
 +                tag : 'div',
 +                cls : 'btn-group roo-upload-cropbox-rotate-left',
 +                action : 'rotate-left',
 +                cn : [
 +                    {
 +                        tag : 'button',
 +                        cls : 'btn btn-default',
 +                        html : '<i class="fa fa-undo"></i>'
 +                    }
 +                ]
 +            },
 +            {
 +                tag : 'div',
 +                cls : 'btn-group roo-upload-cropbox-picture',
 +                action : 'picture',
 +                cn : [
 +                    {
 +                        tag : 'button',
 +                        cls : 'btn btn-default',
 +                        html : '<i class="fa fa-picture-o"></i>'
 +                    }
 +                ]
 +            },
 +            {
 +                tag : 'div',
 +                cls : 'btn-group roo-upload-cropbox-rotate-right',
 +                action : 'rotate-right',
 +                cn : [
 +                    {
 +                        tag : 'button',
 +                        cls : 'btn btn-default',
 +                        html : '<i class="fa fa-repeat"></i>'
 +                    }
 +                ]
 +            }
 +        ],
 +        DOCUMENT : [
 +            {
 +                tag : 'div',
 +                cls : 'btn-group roo-upload-cropbox-rotate-left',
 +                action : 'rotate-left',
 +                cn : [
 +                    {
 +                        tag : 'button',
 +                        cls : 'btn btn-default',
 +                        html : '<i class="fa fa-undo"></i>'
 +                    }
 +                ]
 +            },
 +            {
 +                tag : 'div',
 +                cls : 'btn-group roo-upload-cropbox-download',
 +                action : 'download',
 +                cn : [
 +                    {
 +                        tag : 'button',
 +                        cls : 'btn btn-default',
 +                        html : '<i class="fa fa-download"></i>'
 +                    }
 +                ]
 +            },
 +            {
 +                tag : 'div',
 +                cls : 'btn-group roo-upload-cropbox-crop',
 +                action : 'crop',
 +                cn : [
 +                    {
 +                        tag : 'button',
 +                        cls : 'btn btn-default',
 +                        html : '<i class="fa fa-crop"></i>'
 +                    }
 +                ]
 +            },
 +            {
 +                tag : 'div',
 +                cls : 'btn-group roo-upload-cropbox-trash',
 +                action : 'trash',
 +                cn : [
 +                    {
 +                        tag : 'button',
 +                        cls : 'btn btn-default',
 +                        html : '<i class="fa fa-trash"></i>'
 +                    }
 +                ]
 +            },
 +            {
 +                tag : 'div',
 +                cls : 'btn-group roo-upload-cropbox-rotate-right',
 +                action : 'rotate-right',
 +                cn : [
 +                    {
 +                        tag : 'button',
 +                        cls : 'btn btn-default',
 +                        html : '<i class="fa fa-repeat"></i>'
 +                    }
 +                ]
 +            }
 +        ],
 +        ROTATOR : [
 +            {
 +                tag : 'div',
 +                cls : 'btn-group roo-upload-cropbox-rotate-left',
 +                action : 'rotate-left',
 +                cn : [
 +                    {
 +                        tag : 'button',
 +                        cls : 'btn btn-default',
 +                        html : '<i class="fa fa-undo"></i>'
 +                    }
 +                ]
 +            },
 +            {
 +                tag : 'div',
 +                cls : 'btn-group roo-upload-cropbox-rotate-right',
 +                action : 'rotate-right',
 +                cn : [
 +                    {
 +                        tag : 'button',
 +                        cls : 'btn btn-default',
 +                        html : '<i class="fa fa-repeat"></i>'
 +                    }
 +                ]
 +            }
 +        ]
 +    }
 +});
diff --combined roojs-ui.js
@@@ -947,8 -947,8 +947,8 @@@ this.push({type:'endparagraph',pos:this
  Roo.htmleditor={};
  // Roo/htmleditor/Filter.js
  Roo.htmleditor.Filter=function(A){Roo.apply(this.cfg);};Roo.htmleditor.Filter.prototype={node:false,tag:false,replaceComment:false,replaceTag:false,walk:function(A){Roo.each(Array.from(A.childNodes),function(e){switch(true){case e.nodeType==8&&this.replaceComment!==false:this.replaceComment(e);
- return;case e.nodeType!=1:return;case this.tag===true:case typeof(this.tag)=='object'&&this.tag.indexOf(e.tagName)>-1:case typeof(this.tag)=='string'&&this.tag==e.tagName:if(this.replaceTag&&false===this.replaceTag(e)){return;}if(e.hasChildNodes()){this.walk(e);
- }return;default:if(e.hasChildNodes()){this.walk(e);}}},this);}};
+ return;case e.nodeType!=1:return;case this.tag===true:case e.tagName.indexOf(":")>-1&&typeof(this.tag)=='object'&&this.tag.indexOf(":")>-1:case e.tagName.indexOf(":")>-1&&typeof(this.tag)=='string'&&this.tag==":":case typeof(this.tag)=='object'&&this.tag.indexOf(e.tagName)>-1:case typeof(this.tag)=='string'&&this.tag==e.tagName:if(this.replaceTag&&false===this.replaceTag(e)){return;
+ }if(e.hasChildNodes()){this.walk(e);}return;default:if(e.hasChildNodes()){this.walk(e);}}},this);}};
  // Roo/htmleditor/FilterAttributes.js
  Roo.htmleditor.FilterAttributes=function(A){Roo.apply(this,A);this.attrib_black=this.attrib_black||[];this.attrib_white=this.attrib_white||[];this.attrib_clean=this.attrib_clean||[];this.style_white=this.style_white||[];this.style_black=this.style_black||[];
  this.walk(A.node);};Roo.extend(Roo.htmleditor.FilterAttributes,Roo.htmleditor.Filter,{tag:true,attrib_black:false,attrib_clean:false,attrib_white:false,style_white:false,style_black:false,replaceTag:function(A){if(!A.attributes||!A.attributes.length){return true;
@@@ -984,11 -984,12 +984,12 @@@ return false;}if(A.tagName.toLowerCase(
  A.removeChild(cn);A.parentNode.insertBefore(cn,A);if(cn.nodeType==1){this.replaceTag(cn);}}A.parentNode.removeChild(A);return false;}if(A.className.length){var cn=A.className.split(/\W+/);var C=[];Roo.each(cn,function(F){if(F.match(/Mso[a-zA-Z]+/)){return;
  }C.push(F);});A.className=C.length?C.join(' '):'';if(!C.length){A.removeAttribute("class");}}if(A.hasAttribute("lang")){A.removeAttribute("lang");}if(A.hasAttribute("style")){var D=A.getAttribute("style").split(";");var E=[];Roo.each(D,function(s){if(!s.match(/:/)){return;
  }var kv=s.split(":");if(kv[0].match(/^(mso-|line|font|background|margin|padding|color)/)){return;}E.push(s);});A.setAttribute("style",E.length?E.join(';'):'');if(!E.length){A.removeAttribute('style');}}return true;},styleToObject:function(A){var B=(A.getAttribute("style")||'').split(";");
- var C={};Roo.each(B,function(s){if(!s.match(/:/)){return;}var kv=s.split(":");C[kv[0].trim()]=kv[1];});return C;},replaceDocBullets:function(A){var B=A.getElementsByClassName('ql-indent-1');while(B.length){this.replaceDocBullet(B.item(0));}var B=A.getElementsByClassName('MsoListParagraph');
+ var C={};Roo.each(B,function(s){if(!s.match(/:/)){return;}var kv=s.split(":");C[kv[0].trim()]=kv[1];});return C;},replaceDocBullets:function(A){var B=A.getElementsByClassName('MsoListParagraphCxSpFirst');for(var i=0;i<B.length;i++){B.item(i).className="MsoListParagraph";
+ }var C=A.getElementsByTagName('h2');for(var i=0;i<C.length;i++){if(C.item(i).getAttribute('style').match(/mso-list:/)){C.item(i).className="MsoListParagraph";}}B=A.getElementsByClassName('ql-indent-1');while(B.length){this.replaceDocBullet(B.item(0));}B=A.getElementsByClassName('MsoListParagraph');
  while(B.length){this.replaceDocBullet(B.item(0));}},replaceDocBullet:function(p){var ns=p,A=p.parentNode,B=A.ownerDocument,C=[];while(ns){if(ns.nodeType!=1){ns=ns.nextSibling;continue;}if(!ns.className.match(/(MsoListParagraph|ql-indent-1)/i)){break;}C.push(ns);
  ns=ns.nextSibling;}var ul=A.ownerDocument.createElement('ul');A.insertBefore(ul,p);var D=0;var E=[ul];var F=false;C.forEach(function(n,G){var H=n.getElementsByTagName('span');if(!H.length){A.removeChild(n);return;}var I={};for(var i=0;i<H.length;i++){I=this.styleToObject(H[i]);
  if(typeof(I['mso-list'])=='undefined'){continue;}H[i].parentNode.removeChild(H[i]);break;}I=this.styleToObject(n);if(typeof(I['mso-list'])=='undefined'){A.removeChild(n);return;}var J=(I['mso-list'].split(' ')[1].replace(/level/,'')*1)-1;if(J>D){var K=B.createElement('ul');
- F.appendChild(K);E[J]=K;}D=J;var L=E[J].appendChild(B.createElement('li'));F=L;L.innerHTML=n.innerHTML;A.removeChild(n);},this);}});
if(!F){F=B.createElement('li');E[D].appendChild(F);}F.appendChild(K);E[J]=K;}D=J;var L=E[J].appendChild(B.createElement('li'));F=L;L.innerHTML=n.innerHTML;A.removeChild(n);},this);}});
  // Roo/htmleditor/FilterStyleToTag.js
  Roo.htmleditor.FilterStyleToTag=function(A){this.tags={B:['fontWeight','bold'],I:['fontStyle','italic'],SUP:['verticalAlign','super'],SUB:['verticalAlign','sub']};Roo.apply(this,A);this.walk(A.node);};Roo.extend(Roo.htmleditor.FilterStyleToTag,Roo.htmleditor.Filter,{tag:true,tags:false,replaceTag:function(A){if(A.getAttribute("style")===null){return true;
  }var B=[];for(var k in this.tags){if(A.style[this.tags[k][0]]==this.tags[k][1]){B.push(k);A.style.removeProperty(this.tags[k][0]);}}if(!B.length){return true;}var cn=Array.from(A.childNodes);var nn=A;Roo.each(B,function(t){var nc=A.ownerDocument.createElement(t);
@@@ -1033,10 -1034,10 +1034,10 @@@ C=C||this.namedEntities;return A.replac
  while(i--){C[A[i]]={};}return C;}};Roo.htmleditor.TidyEntities.init();
  // Roo/htmleditor/KeyEnter.js
  Roo.htmleditor.KeyEnter=function(A){Roo.apply(this,A);Roo.get(this.core.doc.body).on('keypress',this.keypress,this);};Roo.htmleditor.KeyEnter.prototype={core:false,keypress:function(e){if(e.charCode!=13&&e.charCode!=10){Roo.log([e.charCode,e]);return true;
- }e.preventDefault();var A=this.core.doc;var B=this.core.getSelection();var C=B.getRangeAt(0);var n=C.commonAncestorContainer;var pc=C.closest(['ol','ul']);var D=C.closest('li');if(!pc||e.ctrlKey){B.insertNode('br','after');this.core.undoManager.addEvent();
this.core.fireEditorEvent(e);return false;}if(D.innerText.trim()==''&&D.previousSibling&&D.previousSibling.nodeName=='LI'&&D.previousSibling.innerText.trim()==''){D.parentNode.removeChild(D.previousSibling);B.cursorAfter(pc);this.core.undoManager.addEvent();
this.core.fireEditorEvent(e);return false;}var li=A.createElement('LI');li.innerHTML='&nbsp;';if(!D||!D.firstSibling){pc.appendChild(li);}else{D.parentNode.insertBefore(li,D.firstSibling);}B.cursorText(li.firstChild);this.core.undoManager.addEvent();this.core.fireEditorEvent(e);
- return false;}};
+ }e.preventDefault();var A=this.core.doc;var B=this.core.getSelection();var C=B.getRangeAt(0);var n=C.commonAncestorContainer;var pc=C.closest(['ol','ul']);var D=C.closest('li');if(!pc||e.ctrlKey){if(!e.ctrlKey){B.insertNode('br','after');}else{var br=A.createElement('br');
br.className='clear';br.setAttribute('style','clear: both');B.insertNode(br,'after');}this.core.undoManager.addEvent();this.core.fireEditorEvent(e);return false;}if(D.innerText.trim()==''&&D.previousSibling&&D.previousSibling.nodeName=='LI'&&D.previousSibling.innerText.trim()==''){D.parentNode.removeChild(D.previousSibling);
B.cursorAfter(pc);this.core.undoManager.addEvent();this.core.fireEditorEvent(e);return false;}var li=A.createElement('LI');li.innerHTML='&nbsp;';if(!D||!D.firstSibling){pc.appendChild(li);}else{D.parentNode.insertBefore(li,D.firstSibling);}B.cursorText(li.firstChild);
this.core.undoManager.addEvent();this.core.fireEditorEvent(e);return false;}};
  // Roo/htmleditor/Block.js
  Roo.htmleditor.Block=function(A){};Roo.htmleditor.Block.factory=function(A){var cc=Roo.htmleditor.Block.cache;var id=Roo.get(A).id;if(typeof(cc[id])!='undefined'&&(!cc[id].node||cc[id].node.closest('body'))){Roo.htmleditor.Block.cache[id].readElement(A);return Roo.htmleditor.Block.cache[id];
  }var db=A.getAttribute('data-block');if(!db){db=A.nodeName.toLowerCase().toUpperCaseFirst();}var B=Roo.htmleditor['Block'+db];if(typeof(B)=='undefined'){Roo.log("OOps missing block : "+'Block'+db);return false;}Roo.htmleditor.Block.cache[id]=new B({node:A}
@@@ -1050,7 -1051,7 +1051,7 @@@ Roo.htmleditor.BlockFigure=function(A){
  }b.image_src=I;b.updateElement();D();A.editorcore.onEditorEvent();},minWidth:250,prompt:true,modal:true,value:b.image_src});}},xns:C.Toolbar},{xtype:'Button',text:'Change Link URL',listeners:{click:function(F,G){var b=B();Roo.MessageBox.show({title:"Link URL",msg:"Enter the url for the link - leave blank to have no link",buttons:Roo.MessageBox.OKCANCEL,fn:function(H,I){if(H!='ok'){return;
  }b.href=I;b.updateElement();D();A.editorcore.onEditorEvent();},minWidth:250,prompt:true,modal:true,value:b.href});}},xns:C.Toolbar},{xtype:'Button',text:'Show Video URL',listeners:{click:function(F,G){Roo.MessageBox.alert("Video URL",B().video_url==''?'This image is not linked ot a video':'The image is linked to: <a target="_new" href="'+B().video_url+'">'+B().video_url+'</a>');
  }},xns:C.Toolbar},{xtype:'TextItem',text:"Width: ",xns:C.Toolbar},{xtype:'ComboBox',allowBlank:false,displayField:'val',editable:true,listWidth:100,triggerAction:'all',typeAhead:true,valueField:'val',width:70,name:'width',listeners:{select:function(F,r,G){A.editorcore.selectNode(A.tb.selectedNode);
- var b=B();b.width=r.get('val');b.updateElement();D();A.editorcore.onEditorEvent();}},xns:C.form,store:{xtype:'SimpleStore',data:[['50%'],['80%'],['100%']],fields:['val'],xns:Roo.data}},{xtype:'TextItem',text:"Align: ",xns:C.Toolbar},{xtype:'ComboBox',allowBlank:false,displayField:'val',editable:true,listWidth:100,triggerAction:'all',typeAhead:true,valueField:'val',width:70,name:'align',listeners:{select:function(F,r,G){A.editorcore.selectNode(A.tb.selectedNode);
+ var b=B();b.width=r.get('val');b.updateElement();D();A.editorcore.onEditorEvent();}},xns:C.form,store:{xtype:'SimpleStore',data:[['100%'],['80%'],['50%'],['20%'],['10%']],fields:['val'],xns:Roo.data}},{xtype:'TextItem',text:"Align: ",xns:C.Toolbar},{xtype:'ComboBox',allowBlank:false,displayField:'val',editable:true,listWidth:100,triggerAction:'all',typeAhead:true,valueField:'val',width:70,name:'align',listeners:{select:function(F,r,G){A.editorcore.selectNode(A.tb.selectedNode);
  var b=B();b.align=r.get('val');b.updateElement();D();A.editorcore.onEditorEvent();}},xns:C.form,store:{xtype:'SimpleStore',data:[['left'],['right'],['center']],fields:['val'],xns:Roo.data}},{xtype:'Button',text:'Hide Caption',name:'caption_display',pressed:false,enableToggle:true,setValue:function(v){this.setText(v?"Hide Caption":"Show Caption");
  this.setPressed(v!='block');},listeners:{toggle:function(F,G){var b=B();b.caption_display=b.caption_display=='block'?'none':'block';this.setText(b.caption_display=='block'?"Hide Caption":"Show Caption");b.updateElement();D();A.editorcore.selectNode(A.tb.selectedNode);
  A.editorcore.onEditorEvent();}},xns:C.Toolbar}];},toObject:function(){var d=document.createElement('div');d.innerHTML=this.caption;var m=this.width!='100%'&&this.align=='center'?'0 auto':0;var iw=this.align=='center'?this.width:'100%';var A={tag:'img',contenteditable:'false',src:this.image_src,alt:d.innerText.replace(/\n/g," ").replace(/\s+/g,' ').trim(),style:{width:iw,maxWidth:iw+' !important',margin:m}
@@@ -1137,7 -1138,7 +1138,7 @@@ this.insertAtCursor('<img src=" + url 
  }C=C.filter(function(g){return !g.path.match(/^rtf\/(head|pgdsctbl|listtable|footerf)/);}).map(function(g){return g.toDataURL();}).filter(function(g){return g!='about:blank';});D=this.cleanWordChars(D);var d=(new DOMParser().parseFromString(D,'text/html')).body;
  var sn=this.getParentElement();if(d.getElementsByTagName('table').length&&sn&&sn.closest('table')){e.preventDefault();this.insertAtCursor("You can not nest tables");return false;}if(C.length>0){Roo.each(d.getElementsByTagName('img'),function(F,i){F.setAttribute('src',C[i]);
  });}if(this.autoClean){new Roo.htmleditor.FilterWord({node:d});new Roo.htmleditor.FilterStyleToTag({node:d});new Roo.htmleditor.FilterAttributes({node:d,attrib_white:['href','src','name','align','colspan','rowspan','data-display','data-width'],attrib_clean:['href','src']}
- );new Roo.htmleditor.FilterBlack({node:d,tag:this.black});new Roo.htmleditor.FilterKeepChildren({node:d,tag:['FONT','O:P']});new Roo.htmleditor.FilterParagraph({node:d});new Roo.htmleditor.FilterSpan({node:d});new Roo.htmleditor.FilterLongBr({node:d});new Roo.htmleditor.FilterComment({node:d}
+ );new Roo.htmleditor.FilterBlack({node:d,tag:this.black});new Roo.htmleditor.FilterKeepChildren({node:d,tag:['FONT',':']});new Roo.htmleditor.FilterParagraph({node:d});new Roo.htmleditor.FilterSpan({node:d});new Roo.htmleditor.FilterLongBr({node:d});new Roo.htmleditor.FilterComment({node:d}
  );}if(this.enableBlocks){Array.from(d.getElementsByTagName('img')).forEach(function(F){if(F.closest('figure')){return;}var G=new Roo.htmleditor.BlockFigure({image_src:F.src});G.updateElement(F);});}this.insertAtCursor(d.innerHTML.replace(/&nbsp;/g,' '));if(this.enableBlocks){Roo.htmleditor.Block.initAll(this.doc.body);
  }e.preventDefault();return false;},onDestroy:function(){if(this.rendered){}},onFirstFocus:function(){this.assignDocWin();this.undoManager=new Roo.lib.UndoManager(100,(this.doc.body||this.doc.documentElement));this.activated=true;if(Roo.isGecko){this.win.focus();
  var s=this.win.getSelection();if(!s.focusNode||s.focusNode.nodeType!=3){var r=s.getRangeAt(0);r.selectNodeContents((this.doc.body||this.doc.documentElement));r.collapse(true);this.deferFocus();}try{this.execCmd('useCSS',true);this.execCmd('styleWithCSS',false);
@@@ -1166,12 -1167,12 +1167,12 @@@ F.collapse(true);var G=C.cloneRange();G
  }catch(e){C.selectNodeContents(B);}A.collapse(true);C.collapse(true);var ss=A.compareBoundaryPoints(Range.START_TO_START,C);var ee=A.compareBoundaryPoints(Range.END_TO_END,C);var D=ss==1;var E=ee==-1;if(D&&E){return 0;}if(!D&&E){return 1;}if(D&&!E){return 2;
  }return 3;},cleanWordChars:function(A){var B=[[8211,"&#8211;"],[8212,"&#8212;"],[8216,"'"],[8217,"'"],[8220,'"'],[8221,'"'],[8226,"*"],[8230,"..."]];var C=A;Roo.each(B,function(sw){var D=new RegExp("\\u"+sw[0].toString(16),"g");C=C.replace(D,sw[1]);});return C;
  },cleanUpChild:function(A){new Roo.htmleditor.FilterComment({node:A});new Roo.htmleditor.FilterAttributes({node:A,attrib_black:this.ablack,attrib_clean:this.aclean,style_white:this.cwhite,style_black:this.cblack});new Roo.htmleditor.FilterBlack({node:A,tag:this.black}
- );new Roo.htmleditor.FilterKeepChildren({node:A,tag:this.tag_remove});},cleanWord:function(A){new Roo.htmleditor.FilterWord({node:A?A:this.doc.body});},cleanTableWidths:function(A){new Roo.htmleditor.FilterTableWidth({node:A?A:this.doc.body});},applyBlacklists:function(){var w=typeof(this.owner.white)!='undefined'&&this.owner.white?this.owner.white:[];
var b=typeof(this.owner.black)!='undefined'&&this.owner.black?this.owner.black:[];this.aclean=typeof(this.owner.aclean)!='undefined'&&this.owner.aclean?this.owner.aclean:Roo.HtmlEditorCore.aclean;this.ablack=typeof(this.owner.ablack)!='undefined'&&this.owner.ablack?this.owner.ablack:Roo.HtmlEditorCore.ablack;
- this.tag_remove=typeof(this.owner.tag_remove)!='undefined'&&this.owner.tag_remove?this.owner.tag_remove:Roo.HtmlEditorCore.tag_remove;this.white=[];this.black=[];Roo.each(Roo.HtmlEditorCore.white,function(A){if(b.indexOf(A)>-1){return;}this.white.push(A);
},this);Roo.each(w,function(A){if(b.indexOf(A)>-1){return;}if(this.white.indexOf(A)>-1){return;}this.white.push(A);},this);Roo.each(Roo.HtmlEditorCore.black,function(A){if(w.indexOf(A)>-1){return;}this.black.push(A);},this);Roo.each(b,function(A){if(w.indexOf(A)>-1){return;
- }if(this.black.indexOf(A)>-1){return;}this.black.push(A);},this);w=typeof(this.owner.cwhite)!='undefined'&&this.owner.cwhite?this.owner.cwhite:[];b=typeof(this.owner.cblack)!='undefined'&&this.owner.cblack?this.owner.cblack:[];this.cwhite=[];this.cblack=[];
- Roo.each(Roo.HtmlEditorCore.cwhite,function(A){if(b.indexOf(A)>-1){return;}this.cwhite.push(A);},this);Roo.each(w,function(A){if(b.indexOf(A)>-1){return;}if(this.cwhite.indexOf(A)>-1){return;}this.cwhite.push(A);},this);Roo.each(Roo.HtmlEditorCore.cblack,function(A){if(w.indexOf(A)>-1){return;
+ );new Roo.htmleditor.FilterKeepChildren({node:A,tag:this.tag_remove});},cleanWord:function(A){new Roo.htmleditor.FilterWord({node:A?A:this.doc.body});new Roo.htmleditor.FilterKeepChildren({node:A?A:this.doc.body,tag:['FONT',':']});},cleanTableWidths:function(A){new Roo.htmleditor.FilterTableWidth({node:A?A:this.doc.body}
);},applyBlacklists:function(){var w=typeof(this.owner.white)!='undefined'&&this.owner.white?this.owner.white:[];var b=typeof(this.owner.black)!='undefined'&&this.owner.black?this.owner.black:[];this.aclean=typeof(this.owner.aclean)!='undefined'&&this.owner.aclean?this.owner.aclean:Roo.HtmlEditorCore.aclean;
+ this.ablack=typeof(this.owner.ablack)!='undefined'&&this.owner.ablack?this.owner.ablack:Roo.HtmlEditorCore.ablack;this.tag_remove=typeof(this.owner.tag_remove)!='undefined'&&this.owner.tag_remove?this.owner.tag_remove:Roo.HtmlEditorCore.tag_remove;this.white=[];
this.black=[];Roo.each(Roo.HtmlEditorCore.white,function(A){if(b.indexOf(A)>-1){return;}this.white.push(A);},this);Roo.each(w,function(A){if(b.indexOf(A)>-1){return;}if(this.white.indexOf(A)>-1){return;}this.white.push(A);},this);Roo.each(Roo.HtmlEditorCore.black,function(A){if(w.indexOf(A)>-1){return;
+ }this.black.push(A);},this);Roo.each(b,function(A){if(w.indexOf(A)>-1){return;}if(this.black.indexOf(A)>-1){return;}this.black.push(A);},this);w=typeof(this.owner.cwhite)!='undefined'&&this.owner.cwhite?this.owner.cwhite:[];b=typeof(this.owner.cblack)!='undefined'&&this.owner.cblack?this.owner.cblack:[];
this.cwhite=[];this.cblack=[];Roo.each(Roo.HtmlEditorCore.cwhite,function(A){if(b.indexOf(A)>-1){return;}this.cwhite.push(A);},this);Roo.each(w,function(A){if(b.indexOf(A)>-1){return;}if(this.cwhite.indexOf(A)>-1){return;}this.cwhite.push(A);},this);Roo.each(Roo.HtmlEditorCore.cblack,function(A){if(w.indexOf(A)>-1){return;
  }this.cblack.push(A);},this);Roo.each(b,function(A){if(w.indexOf(A)>-1){return;}if(this.cblack.indexOf(A)>-1){return;}this.cblack.push(A);},this);},setStylesheets:function(A){if(typeof(A)=='string'){Roo.get(this.iframe.contentDocument.head).createChild({tag:'link',rel:'stylesheet',type:'text/css',href:A}
  );return;}var B=this;Roo.each(A,function(s){if(!s.length){return;}Roo.get(B.iframe.contentDocument.head).createChild({tag:'link',rel:'stylesheet',type:'text/css',href:s});});},updateLanguage:function(){if(!this.iframe||!this.iframe.contentDocument){return;
  }Roo.get(this.iframe.contentDocument.body).attr("lang",this.language);},removeStylesheets:function(){var A=this;Roo.each(Roo.get(A.iframe.contentDocument.head).select('link[rel=stylesheet]',true).elements,function(s){s.remove();});},setStyle:function(A){Roo.get(this.iframe.contentDocument.head).createChild({tag:'style',type:'text/css',html:A}
@@@ -1598,9 -1599,9 +1599,9 @@@ return this.el.getUpdateManager();},_ha
  te.setWidth(A);}if(this.adjustments){A+=this.adjustments[0];B+=this.adjustments[1];}return {"width":A,"height":B};},setSize:function(A,B){if(this.fitToFrame&&!this.ignoreResize(A,B)){if(this.fitContainer&&this.resizeEl!=this.el){this.el.setSize(A,B);}var C=this.adjustForComponents(A,B);
  this.resizeEl.setSize(this.autoWidth?"auto":C.width,this.autoHeight?"auto":C.height);this.fireEvent('resize',this,C.width,C.height);}},getTitle:function(){return this.title;},setTitle:function(A){this.title=A;if(this.region){this.region.updatePanelTitle(this,A);
  }},isClosable:function(){return this.closable;},beforeSlide:function(){this.el.clip();this.resizeEl.clip();},afterSlide:function(){this.el.unclip();this.resizeEl.unclip();},refresh:function(){if(this.refreshDelegate){this.loaded=false;this.refreshDelegate();
 -}},destroy:function(){this.el.removeAllListeners();var A=document.createElement("span");A.appendChild(this.el.dom);A.innerHTML="";this.el.remove();this.el=null;},form:false,view:false,addxtype:function(A){if(A.xtype.match(/^Form$/)){var el;el=this.el.createChild();
 -this.form=new Roo.form.Form(A);if(this.form.allItems.length){this.form.render(el.dom);}return this.form;}if(['View','JsonView','DatePicker'].indexOf(A.xtype)>-1){A.el=this.el.appendChild(document.createElement("div"));var B=new Roo.factory(A);B.render&&B.render(false,'');
 -this.view=B;return B;}return false;}});
 +}},destroy:function(){this.el.removeAllListeners();var A=document.createElement("span");A.appendChild(this.el.dom);A.innerHTML="";this.el.remove();this.el=null;},form:false,view:false,addxtype:function(A){if(A.xtype.match(/^UploadCropbox$/)){this.cropbox=new Roo.factory(A);
 +this.cropbox.render(this.el);return this.cropbox;}if(A.xtype.match(/^Form$/)){var el;el=this.el.createChild();this.form=new Roo.form.Form(A);if(this.form.allItems.length){this.form.render(el.dom);}return this.form;}if(['View','JsonView','DatePicker'].indexOf(A.xtype)>-1){A.el=this.el.appendChild(document.createElement("div"));
 +var B=new Roo.factory(A);B.render&&B.render(false,'');this.view=B;return B;}return false;}});
  // Roo/GridPanel.js
  Roo.GridPanel=function(A,B){if(typeof(A.grid)!='undefined'){B=A;A=B.grid;}this.wrapper=Roo.DomHelper.append(document.body,{tag:"div",cls:"x-layout-grid-wrapper x-layout-inactive-content"},true);this.wrapper.dom.appendChild(A.getGridEl().dom);Roo.GridPanel.superclass.constructor.call(this,this.wrapper,B);
  if(this.toolbar){this.toolbar.el.insertBefore(this.wrapper.dom.firstChild);}if(this.footer&&!this.footer.el&&this.footer.xtype){this.footer.container=this.grid.getView().getFooterPanel(true);this.footer.dataSource=this.grid.dataSource;this.footer=Roo.factory(this.footer,Roo);
@@@ -1929,104 -1930,3 +1930,104 @@@ F.push("(typeof("+G+") == 'undefined')"
  }return "'"+A+H+C+")"+A+"'";};var B;if(Roo.isGecko){B="tpl.compiled = function(values, parent){  with(values) { return '"+tpl.body.replace(/(\r\n|\n)/g,'\\n').replace(/'/g,"\\'").replace(this.re,fn)+"';};};";}else{B=["tpl.compiled = function(values, parent){  with (values) { return ['"];
  B.push(tpl.body.replace(/(\r\n|\n)/g,'\\n').replace(/'/g,"\\'").replace(this.re,fn));B.push("'].join('');};};");B=B.join('');}Roo.debug&&Roo.log(B.replace(/\\n/,'\n'));eval(B);return this;},applyTemplate:function(A){return this.master.compiled.call(this,A,{}
  );},apply:function(){return this.applyTemplate.apply(this,arguments);}});Roo.XTemplate.from=function(el){el=Roo.getDom(el);return new Roo.XTemplate(el.value||el.innerHTML);};
 +// Roo/dialog/namespace.js
 +Roo.dialog={};
 +// Roo/dialog/UploadCropbox.js
 +Roo.dialog.UploadCropbox=function(A){Roo.dialog.UploadCropbox.superclass.constructor.call(this,A);this.addEvents({"beforeselectfile":true,"initial":true,"crop":true,"prepare":true,"exception":true,"beforeloadcanvas":true,"trash":true,"download":true,"footerbuttonclick":true,"resize":true,"rotate":true,"inspect":true,"upload":true,"arrange":true,"loadcanvas":true}
 +);this.buttons=this.buttons||Roo.dialog.UploadCropbox.footer.STANDARD;};Roo.extend(Roo.dialog.UploadCropbox,Roo.Component,{emptyText:'Click to upload image',rotateNotify:'Image is too small to rotate',errorTimeout:3000,scale:0,baseScale:1,rotate:0,dragable:false,pinching:false,mouseX:0,mouseY:0,cropData:false,minWidth:300,minHeight:300,outputMaxWidth:1200,file:false,exif:{}
 +,baseRotate:1,cropType:'image/jpeg',buttons:false,canvasLoaded:false,isDocument:false,method:'POST',paramName:'imageUpload',loadMask:true,loadingText:'Loading...',maskEl:false,getAutoCreate:function(){var A={tag:'div',cls:'roo-upload-cropbox',cn:[{tag:'input',cls:'roo-upload-cropbox-selector',type:'file'}
 +,{tag:'div',cls:'roo-upload-cropbox-body',style:'cursor:pointer',cn:[{tag:'div',cls:'roo-upload-cropbox-preview'},{tag:'div',cls:'roo-upload-cropbox-thumb'},{tag:'div',cls:'roo-upload-cropbox-empty-notify',html:this.emptyText},{tag:'div',cls:'roo-upload-cropbox-error-notify alert alert-danger',html:this.rotateNotify}
 +]},{tag:'div',cls:'roo-upload-cropbox-footer',cn:{tag:'div',cls:'btn-group btn-group-justified roo-upload-cropbox-btn-group',cn:[]}}]};return A;},onRender:function(ct,A){Roo.dialog.UploadCropbox.superclass.onRender.call(this,ct,A);if(this.el){if(this.el.attr('xtype')){this.el.attr('xtypex',this.el.attr('xtype'));
 +this.el.dom.removeAttribute('xtype');this.initEvents();}}else{var B=Roo.apply({},this.getAutoCreate());B.id=this.id||Roo.id();if(this.cls){B.cls=(typeof(B.cls)=='undefined'?this.cls:B.cls)+' '+this.cls;}if(this.style){B.style=(typeof(B.style)=='undefined'?this.style:B.style)+'; '+this.style;
 +}this.el=ct.createChild(B,A);this.initEvents();}if(this.buttons.length){Roo.each(this.buttons,function(bb){var C=this.el.select('.roo-upload-cropbox-footer div.roo-upload-cropbox-btn-group').first().createChild(bb);C.on('click',this.onFooterButtonClick.createDelegate(this,[bb.action],true));
 +},this);}if(this.loadMask){this.maskEl=this.el;}},initEvents:function(){this.urlAPI=(window.createObjectURL&&window)||(window.URL&&URL.revokeObjectURL&&URL)||(window.webkitURL&&webkitURL);this.bodyEl=this.el.select('.roo-upload-cropbox-body',true).first();
 +this.bodyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';this.selectorEl=this.el.select('.roo-upload-cropbox-selector',true).first();this.selectorEl.hide();this.previewEl=this.el.select('.roo-upload-cropbox-preview',true).first();this.previewEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';
 +this.thumbEl=this.el.select('.roo-upload-cropbox-thumb',true).first();this.thumbEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';this.thumbEl.hide();this.notifyEl=this.el.select('.roo-upload-cropbox-empty-notify',true).first();this.notifyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';
 +this.errorEl=this.el.select('.roo-upload-cropbox-error-notify',true).first();this.errorEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';this.errorEl.hide();this.footerEl=this.el.select('.roo-upload-cropbox-footer',true).first();this.footerEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay='block';
 +this.footerEl.hide();this.setThumbBoxSize();this.bind();this.resize();this.fireEvent('initial',this);},bind:function(){var A=this;window.addEventListener("resize",function(){A.resize();});this.bodyEl.on('click',this.beforeSelectFile,this);if(Roo.isTouch){this.bodyEl.on('touchstart',this.onTouchStart,this);
 +this.bodyEl.on('touchmove',this.onTouchMove,this);this.bodyEl.on('touchend',this.onTouchEnd,this);}if(!Roo.isTouch){this.bodyEl.on('mousedown',this.onMouseDown,this);this.bodyEl.on('mousemove',this.onMouseMove,this);var B=(/Firefox/i.test(navigator.userAgent))?'DOMMouseScroll':'mousewheel';
 +this.bodyEl.on(B,this.onMouseWheel,this);Roo.get(document).on('mouseup',this.onMouseUp,this);}this.selectorEl.on('change',this.onFileSelected,this);},reset:function(){this.scale=0;this.baseScale=1;this.rotate=0;this.baseRotate=1;this.dragable=false;this.pinching=false;
 +this.mouseX=0;this.mouseY=0;this.cropData=false;this.notifyEl.dom.innerHTML=this.emptyText;},resize:function(){if(this.fireEvent('resize',this)!=false){this.setThumbBoxPosition();this.setCanvasPosition();}},onFooterButtonClick:function(e,el,o,A){switch(A){case 'rotate-left':this.onRotateLeft(e);
 +break;case 'rotate-right':this.onRotateRight(e);break;case 'picture':this.beforeSelectFile(e);break;case 'trash':this.trash(e);break;case 'crop':this.crop(e);break;case 'download':this.download(e);break;default:break;}this.fireEvent('footerbuttonclick',this,A);
 +},beforeSelectFile:function(e){e.preventDefault();if(this.fireEvent('beforeselectfile',this)!=false){this.selectorEl.dom.click();}},onFileSelected:function(e){e.preventDefault();if(typeof(this.selectorEl.dom.files)=='undefined'||!this.selectorEl.dom.files.length){return;
 +}var A=this.selectorEl.dom.files[0];if(this.fireEvent('inspect',this,A)!=false){this.prepare(A);}},trash:function(e){this.fireEvent('trash',this);},download:function(e){this.fireEvent('download',this);},loadCanvas:function(A){if(this.fireEvent('beforeloadcanvas',this,A)!=false){this.reset();
 +this.imageEl=document.createElement('img');var B=this;this.imageEl.addEventListener("load",function(){B.onLoadCanvas();});this.imageEl.src=A;}},onLoadCanvas:function(){this.imageEl.OriginWidth=this.imageEl.naturalWidth||this.imageEl.width;this.imageEl.OriginHeight=this.imageEl.naturalHeight||this.imageEl.height;
 +if(this.fireEvent('loadcanvas',this,this.imageEl)!=false){this.bodyEl.un('click',this.beforeSelectFile,this);this.notifyEl.hide();this.thumbEl.show();this.footerEl.show();this.baseRotateLevel();if(this.isDocument){this.setThumbBoxSize();}this.setThumbBoxPosition();
 +this.baseScaleLevel();this.draw();this.resize();this.canvasLoaded=true;}if(this.loadMask){this.maskEl.unmask();}},setCanvasPosition:function(){if(!this.canvasEl){return;}var pw=Math.ceil((this.bodyEl.getWidth()-this.canvasEl.width)/2);var ph=Math.ceil((this.bodyEl.getHeight()-this.canvasEl.height)/2);
 +this.previewEl.setLeft(pw);this.previewEl.setTop(ph);},onMouseDown:function(e){e.stopEvent();this.dragable=true;this.pinching=false;if(this.isDocument&&(this.canvasEl.width<this.thumbEl.getWidth()||this.canvasEl.height<this.thumbEl.getHeight())){this.dragable=false;
 +return;}this.mouseX=Roo.isTouch?e.browserEvent.touches[0].pageX:e.getPageX();this.mouseY=Roo.isTouch?e.browserEvent.touches[0].pageY:e.getPageY();},onMouseMove:function(e){e.stopEvent();if(!this.canvasLoaded){return;}if(!this.dragable){return;}var A=Math.ceil(this.thumbEl.getLeft(true));
 +var B=Math.ceil(this.thumbEl.getTop(true));var C=Math.ceil(A+this.thumbEl.getWidth()-this.canvasEl.width);var D=Math.ceil(B+this.thumbEl.getHeight()-this.canvasEl.height);if(A>C){var E=A;A=C;C=E;}if(B>D){var F=B;B=D;D=F;}var x=Roo.isTouch?e.browserEvent.touches[0].pageX:e.getPageX();
 +var y=Roo.isTouch?e.browserEvent.touches[0].pageY:e.getPageY();x=x-this.mouseX;y=y-this.mouseY;var G=Math.ceil(x+this.previewEl.getLeft(true));var H=Math.ceil(y+this.previewEl.getTop(true));G=(G<A)?A:((G>C)?C:G);H=(H<B)?B:((H>D)?D:H);this.previewEl.setLeft(G);
 +this.previewEl.setTop(H);this.mouseX=Roo.isTouch?e.browserEvent.touches[0].pageX:e.getPageX();this.mouseY=Roo.isTouch?e.browserEvent.touches[0].pageY:e.getPageY();},onMouseUp:function(e){e.stopEvent();this.dragable=false;},onMouseWheel:function(e){e.stopEvent();
 +this.startScale=this.scale;this.scale=(e.getWheelDelta()==1)?(this.scale+1):(this.scale-1);if(!this.zoomable()){this.scale=this.startScale;return;}this.draw();return;},zoomable:function(){var A=this.thumbEl.getWidth()/this.minWidth;if(this.minWidth<this.minHeight){A=this.thumbEl.getHeight()/this.minHeight;
 +}var B=Math.ceil(this.imageEl.OriginWidth*this.getScaleLevel()/A);var C=Math.ceil(this.imageEl.OriginHeight*this.getScaleLevel()/A);var D=this.imageEl.OriginWidth;var E=this.imageEl.OriginHeight;if(this.isDocument&&(this.rotate==0||this.rotate==180)&&(B>this.imageEl.OriginWidth||C>this.imageEl.OriginHeight||(B<this.minWidth&&C<this.minHeight))){return false;
 +}if(this.isDocument&&(this.rotate==90||this.rotate==270)&&(B>this.imageEl.OriginWidth||C>this.imageEl.OriginHeight||(B<this.minHeight&&C<this.minWidth))){return false;}if(!this.isDocument&&(this.rotate==0||this.rotate==180)&&((this.imageEl.OriginWidth>=this.minWidth)&&B<this.minWidth||(this.imageEl.OriginHeight>=this.minHeight)&&C<this.minHeight||B>D||C>E)){return false;
 +}if(!this.isDocument&&(this.rotate==90||this.rotate==270)&&(B<this.minHeight||B>this.imageEl.OriginWidth||C<this.minWidth||C>this.imageEl.OriginHeight)){return false;}return true;},onRotateLeft:function(e){if(!this.isDocument&&(this.canvasEl.height<this.thumbEl.getWidth()||this.canvasEl.width<this.thumbEl.getHeight())){var A=this.thumbEl.getWidth()/this.minWidth;
 +var bw=Math.ceil(this.canvasEl.width/this.getScaleLevel());var bh=Math.ceil(this.canvasEl.height/this.getScaleLevel());this.startScale=this.scale;while(this.getScaleLevel()<A){this.scale=this.scale+1;if(!this.zoomable()){break;}if(Math.ceil(bw*this.getScaleLevel())<this.thumbEl.getHeight()||Math.ceil(bh*this.getScaleLevel())<this.thumbEl.getWidth()){continue;
 +}this.rotate=(this.rotate<90)?270:this.rotate-90;this.draw();return;}this.scale=this.startScale;this.onRotateFail();return false;}this.rotate=(this.rotate<90)?270:this.rotate-90;if(this.isDocument){this.setThumbBoxSize();this.setThumbBoxPosition();this.setCanvasPosition();
 +}this.draw();this.fireEvent('rotate',this,'left');},onRotateRight:function(e){if(!this.isDocument&&(this.canvasEl.height<this.thumbEl.getWidth()||this.canvasEl.width<this.thumbEl.getHeight())){var A=this.thumbEl.getWidth()/this.minWidth;var bw=Math.ceil(this.canvasEl.width/this.getScaleLevel());
 +var bh=Math.ceil(this.canvasEl.height/this.getScaleLevel());this.startScale=this.scale;while(this.getScaleLevel()<A){this.scale=this.scale+1;if(!this.zoomable()){break;}if(Math.ceil(bw*this.getScaleLevel())<this.thumbEl.getHeight()||Math.ceil(bh*this.getScaleLevel())<this.thumbEl.getWidth()){continue;
 +}this.rotate=(this.rotate>180)?0:this.rotate+90;this.draw();return;}this.scale=this.startScale;this.onRotateFail();return false;}this.rotate=(this.rotate>180)?0:this.rotate+90;if(this.isDocument){this.setThumbBoxSize();this.setThumbBoxPosition();this.setCanvasPosition();
 +}this.draw();this.fireEvent('rotate',this,'right');},onRotateFail:function(){this.errorEl.show(true);var A=this;(function(){A.errorEl.hide(true);}).defer(this.errorTimeout);},draw:function(){this.previewEl.dom.innerHTML='';var A=document.createElement("canvas");
 +var B=A.getContext("2d");A.width=this.imageEl.OriginWidth*this.getScaleLevel();A.height=this.imageEl.OriginWidth*this.getScaleLevel();var C=this.imageEl.OriginWidth/2;if(this.imageEl.OriginWidth<this.imageEl.OriginHeight){A.width=this.imageEl.OriginHeight*this.getScaleLevel();
 +A.height=this.imageEl.OriginHeight*this.getScaleLevel();C=this.imageEl.OriginHeight/2;}B.scale(this.getScaleLevel(),this.getScaleLevel());B.translate(C,C);B.rotate(this.rotate*Math.PI/180);B.drawImage(this.imageEl,0,0,this.imageEl.OriginWidth,this.imageEl.OriginHeight,C*-1,C*-1,this.imageEl.OriginWidth,this.imageEl.OriginHeight);
 +this.canvasEl=document.createElement("canvas");this.contextEl=this.canvasEl.getContext("2d");switch(this.rotate){case 0:this.canvasEl.width=this.imageEl.OriginWidth*this.getScaleLevel();this.canvasEl.height=this.imageEl.OriginHeight*this.getScaleLevel();this.contextEl.drawImage(A,0,0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);
 +break;case 90:this.canvasEl.width=this.imageEl.OriginHeight*this.getScaleLevel();this.canvasEl.height=this.imageEl.OriginWidth*this.getScaleLevel();if(this.imageEl.OriginWidth>this.imageEl.OriginHeight){this.contextEl.drawImage(A,Math.abs(this.canvasEl.width-this.canvasEl.height),0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);
 +break;}this.contextEl.drawImage(A,0,0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);break;case 180:this.canvasEl.width=this.imageEl.OriginWidth*this.getScaleLevel();this.canvasEl.height=this.imageEl.OriginHeight*this.getScaleLevel();
 +if(this.imageEl.OriginWidth>this.imageEl.OriginHeight){this.contextEl.drawImage(A,0,Math.abs(this.canvasEl.width-this.canvasEl.height),this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);break;}this.contextEl.drawImage(A,Math.abs(this.canvasEl.width-this.canvasEl.height),0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);
 +break;case 270:this.canvasEl.width=this.imageEl.OriginHeight*this.getScaleLevel();this.canvasEl.height=this.imageEl.OriginWidth*this.getScaleLevel();if(this.imageEl.OriginWidth>this.imageEl.OriginHeight){this.contextEl.drawImage(A,0,0,this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);
 +break;}this.contextEl.drawImage(A,0,Math.abs(this.canvasEl.width-this.canvasEl.height),this.canvasEl.width,this.canvasEl.height,0,0,this.canvasEl.width,this.canvasEl.height);break;default:break;}this.previewEl.appendChild(this.canvasEl);this.setCanvasPosition();
 +},crop:function(){if(!this.canvasLoaded){return;}var A=document.createElement("canvas");var B=A.getContext("2d");A.width=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?this.imageEl.OriginWidth:this.imageEl.OriginHeight;A.height=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?this.imageEl.OriginWidth:this.imageEl.OriginHeight;
 +var C=A.width/2;B.translate(C,C);B.rotate(this.rotate*Math.PI/180);B.drawImage(this.imageEl,0,0,this.imageEl.OriginWidth,this.imageEl.OriginHeight,C*-1,C*-1,this.imageEl.OriginWidth,this.imageEl.OriginHeight);var D=document.createElement("canvas");var E=D.getContext("2d");
 +D.width=this.thumbEl.getWidth()/this.getScaleLevel();D.height=this.thumbEl.getHeight()/this.getScaleLevel();switch(this.rotate){case 0:var F=(this.thumbEl.getWidth()/this.getScaleLevel()>this.imageEl.OriginWidth)?this.imageEl.OriginWidth:(this.thumbEl.getWidth()/this.getScaleLevel());
 +var G=(this.thumbEl.getHeight()/this.getScaleLevel()>this.imageEl.OriginHeight)?this.imageEl.OriginHeight:(this.thumbEl.getHeight()/this.getScaleLevel());var x=(this.thumbEl.getLeft(true)>this.previewEl.getLeft(true))?0:((this.previewEl.getLeft(true)-this.thumbEl.getLeft(true))/this.getScaleLevel());
 +var y=(this.thumbEl.getTop(true)>this.previewEl.getTop(true))?0:((this.previewEl.getTop(true)-this.thumbEl.getTop(true))/this.getScaleLevel());var sx=this.thumbEl.getLeft(true)-this.previewEl.getLeft(true);var sy=this.thumbEl.getTop(true)-this.previewEl.getTop(true);
 +sx=sx<0?0:(sx/this.getScaleLevel());sy=sy<0?0:(sy/this.getScaleLevel());if(D.width>this.outputMaxWidth){var H=this.outputMaxWidth/D.width;D.width=D.width*H;D.height=D.height*H;E.scale(H,H);}E.drawImage(A,sx,sy,F,G,x,y,F,G);break;case 90:var F=(this.thumbEl.getWidth()/this.getScaleLevel()>this.imageEl.OriginHeight)?this.imageEl.OriginHeight:(this.thumbEl.getWidth()/this.getScaleLevel());
 +var G=(this.thumbEl.getHeight()/this.getScaleLevel()>this.imageEl.OriginWidth)?this.imageEl.OriginWidth:(this.thumbEl.getHeight()/this.getScaleLevel());var x=(this.thumbEl.getLeft(true)>this.previewEl.getLeft(true))?0:((this.previewEl.getLeft(true)-this.thumbEl.getLeft(true))/this.getScaleLevel());
 +var y=(this.thumbEl.getTop(true)>this.previewEl.getTop(true))?0:((this.previewEl.getTop(true)-this.thumbEl.getTop(true))/this.getScaleLevel());var I=this.minWidth-2*x;var J=this.minHeight-2*y;var H=1;if((x==0&&y==0)||(x==0&&y>0)){H=I/F;}if(x>0&&y==0){H=J/G;
 +}if(x>0&&y>0){H=I/F;if(F<G){H=J/G;}}E.scale(H,H);var sx=Math.min(this.canvasEl.width-this.thumbEl.getWidth(),this.thumbEl.getLeft(true)-this.previewEl.getLeft(true));var sy=Math.min(this.canvasEl.height-this.thumbEl.getHeight(),this.thumbEl.getTop(true)-this.previewEl.getTop(true));
 +sx=sx<0?0:(sx/this.getScaleLevel());sy=sy<0?0:(sy/this.getScaleLevel());sx+=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?Math.abs(this.imageEl.OriginWidth-this.imageEl.OriginHeight):0;E.drawImage(A,sx,sy,F,G,x,y,F,G);break;case 180:var F=(this.thumbEl.getWidth()/this.getScaleLevel()>this.imageEl.OriginWidth)?this.imageEl.OriginWidth:(this.thumbEl.getWidth()/this.getScaleLevel());
 +var G=(this.thumbEl.getHeight()/this.getScaleLevel()>this.imageEl.OriginHeight)?this.imageEl.OriginHeight:(this.thumbEl.getHeight()/this.getScaleLevel());var x=(this.thumbEl.getLeft(true)>this.previewEl.getLeft(true))?0:((this.previewEl.getLeft(true)-this.thumbEl.getLeft(true))/this.getScaleLevel());
 +var y=(this.thumbEl.getTop(true)>this.previewEl.getTop(true))?0:((this.previewEl.getTop(true)-this.thumbEl.getTop(true))/this.getScaleLevel());var I=this.minWidth-2*x;var J=this.minHeight-2*y;var H=1;if((x==0&&y==0)||(x==0&&y>0)){H=I/F;}if(x>0&&y==0){H=J/G;
 +}if(x>0&&y>0){H=I/F;if(F<G){H=J/G;}}E.scale(H,H);var sx=Math.min(this.canvasEl.width-this.thumbEl.getWidth(),this.thumbEl.getLeft(true)-this.previewEl.getLeft(true));var sy=Math.min(this.canvasEl.height-this.thumbEl.getHeight(),this.thumbEl.getTop(true)-this.previewEl.getTop(true));
 +sx=sx<0?0:(sx/this.getScaleLevel());sy=sy<0?0:(sy/this.getScaleLevel());sx+=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?0:Math.abs(this.imageEl.OriginWidth-this.imageEl.OriginHeight);sy+=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?Math.abs(this.imageEl.OriginWidth-this.imageEl.OriginHeight):0;
 +E.drawImage(A,sx,sy,F,G,x,y,F,G);break;case 270:var F=(this.thumbEl.getWidth()/this.getScaleLevel()>this.imageEl.OriginHeight)?this.imageEl.OriginHeight:(this.thumbEl.getWidth()/this.getScaleLevel());var G=(this.thumbEl.getHeight()/this.getScaleLevel()>this.imageEl.OriginWidth)?this.imageEl.OriginWidth:(this.thumbEl.getHeight()/this.getScaleLevel());
 +var x=(this.thumbEl.getLeft(true)>this.previewEl.getLeft(true))?0:((this.previewEl.getLeft(true)-this.thumbEl.getLeft(true))/this.getScaleLevel());var y=(this.thumbEl.getTop(true)>this.previewEl.getTop(true))?0:((this.previewEl.getTop(true)-this.thumbEl.getTop(true))/this.getScaleLevel());
 +var I=this.minWidth-2*x;var J=this.minHeight-2*y;var H=1;if((x==0&&y==0)||(x==0&&y>0)){H=I/F;}if(x>0&&y==0){H=J/G;}if(x>0&&y>0){H=I/F;if(F<G){H=J/G;}}E.scale(H,H);var sx=Math.min(this.canvasEl.width-this.thumbEl.getWidth(),this.thumbEl.getLeft(true)-this.previewEl.getLeft(true));
 +var sy=Math.min(this.canvasEl.height-this.thumbEl.getHeight(),this.thumbEl.getTop(true)-this.previewEl.getTop(true));sx=sx<0?0:(sx/this.getScaleLevel());sy=sy<0?0:(sy/this.getScaleLevel());sy+=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?0:Math.abs(this.imageEl.OriginWidth-this.imageEl.OriginHeight);
 +E.drawImage(A,sx,sy,F,G,x,y,F,G);break;default:break;}this.cropData=D.toDataURL(this.cropType);if(this.fireEvent('crop',this,this.cropData)!==false){this.process(this.file,this.cropData);}return;},setThumbBoxSize:function(){var A,B;if(this.isDocument&&typeof(this.imageEl)!='undefined'){A=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?Math.max(this.minWidth,this.minHeight):Math.min(this.minWidth,this.minHeight);
 +B=(this.imageEl.OriginWidth>this.imageEl.OriginHeight)?Math.min(this.minWidth,this.minHeight):Math.max(this.minWidth,this.minHeight);this.minWidth=A;this.minHeight=B;if(this.rotate==90||this.rotate==270){this.minWidth=B;this.minHeight=A;}}B=300;A=Math.ceil(this.minWidth*B/this.minHeight);
 +if(this.minWidth>this.minHeight){A=300;B=Math.ceil(this.minHeight*A/this.minWidth);}this.thumbEl.setStyle({width:A+'px',height:B+'px'});return;},setThumbBoxPosition:function(){var x=Math.ceil((this.bodyEl.getWidth()-this.thumbEl.getWidth())/2);var y=Math.ceil((this.bodyEl.getHeight()-this.thumbEl.getHeight())/2);
 +this.thumbEl.setLeft(x);this.thumbEl.setTop(y);},baseRotateLevel:function(){this.baseRotate=1;if(typeof(this.exif)!='undefined'&&typeof(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']])!='undefined'&&[1,3,6,8].indexOf(this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']])!=-1){this.baseRotate=this.exif[Roo.dialog.UploadCropbox['tags']['Orientation']];
 +}this.rotate=Roo.dialog.UploadCropbox['Orientation'][this.baseRotate];},baseScaleLevel:function(){var A,B;if(this.isDocument){if(this.baseRotate==6||this.baseRotate==8){B=this.thumbEl.getHeight();this.baseScale=B/this.imageEl.OriginWidth;if(this.imageEl.OriginHeight*this.baseScale>this.thumbEl.getWidth()){A=this.thumbEl.getWidth();
 +this.baseScale=A/this.imageEl.OriginHeight;}return;}B=this.thumbEl.getHeight();this.baseScale=B/this.imageEl.OriginHeight;if(this.imageEl.OriginWidth*this.baseScale>this.thumbEl.getWidth()){A=this.thumbEl.getWidth();this.baseScale=A/this.imageEl.OriginWidth;
 +}return;}if(this.baseRotate==6||this.baseRotate==8){A=this.thumbEl.getHeight();this.baseScale=A/this.imageEl.OriginHeight;if(this.imageEl.OriginHeight*this.baseScale<this.thumbEl.getWidth()){B=this.thumbEl.getWidth();this.baseScale=B/this.imageEl.OriginHeight;
 +}if(this.imageEl.OriginWidth>this.imageEl.OriginHeight){B=this.thumbEl.getWidth();this.baseScale=B/this.imageEl.OriginHeight;if(this.imageEl.OriginWidth*this.baseScale<this.thumbEl.getHeight()){A=this.thumbEl.getHeight();this.baseScale=A/this.imageEl.OriginWidth;
 +}}return;}A=this.thumbEl.getWidth();this.baseScale=A/this.imageEl.OriginWidth;if(this.imageEl.OriginHeight*this.baseScale<this.thumbEl.getHeight()){B=this.thumbEl.getHeight();this.baseScale=B/this.imageEl.OriginHeight;}if(this.imageEl.OriginWidth>this.imageEl.OriginHeight){B=this.thumbEl.getHeight();
 +this.baseScale=B/this.imageEl.OriginHeight;if(this.imageEl.OriginWidth*this.baseScale<this.thumbEl.getWidth()){A=this.thumbEl.getWidth();this.baseScale=A/this.imageEl.OriginWidth;}}if(this.imageEl.OriginWidth<this.minWidth||this.imageEl.OriginHeight<this.minHeight){this.baseScale=A/this.minWidth;
 +}return;},getScaleLevel:function(){return this.baseScale*Math.pow(1.02,this.scale);},onTouchStart:function(e){if(!this.canvasLoaded){this.beforeSelectFile(e);return;}var A=e.browserEvent.touches;if(!A){return;}if(A.length==1){this.onMouseDown(e);return;}if(A.length!=2){return;
 +}var B=[];for(var i=0,C;C=A[i];i++){B.push(C.pageX,C.pageY);}var x=Math.pow(B[0]-B[2],2);var y=Math.pow(B[1]-B[3],2);this.startDistance=Math.sqrt(x+y);this.startScale=this.scale;this.pinching=true;this.dragable=false;},onTouchMove:function(e){if(!this.pinching&&!this.dragable){return;
 +}var A=e.browserEvent.touches;if(!A){return;}if(this.dragable){this.onMouseMove(e);return;}var B=[];for(var i=0,C;C=A[i];i++){B.push(C.pageX,C.pageY);}var x=Math.pow(B[0]-B[2],2);var y=Math.pow(B[1]-B[3],2);this.endDistance=Math.sqrt(x+y);this.scale=this.startScale+Math.floor(Math.log(this.endDistance/this.startDistance)/Math.log(1.1));
 +if(!this.zoomable()){this.scale=this.startScale;return;}this.draw();},onTouchEnd:function(e){this.pinching=false;this.dragable=false;},process:function(A,B){if(this.loadMask){this.maskEl.mask(this.loadingText);}this.xhr=new XMLHttpRequest();A.xhr=this.xhr;
 +this.xhr.open(this.method,this.url,true);var C={"Accept":"application/json","Cache-Control":"no-cache","X-Requested-With":"XMLHttpRequest"};for(var D in C){var E=C[D];if(E){this.xhr.setRequestHeader(D,E);}}var F=this;this.xhr.onload=function(){F.xhrOnLoad(F.xhr);
 +};this.xhr.onerror=function(){F.xhrOnError(F.xhr);};var G=new FormData();G.append('returnHTML','NO');if(B){G.append('crop',B);var H=atob(B.split(',')[1]);var I=[];for(var i=0;i<H.length;i++){I.push(H.charCodeAt(i));}var J=new Blob([new Uint8Array(I)],{type:this.cropType}
 +);G.append(this.paramName,J,A.name);}if(typeof(A.filename)!='undefined'){G.append('filename',A.filename);}if(typeof(A.mimetype)!='undefined'){G.append('mimetype',A.mimetype);}if(this.fireEvent('arrange',this,G)!=false){this.xhr.send(G);};},xhrOnLoad:function(A){if(this.loadMask){this.maskEl.unmask();
 +}if(A.readyState!==4){this.fireEvent('exception',this,A);return;}var B=Roo.decode(A.responseText);if(!B.success){this.fireEvent('exception',this,A);return;}var B=Roo.decode(A.responseText);this.fireEvent('upload',this,B);},xhrOnError:function(){if(this.loadMask){this.maskEl.unmask();
 +}Roo.log('xhr on error');var A=Roo.decode(xhr.responseText);Roo.log(A);},prepare:function(A){if(this.loadMask){this.maskEl.mask(this.loadingText);}this.file=false;this.exif={};if(typeof(A)==='string'){this.loadCanvas(A);return;}if(!A||!this.urlAPI){return;
 +}this.file=A;if(typeof(A.type)!='undefined'&&A.type.length!=0){this.cropType=A.type;}var B=this;if(this.fireEvent('prepare',this,this.file)!=false){var C=new FileReader();C.onload=function(e){if(e.target.error){Roo.log(e.target.error);return;}var D=e.target.result,E=new DataView(D),F=2,G=E.byteLength-4,H,I;
 +if(E.getUint16(0)===0xffd8){while(F<G){H=E.getUint16(F);if((H>=0xffe0&&H<=0xffef)||H===0xfffe){I=E.getUint16(F+2)+2;if(F+I>E.byteLength){Roo.log('Invalid meta data: Invalid segment size.');break;}if(H==0xffe1){B.parseExifData(E,F,I);}F+=I;continue;}break;
 +}}var J=B.urlAPI.createObjectURL(B.file);B.loadCanvas(J);return;};C.readAsArrayBuffer(this.file);}},parseExifData:function(A,B,C){var D=B+10,E,F;if(A.getUint32(B+4)!==0x45786966){return;}if(A.getUint32(B+4)!==0x45786966){return;}if(D+8>A.byteLength){Roo.log('Invalid Exif data: Invalid segment size.');
 +return;}if(A.getUint16(B+8)!==0x0000){Roo.log('Invalid Exif data: Missing byte alignment offset.');return;}switch(A.getUint16(D)){case 0x4949:E=true;break;case 0x4D4D:E=false;break;default:Roo.log('Invalid Exif data: Invalid byte alignment marker.');return;
 +}if(A.getUint16(D+2,E)!==0x002A){Roo.log('Invalid Exif data: Missing TIFF marker.');return;}F=A.getUint32(D+4,E);this.parseExifTags(A,D,D+F,E);},parseExifTags:function(A,B,C,D){var E,F,i;if(C+6>A.byteLength){Roo.log('Invalid Exif data: Invalid directory offset.');
 +return;}E=A.getUint16(C,D);F=C+2+12*E;if(F+4>A.byteLength){Roo.log('Invalid Exif data: Invalid directory size.');return;}for(i=0;i<E;i+=1){this.parseExifTag(A,B,C+2+12*i,D);}return A.getUint32(F,D);},parseExifTag:function(A,B,C,D){var E=A.getUint16(C,D);this.exif[E]=this.getExifValue(A,B,C,A.getUint16(C+2,D),A.getUint32(C+4,D),D);
 +},getExifValue:function(A,B,C,D,E,F){var G=Roo.dialog.UploadCropbox.exifTagTypes[D],H,I,J,i,K,c;if(!G){Roo.log('Invalid Exif data: Invalid tag type.');return;}H=G.size*E;I=H>4?B+A.getUint32(C+8,F):(C+8);if(I+H>A.byteLength){Roo.log('Invalid Exif data: Invalid data offset.');
 +return;}if(E===1){return G.getValue(A,I,F);}J=[];for(i=0;i<E;i+=1){J[i]=G.getValue(A,I+i*G.size,F);}if(G.ascii){K='';for(i=0;i<J.length;i+=1){c=J[i];if(c==='\u0000'){break;}K+=c;}return K;}return J;}});Roo.apply(Roo.dialog.UploadCropbox,{tags:{'Orientation':0x0112
 +}
 +,Orientation:{1:0,3:180,6:90,8:270},exifTagTypes:{1:{getValue:function(A,B){return A.getUint8(B);},size:1},2:{getValue:function(A,B){return String.fromCharCode(A.getUint8(B));},size:1,ascii:true},3:{getValue:function(A,B,C){return A.getUint16(B,C);},size:2}
 +,4:{getValue:function(A,B,C){return A.getUint32(B,C);},size:4},5:{getValue:function(A,B,C){return A.getUint32(B,C)/A.getUint32(B+4,C);},size:8},9:{getValue:function(A,B,C){return A.getInt32(B,C);},size:4},10:{getValue:function(A,B,C){return A.getInt32(B,C)/A.getInt32(B+4,C);
 +},size:8}},footer:{STANDARD:[{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-left',action:'rotate-left',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-undo"></i>'}]},{tag:'div',cls:'btn-group roo-upload-cropbox-picture',action:'picture',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-picture-o"></i>'}
 +]},{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-right',action:'rotate-right',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-repeat"></i>'}]}],DOCUMENT:[{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-left',action:'rotate-left',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-undo"></i>'}
 +]},{tag:'div',cls:'btn-group roo-upload-cropbox-download',action:'download',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-download"></i>'}]},{tag:'div',cls:'btn-group roo-upload-cropbox-crop',action:'crop',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-crop"></i>'}
 +]},{tag:'div',cls:'btn-group roo-upload-cropbox-trash',action:'trash',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-trash"></i>'}]},{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-right',action:'rotate-right',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-repeat"></i>'}
 +]}],ROTATOR:[{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-left',action:'rotate-left',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-undo"></i>'}]},{tag:'div',cls:'btn-group roo-upload-cropbox-rotate-right',action:'rotate-right',cn:[{tag:'button',cls:'btn btn-default',html:'<i class="fa fa-repeat"></i>'}
 +]}]}});