From 0efecd74a533dcaa5f27bf5061618cc54fb2e33e Mon Sep 17 00:00:00 2001 From: Mihai Sucan Date: Fri, 24 Jul 2009 22:03:24 +0300 Subject: [PATCH] Attempt to implement image save using data URLs. The attempt consisted of getting the TinyMCE plugin and the Moodle extension for PaintWeb to update the target image src attribute to hold the data URL generated by the browser. This is doable, but the attempt pretty much failed. Reasons: - TinyMCE does not really allow a plugin to manually change the .src DOM attribute for the image element, thus I must use their dom.setAttrib() method. If I do, their attribute value processing functions break the date URL making it invalid. If I manually set image.src to be what I want, it looks good in the browser, but when you save the textarea content will still point to the old image src attribute. Yay! - For some reason, Webkit considers images with data URLs as "external resources", thus when I draw them in Canvas, the Canvas is marked as dirty (security violation). Therefore, In Chrome/Safari one cannot edit data URLs and save them again. - Firefox crashes/freezes sometimes when TinyMCE + data URLs are used. Uh-oh. --- lang/en_utf8/paintweb.php | 1 - .../tiny_mce/plugins/paintweb/editor_plugin.js | 2 +- .../tiny_mce/plugins/paintweb/editor_plugin_src.js | 41 +++++++++++++-------- lib/paintweb/build/paintweb.js | 2 +- lib/paintweb/build/paintweb.src.js | 42 +++++++++++++++------- lib/paintweb/ext/moodle/gen_moodlelang.php | 4 +-- .../ext/tinymce-plugin/paintweb/editor_plugin.js | 2 +- .../tinymce-plugin/paintweb/editor_plugin_src.js | 41 +++++++++++++-------- lib/paintweb/src/extensions/moodle.js | 42 +++++++++++++++------- 9 files changed, 115 insertions(+), 62 deletions(-) rewrite lib/editor/tinymce/jscripts/tiny_mce/plugins/paintweb/editor_plugin.js (100%) rewrite lib/paintweb/ext/tinymce-plugin/paintweb/editor_plugin.js (100%) diff --git a/lang/en_utf8/paintweb.php b/lang/en_utf8/paintweb.php index e8d11a9e23d..f9c14542ff4 100644 --- a/lang/en_utf8/paintweb.php +++ b/lang/en_utf8/paintweb.php @@ -1,5 +1,4 @@ "+L+"")}D.firstChild.innerHTML=str}}}function M(b){if(!G){return }if(b.successful&&T){T=false;A();return }T=false;if(D){if(b.successful){D.firstChild.innerHTML=Y.getLang("paintweb.statusImageSaved","Image save was succesful!")}else{D.firstChild.innerHTML=Y.getLang("paintweb.statusImageSaveFailed","Image save failed!")}setTimeout(F,O)}}function F(){if(!D||!G||!L){return }var b="";if(L==="dataURL"){b=Y.getLang("paintweb.statusEditingDataURL")}else{b=Y.getLang("paintweb.statusImageEditing","You are editing {file}.").replace("{file}",""+L+"")}D.firstChild.innerHTML=b}function E(){if(!I(G)){G=null;L=null;return }if(K){clearTimeout(K);K=null}L=G.src;if(L.substr(0,5)==="data:"){L="dataURL"}else{L=L.substr(L.lastIndexOf("/")+1)}if(C&&C.parentNode&&Y){C.title=Y.getLang("paintweb.overlayLoading","Loading PaintWeb...");C.replaceChild(document.createTextNode(C.title),C.firstChild)}if(S){S.imageLoad(G);N()}else{a()}}function N(){S.gui.show();Z.style.display="none";if(!D){return }F();var b=U.guiPlaceholder;if(!D.parentNode){b.parentNode.insertBefore(D,b)}}function A(){S.gui.hide();if(C&&Y){C.title=Y.getLang("paintweb.overlayButton","Edit");C.replaceChild(document.createTextNode(C.title),C.firstChild)}if(D&&D.parentNode){Z.parentNode.removeChild(D)}Z.style.display="";G=null;L=null;Y.focus();if(!K){K=setTimeout(B,W)}}function B(){if(S){S.destroy();var b=U.guiPlaceholder.parentNode;b.removeChild(U.guiPlaceholder);S=null;U=null;K=null}}function X(){if(G){return }Y=this;Z=this.getContainer();G=this.selection.getNode();E()}function I(f){if(!f){return false}var b=f.src;if(f.nodeName.toLowerCase()!=="img"||!b){return false}var e=b.indexOf(":"),d=b.substr(0,e+1).toLowerCase();if(d==="data:"){return true}if(d!=="http:"&&d!=="https:"){return false}var c=b.replace(/^https?:\/\//i,"");e=c.indexOf("/");if(e>-1){c=c.substr(0,e)}if(c!==window.location.host){return false}return true}function R(c){if(!c||!c.getDoc){return }var f=c.getDoc();if(!f||!f.getElementsByClassName){return }var b=f.getElementsByClassName(C.className),e;for(var d=0;d"+L+"")}D.firstChild.innerHTML=str}}}function M(c){if(!G){return }if(D){if(c.successful){D.firstChild.innerHTML=Z.getLang("paintweb.statusImageSaved","Image save was succesful!")}else{D.firstChild.innerHTML=Z.getLang("paintweb.statusImageSaveFailed","Image save failed!")}V=setTimeout(F,O)}if(c.successful){if(c.urlNew){Z.dom.setAttrib(G,"src",c.urlNew)}if(T){T=false;A()}}}function F(){if(!D||!G||!L){return }V=null;var c="";if(L==="dataURL"){c=Z.getLang("paintweb.statusEditingDataURL")}else{c=Z.getLang("paintweb.statusImageEditing","You are editing {file}.").replace("{file}",""+L+"")}D.firstChild.innerHTML=c}function E(){if(!I(G)){G=null;L=null;return }if(K){clearTimeout(K);K=null}L=Z.dom.getAttrib(G,"src");if(L.substr(0,5)==="data:"){L="dataURL"}else{L=L.substr(L.lastIndexOf("/")+1)}if(C&&C.parentNode&&Z){C.title=Z.getLang("paintweb.overlayLoading","Loading PaintWeb...");C.replaceChild(document.createTextNode(C.title),C.firstChild)}if(S){S.imageLoad(G);N()}else{b()}}function N(){S.gui.show();a.style.display="none";if(!D){return }F();var c=U.guiPlaceholder;if(!D.parentNode){c.parentNode.insertBefore(D,c)}}function A(){S.gui.hide();if(C&&Z){C.title=Z.getLang("paintweb.overlayButton","Edit");C.replaceChild(document.createTextNode(C.title),C.firstChild)}if(D&&D.parentNode){a.parentNode.removeChild(D)}a.style.display="";G=null;L=null;Z.focus();if(!K){K=setTimeout(B,X)}}function B(){if(S){S.destroy();var c=U.guiPlaceholder.parentNode;c.removeChild(U.guiPlaceholder);S=null;U=null;K=null}}function Y(){if(G){return }Z=this;a=this.getContainer();G=this.selection.getNode();E()}function I(g){if(!g){return false}var c=g.src;if(g.nodeName.toLowerCase()!=="img"||!c){return false}var f=c.indexOf(":"),e=c.substr(0,f+1).toLowerCase();if(e==="data:"){return true}if(e!=="http:"&&e!=="https:"){return false}var d=c.replace(/^https?:\/\//i,"");f=d.indexOf("/");if(f>-1){d=d.substr(0,f)}if(d!==window.location.host){return false}return true}function R(d){if(!d||!d.getDoc){return }var g=d.getDoc();if(!g||!g.getElementsByClassName){return }var c=g.getElementsByClassName(C.className),f;for(var e=0;e. * * $URL: http://code.google.com/p/paintweb $ - * $Date: 2009-07-21 23:00:39 +0300 $ + * $Date: 2009-07-24 21:53:23 +0300 $ */ /** @@ -31,6 +31,7 @@ var overlayButton = null, paintwebInstance = null, pluginBar = null, pluginBarDelay = 5000, // 5 seconds + pluginBarTimeout = null, pwDestroyDelay = 30000, // 30 seconds pwDestroyTimer = null, pwSaveReturn = false, @@ -161,12 +162,16 @@ function pluginCancelButton (ev) { */ function paintwebSave (ev) { if (paintwebConfig.tinymce.imageSaveDataURL) { - targetImage.src = ev.dataURL; - targetFile = 'dataURL'; ev.preventDefault(); - paintwebInstance.events.dispatch(new pwlib.appEvent.imageSaveResult(true)); - } else if (pluginBar && targetEditor) { + var url = targetFile === 'dataURL' ? '-' + : targetEditor.dom.getAttrib(targetImage, + 'src'); + + paintwebInstance.events.dispatch(new pwlib.appEvent.imageSaveResult(true, + url, ev.dataURL)); + + } else if (pluginBar && targetEditor && !pluginBarTimeout) { if (targetFile === 'dataURL') { str = targetEditor.getLang('paintweb.statusSavingDataURL', 'Saving image data URL...'); @@ -190,14 +195,6 @@ function paintwebSaveResult (ev) { return; } - if (ev.successful && pwSaveReturn) { - pwSaveReturn = false; - paintwebHide(); - return; - } - - pwSaveReturn = false; - if (pluginBar) { if (ev.successful) { pluginBar.firstChild.innerHTML @@ -208,7 +205,19 @@ function paintwebSaveResult (ev) { = targetEditor.getLang('paintweb.statusImageSaveFailed', 'Image save failed!'); } - setTimeout(pluginBarResetContent, pluginBarDelay); + + pluginBarTimeout = setTimeout(pluginBarResetContent, pluginBarDelay); + } + + if (ev.successful) { + if (ev.urlNew) { + targetEditor.dom.setAttrib(targetImage, 'src', ev.urlNew); + } + + if (pwSaveReturn) { + pwSaveReturn = false; + paintwebHide(); + } } }; @@ -220,6 +229,8 @@ function pluginBarResetContent () { return; } + pluginBarTimeout = null; + var str = ''; if (targetFile === 'dataURL') { @@ -248,7 +259,7 @@ function paintwebEditStart () { pwDestroyTimer = null; } - targetFile = targetImage.src; + targetFile = targetEditor.dom.getAttrib(targetImage, 'src'); if (targetFile.substr(0, 5) === 'data:') { targetFile = 'dataURL'; diff --git a/lib/paintweb/build/paintweb.js b/lib/paintweb/build/paintweb.js index a843d1ce50b..cdc9dc85d5f 100644 --- a/lib/paintweb/build/paintweb.js +++ b/lib/paintweb/build/paintweb.js @@ -1 +1 @@ -var pwlib={};pwlib.fileCache={};pwlib.tools={};pwlib.extensions={};pwlib.extend=function(){var A,D,B,C;if(typeof arguments[0]==="boolean"){force=arguments[0];dest=arguments[1];D=arguments[2]}else{force=false;dest=arguments[0];D=arguments[1]}if(typeof D==="undefined"){D=dest;dest=this}if(typeof dest==="undefined"){return }for(A in D){B=D[A];C=dest[A];if(force||typeof C==="undefined"){dest[A]=B}}};pwlib.strf=function(D,C){if(!D){return D}var B,A;for(A in C){B=new RegExp("{"+A+"}","g");D=D.replace(B,C[A])}return D};pwlib.jsonParse=function(A){A=A.replace(/\s*\/\*(\s|.)+?\*\//g,"").replace(/^\s*\/\/.*$/gm,"");return JSON.parse(A)};pwlib.xhrLoad=function(A,B,E,C){if(!E){E="GET"}var D=new XMLHttpRequest();D.onreadystatechange=function(){B(D)};D.open(E||"GET",A);D.send(C);return D};pwlib.isSameHost=function(B,D){if(!B||!D){return false}var E=B.indexOf(":"),C=B.substr(0,E+1).toLowerCase();if(C==="data:"){return true}if(C!=="http:"&&C!=="https:"){return false}var A=B.replace(/^https?:\/\//i,"");E=A.indexOf("/");if(E>-1){A=A.substr(0,E)}if(A!==D){return false}return true};pwlib.appEvent=function(B,A){if(typeof B!=="string"){throw new TypeError("The first argument must be a string")}else{if(typeof A==="undefined"){A=false}else{if(typeof A!=="boolean"){throw new TypeError("The second argument must be a boolean")}}}this.target=null;this.cancelable=A;this.defaultPrevented=false;this.type=B;this.preventDefault=function(){if(A){this.defaultPrevented=true}};this.stopPropagation=function(){this.propagationStopped_=true}};pwlib.appEvent.appInit=function(B,A){if(typeof B!=="number"){throw new TypeError("The first argument must be a number.")}this.INIT_NOT_STARTED=0;this.INIT_STARTED=1;this.INIT_DONE=2;this.INIT_ERROR=-1;this.state=B;this.errorMessage=A||null;pwlib.appEvent.call(this,"appInit")};pwlib.appEvent.appDestroy=function(){pwlib.appEvent.call(this,"appDestroy")};pwlib.appEvent.guiShow=function(){pwlib.appEvent.call(this,"guiShow")};pwlib.appEvent.guiHide=function(){pwlib.appEvent.call(this,"guiHide")};pwlib.appEvent.toolPreactivate=function(B,A){if(typeof B!=="string"){throw new TypeError("The first argument must be a string.")}else{if(A!==null&&typeof A!=="string"){throw new TypeError("The second argument must be a string or null.")}}this.id=B;this.prevId=A;pwlib.appEvent.call(this,"toolPreactivate",true)};pwlib.appEvent.toolActivate=function(B,A){if(typeof B!=="string"){throw new TypeError("The first argument must be a string.")}else{if(A!==null&&typeof A!=="string"){throw new TypeError("The second argument must be a string or null.")}}this.id=B;this.prevId=A;pwlib.appEvent.call(this,"toolActivate")};pwlib.appEvent.toolRegister=function(A){if(typeof A!=="string"){throw new TypeError("The first argument must be a string.")}this.id=A;pwlib.appEvent.call(this,"toolRegister")};pwlib.appEvent.toolUnregister=function(A){if(typeof A!=="string"){throw new TypeError("The first argument must be a string.")}this.id=A;pwlib.appEvent.call(this,"toolUnregister")};pwlib.appEvent.extensionRegister=function(A){if(typeof A!=="string"){throw new TypeError("The first argument must be a string.")}this.id=A;pwlib.appEvent.call(this,"extensionRegister")};pwlib.appEvent.extensionUnregister=function(A){if(typeof A!=="string"){throw new TypeError("The first argument must be a string.")}this.id=A;pwlib.appEvent.call(this,"extensionUnregister")};pwlib.appEvent.commandRegister=function(A){if(typeof A!=="string"){throw new TypeError("The first argument must be a string.")}this.id=A;pwlib.appEvent.call(this,"commandRegister")};pwlib.appEvent.commandUnregister=function(A){if(typeof A!=="string"){throw new TypeError("The first argument must be a string.")}this.id=A;pwlib.appEvent.call(this,"commandUnregister")};pwlib.appEvent.imageSave=function(C,B,A){this.dataURL=C;this.width=B;this.height=A;pwlib.appEvent.call(this,"imageSave",true)};pwlib.appEvent.imageSaveResult=function(C,A,B){this.successful=C;this.url=A;this.urlNew=B;pwlib.appEvent.call(this,"imageSaveResult")};pwlib.appEvent.historyUpdate=function(C,A,B){if(typeof C!=="number"||typeof A!=="number"||typeof B!=="number"){throw new TypeError("All arguments must be numbers.")}this.currentPos=C;this.previousPos=A;this.states=B;pwlib.appEvent.call(this,"historyUpdate")};pwlib.appEvent.imageSizeChange=function(B,A){if(typeof B!=="number"||typeof A!=="number"){throw new TypeError("Both arguments must be numbers.")}this.width=B;this.height=A;pwlib.appEvent.call(this,"imageSizeChange")};pwlib.appEvent.canvasSizeChange=function(B,A,C){if(typeof B!=="number"||typeof A!=="number"||typeof C!=="number"){throw new TypeError("All the arguments must be numbers.")}this.width=B;this.height=A;this.scale=C;pwlib.appEvent.call(this,"canvasSizeChange")};pwlib.appEvent.imageZoom=function(A){if(typeof A!=="number"){throw new TypeError("The first argument must be a number.")}this.zoom=A;pwlib.appEvent.call(this,"imageZoom",true)};pwlib.appEvent.imageCrop=function(B,D,C,A){if(typeof B!=="number"||typeof D!=="number"||typeof C!=="number"||typeof A!=="number"){throw new TypeError("All arguments must be numbers.")}this.x=B;this.y=D;this.width=C;this.height=A;pwlib.appEvent.call(this,"imageCrop",true)};pwlib.appEvent.configChange=function(D,A,B,E,C){if(typeof B!=="string"){throw new TypeError("The third argument must be a string.")}else{if(typeof E!=="string"){throw new TypeError("The fourth argument must be a string.")}else{if(typeof C!=="object"){throw new TypeError("The fifth argument must be an object.")}}}this.value=D;this.previousValue=A;this.config=B;this.group=E;this.groupRef=C;pwlib.appEvent.call(this,"configChange")};pwlib.appEvent.shadowAllow=function(A){if(typeof A!=="boolean"){throw new TypeError("The first argument must be a boolean.")}this.allowed=A;pwlib.appEvent.call(this,"shadowAllow")};pwlib.appEvent.clipboardUpdate=function(A){this.data=A;pwlib.appEvent.call(this,"clipboardUpdate")};pwlib.appEvents=function(C){var B={};var A=1;this.add=function(E,D){if(typeof E!=="string"){throw new TypeError("The first argument must be a string.")}else{if(typeof D!=="function"){throw new TypeError("The second argument must be a function.")}}var F=A++;if(!(E in B)){B[E]={}}B[E][F]=D;return F};this.remove=function(D,E){if(typeof D!=="string"){throw new TypeError("The first argument must be a string.")}if(!(D in B)||!(E in B[D])){return }delete B[D][E]};this.dispatch=function(E){if(typeof E!=="object"){throw new TypeError("The second argument must be an object.")}else{if(typeof E.type!=="string"){throw new TypeError("The second argument must be an application event object.")}}if(!(E.type in B)){return false}E.target=C;var F,D=B[E.type];for(F in D){D[F].call(C,E);if(E.propagationStopped_){break}}return E.defaultPrevented}};pwlib.browser={};(function(){var A="";if(window.navigator&&window.navigator.userAgent){A=window.navigator.userAgent.toLowerCase()}pwlib.browser.opera=window.opera?true:/\bopera\b/.test(A);pwlib.browser.webkit=/\b(applewebkit|webkit)\b/.test(A);pwlib.browser.firefox=/\bfirefox\b/.test(A)&&!pwlib.browser.opera;pwlib.browser.gecko=/\bgecko\b/.test(A)&&!pwlib.browser.opera&&!pwlib.browser.webkit;pwlib.browser.msie=/\bmsie\b/.test(A)&&!pwlib.browser.opera;pwlib.browser.presto=/\bpresto\b/.test(A)||pwlib.browser.opera;pwlib.browser.os=(A.match(/\b(windows|linux)\b/)||[])[1];pwlib.browser.olpcxo=A.match(/\bolpc\b/)&&A.match(/\bxo\b/);delete A})();pwlib.dom={};pwlib.dom.keyNames={Help:6,Backspace:8,Tab:9,Clear:12,Enter:13,Shift:16,Control:17,Alt:18,Pause:19,CapsLock:20,Cancel:24,Escape:27,Space:32,PageUp:33,PageDown:34,End:35,Home:36,Left:37,Up:38,Right:39,Down:40,PrintScreen:44,Insert:45,Delete:46,Win:91,ContextMenu:93,"*":106,"+":107,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,NumLock:144,";":186,"=":187,",":188,"-":189,".":190,"/":191,"`":192,"[":219,"\\":220,"]":221,"'":222};pwlib.dom.keyCodes={3:"Enter",6:"Help",8:"Backspace",9:"Tab",10:"Enter",12:"Clear",13:"Enter",14:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",24:"Cancel",27:"Escape",32:"Space",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"Left",38:"Up",39:"Right",40:"Down",45:"Insert",46:"Delete",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9",106:"*",107:"+",109:"-",110:".",111:"/",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",127:"Delete",144:"NumLock",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'"};if(pwlib.browser.gecko){pwlib.dom.keyCodes[3]="Cancel"}pwlib.dom.keyCodes_fixes={42:pwlib.dom.keyNames["*"],47:pwlib.dom.keyNames["/"],59:pwlib.dom.keyNames[";"],61:pwlib.dom.keyNames["="],96:48,97:49,98:50,99:51,100:52,101:53,102:54,103:55,104:56,105:57,109:pwlib.dom.keyNames["-"],110:pwlib.dom.keyNames["."],111:pwlib.dom.keyNames["/"]};pwlib.dom.keyCodes_Safari2={63232:pwlib.dom.keyNames.Up,63233:pwlib.dom.keyNames.Down,63234:pwlib.dom.keyNames.Left,63235:pwlib.dom.keyNames.Right,63236:pwlib.dom.keyNames.F1,63237:pwlib.dom.keyNames.F2,63238:pwlib.dom.keyNames.F3,63239:pwlib.dom.keyNames.F4,63240:pwlib.dom.keyNames.F5,63241:pwlib.dom.keyNames.F6,63242:pwlib.dom.keyNames.F7,63243:pwlib.dom.keyNames.F8,63244:pwlib.dom.keyNames.F9,63245:pwlib.dom.keyNames.F10,63246:pwlib.dom.keyNames.F11,63247:pwlib.dom.keyNames.F12,63248:pwlib.dom.keyNames.PrintScreen,63272:pwlib.dom.keyNames.Delete,63273:pwlib.dom.keyNames.Home,63275:pwlib.dom.keyNames.End,63276:pwlib.dom.keyNames.PageUp,63277:pwlib.dom.keyNames.PageDown,63289:pwlib.dom.keyNames.NumLock,63302:pwlib.dom.keyNames.Insert};pwlib.dom.KeyboardEventListener=function(O,N){var H=null;var L=null;var G=null;var I=null;var F=false;if(!N){throw new TypeError("The first argument must be of type an object.")}if(!N.keydown&&!N.keypress&&!N.keyup){throw new TypeError("The provided handlers object has no keyboard eventhandler.")}if(N.keydown&&typeof N.keydown!=="function"){throw new TypeError("The keydown event handler is not a function!")}if(N.keypress&&typeof N.keypress!=="function"){throw new TypeError("The keypress event handler is not a function!")}if(N.keyup&&typeof N.keyup!=="function"){throw new TypeError("The keyup event handler is not a function!")}this.attach=function(){H=null;L=null;G=null;I=null;F=false;O.addEventListener("keydown",E,false);O.addEventListener("keypress",C,false);O.addEventListener("keyup",B,false)};this.detach=function(){O.removeEventListener("keydown",E,false);O.removeEventListener("keypress",C,false);O.removeEventListener("keyup",B,false);H=null;L=null;G=null;I=null;F=false};function J(Q,R){if(!N[Q]){return }var P=N[Q];if(Q===R.type){P.call(O,R)}else{var S={};pwlib.extend(S,R);S.type=Q;S.preventDefault=function(){R.preventDefault()};P.call(O,S)}}function E(Q){var P=L;G=null;I=null;K(Q);Q.keyCode_=H;Q.key_=L;Q.repeat_=L&&P===L?true:false;F=Q.repeat_;if(!F){J("keydown",Q)}if(!A(L)&&!D(Q)){Q.type_="keydown";C(Q)}}function C(P){if(!H){K(P);F=false}P.keyCode_=H;P.key_=L;M(P);P.charCode_=G;P.char_=I;P.repeat_=F;if(!F){F=true}if(!A(L)){J("keypress",P)}}function B(P){K(P);P.keyCode_=H;P.key_=L;P.charCode_=G;P.char_=I;J("keyup",P);H=null;L=null;G=null;I=null;F=false}function A(P){switch(P){case"Shift":case"Control":case"Alt":case"Meta":case"Win":return true;default:return false}}function D(P){if((L==="Up"||L==="Down")&&pwlib.browser.gecko&&P.target&&P.target.tagName.toLowerCase()==="input"){return false}if(!pwlib.browser.msie&&!pwlib.browser.webkit){return true}if(L&&L!=="Space"&&L!=="Enter"&&L!=="Escape"&&L.length!==1){return false}if(pwlib.browser.webkit&&L==="Escape"){return false}if(pwlib.browser.msie&&!P.shiftKey&&(P.ctrlKey||P.altKey)){return false}return true}function K(Q){if(Q.type==="keyup"&&!Q.keyCode&&!Q.which&&(!Q.keyIdentifier||Q.keyIdentifier==="Unidentified"||Q.keyIdentifier==="U+0000")){return }H=null;L=null;if(Q.keyCode||Q.which){H=Q.keyCode||Q.which;if(pwlib.browser.webkit){if(H==25&&this.shiftKey){H=pwlib.dom.keyNames.Tab}else{if(H>=63232&&H in pwlib.dom.keyCodes_Safari2){H=pwlib.dom.keyCodes_Safari2[H]}}}if(H in pwlib.dom.keyCodes_fixes){H=pwlib.dom.keyCodes_fixes[H]}L=pwlib.dom.keyCodes[H]||String.fromCharCode(H);return }var P=null,R=null,S=Q.keyIdentifier;if(!S||S==="Unidentified"||S==="U+0000"){return }if(S.substr(0,2)==="U+"){R=parseInt(S.substr(2),16)}else{if(S.length===1){R=S.charCodeAt(0);P=S}else{H=pwlib.dom.keyNames[S]||null;L=S;return }}if(R in pwlib.dom.keyCodes&&(R<=32||R==127||R==144)){L=pwlib.dom.keyCodes[R]}else{if(!P){P=String.fromCharCode(R)}L=P.toUpperCase();if(P!==L){R=L.charCodeAt(0)}}if(L==="Delete"||L.length===1&&L in pwlib.dom.keyNames){R=pwlib.dom.keyNames[L]}H=R}function M(R){G=null;I=null;if(R.charCode){G=R.charCode;I=String.fromCharCode(R.charCode);return }if(R.keyCode||R.which){var T=R.keyCode||R.which;var S=false;switch(T){case pwlib.dom.keyNames.Tab:case pwlib.dom.keyNames.Enter:case pwlib.dom.keyNames.Space:S=true}if(!S&&L&&L.length!==1){return }if(R.type_==="keydown"){var Q=pwlib.dom.keyCodes[T];if(Q&&Q.length===1){G=Q.charCodeAt(0);I=Q}}else{if(T>=32||S){G=T;I=String.fromCharCode(T)}}if(G){return }}var V=null,P=null,U=R.keyIdentifier;if(U&&U!=="Unidentified"&&U!=="U+0000"&&(U.substr(0,2)==="U+"||U.length===1)){if(U.length===1){P=U.charCodeAt(0);V=U}else{P=parseInt(U.substr(2),16)}if(P==pwlib.dom.keyNames.Tab||P==pwlib.dom.keyNames.Enter||P>=32&&P!=127&&P!=pwlib.dom.keyNames.NumLock){G=P;I=V||String.fromCharCode(P);return }}if(L&&L.length===1){G=L.charCodeAt(0);I=L}}this.attach()};pwlib.tools.selection=function(E){var K=this,R=pwlib.appEvent,N=E.buffer.context,q=E.win.clearInterval,f=E.config.selection,i=E.gui,H=E.image,I=E.lang,e=E.layer.canvas,V=E.layer.context,B=null,U=Math.abs,o=Math.min,r=Math.round,Z=E.mouse,J=E.win.setInterval,S=E.toolSnapXY;var X=null;var h=false;this.STATE_PENDING=-1;this.STATE_NONE=0;this.STATE_DRAWING=1;this.STATE_SELECTED=2;this.STATE_DRAGGING=3;this.STATE_RESIZING=4;this.state=this.STATE_NONE;var O=0;var C=0;this.selection={x:0,y:0,width:0,height:0,widthOriginal:0,heightOriginal:0,layerCleared:false,marquee:null,context:null,canvas:null};var c="out";var a=null;var Y=this.selection,l=f.borderWidth*2,T=null,j=null,P=false,L=false;var g=null;this.preActivate=function(){if(!("canvasContainer" in i.elems)){alert(I.errorToolActivate);return false}Y.canvas=E.doc.createElement("canvas");if(!Y.canvas){alert(I.errorToolActivate);return false}Y.canvas.width=5;Y.canvas.height=5;Y.context=Y.canvas.getContext("2d");if(!Y.context){alert(I.errorToolActivate);return false}Y.marquee=E.doc.createElement("div");if(!Y.marquee){alert(I.errorToolActivate);return false}Y.marquee.className=i.classPrefix+"selectionMarquee";B=Y.marquee.style;return true};this.activate=function(){if(!V.putImageData||!V.getImageData){f.transparent=true}b();B.borderWidth=f.borderWidth+"px";Y.marquee.addEventListener("mousedown",M,false);Y.marquee.addEventListener("mousemove",Q,false);Y.marquee.addEventListener("mouseup",G,false);i.elems.canvasContainer.appendChild(Y.marquee);E.shadowDisallow();T=E.events.add("canvasSizeChange",D);j=E.events.add("configChange",W);E.commandRegister("selectionCrop",K.selectionCrop);E.commandRegister("selectionDelete",K.selectionDelete);E.commandRegister("selectionFill",K.selectionFill);if(!X){X=J(p,E.config.toolDrawDelay)}return true};this.deactivate=function(){if(X){q(X);X=null}K.selectionMerge();Y.marquee.removeEventListener("mousedown",M,false);Y.marquee.removeEventListener("mousemove",Q,false);Y.marquee.removeEventListener("mouseup",G,false);B=null;i.elems.canvasContainer.removeChild(Y.marquee);delete Y.context,Y.canvas,Y.marquee;E.shadowAllow();if(T){E.events.remove("canvasSizeChange",T)}if(j){E.events.remove("configChange",j)}E.commandUnregister("selectionCrop");E.commandUnregister("selectionDelete");E.commandUnregister("selectionFill");return true};this.mousedown=function(s){if(K.state!==K.STATE_NONE&&K.state!==K.STATE_SELECTED){return false}O=Z.x;C=Z.y;L=s.shiftKey;P=s.ctrlKey;g=null;if(K.state===K.STATE_NONE){K.state=K.STATE_DRAWING;B.display="";i.statusShow("selectionDraw");return true}F();switch(c){case"out":K.state=K.STATE_PENDING;b();i.statusShow("selectionActive");k();return true;case"in":K.state=K.STATE_DRAGGING;i.statusShow("selectionDrag");break;case"border":K.state=K.STATE_RESIZING;i.statusShow("selectionResize")}if(s.ctrlKey){f.transform=!f.transform}if(Y.layerCleared&&!f.transform){k()}else{if(!Y.layerCleared&&f.transform){n()}}return true};this.mousemove=function(s){L=s.shiftKey;h=true};function p(){if(!h){return }switch(K.state){case K.STATE_PENDING:K.state=K.STATE_DRAWING;B.display="";i.statusShow("selectionDraw");case K.STATE_DRAWING:d();break;case K.STATE_SELECTED:F();break;case K.STATE_DRAGGING:m();break;case K.STATE_RESIZING:A()}h=false}this.mouseup=function(s){if(K.state!==K.STATE_PENDING&&Z.x===O&&Z.y===C){return true}h=false;L=s.shiftKey;if(P){f.transform=!f.transform}if(K.state===K.STATE_PENDING){K.state=K.STATE_NONE;E.events.dispatch(new R.selectionChange(K.state));return true}else{if(!g){K.state=K.STATE_NONE;b();i.statusShow("selectionActive");E.events.dispatch(new R.selectionChange(K.state));return true}}Y.x=g.x;Y.y=g.y;if("width" in g){Y.width=g.width;Y.height=g.height}K.state=K.STATE_SELECTED;E.events.dispatch(new R.selectionChange(K.state,Y.x,Y.y,Y.width,Y.height));i.statusShow("selectionAvailable");return true};function M(s){if(Z.buttonDown){return }Z.buttonDown=true;s.preventDefault();K.mousedown(s)}function Q(s){if("layerX" in s){Z.x=r((this.offsetLeft+s.layerX)/H.canvasScale);Z.y=r((this.offsetTop+s.layerY)/H.canvasScale)}else{if("offsetX" in s){Z.x=r((this.offsetLeft+s.offsetX)/H.canvasScale);Z.y=r((this.offsetTop+s.offsetY)/H.canvasScale)}}L=s.shiftKey;h=true}function G(s){if(!Z.buttonDown){return }Z.buttonDown=false;s.preventDefault();K.mouseup(s)}function b(){B.display="none";B.top="-"+(l+50)+"px";B.left="-"+(l+50)+"px";B.width="1px";B.height="1px";B.cursor=""}function d(){var s=o(Z.x,O),AA=o(Z.y,C),t=U(Z.x-O),v=U(Z.y-C);if(L){if(t>v){if(AA===Z.y){AA-=t-v}v=t}else{if(s===Z.x){s-=v-t}t=v}}var z=t*H.canvasScale-l,u=v*H.canvasScale-l;if(z<1||u<1){g=null;return }B.top=(AA*H.canvasScale)+"px";B.left=(s*H.canvasScale)+"px";B.width=z+"px";B.height=u+"px";g={x:s,y:AA,width:t,height:v}}function m(){if(L){S(O,C)}var s=Y.x+Z.x-O,t=Y.y+Z.y-C;if(f.transform){N.clearRect(0,0,H.width,H.height);if(!f.transparent){N.fillRect(s,t,Y.width,Y.height)}N.drawImage(Y.canvas,s,t,Y.width,Y.height)}B.top=(t*H.canvasScale)+"px";B.left=(s*H.canvasScale)+"px";g={x:s,y:t}}function A(){var u=Z.x-O,t=Z.y-C,AD=Y.x,AC=Y.y,AE=Y.width,z=Y.height;switch(a){case"nw":AD+=u;AC+=t;AE-=u;z-=t;break;case"n":AC+=t;z-=t;break;case"ne":AC+=t;AE+=u;z-=t;break;case"e":AE+=u;break;case"se":AE+=u;z+=t;break;case"s":z+=t;break;case"sw":AD+=u;AE-=u;z+=t;break;case"w":AD+=u;AE-=u;break;default:g=null;return }if(!AE||!z){g=null;return }if(L){var s=Y.width/Y.height,v=AE,AB=z;switch(a.charAt(0)){case"n":case"s":v=r(z*s);break;default:AB=r(AE/s)}switch(a){case"nw":case"sw":AD-=v-AE;AC-=AB-z}AE=v;z=AB}if(AE<0){AD+=AE;AE*=-1}if(z<0){AC+=z;z*=-1}var AF=AE*H.canvasScale-l,AA=z*H.canvasScale-l;if(AF<1||AA<1){g=null;return }if(f.transform){N.clearRect(0,0,H.width,H.height);if(!f.transparent){N.fillRect(AD,AC,AE,z)}N.drawImage(Y.canvas,AD,AC,AE,z)}B.top=(AC*H.canvasScale)+"px";B.left=(AD*H.canvasScale)+"px";B.width=AF+"px";B.height=AA+"px";g={x:AD,y:AC,width:AE,height:z}}function F(){var x=f.borderWidth/H.canvasScale,AB="",u=Y.x+Y.width,z=Y.y+Y.height,t=u-x,s=z-x,v=Y.x,AA=Y.y,y=Y.x+x,w=Y.y+x;c="out";if(Z.xy&&Z.y>w){AB="move";c="in"}else{if(Z.x>=v&&Z.x<=u&&Z.y>=AA&&Z.y<=w){AB="n"}else{if(Z.x>=v&&Z.x<=u&&Z.y>=s&&Z.y<=z){AB="s"}}if(Z.y>=AA&&Z.y<=z&&Z.x>=v&&Z.x<=y){AB+="w"}else{if(Z.y>=AA&&Z.y<=z&&Z.x>=t&&Z.x<=u){AB+="e"}}if(AB!==""){a=AB;AB+="-resize";c="border"}}if(AB!==B.cursor){B.cursor=AB}}function D(s){if(K.state!==K.STATE_SELECTED){return }B.top=(Y.y*s.scale)+"px";B.left=(Y.x*s.scale)+"px";B.width=(Y.width*s.scale-l)+"px";B.height=(Y.height*s.scale-l)+"px"}function W(s){if(s.group!=="selection"||s.config!=="transparent"||!f.transform||K.state!==K.STATE_SELECTED){return }if(!Y.layerCleared){n()}N.clearRect(Y.x,Y.y,Y.width,Y.height);if(!s.value){N.fillRect(Y.x,Y.y,Y.width,Y.height)}N.drawImage(Y.canvas,Y.x,Y.y,Y.width,Y.height)}function n(){var s=Y.x,AC=Y.y,u=Y.width,z=Y.height,AB=Y.x+Y.width,AA=Y.y+Y.height,v=0,t=0;Y.widthOriginal=u;Y.heightOriginal=z;if(s<0){u+=s;v-=s;s=0}if(AC<0){z+=AC;t-=AC;AC=0}if(AB>H.width){u=H.width-Y.x}if(AA>H.height){z=H.height-Y.y}if(!f.transparent){N.fillRect(s,AC,u,z)}N.drawImage(e,s,AC,u,z,s,AC,u,z);Y.canvas.width=Y.widthOriginal;Y.canvas.height=Y.heightOriginal;Y.context.drawImage(e,s,AC,u,z,v,t,u,z);V.clearRect(s,AC,u,z);Y.layerCleared=true;E.historyAdd()}function k(){if(!Y.layerCleared){return }if(!f.transparent){V.fillRect(Y.x,Y.y,Y.width,Y.height)}V.drawImage(Y.canvas,Y.x,Y.y,Y.width,Y.height);N.clearRect(Y.x,Y.y,Y.width,Y.height);Y.layerCleared=false;Y.canvas.width=5;Y.canvas.height=5;E.historyAdd()}this.selectionMerge=function(){if(K.state!==K.STATE_SELECTED){return false}k();K.state=K.STATE_NONE;b();i.statusShow("selectionActive");E.events.dispatch(new R.selectionChange(K.state));return true};this.selectAll=function(){if(K.state!==K.STATE_NONE&&K.state!==K.STATE_SELECTED){return false}if(K.state===K.STATE_SELECTED){k()}else{K.state=K.STATE_SELECTED;B.display=""}Y.x=0;Y.y=0;Y.width=H.width;Y.height=H.height;B.top="0px";B.left="0px";B.width=(Y.width*H.canvasScale-l)+"px";B.height=(Y.height*H.canvasScale-l)+"px";F();E.events.dispatch(new R.selectionChange(K.state,Y.x,Y.y,Y.width,Y.height));return true};this.selectionCut=function(){if(!K.selectionCopy()){return false}if(Y.layerCleared){N.clearRect(Y.x,Y.y,Y.width,Y.height);Y.canvas.width=5;Y.canvas.height=5;Y.layerCleared=false}else{V.clearRect(Y.x,Y.y,Y.width,Y.height);E.historyAdd()}K.state=K.STATE_NONE;b();E.events.dispatch(new R.selectionChange(K.state));i.statusShow("selectionActive");return true};this.selectionCopy=function(){if(K.state!==K.STATE_SELECTED){return false}if(!V.getImageData||!V.putImageData){alert(I.errorClipboardUnsupported);return false}if(!Y.layerCleared){var s=Y.width,t=Y.height,v=Y.width+Y.x;sumY=Y.height+Y.y;if(v>H.width){s=H.width-Y.x}if(sumY>H.height){t=H.height-Y.y}try{E.clipboard=V.getImageData(Y.x,Y.y,s,t)}catch(u){alert(I.failedSelectionCopy);return false}}else{try{E.clipboard=Y.context.getImageData(0,0,Y.widthOriginal,Y.heightOriginal)}catch(u){alert(I.failedSelectionCopy);return false}}E.events.dispatch(new R.clipboardUpdate(E.clipboard));return true};this.clipboardPaste=function(){if(!E.clipboard||K.state!==K.STATE_NONE&&K.state!==K.STATE_SELECTED){return false}if(!V.getImageData||!V.putImageData){alert(I.errorClipboardUnsupported);return false}var s=r(i.elems.viewport.scrollLeft/H.canvasScale),v=r(i.elems.viewport.scrollTop/H.canvasScale),t=E.clipboard.width,u=E.clipboard.height;Y.canvas.width=t;Y.canvas.height=u;Y.context.putImageData(E.clipboard,0,0);if(K.state===K.STATE_SELECTED){N.clearRect(Y.x,Y.y,Y.width,Y.height)}else{K.state=K.STATE_SELECTED}if(!f.transparent){N.fillRect(s,v,t,u)}N.drawImage(Y.canvas,s,v,t,u);Y.widthOriginal=Y.width=t;Y.heightOriginal=Y.height=u;Y.x=s;Y.y=v;Y.layerCleared=true;B.top=(v*H.canvasScale)+"px";B.left=(s*H.canvasScale)+"px";B.width=(t*H.canvasScale-l)+"px";B.height=(u*H.canvasScale-l)+"px";B.display="";if(!f.transform){f.transform=true;E.events.dispatch(new R.configChange(true,false,"transform","selection",f))}F();E.events.dispatch(new R.selectionChange(K.state,Y.x,Y.y,Y.width,Y.height));i.statusShow("selectionAvailable");return true};this.selectionDelete=function(){if(K.state!==K.STATE_SELECTED){return false}if(!Y.layerCleared){V.clearRect(Y.x,Y.y,Y.width,Y.height);E.historyAdd()}else{N.clearRect(Y.x,Y.y,Y.width,Y.height);Y.layerCleared=false;Y.canvas.width=5;Y.canvas.height=5;if(f.transform){f.transform=false;E.events.dispatch(new R.configChange(false,true,"transform","selection",f))}}return true};this.selectionDrop=function(){if(K.state!==K.STATE_SELECTED){return false}if(Y.layerCleared){N.clearRect(Y.x,Y.y,Y.width,Y.height);Y.canvas.width=5;Y.canvas.height=5;Y.layerCleared=false}K.state=K.STATE_NONE;b();i.statusShow("selectionActive");E.events.dispatch(new R.selectionChange(K.state));return true};this.selectionFill=function(){if(K.state!==K.STATE_SELECTED){return false}if(Y.layerCleared){Y.context.fillStyle=N.fillStyle;Y.context.fillRect(0,0,Y.widthOriginal,Y.heightOriginal);N.fillRect(Y.x,Y.y,Y.width,Y.height)}else{V.fillStyle=N.fillStyle;V.fillRect(Y.x,Y.y,Y.width,Y.height);E.historyAdd()}return true};this.selectionCrop=function(){if(K.state!==K.STATE_SELECTED){return false}K.selectionMerge();var s=Y.width,t=Y.height,v=Y.x+s,u=Y.y+t;if(v>H.width){s-=v-H.width}if(u>H.height){t-=u-H.height}E.imageCrop(Y.x,Y.y,s,t);return true};this.keydown=function(s){switch(s.kid_){case f.keys.transformToggle:f.transform=!f.transform;E.events.dispatch(new R.configChange(f.transform,!f.transform,"transform","selection",f));break;case f.keys.selectionCrop:return K.selectionCrop(s);case f.keys.selectionDelete:return K.selectionDelete(s);case f.keys.selectionDrop:return K.selectionDrop(s);case f.keys.selectionFill:return K.selectionFill(s);default:return false}return true}};pwlib.appEvent.selectionChange=function(D,B,E,C,A){this.STATE_NONE=0;this.STATE_SELECTED=2;this.state=D;this.x=B;this.y=E;this.width=C;this.height=A;pwlib.appEvent.call(this,"selectionChange")};pwlib.tools.hand=function(F){var J=this,A=F.buffer.canvas,N=A.style,E=F.config;clearInterval=F.win.clearInterval,image=F.image,MathRound=Math.round,mouse=F.mouse,viewport=F.gui.elems.viewport,vheight=0,vwidth=0,setInterval=F.win.setInterval;var C=null;var L=false;this.prevTool=null;var D=0,M=0,B=0,K=0,H=0,I=0;this.preActivate=function(){if(!viewport){return false}J.prevTool=F.tool._id;var R=F.win.getComputedStyle(viewport,null),S=parseInt(N.width),Q=parseInt(N.height);vwidth=parseInt(R.width),vheight=parseInt(R.height);if(vheightS){if(T==J.y){T-=R-S}S=R}else{if(Q==J.x){Q-=S-R}R=S}}if(E.shapeType!="stroke"){B.fillRect(Q,T,R,S)}if(E.shapeType!="fill"){B.strokeRect(Q,T,R,S)}P=false};this.mouseup=function(Q){if(J.x==D&&J.y==M){J.buttonDown=true;return true}if(A){O(A);A=null}K=Q.shiftKey;L.draw();F.layerUpdate();C.statusShow("rectangleActive");return true};this.keydown=function(Q){if(!J.buttonDown||Q.kid_!="Escape"){return false}if(A){O(A);A=null}B.clearRect(0,0,G.width,G.height);J.buttonDown=false;P=false;C.statusShow("rectangleActive");return true}};pwlib.tools.ellipse=function(G){var M=this,Q=G.win.clearInterval,F=G.config,B=G.buffer.context,C=G.gui,H=G.image,E=Math.max,P=Math.min,J=G.mouse,I=G.win.setInterval;var A=null;var L=false;var R=false;var N=4*((Math.SQRT2-1)/3);var D=0;var O=0;this.deactivate=function(){if(A){Q(A);A=null}if(J.buttonDown){B.clearRect(0,0,H.width,H.height)}R=false;return true};this.mousedown=function(K){D=J.x;O=J.y;if(!A){A=I(M.draw,F.toolDrawDelay)}L=K.shiftKey;R=false;C.statusShow("ellipseMousedown");return true};this.mousemove=function(K){L=K.shiftKey;R=true};this.draw=function(){if(!R){return }B.clearRect(0,0,H.width,H.height);var Z=P(J.x,D),Y=E(J.x,D),W=P(J.y,O),V=E(J.y,O);var a=Y-Z,X=V-W;if(!a||!X){R=false;return }if(L){if(a>X){V=W+a;if(W==J.y){W-=a-X;V-=a-X}X=a}else{Y=Z+X;if(Z==J.x){Z-=X-a;Y-=X-a}a=X}}var S=a/2,K=X/2;var U=Z+S,T=W+K;S*=N;K*=N;B.beginPath();B.moveTo(U,W);B.bezierCurveTo(U+S,W,Y,T-K,Y,T);B.bezierCurveTo(Y,T+K,U+S,V,U,V);B.bezierCurveTo(U-S,V,Z,T+K,Z,T);B.bezierCurveTo(Z,T-K,U-S,W,U,W);if(F.shapeType!="stroke"){B.fill()}if(F.shapeType!="fill"){B.stroke()}B.closePath();R=false};this.mouseup=function(K){if(J.x==D&&J.y==O){J.buttonDown=true;return true}if(A){Q(A);A=null}L=K.shiftKey;M.draw();G.layerUpdate();C.statusShow("ellipseActive");return true};this.keydown=function(K){if(!J.buttonDown||K.kid_!="Escape"){return false}if(A){Q(A);A=null}B.clearRect(0,0,H.width,H.height);J.buttonDown=false;R=false;C.statusShow("ellipseActive");return true}};pwlib.tools.polygon=function(F){var L=this,N=F.win.clearInterval,D=F.config,B=F.buffer.context,C=F.gui,G=F.image,H=Math.abs,J=F.mouse,I=F.win.setInterval,E=F.toolSnapXY;var M=[];var A=null;var K=false;var O=false;this.deactivate=function(){if(A){N(A);A=null}if(M.length){B.clearRect(0,0,G.width,G.height)}O=false;M=[];return true};this.mousedown=function(P){if(M.length==0){M.push([J.x,J.y])}if(!A){A=I(L.draw,D.toolDrawDelay)}K=P.shiftKey;O=false;C.statusShow("polygonMousedown");return true};this.mousemove=function(P){K=P.shiftKey;O=true};this.draw=function(Q){if(!O){return }var R=M.length;if(!R||(R==1&&!J.buttonDown)){O=false;return }if(J.buttonDown&&K){E(M[R-1][0],M[R-1][1])}B.clearRect(0,0,G.width,G.height);B.beginPath();B.moveTo(M[0][0],M[0][1]);for(var P=0;P3){C.statusShow("polygonEnd")}else{C.statusShow("polygonAddPoint")}M.push([J.x,J.y]);L.draw();return true};this.keydown=function(P){var Q=M.length;if(!Q||(P.kid_!="Escape"&&P.kid_!="Enter")){return false}if(A){N(A);A=null}J.buttonDown=false;if(P.kid_=="Escape"){B.clearRect(0,0,G.width,G.height);O=false}else{if(P.kid_=="Enter"){M.push([J.x,J.y]);M.push(M[0]);O=true;L.draw();F.layerUpdate()}}M=[];C.statusShow("polygonActive");return true}};pwlib.tools.line=function(G){var L=this,N=G.win.clearInterval,E=G.config,B=G.buffer.context,C=G.gui,H=G.image,J=G.mouse,I=G.win.setInterval,F=G.toolSnapXY;var A=null;var K=false;var O=false;var D=0;var M=0;this.deactivate=function(){if(A){N(A);A=null}if(J.buttonDown){B.clearRect(0,0,H.width,H.height)}O=false;return true};this.mousedown=function(P){D=J.x;M=J.y;if(!A){A=I(L.draw,E.toolDrawDelay)}K=P.shiftKey;O=false;C.statusShow("lineMousedown");return true};this.mousemove=function(P){K=P.shiftKey;O=true};this.draw=function(){if(!O){return }B.clearRect(0,0,H.width,H.height);if(K){F(D,M)}B.beginPath();B.moveTo(D,M);B.lineTo(J.x,J.y);B.stroke();B.closePath();O=false};this.mouseup=function(P){if(J.x==D&&J.y==M){J.buttonDown=true;return true}if(A){N(A);A=null}K=P.shiftKey;L.draw();C.statusShow("lineActive");G.layerUpdate();return true};this.keydown=function(P){if(!J.buttonDown||P.kid_!="Escape"){return false}if(A){N(A);A=null}B.clearRect(0,0,H.width,H.height);J.buttonDown=false;O=false;C.statusShow("lineActive");return true}};pwlib.tools.text=function(L){var J=this,O=L.win.clearInterval,X=L.config.text,E=L.buffer.context,Z=L.doc,R=L.gui,T=L.image,a=L.lang,W=Math.round,P=L.mouse,B=L.win.setInterval;var N=null;var D=L.tool?L.tool._id:null;var V=false;var Y=null,S=null,I=null,H="http://www.w3.org/2000/svg",Q=null,K=null,G=0,A=0;this.preActivate=function(){if(!R.inputs.textString||!R.inputs.text_fontFamily||!R.elems.viewport){return false}if(E.fillText&&E.strokeText){return true}if(E.mozPathText){return true}alert(a.errorTextUnsupported);return false};this.activate=function(){P.x=Math.round(R.elems.viewport.scrollLeft/T.canvasScale),P.y=Math.round(R.elems.viewport.scrollTop/T.canvasScale),S=R.inputs.text_fontFamily;Y=R.inputs.textString;if(!E.fillText&&pwlib.browser.opera){I=L.events.add("configChange",F);Y.addEventListener("input",F,false);Y.addEventListener("change",F,false)}else{I=L.events.add("configChange",C);Y.addEventListener("input",C,false);Y.addEventListener("change",C,false)}if(E.fillText&&E.strokeText){J.draw=J.draw_spec}else{if(pwlib.browser.opera){J.draw=J.draw_opera;M()}else{if(E.mozPathText){J.draw=J.draw_moz;G=E.mozMeasureText(Y.value)}}}if(!N){N=B(J.draw,L.config.toolDrawDelay)}V=true};this.deactivate=function(){if(N){O(N);N=null}V=false;if(I){L.events.remove("configChange",I)}if(!E.fillText&&pwlib.browser.opera){Y.removeEventListener("input",F,false);Y.removeEventListener("change",F,false)}else{Y.removeEventListener("input",C,false);Y.removeEventListener("change",C,false)}K=null;Q=null;E.clearRect(0,0,T.width,T.height);return true};function M(){Q=Z.createElementNS(H,"svg");Q.setAttributeNS(H,"version","1.1");K=Z.createElementNS(H,"text");K.appendChild(Z.createTextNode(Y.value));Q.appendChild(K);K.style.font=E.font;if(L.config.shapeType!=="stroke"){K.style.fill=E.fillStyle}else{K.style.fill="none"}if(L.config.shapeType!=="fill"){K.style.stroke=E.strokeStyle;K.style.strokeWidth=E.lineWidth}else{K.style.stroke="none";K.style.strokeWidth=E.lineWidth}G=K.getComputedTextLength();A=K.getBBox().height;Q.setAttributeNS(H,"width",G);Q.setAttributeNS(H,"height",A+10);K.setAttributeNS(H,"x",0);K.setAttributeNS(H,"y",A)}function C(c){if(c.type==="input"||c.type==="change"||(!c.group&&c.config==="shapeType")||(c.group==="line"&&c.config==="lineWidth")){V=true;if(!E.fillText&&E.mozMeasureText){G=E.mozMeasureText(Y.value)}return }if(c.type!=="configChange"&&c.group!=="text"){return }var b="";switch(c.config){case"fontFamily":if(c.value==="+"){U(c)}case"bold":case"italic":case"fontSize":if(X.bold){b+="bold "}if(X.italic){b+="italic "}b+=X.fontSize+"px "+X.fontFamily;E.font=b;if("mozTextStyle" in E){E.mozTextStyle=b}case"textAlign":case"textBaseline":V=true}if(c.config!=="textAlign"&&c.config!=="textBaseline"&&!E.fillText&&E.mozMeasureText){G=E.mozMeasureText(Y.value)}}function F(c){if(c.type==="input"||c.type==="change"){K.replaceChild(Z.createTextNode(this.value),K.firstChild);V=true}if(!c.group&&c.config==="shapeType"){if(c.value!=="stroke"){K.style.fill=E.fillStyle}else{K.style.fill="none"}if(c.value!=="fill"){K.style.stroke=E.strokeStyle;K.style.strokeWidth=E.lineWidth}else{K.style.stroke="none";K.style.strokeWidth=E.lineWidth}V=true}if(!c.group&&c.config==="fillStyle"){if(L.config.shapeType!=="stroke"){K.style.fill=c.value;V=true}}if((!c.group&&c.config==="strokeStyle")||(c.group==="line"&&c.config==="lineWidth")){if(L.config.shapeType!=="fill"){K.style.stroke=E.strokeStyle;K.style.strokeWidth=E.lineWidth;V=true}}if(c.type==="configChange"&&c.group==="text"){var b="";switch(c.config){case"fontFamily":if(c.value==="+"){U(c)}case"bold":case"italic":case"fontSize":if(X.bold){b+="bold "}if(X.italic){b+="italic "}b+=X.fontSize+"px "+X.fontFamily;E.font=b;K.style.font=b;case"textAlign":case"textBaseline":V=true}}G=K.getComputedTextLength();A=K.getBBox().height;Q.setAttributeNS(H,"width",G);Q.setAttributeNS(H,"height",A+10);K.setAttributeNS(H,"x",0);K.setAttributeNS(H,"y",A)}function U(f){var e=prompt(a.promptTextFont)||"";e=e.replace(/^\s+/,"").replace(/\s+$/,"")||f.previousValue;var c,d=e.toLowerCase(),g=S.options.length;for(var b=0;bZ){if(a==K.y){a-=Y-Z}Z=T(Y/C)}else{if(X==K.x){X-=Z-Y}Y=T(Z*C)}}E.drawImage(Q,X,a,Y,Z)}else{E.drawImage(Q,K.x,K.y)}O=false};this.mouseup=function(X){if(!B){return false}if(I){J(I);I=null}H.layerUpdate();if(D){H.toolActivate(D,X)}if(X.stopPropagation){X.stopPropagation()}};this.keydown=function(X){if(!D||X.kid_!="Escape"){return false}if(I){J(I);I=null}K.buttonDown=false;H.toolActivate(D,X);return true}};pwlib.tools.pencil=function(D){var H=this,K=D.win.clearInterval,B=D.buffer.context,E=D.image,G=D.mouse,F=D.win.setInterval;var A=null;var J=[];var C=0;var I=0;this.deactivate=function(){if(A){K(A);A=null}if(G.buttonDown){B.clearRect(0,0,E.width,E.height)}J=[]};this.mousedown=function(){C=G.x;I=G.y;J=[];if(!A){A=F(H.draw,D.config.toolDrawDelay)}return true};this.mousemove=function(){if(G.buttonDown){J.push(G.x,G.y)}};this.draw=function(){var L=0,M=J.length;if(!M){return }B.beginPath();B.moveTo(C,I);while(LN){P=N}}if(P!=this.value){this.value=P}}if(this._ckey==="hex"){I.color[this._ckey]=this.value}else{if(I.ckey_grouping[this._ckey]==="lab"){I.color[this._ckey]=parseInt(this.value)}else{I.color[this._ckey]=parseInt(this.value)/E.inputValues[this._ckey][1]}}I.update_color(this._ckey)};this.update_color=function(N){var O=I.ckey_grouping[N]||N;switch(O){case"rgb":I.rgb2hsv();I.rgb2hex();I.rgb2lab();I.rgb2cmyk();break;case"hsv":I.hsv2rgb();I.rgb2hex();I.rgb2lab();I.rgb2cmyk();break;case"hex":I.hex2rgb();I.rgb2hsv();I.rgb2lab();I.rgb2cmyk();break;case"lab":I.lab2rgb();I.rgb2hsv();I.rgb2hex();I.rgb2cmyk();break;case"cmyk":I.cmyk2rgb();I.rgb2lab();I.rgb2hsv();I.rgb2hex()}I.update_preview();I.update_inputs();if(N!=="alpha"){I.update_canvas(N)}};this.update_preview=function(){var Q=G(I.color.red*255),P=G(I.color.green*255),N=G(I.color.blue*255),O=I.elems.colorActive.style;O.backgroundColor="rgb("+Q+","+P+","+N+")";O.opacity=I.color.alpha};this.update_inputs=function(){var N;for(var O in I.inputs){N=I.inputs[O];N._old_value=N.value;if(N._ckey==="hex"){N.value=I.color[O]}else{if(I.ckey_grouping[N._ckey]==="lab"){N.value=G(I.color[O])}else{N.value=G(I.color[O]*E.inputValues[O][1])}}}};this.rgb2cmyk=function(){var Q=I.color,U,V,S,N,O=Q.red,P=Q.green,T=Q.blue;U=1-O;V=1-P;S=1-T;N=J(U,V,S,1);if(N===1){U=V=S=0}else{var R=1-N;U=(U-N)/R;V=(V-N)/R;S=(S-N)/R}Q.cyan=U;Q.magenta=V;Q.yellow=S;Q.black=N};this.cmyk2rgb=function(){var O=I.color,N=1-O.black;O.red=1-O.cyan*N-O.black;O.green=1-O.magenta*N-O.black;O.blue=1-O.yellow*N-O.black};this.rgb2hsv=function(){var S,O,N,P=I.color.red,Q=I.color.green,U=I.color.blue,R=J(P,Q,U),T=D(P,Q,U),V=T-R,N=T;if(V===0){S=O=0}else{O=V/T;if(T===P){S=(Q-U)/V}else{if(T===Q){S=(U-P)/V+2}else{if(T===U){S=(P-Q)/V+4}}}S/=6;if(S<0){S+=1}}I.color.hue=S;I.color.sat=O;I.color.val=N};this.hsv2rgb=function(Z,W){var R=I.color,P,Q,a,Y,O,N;if(W){Y=W[0];O=W[1];N=W[2]}else{Y=R.hue,O=R.sat,N=R.val}if(O===0){P=Q=a=N}else{var V=Y*6;var T=A(V);var X=N*(1-O),U=N*(1-O*(V-T)),S=N*(1-O*(1-(V-T)));if(T===0||T===6){P=N;Q=S;a=X}else{if(T===1){P=U;Q=N;a=X}else{if(T===2){P=X;Q=N;a=S}else{if(T===3){P=X;Q=U;a=N}else{if(T===4){P=S;Q=X;a=N}else{if(T===5){P=N;Q=X;a=U}}}}}}}if(!Z){R.red=P;R.green=Q;R.blue=a}return[P,Q,a]};this.rgb2hex=function(){var Q="#",O=["red","green","blue"],P,R,N=I.color;for(P=0;P<3;P++){R=G(N[O[P]]*255).toString(16);if(R.length===1){R="0"+R}Q+=R}N.hex=Q};this.hex2rgb=function(){var O=["red","green","blue"],P,R,N=I.color,Q=N.hex;Q=Q.substr(1);if(Q.length!==6){return }for(P=0;P<3;P++){R=Q.substr(P*2,2);N[O[P]]=parseInt(R,16)/255}};this.rgb2lab=function(){var N=I.color,O=I.xyz2lab(I.rgb2xyz([N.red,N.green,N.blue]));N.cie_l=O[0];N.cie_a=O[1];N.cie_b=O[2]};this.lab2rgb=function(){var N=I.color,O=I.xyz2rgb(I.lab2xyz(N.cie_l,N.cie_a,N.cie_b));N.red=O[0];N.green=O[1];N.blue=O[2]};this.xyz2lab=function(R){var P=E.lab,S=216/24389,Q=24389/27;R[0]/=P.w_x;R[1]/=P.w_y;R[2]/=P.w_z;if(R[0]>S){R[0]=M(R[0],1/3)}else{R[0]=(Q*R[0]+16)/116}if(R[1]>S){R[1]=M(R[1],1/3)}else{R[1]=(Q*R[1]+16)/116}if(R[2]>S){R[2]=M(R[2],1/3)}else{R[2]=(Q*R[2]+16)/116}var O=116*R[1]-16,N=500*(R[0]-R[1]),T=200*(R[1]-R[2]);return[O,N,T]};this.lab2xyz=function(N,T,R){var U=(N+16)/116,V=U+T/500,S=U-R/200,Q=6/29,O=1/3*M(29/6,2),W=16/116,P=E.lab;if(V>Q){V=M(V,3)}else{V=(V-W)/O}if(U>Q){U=M(U,3)}else{U=(U-W)/O}if(S>Q){S=M(S,3)}else{S=(S-W)/O}V*=P.w_x;U*=P.w_y;S*=P.w_z;return[V,U,S]};this.xyz2rgb=function(N){var O=I.calc_m1x3(N,E.lab.m_i);if(O[0]>0.0031308){O[0]=1.055*M(O[0],1/2.4)-0.055}else{O[0]*=12.9232}if(O[1]>0.0031308){O[1]=1.055*M(O[1],1/2.4)-0.055}else{O[1]*=12.9232}if(O[2]>0.0031308){O[2]=1.055*M(O[2],1/2.4)-0.055}else{O[2]*=12.9232}if(O[0]<0){O[0]=0}else{if(O[0]>1){O[0]=1}}if(O[1]<0){O[1]=0}else{if(O[1]>1){O[1]=1}}if(O[2]<0){O[2]=0}else{if(O[2]>1){O[2]=1}}return O};this.rgb2xyz=function(N){if(N[0]>0.04045){N[0]=M((N[0]+0.055)/1.055,2.4)}else{N[0]/=12.9232}if(N[1]>0.04045){N[1]=M((N[1]+0.055)/1.055,2.4)}else{N[1]/=12.9232}if(N[2]>0.04045){N[2]=M((N[2]+0.055)/1.055,2.4)}else{N[2]/=12.9232}return I.calc_m1x3(N,E.lab.m)};this.update_canvas=function(U,P){if(I.panelSelector.tabId!=="mixer"&&!P){I.update_canvas_needed=true;return true}I.update_canvas_needed=false;var Q=I.elems.slider.style,T=I.elems.chartDot.style,R=I.color,N=I.ckey_active,Y=I.ckey_active_group,S=I.ckey_adjoint,O=I.chartWidth/H,Z=I.chartHeight/H,X,W,V;if(U!==S[0]&&U!==S[1]&&I.ev_canvas_mode!=="chart"){if(Y==="lab"){V=(R[N]-E.inputValues[N][0])/I.abs_max[N]}else{V=R[N]}if(N!=="hue"&&Y!=="lab"){V=1-V}Q.top=G(V*Z)+"px"}if(U!==N){if(Y==="lab"){X=(R[S[0]]-E.inputValues[S[0]][0])/I.abs_max[S[0]];W=(R[S[1]]-E.inputValues[S[1]][0])/I.abs_max[S[1]]}else{X=R[S[0]];W=1-R[S[1]]}T.top=G(W*Z)+"px";T.left=G(X*O)+"px"}if(!I.draw_chart(U)||!I.draw_slider(U)){return false}else{return true}};this.ev_canvas=function(S){S.preventDefault();if(S.type==="mousedown"&&!I.ev_canvas_mode){I.ev_canvas_mode=true;K.addEventListener("mouseup",I.ev_canvas,false)}if(!I.ev_canvas_mode){return false}if(S.type==="mouseup"){I.ev_canvas_mode=false;K.removeEventListener("mouseup",I.ev_canvas,false)}var N=I.elems;if(S.target===N.controls){var U,T,O=I.context2d.canvas.width,V=I.context2d.canvas.height;if(S.layerX||S.layerX===0){U=S.layerX*H;T=S.layerY*H}else{if(S.offsetX||S.offsetX===0){U=S.offsetX*H;T=S.offsetY*H}}if(U>=0&&U<=I.chartWidth){mode="chart"}else{if(U>=I.sliderX&&U<=O){mode="slider"}}}else{if(S.target===N.chartDot){mode="chart"}else{if(S.target===N.slider){mode="slider"}}}if(mode&&I.ev_canvas_mode===true){I.ev_canvas_mode=mode}if(!mode||I.ev_canvas_mode!==mode||S.target!==N.controls){return false}var P=I.color,R=U/I.chartWidth,Q=T/V;if(mode==="slider"){if(I.ckey_active==="hue"){P[I.ckey_active]=Q}else{if(I.ckey_active_group==="lab"){P[I.ckey_active]=I.abs_max[I.ckey_active]*Q+E.inputValues[I.ckey_active][0]}else{P[I.ckey_active]=1-Q}}return I.update_color(I.ckey_active)}else{if(mode==="chart"){if(R>1){return false}if(I.ckey_active_group==="lab"){R=I.abs_max[I.ckey_adjoint[0]]*R+E.inputValues[I.ckey_adjoint[0]][0];Q=I.abs_max[I.ckey_adjoint[1]]*Q+E.inputValues[I.ckey_adjoint[1]][0]}else{Q=1-Q}P[I.ckey_adjoint[0]]=R;P[I.ckey_adjoint[1]]=Q;return I.update_color(I.ckey_active_group)}}return false};this.draw_chart=function(P){var Q=I.context2d,O,b,S,c;if(P===I.ckey_adjoint[0]||P===I.ckey_adjoint[1]||(I.ev_canvas_mode==="chart"&&P===I.ckey_active_group)){return true}var W=I.chartWidth,e=I.chartHeight;Q.clearRect(0,0,W,e);if(I.ckey_active==="sat"){if(I.color.sat>0){O=Q.createLinearGradient(0,0,W,0);for(c=0;c<=6;c++){b="rgb("+L[c][0]+", "+L[c][1]+", "+L[c][2]+")";O.addColorStop(c*1/6,b)}Q.fillStyle=O;Q.fillRect(0,0,W,e);O=Q.createLinearGradient(0,0,0,e);O.addColorStop(0,"rgba(0, 0, 0, 0)");O.addColorStop(1,"rgba(0, 0, 0, 1)");Q.fillStyle=O;Q.fillRect(0,0,W,e)}if(I.color.sat<1){S=1-I.color.sat;O=Q.createLinearGradient(0,0,0,e);O.addColorStop(0,"rgba(255, 255, 255, "+S+")");O.addColorStop(1,"rgba( 0, 0, 0, "+S+")");Q.fillStyle=O;Q.fillRect(0,0,W,e)}}else{if(I.ckey_active==="val"){if(I.color.val>0){O=Q.createLinearGradient(0,0,W,0);for(c=0;c<=6;c++){b="rgb("+L[c][0]+", "+L[c][1]+", "+L[c][2]+")";O.addColorStop(c*1/6,b)}Q.fillStyle=O;Q.fillRect(0,0,W,e);O=Q.createLinearGradient(0,0,0,e);O.addColorStop(0,"rgba(255, 255, 255, 0)");O.addColorStop(1,"rgba(255, 255, 255, 1)");Q.fillStyle=O;Q.fillRect(0,0,W,e)}if(I.color.val<1){Q.fillStyle="rgba(0, 0, 0, "+(1-I.color.val)+")";Q.fillRect(0,0,W,e)}}else{if(I.ckey_active==="hue"){if(I.color.sat===1&&I.color.val===1){b=[I.color.red,I.color.green,I.color.blue]}else{b=I.hsv2rgb(true,[I.color.hue,1,1])}for(c=0;c<3;c++){b[c]=G(b[c]*255)}Q.fillStyle="rgb("+b[0]+", "+b[1]+", "+b[2]+")";Q.fillRect(0,0,W,e);O=Q.createLinearGradient(0,0,W,0);O.addColorStop(0,"rgba(255, 255, 255, 1)");O.addColorStop(1,"rgba(255, 255, 255, 0)");Q.fillStyle=O;Q.fillRect(0,0,W,e);O=Q.createLinearGradient(0,0,0,e);O.addColorStop(0,"rgba(0, 0, 0, 0)");O.addColorStop(1,"rgba(0, 0, 0, 1)");Q.fillStyle=O;Q.fillRect(0,0,W,e)}else{if(I.ckey_active_group==="rgb"){var f,d;b={red:0,green:0,blue:0};b[I.ckey_active]=G(I.color[I.ckey_active]*255);f={red:0,green:0,blue:0};f[I.ckey_adjoint[1]]=255;d={red:0,green:0,blue:0};d[I.ckey_adjoint[0]]=255;Q.fillStyle="rgb("+b.red+","+b.green+","+b.blue+")";Q.fillRect(0,0,W,e);var V=Q.globalCompositeOperation;Q.globalCompositeOperation="lighter";O=Q.createLinearGradient(0,0,0,e);O.addColorStop(0,"rgba("+f.red+","+f.green+","+f.blue+", 1)");O.addColorStop(1,"rgba("+f.red+","+f.green+","+f.blue+", 0)");Q.fillStyle=O;Q.fillRect(0,0,W,e);O=Q.createLinearGradient(0,0,W,0);O.addColorStop(0,"rgba("+d.red+","+d.green+","+d.blue+", 0)");O.addColorStop(1,"rgba("+d.red+","+d.green+","+d.blue+", 1)");Q.fillStyle=O;Q.fillRect(0,0,W,e);Q.globalCompositeOperation=V}else{if(I.ckey_active_group==="lab"){var g=false;if(Q.createImageData){g=Q.createImageData(W,e)}else{if(Q.getImageData){g=Q.getImageData(0,0,W,e)}else{g={width:W,height:e,data:new Array(W*e*4)}}}var R=g.data,Y=g.data.length-1,c=-1,X=0,a,Z,j=[],N=[],U,T;U=I.ckey_adjoint[0];T=I.ckey_adjoint[1];b={cie_l:I.color.cie_l,cie_a:I.color.cie_a,cie_b:I.color.cie_b};a=I.abs_max[U]/W;Z=I.abs_max[T]/e;b[U]=E.inputValues[U][0];b[T]=E.inputValues[T][0];while(c1){Q=true}if(N.currentPosE.zIndex_){E.zIndex_=f}G.container.className+=" "+Q.classPrefix+"floatingPanel "+Q.classPrefix+"floatingPanel_"+G.id;d.className+=" "+Q.classPrefix+"floatingPanel_content";G.content=d;Z.className+=" "+Q.classPrefix+"floatingPanel_title";Z.replaceChild(X.createTextNode(Y.floatingPanels[G.id]),Z.firstChild);Z.addEventListener("mousedown",A,false);if(G.container.getAttribute("data-pwPanelHide")==="true"){G.hide()}else{G.state=G.STATE_VISIBLE}var a=G.container.parentNode,e=null;while(!e&&a){if(a.nodeName.toLowerCase()==="html"){e=a;break}b=J.getComputedStyle(a,null);if(b&&(b.overflow==="scroll"||b.overflow==="auto")){e=a}else{a=a.parentNode}}G.viewport=e;M=X.createElement("a");M.href="#";M.title=Y.floatingPanelMinimize;M.className=Q.classPrefix+"floatingPanel_minimize";M.addEventListener("click",B,false);M.appendChild(X.createTextNode(M.title));G.container.insertBefore(M,d);R=X.createElement("a");R.href="#";R.title=Y.floatingPanelClose;R.className=Q.classPrefix+"floatingPanel_close";R.addEventListener("click",U,false);R.appendChild(X.createTextNode(R.title));G.container.insertBefore(R,d);if(G.container.getAttribute("data-pwPanelResizable")==="true"){var c=X.createElement("div");c.className=Q.classPrefix+"floatingPanel_resizer";G.container.appendChild(c);G.resizer=new pwlib.guiResizer(Q,c,G.container)}}function B(Z){Z.preventDefault();this.focus();var a=" "+Q.classPrefix+"floatingPanel_minimized";if(G.state===G.STATE_MINIMIZED){G.state=G.STATE_VISIBLE;this.title=Y.floatingPanelMinimize;this.className=Q.classPrefix+"floatingPanel_minimize";this.replaceChild(X.createTextNode(this.title),this.firstChild);if(G.container.className.indexOf(a)!==-1){G.container.className=G.container.className.replace(a,"")}}else{if(G.state===G.STATE_VISIBLE){G.state=G.STATE_MINIMIZED;this.title=Y.floatingPanelRestore;this.className=Q.classPrefix+"floatingPanel_restore";this.replaceChild(X.createTextNode(this.title),this.firstChild);if(G.container.className.indexOf(a)===-1){G.container.className+=a}}}G.events.dispatch(new V.guiFloatingPanelStateChange(G.state));G.bringOnTop()}function U(Z){Z.preventDefault();G.hide();T.focus()}function A(a){G.state=G.STATE_DRAGGING;P=a.clientX;O=a.clientY;var Z=J.getComputedStyle(G.container,null);K=parseInt(Z.top);L=parseInt(Z.left);if(G.viewport){H=G.viewport.scrollLeft;W=G.viewport.scrollTop}G.bringOnTop();X.addEventListener("mousemove",I,false);X.addEventListener("mouseup",F,false);G.events.dispatch(new V.guiFloatingPanelStateChange(G.state));if(a.preventDefault){a.preventDefault()}}function I(a){var Z=L+a.clientX-P,b=K+a.clientY-O;if(G.viewport){if(G.viewport.scrollLeft!==H){Z+=G.viewport.scrollLeft-H}if(G.viewport.scrollTop!==W){b+=G.viewport.scrollTop-W}}C.left=Z+"px";C.top=b+"px"}function F(Z){if(G.container.className.indexOf(" "+Q.classPrefix+"floatingPanel_minimized")!==-1){G.state=G.STATE_MINIMIZED}else{G.state=G.STATE_VISIBLE}X.removeEventListener("mousemove",I,false);X.removeEventListener("mouseup",F,false);T.focus();G.events.dispatch(new V.guiFloatingPanelStateChange(G.state))}this.bringOnTop=function(){E.zIndex_+=D;C.zIndex=E.zIndex_};this.hide=function(){C.display="none";G.state=G.STATE_HIDDEN;G.events.dispatch(new V.guiFloatingPanelStateChange(G.state))};this.show=function(){if(G.state===G.STATE_VISIBLE){return }C.display="block";G.state=G.STATE_VISIBLE;var Z=" "+Q.classPrefix+"floatingPanel_minimized";if(G.container.className.indexOf(Z)!==-1){G.container.className=G.container.className.replace(Z,"");M.className=Q.classPrefix+"floatingPanel_minimize";M.title=Y.floatingPanelMinimize;M.replaceChild(X.createTextNode(M.title),M.firstChild)}G.events.dispatch(new V.guiFloatingPanelStateChange(G.state));G.bringOnTop()};this.toggle=function(){if(G.state===G.STATE_VISIBLE||G.state===G.STATE_MINIMIZED){G.hide()}else{G.show()}};S()};pwlib.appEvent.guiFloatingPanelStateChange=function(A){this.STATE_HIDDEN=0;this.STATE_VISIBLE=1;this.STATE_MINIMIZED=3;this.STATE_DRAGGING=4;this.state=A;pwlib.appEvent.call(this,"guiFloatingPanelStateChange")};pwlib.guiResizer=function(O,J,K){var F=this,B=K.style,R=O.app.doc,D=pwlib.appEvent.guiResizeEnd,L=pwlib.appEvent.guiResizeStart,I=O.app.win;this.events=null;this.resizeHandle=J;this.container=K;this.viewport=null;this.resizing=false;var N=0,M=0;var S=0,C=0;var G=0,Q=0;function P(){F.events=new pwlib.appEvents(F);J.addEventListener("mousedown",A,false);var U,T=F.container.parentNode,V=null;while(!V&&T){if(T.nodeName.toLowerCase()==="html"){V=T;break}U=I.getComputedStyle(T,null);if(U&&(U.overflow==="scroll"||U.overflow==="auto")){V=T}else{T=T.parentNode}}F.viewport=V}function A(V){N=V.clientX;M=V.clientY;var T=I.getComputedStyle(F.container,null);S=parseInt(T.width);C=parseInt(T.height);var U=F.events.dispatch(new L(N,M,S,C));if(U){return }if(F.viewport){G=F.viewport.scrollLeft;Q=F.viewport.scrollTop}F.resizing=true;R.addEventListener("mousemove",H,false);R.addEventListener("mouseup",E,false);if(V.preventDefault){V.preventDefault()}if(V.stopPropagation){V.stopPropagation()}}function H(V){var T=S+V.clientX-N,U=C+V.clientY-M;if(F.viewport){if(F.viewport.scrollLeft!==G){T+=F.viewport.scrollLeft-G}if(F.viewport.scrollTop!==Q){U+=F.viewport.scrollTop-Q}}B.width=T+"px";B.height=U+"px"}function E(U){var T=F.events.dispatch(new D(U.clientX,U.clientY,parseInt(B.width),parseInt(B.height)));if(T){return }F.resizing=false;R.removeEventListener("mousemove",H,false);R.removeEventListener("mouseup",E,false)}P()};pwlib.appEvent.guiResizeStart=function(B,D,C,A){this.x=B;this.y=D;this.width=C;this.height=A;pwlib.appEvent.call(this,"guiResizeStart",true)};pwlib.appEvent.guiResizeEnd=function(B,D,C,A){this.x=B;this.y=D;this.width=C;this.height=A;pwlib.appEvent.call(this,"guiResizeEnd",true)};pwlib.guiTabPanel=function(B,A){var E=this,D=pwlib.appEvent,G=B.app.doc,C=B.app.lang;this.events=null;this.id=null;this.tabs={};this.tabButtons=null;this.container=A;this.tabId=null;var H=null;function I(){E.events=new pwlib.appEvents(E);E.id=E.container.getAttribute("data-pwTabPanel");E.container.className+=" "+B.classPrefix+"tabPanel "+B.classPrefix+"tabPanel_"+E.id;var L=G.createElement("ul"),P=null,O=E.container.getAttribute("data-pwTabDefault")||null,R=E.container.childNodes,Q=Node.ELEMENT_NODE,K=null,J=null,N=null;L.className=B.classPrefix+"tabsList";for(var M=0;K=R[M];M++){if(K.nodeType!==Q){continue}J=K.getAttribute("data-pwTab");if(!J){continue}K.className+=" "+B.classPrefix+"tab "+B.classPrefix+E.id+"_"+J;P=G.createElement("li");P._pwTab=J;N=G.createElement("a");N.href="#";N.addEventListener("click",F,false);if(E.id in C.tabs){N.title=C.tabs[E.id][J+"Title"]||C.tabs[E.id][J];N.appendChild(G.createTextNode(C.tabs[E.id][J]))}if((O&&J===O)||(!O&&!E.tabId)){E.tabId=J;P.className=B.classPrefix+"tabActive"}else{H=J;K.style.display="none"}if(K.getAttribute("data-pwTabHide")==="true"){P.style.display="none"}E.tabs[J]={container:K,button:P};P.appendChild(N);L.appendChild(P)}E.tabButtons=L;E.container.appendChild(L)}function F(J){J.preventDefault();E.tabActivate(this.parentNode._pwTab)}this.tabActivate=function(J){if(!J||!(J in this.tabs)){return false}else{if(J===this.tabId){return true}}var M=new D.guiTabActivate(J,this.tabId),L=this.events.dispatch(M),K=null,N=null;if(L){return false}if(this.tabId in this.tabs){K=this.tabs[this.tabId].container;K.style.display="none";N=this.tabs[this.tabId].button;N.className="";H=this.tabId}K=this.tabs[J].container;K.style.display="";N=this.tabs[J].button;N.className=B.classPrefix+"tabActive";N.style.display="";N.firstChild.focus();this.tabId=J;return true};this.tabHide=function(J){if(!(J in this.tabs)){return false}if(this.tabId===J){this.tabActivate(H)}this.tabs[J].button.style.display="none";return true};this.tabShow=function(J){if(!(J in this.tabs)){return false}this.tabs[J].button.style.display="";return true};I()};pwlib.appEvent.guiTabActivate=function(A,B){this.tabId=A;this.prevTabId=B;pwlib.appEvent.call(this,"guiTabActivate",true)};pwlib.guiColorInput=function(A,J){var I=this,G=null,C=A.app.config,K=A.app.doc,F=Math.round,B=A.app.lang;this.id=null;this.input=J;this.configProperty=null;this.configGroup=null;this.configGroupRef=null;this.color={red:0,green:0,blue:0,alpha:0};function L(){var M=I.input.getAttribute("data-pwColorInput"),X=M.replace(".","_"),S=M.split("."),T=S.pop(),W=S.join("."),U=C,N=B.inputs,V=I.input.parentNode,R=K.createElement("a"),P;for(var Q=0,O=S.length;Q

PaintWeb

  • Undo
  • Redo
  •  
  • Clear image
  • Save image
  • Insert image
  •  
  • Cut selection
  • Copy selection
  • Clipboard paste
  •  
  • Color picker
  •  
  • Selection
  • Hand
  •  
  • Rectangle
  • Ellipse
  • Polygon
  • Line
  • B\u00e9zier curve
  • Text
  • Pencil
  •  
  • Eraser

Fill  

Stroke  

Line cap

Butt
Square
Round

Line join

Miter
Round
Bevel

Shape type

Both
Fill
Stroke

Cut selection

Copy selection

Clipboard paste

Crop selection

Delete selection

Fill selection

Bold
Italic

Text alignment

Left
Center
Right

Color  

About

Resize the image Canvas

WxH

Status

Color mixer

  1.   Active
  2.   Old
  1. Close
  2. Cancel
  3. Save color
  4. Pick color
Your browser does not support Canvas.

About

The project is currently undergoing heavy development for the purpose of integrating it into Moodle.

For user and developer documentation please check out the project site.

';function PaintWeb(win,doc){var _self=this;if(!win){win=window}if(!doc){doc=document}this.version=0.9;this.build=20090724;this.config={showErrors:true};this.lang={noComputedStyle:"Error: window.getComputedStyle is not available.",noXMLHttpRequest:"Error: window.XMLHttpRequest is not available.",noCanvasSupport:"Error: Your browser does not support Canvas.",guiPlaceholderWrong:"Error: The config.guiPlaceholder property must reference a DOM element!",initHandlerMustBeFunction:"The first argument must be a function.",noConfigFile:"Error: You must point to a configuration file by setting the config.configFile property!",failedConfigLoad:"Error: Failed loading the configuration file.",failedLangLoad:"Error: Failed loading the language file."};this.buffer={canvas:null,context:null};this.layer={id:null,canvas:null,context:null};this.tool=null;this.elems={};this.mouse={x:0,y:0,buttonDown:false};this.extensions={};this.commands={};this.gui=null;this.doc=doc;this.win=win;this.image={width:0,height:0,zoom:1,canvasScale:1};this.resolution={elem:null,elemId:"paintweb_resInfo",cssText:"@media screen and (resolution:96dpi){#paintweb_resInfo{width:96px}}@media screen and (resolution:134dpi){#paintweb_resInfo{width:134px}}@media screen and (resolution:200dpi){#paintweb_resInfo{width:200px}}@media screen and (resolution:300dpi){#paintweb_resInfo{width:300px}}#paintweb_resInfo{display:block;height:100%;left:-3000px;position:fixed;top:0;visibility:hidden;z-index:-32}",dpiOptimal:96,dpiLocal:96,browserZoom:1,scale:-1};this.history={pos:0,states:[]};this.shadowSupported=true;this.shadowAllowed=true;this.clipboard=false;this.initialized=PaintWeb.INIT_NOT_STARTED;this.events=null;this.UID=0;this.stateProperties=["strokeStyle","fillStyle","globalAlpha","lineWidth","lineCap","lineJoin","miterLimit","shadowOffsetX","shadowOffsetY","shadowBlur","shadowColor","globalCompositeOperation","font","textAlign","textBaseline"];var kbListener_=null;var temp_={onInit:null,toolsLoadQueue:0,extensionsLoadQueue:0};var MathAbs=Math.abs,MathFloor=Math.floor,MathMax=Math.max,MathMin=Math.min,MathRound=Math.round,pwlib=null,appEvent=null,lang=this.lang;function preInit(){var d=new Date();if(_self.build===-1){var dateArr=[d.getFullYear(),d.getMonth()+1,d.getDate()];if(dateArr[1]<10){dateArr[1]="0"+dateArr[1]}if(dateArr[2]<10){dateArr[2]="0"+dateArr[2]}_self.build=dateArr.join("")}_self.UID=d.getMilliseconds()*MathRound(Math.random()*100);_self.elems.head=doc.getElementsByTagName("head")[0]||doc.body}this.init=function(handler){if(this.initialized===PaintWeb.INIT_DONE){return true}this.initialized=PaintWeb.INIT_STARTED;if(handler&&typeof handler!=="function"){throw new TypeError(lang.initHandlerMustBeFunction)}temp_.onInit=handler;if(!doc.createElement("canvas").getContext){this.initError(lang.noCanvasSupport);return false}if(!window.getComputedStyle){this.initError(lang.noComputedStyle);return false}if(!window.XMLHttpRequest){this.initError(lang.noXMLHttpRequest);return false}if(!this.config.configFile){this.initError(lang.noConfigFile);return false}if(typeof this.config.guiPlaceholder!=="object"||this.config.guiPlaceholder.nodeType!==Node.ELEMENT_NODE){this.initError(lang.guiPlaceholderWrong);return false}if(typeof this.config.imageLoad!=="object"||this.config.imageLoad.nodeType!==Node.ELEMENT_NODE){this.config.imageLoad=null}if(!window.JSON){this.scriptLoad(PaintWeb.baseFolder+"includes/json2.js",this.jsonlibReady)}else{this.jsonlibReady()}return true};this.jsonlibReady=function(){if(window.pwlib){_self.pwlibReady()}else{_self.scriptLoad(PaintWeb.baseFolder+"includes/lib.js",_self.pwlibReady)}};this.pwlibReady=function(){pwlib=window.pwlib;appEvent=pwlib.appEvent;_self.events=new pwlib.appEvents(_self);if(typeof temp_.onInit==="function"){_self.events.add("appInit",temp_.onInit);delete temp_.onInit}_self.configLoad()};this.initError=function(msg){switch(this.initialized){case PaintWeb.INIT_ERROR:case PaintWeb.INIT_DONE:case PaintWeb.INIT_NOT_STARTED:return }this.initialized=PaintWeb.INIT_ERROR;var ev=null;if(this.events&&"dispatch" in this.events&&appEvent&&"appInit" in appEvent){ev=new appEvent.appInit(this.initialized,msg);this.events.dispatch(ev)}else{if(typeof temp_.onInit==="function"){ev={type:"appInit",state:this.initialized,errorMessage:msg};temp_.onInit.call(this,ev)}}if(this.config.showErrors){alert(msg)}else{if(window.console&&console.log){console.log(msg)}}};this.configLoad=function(){pwlib.xhrLoad(PaintWeb.baseFolder+this.config.configFile,this.configReady)};this.configReady=function(xhr){if(!xhr||xhr.readyState!==4){return }if((xhr.status!==304&&xhr.status!==200)||!xhr.responseText){_self.initError(lang.failedConfigLoad);return }var config=pwlib.jsonParse(xhr.responseText);pwlib.extend(_self.config,config);_self.langLoad()};this.langLoad=function(){var id=this.config.lang,file=PaintWeb.baseFolder;if(!(id in this.config.languages)){id=this.config.lang="en"}if("file" in this.config.languages[id]){file+=this.config.languages[id].file}else{file+=this.config.langFolder+"/"+id+".json"}pwlib.xhrLoad(file,this.langReady)};this.langReady=function(xhr){if(!xhr||xhr.readyState!==4){return }if((xhr.status!==304&&xhr.status!==200)||!xhr.responseText){_self.initError(lang.failedLangLoad);return }pwlib.extend(_self.lang,pwlib.jsonParse(xhr.responseText));if(_self.initCanvas()&&_self.initContext()){_self.guiLoad()}else{_self.initError(lang.errorInitCanvas)}};this.initCommands=function(){if(this.commandRegister("historyUndo",this.historyUndo)&&this.commandRegister("historyRedo",this.historyRedo)&&this.commandRegister("selectAll",this.selectAll)&&this.commandRegister("selectionCut",this.selectionCut)&&this.commandRegister("selectionCopy",this.selectionCopy)&&this.commandRegister("clipboardPaste",this.clipboardPaste)&&this.commandRegister("imageSave",this.imageSave)&&this.commandRegister("imageClear",this.imageClear)&&this.commandRegister("swapFillStroke",this.swapFillStroke)&&this.commandRegister("imageZoomIn",this.imageZoomIn)&&this.commandRegister("imageZoomOut",this.imageZoomOut)&&this.commandRegister("imageZoomReset",this.imageZoomReset)){return true}else{this.initError(lang.errorInitCommands);return false}};this.guiLoad=function(){var cfg=this.config,gui=this.config.gui,base=PaintWeb.baseFolder+cfg.interfacesFolder+"/"+gui+"/",style=base+cfg.guiStyle,script=base+cfg.guiScript;this.styleLoad(gui+"style",style);if(pwlib.gui){this.guiScriptReady()}else{this.scriptLoad(script,this.guiScriptReady)}};this.guiScriptReady=function(){var cfg=_self.config,gui=_self.config.gui,base=cfg.interfacesFolder+"/"+gui+"/",markup=base+cfg.guiMarkup;_self.gui=new pwlib.gui(_self);if(markup in pwlib.fileCache){if(_self.gui.init(pwlib.fileCache[markup])){_self.initTools()}else{_self.initError(lang.errorInitGUI)}}else{pwlib.xhrLoad(PaintWeb.baseFolder+markup,_self.guiMarkupReady)}};this.guiMarkupReady=function(xhr){if(!xhr||xhr.readyState!==4){return }if((xhr.status!==304&&xhr.status!==200)||!xhr.responseXML){_self.initError(lang.failedMarkupLoad);return }if(_self.gui.init(xhr.responseXML)){_self.initTools()}else{_self.initError(lang.errorInitGUI)}};this.initCanvas=function(){var cfg=this.config,res=this.resolution,resInfo=doc.getElementById(res.elemId),layerCanvas=doc.createElement("canvas"),bufferCanvas=doc.createElement("canvas"),layerContext=layerCanvas.getContext("2d"),bufferContext=bufferCanvas.getContext("2d"),width=cfg.imageWidth,height=cfg.imageHeight,imageLoad=cfg.imageLoad;if(!resInfo){var style=doc.createElement("style");style.type="text/css";style.appendChild(doc.createTextNode(res.cssText));_self.elems.head.appendChild(style);resInfo=doc.createElement("div");resInfo.id=res.elemId;doc.body.appendChild(resInfo)}if(!resInfo){this.initError(lang.errorInitCanvas);return false}if(!layerCanvas||!bufferCanvas||!layerContext||!bufferContext){this.initError(lang.noCanvasSupport);return false}if(!pwlib.isSameHost(imageLoad.src,win.location.host)){cfg.imageLoad=imageLoad=null;alert(lang.imageLoadDifferentHost)}if(imageLoad){width=parseInt(imageLoad.width);height=parseInt(imageLoad.height)}res.elem=resInfo;this.image.width=layerCanvas.width=bufferCanvas.width=width;this.image.height=layerCanvas.height=bufferCanvas.height=height;this.layer.canvas=layerCanvas;this.layer.context=layerContext;this.buffer.canvas=bufferCanvas;this.buffer.context=bufferContext;if(imageLoad){layerContext.drawImage(imageLoad,0,0)}var events=["dblclick","click","mousedown","mouseup","mousemove","contextmenu"],n=events.length;for(var i=0;imax){val=max}else{if(!isNaN(min)&&valconfig.imageZoomMax){level=config.imageZoomMax}else{if(level=image.width||cropY>=image.height){return false}var cancel=this.events.dispatch(new appEvent.imageCrop(cropX,cropY,cropWidth,cropHeight));if(cancel){return false}if(cropWidth>this.config.imageWidthMax){cropWidth=this.config.imageWidthMax}if(cropHeight>this.config.imageHeightMax){cropHeight=this.config.imageHeightMax}if(cropX===0&&cropY===0&&image.width===cropWidth&&image.height===cropHeight){return true}var scaledWidth=cropWidth*image.canvasScale,scaledHeight=cropHeight*image.canvasScale;bufferCanvas.style.width=layerCanvas.style.width=scaledWidth+"px";bufferCanvas.style.height=layerCanvas.style.height=scaledHeight+"px";var state=this.stateSave(layerContext),dataWidth=MathMin(image.width,cropWidth),dataHeight=MathMin(image.height,cropHeight),sumX=cropX+dataWidth,sumY=cropY+dataHeight;if(sumX>image.width){dataWidth-=sumX-image.width}if(sumY>image.height){dataHeight-=sumY-image.height}var idata=null;if(layerContext.getImageData){try{idata=layerContext.getImageData(cropX,cropY,dataWidth,dataHeight)}catch(err){return false}}layerCanvas.width=cropWidth;layerCanvas.height=cropHeight;if(idata&&layerContext.putImageData){layerContext.putImageData(idata,0,0)}this.stateRestore(layerContext,state);state=this.stateSave(bufferContext);idata=null;if(bufferContext.getImageData){try{idata=bufferContext.getImageData(cropX,cropY,dataWidth,dataHeight)}catch(err){}}bufferCanvas.width=cropWidth;bufferCanvas.height=cropHeight;if(idata&&bufferContext.putImageData){bufferContext.putImageData(idata,0,0)}this.stateRestore(bufferContext,state);image.width=cropWidth;image.height=cropHeight;this.events.dispatch(new appEvent.imageSizeChange(cropWidth,cropHeight));this.events.dispatch(new appEvent.canvasSizeChange(scaledWidth,scaledHeight,image.canvasScale));return true};this.stateSave=function(context){if(!context||!context.canvas||!this.stateProperties){return false}var stateObj={},prop=null,n=this.stateProperties.length;for(var i=0;ithis.config.historyLimit){history.states.splice(0,history.states.length-this.config.historyLimit)}history.pos=history.states.length;this.events.dispatch(new appEvent.historyUpdate(history.pos,prevPos,history.pos));return true};this.historyGoto=function(pos){var layerContext=this.layer.context,image=this.image,history=this.history;if(!history.states.length||!layerContext.putImageData){return false}var cpos=history.pos;if(pos==="undo"){pos=cpos-1}else{if(pos==="redo"){pos=cpos+1}}if(pos===cpos||pos<1||pos>history.states.length){return false}var himg=history.states[pos-1];if(!himg){return false}var w=MathMin(image.width,himg.width),h=MathMin(image.height,himg.height);layerContext.clearRect(0,0,image.width,image.height);try{layerContext.putImageData(himg,0,0,0,0,w,h)}catch(err){var tmp=doc.createElement("canvas");tmp.width=himg.width;tmp.height=himg.height;var tmp2=tmp.getContext("2d");tmp2.putImageData(himg,0,0);layerContext.drawImage(tmp,0,0);delete tmp2,tmp}history.pos=pos;this.events.dispatch(new appEvent.historyUpdate(pos,cpos,history.states.length));return true};this.historyReset=function(){this.history.pos=0;this.history.states=[];this.events.dispatch(new appEvent.historyUpdate(0,0,0))};this.toolSnapXY=function(x,y){var diffx=MathAbs(_self.mouse.x-x),diffy=MathAbs(_self.mouse.y-y);if(diffx>diffy){_self.mouse.y=y}else{_self.mouse.x=x}};this.toolActivate=function(id,ev){if(!id||!(id in pwlib.tools)||typeof pwlib.tools[id]!=="function"){return false}var tool=pwlib.tools[id],prevId=this.tool?this.tool._id:null;if(prevId&&this.tool instanceof pwlib.tools[id]){return true}var cancel=this.events.dispatch(new appEvent.toolPreactivate(id,prevId));if(cancel){return false}var tool_obj=new tool(this,ev);if(!tool_obj){return false}if("preActivate" in tool_obj&&!tool_obj.preActivate(ev)){tool_obj=null;return false}if(this.tool&&"deactivate" in this.tool){this.tool.deactivate(ev)}this.tool=tool_obj;this.mouse.buttonDown=false;if("activate" in this.tool){this.tool.activate(ev)}this.events.dispatch(new appEvent.toolActivate(id,prevId));return true};this.toolRegister=function(id){if(typeof id!=="string"||!id){return false}var tool=pwlib.tools[id];if(typeof tool!=="function"){return false}tool.prototype._id=id;this.events.dispatch(new appEvent.toolRegister(id));if(!this.tool&&id===this.config.toolDefault){return this.toolActivate(id)}else{return true}};this.toolUnregister=function(id){if(typeof id!=="string"||!id||!(id in pwlib.tools)){return false}this.events.dispatch(new appEvent.toolUnregister(id));return true};this.extensionRegister=function(id){if(typeof id!=="string"||!id){return false}var func=pwlib.extensions[id];if(typeof func!=="function"){return false}func.prototype._id=id;var obj=new func(_self);if("extensionRegister" in obj&&!obj.extensionRegister()){return false}this.extensions[id]=obj;this.events.dispatch(new appEvent.extensionRegister(id));return true};this.extensionUnregister=function(id){if(typeof id!=="string"||!id||!(id in this.extensions)){return false}this.events.dispatch(new appEvent.extensionUnregister(id));if("extensionUnregister" in this.extensions[id]){this.extensions[id].extensionUnregister()}delete this.extensions[id];return true};this.commandRegister=function(id,func){if(typeof id!=="string"||!id||typeof func!=="function"||id in this.commands){return false}this.commands[id]=func;this.events.dispatch(new appEvent.commandRegister(id));return true};this.commandUnregister=function(id){if(typeof id!=="string"||!id||!(id in this.commands)){return false}this.events.dispatch(new appEvent.commandUnregister(id));delete this.commands[id];return true};this.scriptLoad=function(url,handler){if(!handler){var elem=doc.createElement("script");elem.type="text/javascript";elem.src=url;this.elems.head.appendChild(elem);return }var xhr=new XMLHttpRequest();xhr.onreadystatechange=function(){if(!xhr||xhr.readyState!==4){return }else{if((xhr.status!==304&&xhr.status!==200)||!xhr.responseText){handler(false,xhr)}else{try{eval.call(win,xhr.responseText)}catch(err){eval(xhr.responseText,win)}handler(true,xhr)}}xhr=null};xhr.open("GET",url);xhr.send("")};this.styleLoad=function(id,url,media,handler){id="paintweb_style_"+id;var elem=doc.getElementById(id);if(elem){return }if(!media){media="screen, projection"}elem=doc.createElement("link");if(handler){elem.addEventListener("load",handler,false)}elem.id=id;elem.rel="stylesheet";elem.type="text/css";elem.media=media;elem.href=url;this.elems.head.appendChild(elem)};this.historyUndo=function(){return _self.historyGoto("undo")};this.historyRedo=function(){return _self.historyGoto("redo")};this.imageLoad=function(importImage){if(!importImage||!importImage.width||!importImage.height||importImage.nodeType!==Node.ELEMENT_NODE||!pwlib.isSameHost(importImage.src,win.location.host)){return false}this.historyReset();var layerContext=this.layer.context,layerCanvas=this.layer.canvas,layerStyle=layerCanvas.style,bufferCanvas=this.buffer.canvas,bufferStyle=bufferCanvas.style,image=this.image,styleWidth=importImage.width*image.canvasScale,styleHeight=importImage.height*image.canvasScale,result=true;bufferCanvas.width=layerCanvas.width=importImage.width;bufferCanvas.height=layerCanvas.height=importImage.height;try{layerContext.drawImage(importImage,0,0)}catch(err){result=false;bufferCanvas.width=layerCanvas.width=image.width;bufferCanvas.height=layerCanvas.height=image.height}if(result){image.width=importImage.width;image.height=importImage.height;bufferStyle.width=layerStyle.width=styleWidth+"px";bufferStyle.height=layerStyle.height=styleHeight+"px";_self.config.imageLoad=importImage;this.events.dispatch(new appEvent.imageSizeChange(image.width,image.height));this.events.dispatch(new appEvent.canvasSizeChange(styleWidth,styleHeight,image.canvasScale))}this.historyAdd();return result};this.imageClear=function(ev){_self.layer.context.clearRect(0,0,_self.image.width,_self.image.height);_self.historyAdd()};this.imageSave=function(){var canvas=_self.layer.canvas,idata=null;if(!canvas.toDataURL){return false}try{idata=canvas.toDataURL()}catch(err){alert(lang.errorImageSave+"\n"+err);return false}if(!idata||idata.toLowerCase()==="data:"){return false}var img=_self.image,ev=new appEvent.imageSave(idata,img.width,img.height),cancel=_self.events.dispatch(ev);if(cancel){return true}var imgwin=_self.win.open();if(!imgwin){return false}imgwin.location=idata;idata=null;_self.events.dispatch(new appEvent.imageSaveResult(true));return true};this.swapFillStroke=function(){var fillStyle=_self.config.fillStyle,strokeStyle=_self.config.strokeStyle;_self.config.fillStyle=strokeStyle;_self.config.strokeStyle=fillStyle;var ev=new appEvent.configChange(strokeStyle,fillStyle,"fillStyle","",_self.config);_self.events.dispatch(ev);ev=new appEvent.configChange(fillStyle,strokeStyle,"strokeStyle","",_self.config);_self.events.dispatch(ev)};this.selectAll=function(ev){if(_self.toolActivate("selection",ev)){return _self.tool.selectAll(ev)}else{return false}};this.selectionCut=function(ev){if(!_self.tool||_self.tool._id!=="selection"){return false}else{return _self.tool.selectionCut(ev)}};this.selectionCopy=function(ev){if(!_self.tool||_self.tool._id!=="selection"){return false}else{return _self.tool.selectionCopy(ev)}};this.clipboardPaste=function(ev){if(!_self.clipboard||!_self.toolActivate("selection",ev)){return false}else{return _self.tool.clipboardPaste(ev)}};this.configChangeHandler=function(ev){if(ev.group==="shadow"&&_self.shadowSupported&&_self.shadowAllowed){var context=_self.layer.context,cfg=ev.groupRef;if(ev.config==="enable"){if(ev.value){context.shadowColor=cfg.shadowColor;context.shadowOffsetX=cfg.shadowOffsetX;context.shadowOffsetY=cfg.shadowOffsetY;context.shadowBlur=cfg.shadowBlur}else{context.shadowColor="rgba(0,0,0,0)";context.shadowOffsetX=0;context.shadowOffsetY=0;context.shadowBlur=0}return }if(!cfg.enable){return }switch(ev.config){case"shadowBlur":case"shadowOffsetX":case"shadowOffsetY":ev.value=parseInt(ev.value);case"shadowColor":context[ev.config]=ev.value}}else{if(ev.group==="line"){switch(ev.config){case"lineWidth":case"miterLimit":ev.value=parseInt(ev.value);case"lineJoin":case"lineCap":_self.buffer.context[ev.config]=ev.value}}else{if(ev.group==="text"){switch(ev.config){case"textAlign":case"textBaseline":_self.buffer.context[ev.config]=ev.value}}else{if(!ev.group){switch(ev.config){case"fillStyle":case"strokeStyle":_self.buffer.context[ev.config]=ev.value}}}}}};this.destroy=function(){this.events.dispatch(new appEvent.appDestroy());for(var cmd in this.commands){this.commandUnregister(cmd)}for(var ext in this.extensions){this.extensionUnregister(ext)}for(var tool in this.gui.tools){this.toolUnregister(tool)}this.gui.destroy();this.initialized=PaintWeb.INIT_NOT_STARTED};this.toString=function(){return"PaintWeb v"+this.version+" (build "+this.build+")"};preInit()}PaintWeb.INIT_NOT_STARTED=0;PaintWeb.INIT_STARTED=1;PaintWeb.INIT_DONE=2;PaintWeb.INIT_ERROR=-1;PaintWeb.baseFolder="";(function(){var A=document.getElementsByTagName("script"),E=A.length,D,C;for(var B=0;B-1){A=A.substr(0,E)}if(A!==D){return false}return true};pwlib.appEvent=function(B,A){if(typeof B!=="string"){throw new TypeError("The first argument must be a string")}else{if(typeof A==="undefined"){A=false}else{if(typeof A!=="boolean"){throw new TypeError("The second argument must be a boolean")}}}this.target=null;this.cancelable=A;this.defaultPrevented=false;this.type=B;this.preventDefault=function(){if(A){this.defaultPrevented=true}};this.stopPropagation=function(){this.propagationStopped_=true}};pwlib.appEvent.appInit=function(B,A){if(typeof B!=="number"){throw new TypeError("The first argument must be a number.")}this.INIT_NOT_STARTED=0;this.INIT_STARTED=1;this.INIT_DONE=2;this.INIT_ERROR=-1;this.state=B;this.errorMessage=A||null;pwlib.appEvent.call(this,"appInit")};pwlib.appEvent.appDestroy=function(){pwlib.appEvent.call(this,"appDestroy")};pwlib.appEvent.guiShow=function(){pwlib.appEvent.call(this,"guiShow")};pwlib.appEvent.guiHide=function(){pwlib.appEvent.call(this,"guiHide")};pwlib.appEvent.toolPreactivate=function(B,A){if(typeof B!=="string"){throw new TypeError("The first argument must be a string.")}else{if(A!==null&&typeof A!=="string"){throw new TypeError("The second argument must be a string or null.")}}this.id=B;this.prevId=A;pwlib.appEvent.call(this,"toolPreactivate",true)};pwlib.appEvent.toolActivate=function(B,A){if(typeof B!=="string"){throw new TypeError("The first argument must be a string.")}else{if(A!==null&&typeof A!=="string"){throw new TypeError("The second argument must be a string or null.")}}this.id=B;this.prevId=A;pwlib.appEvent.call(this,"toolActivate")};pwlib.appEvent.toolRegister=function(A){if(typeof A!=="string"){throw new TypeError("The first argument must be a string.")}this.id=A;pwlib.appEvent.call(this,"toolRegister")};pwlib.appEvent.toolUnregister=function(A){if(typeof A!=="string"){throw new TypeError("The first argument must be a string.")}this.id=A;pwlib.appEvent.call(this,"toolUnregister")};pwlib.appEvent.extensionRegister=function(A){if(typeof A!=="string"){throw new TypeError("The first argument must be a string.")}this.id=A;pwlib.appEvent.call(this,"extensionRegister")};pwlib.appEvent.extensionUnregister=function(A){if(typeof A!=="string"){throw new TypeError("The first argument must be a string.")}this.id=A;pwlib.appEvent.call(this,"extensionUnregister")};pwlib.appEvent.commandRegister=function(A){if(typeof A!=="string"){throw new TypeError("The first argument must be a string.")}this.id=A;pwlib.appEvent.call(this,"commandRegister")};pwlib.appEvent.commandUnregister=function(A){if(typeof A!=="string"){throw new TypeError("The first argument must be a string.")}this.id=A;pwlib.appEvent.call(this,"commandUnregister")};pwlib.appEvent.imageSave=function(C,B,A){this.dataURL=C;this.width=B;this.height=A;pwlib.appEvent.call(this,"imageSave",true)};pwlib.appEvent.imageSaveResult=function(C,A,B){this.successful=C;this.url=A;this.urlNew=B;pwlib.appEvent.call(this,"imageSaveResult")};pwlib.appEvent.historyUpdate=function(C,A,B){if(typeof C!=="number"||typeof A!=="number"||typeof B!=="number"){throw new TypeError("All arguments must be numbers.")}this.currentPos=C;this.previousPos=A;this.states=B;pwlib.appEvent.call(this,"historyUpdate")};pwlib.appEvent.imageSizeChange=function(B,A){if(typeof B!=="number"||typeof A!=="number"){throw new TypeError("Both arguments must be numbers.")}this.width=B;this.height=A;pwlib.appEvent.call(this,"imageSizeChange")};pwlib.appEvent.canvasSizeChange=function(B,A,C){if(typeof B!=="number"||typeof A!=="number"||typeof C!=="number"){throw new TypeError("All the arguments must be numbers.")}this.width=B;this.height=A;this.scale=C;pwlib.appEvent.call(this,"canvasSizeChange")};pwlib.appEvent.imageZoom=function(A){if(typeof A!=="number"){throw new TypeError("The first argument must be a number.")}this.zoom=A;pwlib.appEvent.call(this,"imageZoom",true)};pwlib.appEvent.imageCrop=function(B,D,C,A){if(typeof B!=="number"||typeof D!=="number"||typeof C!=="number"||typeof A!=="number"){throw new TypeError("All arguments must be numbers.")}this.x=B;this.y=D;this.width=C;this.height=A;pwlib.appEvent.call(this,"imageCrop",true)};pwlib.appEvent.configChange=function(D,A,B,E,C){if(typeof B!=="string"){throw new TypeError("The third argument must be a string.")}else{if(typeof E!=="string"){throw new TypeError("The fourth argument must be a string.")}else{if(typeof C!=="object"){throw new TypeError("The fifth argument must be an object.")}}}this.value=D;this.previousValue=A;this.config=B;this.group=E;this.groupRef=C;pwlib.appEvent.call(this,"configChange")};pwlib.appEvent.shadowAllow=function(A){if(typeof A!=="boolean"){throw new TypeError("The first argument must be a boolean.")}this.allowed=A;pwlib.appEvent.call(this,"shadowAllow")};pwlib.appEvent.clipboardUpdate=function(A){this.data=A;pwlib.appEvent.call(this,"clipboardUpdate")};pwlib.appEvents=function(C){var B={};var A=1;this.add=function(E,D){if(typeof E!=="string"){throw new TypeError("The first argument must be a string.")}else{if(typeof D!=="function"){throw new TypeError("The second argument must be a function.")}}var F=A++;if(!(E in B)){B[E]={}}B[E][F]=D;return F};this.remove=function(D,E){if(typeof D!=="string"){throw new TypeError("The first argument must be a string.")}if(!(D in B)||!(E in B[D])){return }delete B[D][E]};this.dispatch=function(E){if(typeof E!=="object"){throw new TypeError("The second argument must be an object.")}else{if(typeof E.type!=="string"){throw new TypeError("The second argument must be an application event object.")}}if(!(E.type in B)){return false}E.target=C;var F,D=B[E.type];for(F in D){D[F].call(C,E);if(E.propagationStopped_){break}}return E.defaultPrevented}};pwlib.browser={};(function(){var A="";if(window.navigator&&window.navigator.userAgent){A=window.navigator.userAgent.toLowerCase()}pwlib.browser.opera=window.opera?true:/\bopera\b/.test(A);pwlib.browser.webkit=/\b(applewebkit|webkit)\b/.test(A);pwlib.browser.firefox=/\bfirefox\b/.test(A)&&!pwlib.browser.opera;pwlib.browser.gecko=/\bgecko\b/.test(A)&&!pwlib.browser.opera&&!pwlib.browser.webkit;pwlib.browser.msie=/\bmsie\b/.test(A)&&!pwlib.browser.opera;pwlib.browser.presto=/\bpresto\b/.test(A)||pwlib.browser.opera;pwlib.browser.os=(A.match(/\b(windows|linux)\b/)||[])[1];pwlib.browser.olpcxo=A.match(/\bolpc\b/)&&A.match(/\bxo\b/);delete A})();pwlib.dom={};pwlib.dom.keyNames={Help:6,Backspace:8,Tab:9,Clear:12,Enter:13,Shift:16,Control:17,Alt:18,Pause:19,CapsLock:20,Cancel:24,Escape:27,Space:32,PageUp:33,PageDown:34,End:35,Home:36,Left:37,Up:38,Right:39,Down:40,PrintScreen:44,Insert:45,Delete:46,Win:91,ContextMenu:93,"*":106,"+":107,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,NumLock:144,";":186,"=":187,",":188,"-":189,".":190,"/":191,"`":192,"[":219,"\\":220,"]":221,"'":222};pwlib.dom.keyCodes={3:"Enter",6:"Help",8:"Backspace",9:"Tab",10:"Enter",12:"Clear",13:"Enter",14:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",24:"Cancel",27:"Escape",32:"Space",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"Left",38:"Up",39:"Right",40:"Down",45:"Insert",46:"Delete",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9",106:"*",107:"+",109:"-",110:".",111:"/",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",127:"Delete",144:"NumLock",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'"};if(pwlib.browser.gecko){pwlib.dom.keyCodes[3]="Cancel"}pwlib.dom.keyCodes_fixes={42:pwlib.dom.keyNames["*"],47:pwlib.dom.keyNames["/"],59:pwlib.dom.keyNames[";"],61:pwlib.dom.keyNames["="],96:48,97:49,98:50,99:51,100:52,101:53,102:54,103:55,104:56,105:57,109:pwlib.dom.keyNames["-"],110:pwlib.dom.keyNames["."],111:pwlib.dom.keyNames["/"]};pwlib.dom.keyCodes_Safari2={63232:pwlib.dom.keyNames.Up,63233:pwlib.dom.keyNames.Down,63234:pwlib.dom.keyNames.Left,63235:pwlib.dom.keyNames.Right,63236:pwlib.dom.keyNames.F1,63237:pwlib.dom.keyNames.F2,63238:pwlib.dom.keyNames.F3,63239:pwlib.dom.keyNames.F4,63240:pwlib.dom.keyNames.F5,63241:pwlib.dom.keyNames.F6,63242:pwlib.dom.keyNames.F7,63243:pwlib.dom.keyNames.F8,63244:pwlib.dom.keyNames.F9,63245:pwlib.dom.keyNames.F10,63246:pwlib.dom.keyNames.F11,63247:pwlib.dom.keyNames.F12,63248:pwlib.dom.keyNames.PrintScreen,63272:pwlib.dom.keyNames.Delete,63273:pwlib.dom.keyNames.Home,63275:pwlib.dom.keyNames.End,63276:pwlib.dom.keyNames.PageUp,63277:pwlib.dom.keyNames.PageDown,63289:pwlib.dom.keyNames.NumLock,63302:pwlib.dom.keyNames.Insert};pwlib.dom.KeyboardEventListener=function(O,N){var H=null;var L=null;var G=null;var I=null;var F=false;if(!N){throw new TypeError("The first argument must be of type an object.")}if(!N.keydown&&!N.keypress&&!N.keyup){throw new TypeError("The provided handlers object has no keyboard eventhandler.")}if(N.keydown&&typeof N.keydown!=="function"){throw new TypeError("The keydown event handler is not a function!")}if(N.keypress&&typeof N.keypress!=="function"){throw new TypeError("The keypress event handler is not a function!")}if(N.keyup&&typeof N.keyup!=="function"){throw new TypeError("The keyup event handler is not a function!")}this.attach=function(){H=null;L=null;G=null;I=null;F=false;O.addEventListener("keydown",E,false);O.addEventListener("keypress",C,false);O.addEventListener("keyup",B,false)};this.detach=function(){O.removeEventListener("keydown",E,false);O.removeEventListener("keypress",C,false);O.removeEventListener("keyup",B,false);H=null;L=null;G=null;I=null;F=false};function J(Q,R){if(!N[Q]){return }var P=N[Q];if(Q===R.type){P.call(O,R)}else{var S={};pwlib.extend(S,R);S.type=Q;S.preventDefault=function(){R.preventDefault()};P.call(O,S)}}function E(Q){var P=L;G=null;I=null;K(Q);Q.keyCode_=H;Q.key_=L;Q.repeat_=L&&P===L?true:false;F=Q.repeat_;if(!F){J("keydown",Q)}if(!A(L)&&!D(Q)){Q.type_="keydown";C(Q)}}function C(P){if(!H){K(P);F=false}P.keyCode_=H;P.key_=L;M(P);P.charCode_=G;P.char_=I;P.repeat_=F;if(!F){F=true}if(!A(L)){J("keypress",P)}}function B(P){K(P);P.keyCode_=H;P.key_=L;P.charCode_=G;P.char_=I;J("keyup",P);H=null;L=null;G=null;I=null;F=false}function A(P){switch(P){case"Shift":case"Control":case"Alt":case"Meta":case"Win":return true;default:return false}}function D(P){if((L==="Up"||L==="Down")&&pwlib.browser.gecko&&P.target&&P.target.tagName.toLowerCase()==="input"){return false}if(!pwlib.browser.msie&&!pwlib.browser.webkit){return true}if(L&&L!=="Space"&&L!=="Enter"&&L!=="Escape"&&L.length!==1){return false}if(pwlib.browser.webkit&&L==="Escape"){return false}if(pwlib.browser.msie&&!P.shiftKey&&(P.ctrlKey||P.altKey)){return false}return true}function K(Q){if(Q.type==="keyup"&&!Q.keyCode&&!Q.which&&(!Q.keyIdentifier||Q.keyIdentifier==="Unidentified"||Q.keyIdentifier==="U+0000")){return }H=null;L=null;if(Q.keyCode||Q.which){H=Q.keyCode||Q.which;if(pwlib.browser.webkit){if(H==25&&this.shiftKey){H=pwlib.dom.keyNames.Tab}else{if(H>=63232&&H in pwlib.dom.keyCodes_Safari2){H=pwlib.dom.keyCodes_Safari2[H]}}}if(H in pwlib.dom.keyCodes_fixes){H=pwlib.dom.keyCodes_fixes[H]}L=pwlib.dom.keyCodes[H]||String.fromCharCode(H);return }var P=null,R=null,S=Q.keyIdentifier;if(!S||S==="Unidentified"||S==="U+0000"){return }if(S.substr(0,2)==="U+"){R=parseInt(S.substr(2),16)}else{if(S.length===1){R=S.charCodeAt(0);P=S}else{H=pwlib.dom.keyNames[S]||null;L=S;return }}if(R in pwlib.dom.keyCodes&&(R<=32||R==127||R==144)){L=pwlib.dom.keyCodes[R]}else{if(!P){P=String.fromCharCode(R)}L=P.toUpperCase();if(P!==L){R=L.charCodeAt(0)}}if(L==="Delete"||L.length===1&&L in pwlib.dom.keyNames){R=pwlib.dom.keyNames[L]}H=R}function M(R){G=null;I=null;if(R.charCode){G=R.charCode;I=String.fromCharCode(R.charCode);return }if(R.keyCode||R.which){var T=R.keyCode||R.which;var S=false;switch(T){case pwlib.dom.keyNames.Tab:case pwlib.dom.keyNames.Enter:case pwlib.dom.keyNames.Space:S=true}if(!S&&L&&L.length!==1){return }if(R.type_==="keydown"){var Q=pwlib.dom.keyCodes[T];if(Q&&Q.length===1){G=Q.charCodeAt(0);I=Q}}else{if(T>=32||S){G=T;I=String.fromCharCode(T)}}if(G){return }}var V=null,P=null,U=R.keyIdentifier;if(U&&U!=="Unidentified"&&U!=="U+0000"&&(U.substr(0,2)==="U+"||U.length===1)){if(U.length===1){P=U.charCodeAt(0);V=U}else{P=parseInt(U.substr(2),16)}if(P==pwlib.dom.keyNames.Tab||P==pwlib.dom.keyNames.Enter||P>=32&&P!=127&&P!=pwlib.dom.keyNames.NumLock){G=P;I=V||String.fromCharCode(P);return }}if(L&&L.length===1){G=L.charCodeAt(0);I=L}}this.attach()};pwlib.tools.selection=function(E){var K=this,R=pwlib.appEvent,N=E.buffer.context,q=E.win.clearInterval,f=E.config.selection,i=E.gui,H=E.image,I=E.lang,e=E.layer.canvas,V=E.layer.context,B=null,U=Math.abs,o=Math.min,r=Math.round,Z=E.mouse,J=E.win.setInterval,S=E.toolSnapXY;var X=null;var h=false;this.STATE_PENDING=-1;this.STATE_NONE=0;this.STATE_DRAWING=1;this.STATE_SELECTED=2;this.STATE_DRAGGING=3;this.STATE_RESIZING=4;this.state=this.STATE_NONE;var O=0;var C=0;this.selection={x:0,y:0,width:0,height:0,widthOriginal:0,heightOriginal:0,layerCleared:false,marquee:null,context:null,canvas:null};var c="out";var a=null;var Y=this.selection,l=f.borderWidth*2,T=null,j=null,P=false,L=false;var g=null;this.preActivate=function(){if(!("canvasContainer" in i.elems)){alert(I.errorToolActivate);return false}Y.canvas=E.doc.createElement("canvas");if(!Y.canvas){alert(I.errorToolActivate);return false}Y.canvas.width=5;Y.canvas.height=5;Y.context=Y.canvas.getContext("2d");if(!Y.context){alert(I.errorToolActivate);return false}Y.marquee=E.doc.createElement("div");if(!Y.marquee){alert(I.errorToolActivate);return false}Y.marquee.className=i.classPrefix+"selectionMarquee";B=Y.marquee.style;return true};this.activate=function(){if(!V.putImageData||!V.getImageData){f.transparent=true}b();B.borderWidth=f.borderWidth+"px";Y.marquee.addEventListener("mousedown",M,false);Y.marquee.addEventListener("mousemove",Q,false);Y.marquee.addEventListener("mouseup",G,false);i.elems.canvasContainer.appendChild(Y.marquee);E.shadowDisallow();T=E.events.add("canvasSizeChange",D);j=E.events.add("configChange",W);E.commandRegister("selectionCrop",K.selectionCrop);E.commandRegister("selectionDelete",K.selectionDelete);E.commandRegister("selectionFill",K.selectionFill);if(!X){X=J(p,E.config.toolDrawDelay)}return true};this.deactivate=function(){if(X){q(X);X=null}K.selectionMerge();Y.marquee.removeEventListener("mousedown",M,false);Y.marquee.removeEventListener("mousemove",Q,false);Y.marquee.removeEventListener("mouseup",G,false);B=null;i.elems.canvasContainer.removeChild(Y.marquee);delete Y.context,Y.canvas,Y.marquee;E.shadowAllow();if(T){E.events.remove("canvasSizeChange",T)}if(j){E.events.remove("configChange",j)}E.commandUnregister("selectionCrop");E.commandUnregister("selectionDelete");E.commandUnregister("selectionFill");return true};this.mousedown=function(s){if(K.state!==K.STATE_NONE&&K.state!==K.STATE_SELECTED){return false}O=Z.x;C=Z.y;L=s.shiftKey;P=s.ctrlKey;g=null;if(K.state===K.STATE_NONE){K.state=K.STATE_DRAWING;B.display="";i.statusShow("selectionDraw");return true}F();switch(c){case"out":K.state=K.STATE_PENDING;b();i.statusShow("selectionActive");k();return true;case"in":K.state=K.STATE_DRAGGING;i.statusShow("selectionDrag");break;case"border":K.state=K.STATE_RESIZING;i.statusShow("selectionResize")}if(s.ctrlKey){f.transform=!f.transform}if(Y.layerCleared&&!f.transform){k()}else{if(!Y.layerCleared&&f.transform){n()}}return true};this.mousemove=function(s){L=s.shiftKey;h=true};function p(){if(!h){return }switch(K.state){case K.STATE_PENDING:K.state=K.STATE_DRAWING;B.display="";i.statusShow("selectionDraw");case K.STATE_DRAWING:d();break;case K.STATE_SELECTED:F();break;case K.STATE_DRAGGING:m();break;case K.STATE_RESIZING:A()}h=false}this.mouseup=function(s){if(K.state!==K.STATE_PENDING&&Z.x===O&&Z.y===C){return true}h=false;L=s.shiftKey;if(P){f.transform=!f.transform}if(K.state===K.STATE_PENDING){K.state=K.STATE_NONE;E.events.dispatch(new R.selectionChange(K.state));return true}else{if(!g){K.state=K.STATE_NONE;b();i.statusShow("selectionActive");E.events.dispatch(new R.selectionChange(K.state));return true}}Y.x=g.x;Y.y=g.y;if("width" in g){Y.width=g.width;Y.height=g.height}K.state=K.STATE_SELECTED;E.events.dispatch(new R.selectionChange(K.state,Y.x,Y.y,Y.width,Y.height));i.statusShow("selectionAvailable");return true};function M(s){if(Z.buttonDown){return }Z.buttonDown=true;s.preventDefault();K.mousedown(s)}function Q(s){if("layerX" in s){Z.x=r((this.offsetLeft+s.layerX)/H.canvasScale);Z.y=r((this.offsetTop+s.layerY)/H.canvasScale)}else{if("offsetX" in s){Z.x=r((this.offsetLeft+s.offsetX)/H.canvasScale);Z.y=r((this.offsetTop+s.offsetY)/H.canvasScale)}}L=s.shiftKey;h=true}function G(s){if(!Z.buttonDown){return }Z.buttonDown=false;s.preventDefault();K.mouseup(s)}function b(){B.display="none";B.top="-"+(l+50)+"px";B.left="-"+(l+50)+"px";B.width="1px";B.height="1px";B.cursor=""}function d(){var s=o(Z.x,O),AA=o(Z.y,C),t=U(Z.x-O),v=U(Z.y-C);if(L){if(t>v){if(AA===Z.y){AA-=t-v}v=t}else{if(s===Z.x){s-=v-t}t=v}}var z=t*H.canvasScale-l,u=v*H.canvasScale-l;if(z<1||u<1){g=null;return }B.top=(AA*H.canvasScale)+"px";B.left=(s*H.canvasScale)+"px";B.width=z+"px";B.height=u+"px";g={x:s,y:AA,width:t,height:v}}function m(){if(L){S(O,C)}var s=Y.x+Z.x-O,t=Y.y+Z.y-C;if(f.transform){N.clearRect(0,0,H.width,H.height);if(!f.transparent){N.fillRect(s,t,Y.width,Y.height)}N.drawImage(Y.canvas,s,t,Y.width,Y.height)}B.top=(t*H.canvasScale)+"px";B.left=(s*H.canvasScale)+"px";g={x:s,y:t}}function A(){var u=Z.x-O,t=Z.y-C,AD=Y.x,AC=Y.y,AE=Y.width,z=Y.height;switch(a){case"nw":AD+=u;AC+=t;AE-=u;z-=t;break;case"n":AC+=t;z-=t;break;case"ne":AC+=t;AE+=u;z-=t;break;case"e":AE+=u;break;case"se":AE+=u;z+=t;break;case"s":z+=t;break;case"sw":AD+=u;AE-=u;z+=t;break;case"w":AD+=u;AE-=u;break;default:g=null;return }if(!AE||!z){g=null;return }if(L){var s=Y.width/Y.height,v=AE,AB=z;switch(a.charAt(0)){case"n":case"s":v=r(z*s);break;default:AB=r(AE/s)}switch(a){case"nw":case"sw":AD-=v-AE;AC-=AB-z}AE=v;z=AB}if(AE<0){AD+=AE;AE*=-1}if(z<0){AC+=z;z*=-1}var AF=AE*H.canvasScale-l,AA=z*H.canvasScale-l;if(AF<1||AA<1){g=null;return }if(f.transform){N.clearRect(0,0,H.width,H.height);if(!f.transparent){N.fillRect(AD,AC,AE,z)}N.drawImage(Y.canvas,AD,AC,AE,z)}B.top=(AC*H.canvasScale)+"px";B.left=(AD*H.canvasScale)+"px";B.width=AF+"px";B.height=AA+"px";g={x:AD,y:AC,width:AE,height:z}}function F(){var x=f.borderWidth/H.canvasScale,AB="",u=Y.x+Y.width,z=Y.y+Y.height,t=u-x,s=z-x,v=Y.x,AA=Y.y,y=Y.x+x,w=Y.y+x;c="out";if(Z.xy&&Z.y>w){AB="move";c="in"}else{if(Z.x>=v&&Z.x<=u&&Z.y>=AA&&Z.y<=w){AB="n"}else{if(Z.x>=v&&Z.x<=u&&Z.y>=s&&Z.y<=z){AB="s"}}if(Z.y>=AA&&Z.y<=z&&Z.x>=v&&Z.x<=y){AB+="w"}else{if(Z.y>=AA&&Z.y<=z&&Z.x>=t&&Z.x<=u){AB+="e"}}if(AB!==""){a=AB;AB+="-resize";c="border"}}if(AB!==B.cursor){B.cursor=AB}}function D(s){if(K.state!==K.STATE_SELECTED){return }B.top=(Y.y*s.scale)+"px";B.left=(Y.x*s.scale)+"px";B.width=(Y.width*s.scale-l)+"px";B.height=(Y.height*s.scale-l)+"px"}function W(s){if(s.group!=="selection"||s.config!=="transparent"||!f.transform||K.state!==K.STATE_SELECTED){return }if(!Y.layerCleared){n()}N.clearRect(Y.x,Y.y,Y.width,Y.height);if(!s.value){N.fillRect(Y.x,Y.y,Y.width,Y.height)}N.drawImage(Y.canvas,Y.x,Y.y,Y.width,Y.height)}function n(){var s=Y.x,AC=Y.y,u=Y.width,z=Y.height,AB=Y.x+Y.width,AA=Y.y+Y.height,v=0,t=0;Y.widthOriginal=u;Y.heightOriginal=z;if(s<0){u+=s;v-=s;s=0}if(AC<0){z+=AC;t-=AC;AC=0}if(AB>H.width){u=H.width-Y.x}if(AA>H.height){z=H.height-Y.y}if(!f.transparent){N.fillRect(s,AC,u,z)}N.drawImage(e,s,AC,u,z,s,AC,u,z);Y.canvas.width=Y.widthOriginal;Y.canvas.height=Y.heightOriginal;Y.context.drawImage(e,s,AC,u,z,v,t,u,z);V.clearRect(s,AC,u,z);Y.layerCleared=true;E.historyAdd()}function k(){if(!Y.layerCleared){return }if(!f.transparent){V.fillRect(Y.x,Y.y,Y.width,Y.height)}V.drawImage(Y.canvas,Y.x,Y.y,Y.width,Y.height);N.clearRect(Y.x,Y.y,Y.width,Y.height);Y.layerCleared=false;Y.canvas.width=5;Y.canvas.height=5;E.historyAdd()}this.selectionMerge=function(){if(K.state!==K.STATE_SELECTED){return false}k();K.state=K.STATE_NONE;b();i.statusShow("selectionActive");E.events.dispatch(new R.selectionChange(K.state));return true};this.selectAll=function(){if(K.state!==K.STATE_NONE&&K.state!==K.STATE_SELECTED){return false}if(K.state===K.STATE_SELECTED){k()}else{K.state=K.STATE_SELECTED;B.display=""}Y.x=0;Y.y=0;Y.width=H.width;Y.height=H.height;B.top="0px";B.left="0px";B.width=(Y.width*H.canvasScale-l)+"px";B.height=(Y.height*H.canvasScale-l)+"px";F();E.events.dispatch(new R.selectionChange(K.state,Y.x,Y.y,Y.width,Y.height));return true};this.selectionCut=function(){if(!K.selectionCopy()){return false}if(Y.layerCleared){N.clearRect(Y.x,Y.y,Y.width,Y.height);Y.canvas.width=5;Y.canvas.height=5;Y.layerCleared=false}else{V.clearRect(Y.x,Y.y,Y.width,Y.height);E.historyAdd()}K.state=K.STATE_NONE;b();E.events.dispatch(new R.selectionChange(K.state));i.statusShow("selectionActive");return true};this.selectionCopy=function(){if(K.state!==K.STATE_SELECTED){return false}if(!V.getImageData||!V.putImageData){alert(I.errorClipboardUnsupported);return false}if(!Y.layerCleared){var s=Y.width,t=Y.height,v=Y.width+Y.x;sumY=Y.height+Y.y;if(v>H.width){s=H.width-Y.x}if(sumY>H.height){t=H.height-Y.y}try{E.clipboard=V.getImageData(Y.x,Y.y,s,t)}catch(u){alert(I.failedSelectionCopy);return false}}else{try{E.clipboard=Y.context.getImageData(0,0,Y.widthOriginal,Y.heightOriginal)}catch(u){alert(I.failedSelectionCopy);return false}}E.events.dispatch(new R.clipboardUpdate(E.clipboard));return true};this.clipboardPaste=function(){if(!E.clipboard||K.state!==K.STATE_NONE&&K.state!==K.STATE_SELECTED){return false}if(!V.getImageData||!V.putImageData){alert(I.errorClipboardUnsupported);return false}var s=r(i.elems.viewport.scrollLeft/H.canvasScale),v=r(i.elems.viewport.scrollTop/H.canvasScale),t=E.clipboard.width,u=E.clipboard.height;Y.canvas.width=t;Y.canvas.height=u;Y.context.putImageData(E.clipboard,0,0);if(K.state===K.STATE_SELECTED){N.clearRect(Y.x,Y.y,Y.width,Y.height)}else{K.state=K.STATE_SELECTED}if(!f.transparent){N.fillRect(s,v,t,u)}N.drawImage(Y.canvas,s,v,t,u);Y.widthOriginal=Y.width=t;Y.heightOriginal=Y.height=u;Y.x=s;Y.y=v;Y.layerCleared=true;B.top=(v*H.canvasScale)+"px";B.left=(s*H.canvasScale)+"px";B.width=(t*H.canvasScale-l)+"px";B.height=(u*H.canvasScale-l)+"px";B.display="";if(!f.transform){f.transform=true;E.events.dispatch(new R.configChange(true,false,"transform","selection",f))}F();E.events.dispatch(new R.selectionChange(K.state,Y.x,Y.y,Y.width,Y.height));i.statusShow("selectionAvailable");return true};this.selectionDelete=function(){if(K.state!==K.STATE_SELECTED){return false}if(!Y.layerCleared){V.clearRect(Y.x,Y.y,Y.width,Y.height);E.historyAdd()}else{N.clearRect(Y.x,Y.y,Y.width,Y.height);Y.layerCleared=false;Y.canvas.width=5;Y.canvas.height=5;if(f.transform){f.transform=false;E.events.dispatch(new R.configChange(false,true,"transform","selection",f))}}return true};this.selectionDrop=function(){if(K.state!==K.STATE_SELECTED){return false}if(Y.layerCleared){N.clearRect(Y.x,Y.y,Y.width,Y.height);Y.canvas.width=5;Y.canvas.height=5;Y.layerCleared=false}K.state=K.STATE_NONE;b();i.statusShow("selectionActive");E.events.dispatch(new R.selectionChange(K.state));return true};this.selectionFill=function(){if(K.state!==K.STATE_SELECTED){return false}if(Y.layerCleared){Y.context.fillStyle=N.fillStyle;Y.context.fillRect(0,0,Y.widthOriginal,Y.heightOriginal);N.fillRect(Y.x,Y.y,Y.width,Y.height)}else{V.fillStyle=N.fillStyle;V.fillRect(Y.x,Y.y,Y.width,Y.height);E.historyAdd()}return true};this.selectionCrop=function(){if(K.state!==K.STATE_SELECTED){return false}K.selectionMerge();var s=Y.width,t=Y.height,v=Y.x+s,u=Y.y+t;if(v>H.width){s-=v-H.width}if(u>H.height){t-=u-H.height}E.imageCrop(Y.x,Y.y,s,t);return true};this.keydown=function(s){switch(s.kid_){case f.keys.transformToggle:f.transform=!f.transform;E.events.dispatch(new R.configChange(f.transform,!f.transform,"transform","selection",f));break;case f.keys.selectionCrop:return K.selectionCrop(s);case f.keys.selectionDelete:return K.selectionDelete(s);case f.keys.selectionDrop:return K.selectionDrop(s);case f.keys.selectionFill:return K.selectionFill(s);default:return false}return true}};pwlib.appEvent.selectionChange=function(D,B,E,C,A){this.STATE_NONE=0;this.STATE_SELECTED=2;this.state=D;this.x=B;this.y=E;this.width=C;this.height=A;pwlib.appEvent.call(this,"selectionChange")};pwlib.tools.hand=function(F){var J=this,A=F.buffer.canvas,N=A.style,E=F.config;clearInterval=F.win.clearInterval,image=F.image,MathRound=Math.round,mouse=F.mouse,viewport=F.gui.elems.viewport,vheight=0,vwidth=0,setInterval=F.win.setInterval;var C=null;var L=false;this.prevTool=null;var D=0,M=0,B=0,K=0,H=0,I=0;this.preActivate=function(){if(!viewport){return false}J.prevTool=F.tool._id;var R=F.win.getComputedStyle(viewport,null),S=parseInt(N.width),Q=parseInt(N.height);vwidth=parseInt(R.width),vheight=parseInt(R.height);if(vheightS){if(T==J.y){T-=R-S}S=R}else{if(Q==J.x){Q-=S-R}R=S}}if(E.shapeType!="stroke"){B.fillRect(Q,T,R,S)}if(E.shapeType!="fill"){B.strokeRect(Q,T,R,S)}P=false};this.mouseup=function(Q){if(J.x==D&&J.y==M){J.buttonDown=true;return true}if(A){O(A);A=null}K=Q.shiftKey;L.draw();F.layerUpdate();C.statusShow("rectangleActive");return true};this.keydown=function(Q){if(!J.buttonDown||Q.kid_!="Escape"){return false}if(A){O(A);A=null}B.clearRect(0,0,G.width,G.height);J.buttonDown=false;P=false;C.statusShow("rectangleActive");return true}};pwlib.tools.ellipse=function(G){var M=this,Q=G.win.clearInterval,F=G.config,B=G.buffer.context,C=G.gui,H=G.image,E=Math.max,P=Math.min,J=G.mouse,I=G.win.setInterval;var A=null;var L=false;var R=false;var N=4*((Math.SQRT2-1)/3);var D=0;var O=0;this.deactivate=function(){if(A){Q(A);A=null}if(J.buttonDown){B.clearRect(0,0,H.width,H.height)}R=false;return true};this.mousedown=function(K){D=J.x;O=J.y;if(!A){A=I(M.draw,F.toolDrawDelay)}L=K.shiftKey;R=false;C.statusShow("ellipseMousedown");return true};this.mousemove=function(K){L=K.shiftKey;R=true};this.draw=function(){if(!R){return }B.clearRect(0,0,H.width,H.height);var Z=P(J.x,D),Y=E(J.x,D),W=P(J.y,O),V=E(J.y,O);var a=Y-Z,X=V-W;if(!a||!X){R=false;return }if(L){if(a>X){V=W+a;if(W==J.y){W-=a-X;V-=a-X}X=a}else{Y=Z+X;if(Z==J.x){Z-=X-a;Y-=X-a}a=X}}var S=a/2,K=X/2;var U=Z+S,T=W+K;S*=N;K*=N;B.beginPath();B.moveTo(U,W);B.bezierCurveTo(U+S,W,Y,T-K,Y,T);B.bezierCurveTo(Y,T+K,U+S,V,U,V);B.bezierCurveTo(U-S,V,Z,T+K,Z,T);B.bezierCurveTo(Z,T-K,U-S,W,U,W);if(F.shapeType!="stroke"){B.fill()}if(F.shapeType!="fill"){B.stroke()}B.closePath();R=false};this.mouseup=function(K){if(J.x==D&&J.y==O){J.buttonDown=true;return true}if(A){Q(A);A=null}L=K.shiftKey;M.draw();G.layerUpdate();C.statusShow("ellipseActive");return true};this.keydown=function(K){if(!J.buttonDown||K.kid_!="Escape"){return false}if(A){Q(A);A=null}B.clearRect(0,0,H.width,H.height);J.buttonDown=false;R=false;C.statusShow("ellipseActive");return true}};pwlib.tools.polygon=function(F){var L=this,N=F.win.clearInterval,D=F.config,B=F.buffer.context,C=F.gui,G=F.image,H=Math.abs,J=F.mouse,I=F.win.setInterval,E=F.toolSnapXY;var M=[];var A=null;var K=false;var O=false;this.deactivate=function(){if(A){N(A);A=null}if(M.length){B.clearRect(0,0,G.width,G.height)}O=false;M=[];return true};this.mousedown=function(P){if(M.length==0){M.push([J.x,J.y])}if(!A){A=I(L.draw,D.toolDrawDelay)}K=P.shiftKey;O=false;C.statusShow("polygonMousedown");return true};this.mousemove=function(P){K=P.shiftKey;O=true};this.draw=function(Q){if(!O){return }var R=M.length;if(!R||(R==1&&!J.buttonDown)){O=false;return }if(J.buttonDown&&K){E(M[R-1][0],M[R-1][1])}B.clearRect(0,0,G.width,G.height);B.beginPath();B.moveTo(M[0][0],M[0][1]);for(var P=0;P3){C.statusShow("polygonEnd")}else{C.statusShow("polygonAddPoint")}M.push([J.x,J.y]);L.draw();return true};this.keydown=function(P){var Q=M.length;if(!Q||(P.kid_!="Escape"&&P.kid_!="Enter")){return false}if(A){N(A);A=null}J.buttonDown=false;if(P.kid_=="Escape"){B.clearRect(0,0,G.width,G.height);O=false}else{if(P.kid_=="Enter"){M.push([J.x,J.y]);M.push(M[0]);O=true;L.draw();F.layerUpdate()}}M=[];C.statusShow("polygonActive");return true}};pwlib.tools.line=function(G){var L=this,N=G.win.clearInterval,E=G.config,B=G.buffer.context,C=G.gui,H=G.image,J=G.mouse,I=G.win.setInterval,F=G.toolSnapXY;var A=null;var K=false;var O=false;var D=0;var M=0;this.deactivate=function(){if(A){N(A);A=null}if(J.buttonDown){B.clearRect(0,0,H.width,H.height)}O=false;return true};this.mousedown=function(P){D=J.x;M=J.y;if(!A){A=I(L.draw,E.toolDrawDelay)}K=P.shiftKey;O=false;C.statusShow("lineMousedown");return true};this.mousemove=function(P){K=P.shiftKey;O=true};this.draw=function(){if(!O){return }B.clearRect(0,0,H.width,H.height);if(K){F(D,M)}B.beginPath();B.moveTo(D,M);B.lineTo(J.x,J.y);B.stroke();B.closePath();O=false};this.mouseup=function(P){if(J.x==D&&J.y==M){J.buttonDown=true;return true}if(A){N(A);A=null}K=P.shiftKey;L.draw();C.statusShow("lineActive");G.layerUpdate();return true};this.keydown=function(P){if(!J.buttonDown||P.kid_!="Escape"){return false}if(A){N(A);A=null}B.clearRect(0,0,H.width,H.height);J.buttonDown=false;O=false;C.statusShow("lineActive");return true}};pwlib.tools.text=function(L){var J=this,O=L.win.clearInterval,X=L.config.text,E=L.buffer.context,Z=L.doc,R=L.gui,T=L.image,a=L.lang,W=Math.round,P=L.mouse,B=L.win.setInterval;var N=null;var D=L.tool?L.tool._id:null;var V=false;var Y=null,S=null,I=null,H="http://www.w3.org/2000/svg",Q=null,K=null,G=0,A=0;this.preActivate=function(){if(!R.inputs.textString||!R.inputs.text_fontFamily||!R.elems.viewport){return false}if(E.fillText&&E.strokeText){return true}if(E.mozPathText){return true}alert(a.errorTextUnsupported);return false};this.activate=function(){P.x=Math.round(R.elems.viewport.scrollLeft/T.canvasScale),P.y=Math.round(R.elems.viewport.scrollTop/T.canvasScale),S=R.inputs.text_fontFamily;Y=R.inputs.textString;if(!E.fillText&&pwlib.browser.opera){I=L.events.add("configChange",F);Y.addEventListener("input",F,false);Y.addEventListener("change",F,false)}else{I=L.events.add("configChange",C);Y.addEventListener("input",C,false);Y.addEventListener("change",C,false)}if(E.fillText&&E.strokeText){J.draw=J.draw_spec}else{if(pwlib.browser.opera){J.draw=J.draw_opera;M()}else{if(E.mozPathText){J.draw=J.draw_moz;G=E.mozMeasureText(Y.value)}}}if(!N){N=B(J.draw,L.config.toolDrawDelay)}V=true};this.deactivate=function(){if(N){O(N);N=null}V=false;if(I){L.events.remove("configChange",I)}if(!E.fillText&&pwlib.browser.opera){Y.removeEventListener("input",F,false);Y.removeEventListener("change",F,false)}else{Y.removeEventListener("input",C,false);Y.removeEventListener("change",C,false)}K=null;Q=null;E.clearRect(0,0,T.width,T.height);return true};function M(){Q=Z.createElementNS(H,"svg");Q.setAttributeNS(H,"version","1.1");K=Z.createElementNS(H,"text");K.appendChild(Z.createTextNode(Y.value));Q.appendChild(K);K.style.font=E.font;if(L.config.shapeType!=="stroke"){K.style.fill=E.fillStyle}else{K.style.fill="none"}if(L.config.shapeType!=="fill"){K.style.stroke=E.strokeStyle;K.style.strokeWidth=E.lineWidth}else{K.style.stroke="none";K.style.strokeWidth=E.lineWidth}G=K.getComputedTextLength();A=K.getBBox().height;Q.setAttributeNS(H,"width",G);Q.setAttributeNS(H,"height",A+10);K.setAttributeNS(H,"x",0);K.setAttributeNS(H,"y",A)}function C(c){if(c.type==="input"||c.type==="change"||(!c.group&&c.config==="shapeType")||(c.group==="line"&&c.config==="lineWidth")){V=true;if(!E.fillText&&E.mozMeasureText){G=E.mozMeasureText(Y.value)}return }if(c.type!=="configChange"&&c.group!=="text"){return }var b="";switch(c.config){case"fontFamily":if(c.value==="+"){U(c)}case"bold":case"italic":case"fontSize":if(X.bold){b+="bold "}if(X.italic){b+="italic "}b+=X.fontSize+"px "+X.fontFamily;E.font=b;if("mozTextStyle" in E){E.mozTextStyle=b}case"textAlign":case"textBaseline":V=true}if(c.config!=="textAlign"&&c.config!=="textBaseline"&&!E.fillText&&E.mozMeasureText){G=E.mozMeasureText(Y.value)}}function F(c){if(c.type==="input"||c.type==="change"){K.replaceChild(Z.createTextNode(this.value),K.firstChild);V=true}if(!c.group&&c.config==="shapeType"){if(c.value!=="stroke"){K.style.fill=E.fillStyle}else{K.style.fill="none"}if(c.value!=="fill"){K.style.stroke=E.strokeStyle;K.style.strokeWidth=E.lineWidth}else{K.style.stroke="none";K.style.strokeWidth=E.lineWidth}V=true}if(!c.group&&c.config==="fillStyle"){if(L.config.shapeType!=="stroke"){K.style.fill=c.value;V=true}}if((!c.group&&c.config==="strokeStyle")||(c.group==="line"&&c.config==="lineWidth")){if(L.config.shapeType!=="fill"){K.style.stroke=E.strokeStyle;K.style.strokeWidth=E.lineWidth;V=true}}if(c.type==="configChange"&&c.group==="text"){var b="";switch(c.config){case"fontFamily":if(c.value==="+"){U(c)}case"bold":case"italic":case"fontSize":if(X.bold){b+="bold "}if(X.italic){b+="italic "}b+=X.fontSize+"px "+X.fontFamily;E.font=b;K.style.font=b;case"textAlign":case"textBaseline":V=true}}G=K.getComputedTextLength();A=K.getBBox().height;Q.setAttributeNS(H,"width",G);Q.setAttributeNS(H,"height",A+10);K.setAttributeNS(H,"x",0);K.setAttributeNS(H,"y",A)}function U(f){var e=prompt(a.promptTextFont)||"";e=e.replace(/^\s+/,"").replace(/\s+$/,"")||f.previousValue;var c,d=e.toLowerCase(),g=S.options.length;for(var b=0;bZ){if(a==K.y){a-=Y-Z}Z=T(Y/C)}else{if(X==K.x){X-=Z-Y}Y=T(Z*C)}}E.drawImage(Q,X,a,Y,Z)}else{E.drawImage(Q,K.x,K.y)}O=false};this.mouseup=function(X){if(!B){return false}if(I){J(I);I=null}H.layerUpdate();if(D){H.toolActivate(D,X)}if(X.stopPropagation){X.stopPropagation()}};this.keydown=function(X){if(!D||X.kid_!="Escape"){return false}if(I){J(I);I=null}K.buttonDown=false;H.toolActivate(D,X);return true}};pwlib.tools.pencil=function(D){var H=this,K=D.win.clearInterval,B=D.buffer.context,E=D.image,G=D.mouse,F=D.win.setInterval;var A=null;var J=[];var C=0;var I=0;this.deactivate=function(){if(A){K(A);A=null}if(G.buttonDown){B.clearRect(0,0,E.width,E.height)}J=[]};this.mousedown=function(){C=G.x;I=G.y;J=[];if(!A){A=F(H.draw,D.config.toolDrawDelay)}return true};this.mousemove=function(){if(G.buttonDown){J.push(G.x,G.y)}};this.draw=function(){var L=0,M=J.length;if(!M){return }B.beginPath();B.moveTo(C,I);while(LN){P=N}}if(P!=this.value){this.value=P}}if(this._ckey==="hex"){I.color[this._ckey]=this.value}else{if(I.ckey_grouping[this._ckey]==="lab"){I.color[this._ckey]=parseInt(this.value)}else{I.color[this._ckey]=parseInt(this.value)/E.inputValues[this._ckey][1]}}I.update_color(this._ckey)};this.update_color=function(N){var O=I.ckey_grouping[N]||N;switch(O){case"rgb":I.rgb2hsv();I.rgb2hex();I.rgb2lab();I.rgb2cmyk();break;case"hsv":I.hsv2rgb();I.rgb2hex();I.rgb2lab();I.rgb2cmyk();break;case"hex":I.hex2rgb();I.rgb2hsv();I.rgb2lab();I.rgb2cmyk();break;case"lab":I.lab2rgb();I.rgb2hsv();I.rgb2hex();I.rgb2cmyk();break;case"cmyk":I.cmyk2rgb();I.rgb2lab();I.rgb2hsv();I.rgb2hex()}I.update_preview();I.update_inputs();if(N!=="alpha"){I.update_canvas(N)}};this.update_preview=function(){var Q=G(I.color.red*255),P=G(I.color.green*255),N=G(I.color.blue*255),O=I.elems.colorActive.style;O.backgroundColor="rgb("+Q+","+P+","+N+")";O.opacity=I.color.alpha};this.update_inputs=function(){var N;for(var O in I.inputs){N=I.inputs[O];N._old_value=N.value;if(N._ckey==="hex"){N.value=I.color[O]}else{if(I.ckey_grouping[N._ckey]==="lab"){N.value=G(I.color[O])}else{N.value=G(I.color[O]*E.inputValues[O][1])}}}};this.rgb2cmyk=function(){var Q=I.color,U,V,S,N,O=Q.red,P=Q.green,T=Q.blue;U=1-O;V=1-P;S=1-T;N=J(U,V,S,1);if(N===1){U=V=S=0}else{var R=1-N;U=(U-N)/R;V=(V-N)/R;S=(S-N)/R}Q.cyan=U;Q.magenta=V;Q.yellow=S;Q.black=N};this.cmyk2rgb=function(){var O=I.color,N=1-O.black;O.red=1-O.cyan*N-O.black;O.green=1-O.magenta*N-O.black;O.blue=1-O.yellow*N-O.black};this.rgb2hsv=function(){var S,O,N,P=I.color.red,Q=I.color.green,U=I.color.blue,R=J(P,Q,U),T=D(P,Q,U),V=T-R,N=T;if(V===0){S=O=0}else{O=V/T;if(T===P){S=(Q-U)/V}else{if(T===Q){S=(U-P)/V+2}else{if(T===U){S=(P-Q)/V+4}}}S/=6;if(S<0){S+=1}}I.color.hue=S;I.color.sat=O;I.color.val=N};this.hsv2rgb=function(Z,W){var R=I.color,P,Q,a,Y,O,N;if(W){Y=W[0];O=W[1];N=W[2]}else{Y=R.hue,O=R.sat,N=R.val}if(O===0){P=Q=a=N}else{var V=Y*6;var T=A(V);var X=N*(1-O),U=N*(1-O*(V-T)),S=N*(1-O*(1-(V-T)));if(T===0||T===6){P=N;Q=S;a=X}else{if(T===1){P=U;Q=N;a=X}else{if(T===2){P=X;Q=N;a=S}else{if(T===3){P=X;Q=U;a=N}else{if(T===4){P=S;Q=X;a=N}else{if(T===5){P=N;Q=X;a=U}}}}}}}if(!Z){R.red=P;R.green=Q;R.blue=a}return[P,Q,a]};this.rgb2hex=function(){var Q="#",O=["red","green","blue"],P,R,N=I.color;for(P=0;P<3;P++){R=G(N[O[P]]*255).toString(16);if(R.length===1){R="0"+R}Q+=R}N.hex=Q};this.hex2rgb=function(){var O=["red","green","blue"],P,R,N=I.color,Q=N.hex;Q=Q.substr(1);if(Q.length!==6){return }for(P=0;P<3;P++){R=Q.substr(P*2,2);N[O[P]]=parseInt(R,16)/255}};this.rgb2lab=function(){var N=I.color,O=I.xyz2lab(I.rgb2xyz([N.red,N.green,N.blue]));N.cie_l=O[0];N.cie_a=O[1];N.cie_b=O[2]};this.lab2rgb=function(){var N=I.color,O=I.xyz2rgb(I.lab2xyz(N.cie_l,N.cie_a,N.cie_b));N.red=O[0];N.green=O[1];N.blue=O[2]};this.xyz2lab=function(R){var P=E.lab,S=216/24389,Q=24389/27;R[0]/=P.w_x;R[1]/=P.w_y;R[2]/=P.w_z;if(R[0]>S){R[0]=M(R[0],1/3)}else{R[0]=(Q*R[0]+16)/116}if(R[1]>S){R[1]=M(R[1],1/3)}else{R[1]=(Q*R[1]+16)/116}if(R[2]>S){R[2]=M(R[2],1/3)}else{R[2]=(Q*R[2]+16)/116}var O=116*R[1]-16,N=500*(R[0]-R[1]),T=200*(R[1]-R[2]);return[O,N,T]};this.lab2xyz=function(N,T,R){var U=(N+16)/116,V=U+T/500,S=U-R/200,Q=6/29,O=1/3*M(29/6,2),W=16/116,P=E.lab;if(V>Q){V=M(V,3)}else{V=(V-W)/O}if(U>Q){U=M(U,3)}else{U=(U-W)/O}if(S>Q){S=M(S,3)}else{S=(S-W)/O}V*=P.w_x;U*=P.w_y;S*=P.w_z;return[V,U,S]};this.xyz2rgb=function(N){var O=I.calc_m1x3(N,E.lab.m_i);if(O[0]>0.0031308){O[0]=1.055*M(O[0],1/2.4)-0.055}else{O[0]*=12.9232}if(O[1]>0.0031308){O[1]=1.055*M(O[1],1/2.4)-0.055}else{O[1]*=12.9232}if(O[2]>0.0031308){O[2]=1.055*M(O[2],1/2.4)-0.055}else{O[2]*=12.9232}if(O[0]<0){O[0]=0}else{if(O[0]>1){O[0]=1}}if(O[1]<0){O[1]=0}else{if(O[1]>1){O[1]=1}}if(O[2]<0){O[2]=0}else{if(O[2]>1){O[2]=1}}return O};this.rgb2xyz=function(N){if(N[0]>0.04045){N[0]=M((N[0]+0.055)/1.055,2.4)}else{N[0]/=12.9232}if(N[1]>0.04045){N[1]=M((N[1]+0.055)/1.055,2.4)}else{N[1]/=12.9232}if(N[2]>0.04045){N[2]=M((N[2]+0.055)/1.055,2.4)}else{N[2]/=12.9232}return I.calc_m1x3(N,E.lab.m)};this.update_canvas=function(U,P){if(I.panelSelector.tabId!=="mixer"&&!P){I.update_canvas_needed=true;return true}I.update_canvas_needed=false;var Q=I.elems.slider.style,T=I.elems.chartDot.style,R=I.color,N=I.ckey_active,Y=I.ckey_active_group,S=I.ckey_adjoint,O=I.chartWidth/H,Z=I.chartHeight/H,X,W,V;if(U!==S[0]&&U!==S[1]&&I.ev_canvas_mode!=="chart"){if(Y==="lab"){V=(R[N]-E.inputValues[N][0])/I.abs_max[N]}else{V=R[N]}if(N!=="hue"&&Y!=="lab"){V=1-V}Q.top=G(V*Z)+"px"}if(U!==N){if(Y==="lab"){X=(R[S[0]]-E.inputValues[S[0]][0])/I.abs_max[S[0]];W=(R[S[1]]-E.inputValues[S[1]][0])/I.abs_max[S[1]]}else{X=R[S[0]];W=1-R[S[1]]}T.top=G(W*Z)+"px";T.left=G(X*O)+"px"}if(!I.draw_chart(U)||!I.draw_slider(U)){return false}else{return true}};this.ev_canvas=function(S){S.preventDefault();if(S.type==="mousedown"&&!I.ev_canvas_mode){I.ev_canvas_mode=true;K.addEventListener("mouseup",I.ev_canvas,false)}if(!I.ev_canvas_mode){return false}if(S.type==="mouseup"){I.ev_canvas_mode=false;K.removeEventListener("mouseup",I.ev_canvas,false)}var N=I.elems;if(S.target===N.controls){var U,T,O=I.context2d.canvas.width,V=I.context2d.canvas.height;if(S.layerX||S.layerX===0){U=S.layerX*H;T=S.layerY*H}else{if(S.offsetX||S.offsetX===0){U=S.offsetX*H;T=S.offsetY*H}}if(U>=0&&U<=I.chartWidth){mode="chart"}else{if(U>=I.sliderX&&U<=O){mode="slider"}}}else{if(S.target===N.chartDot){mode="chart"}else{if(S.target===N.slider){mode="slider"}}}if(mode&&I.ev_canvas_mode===true){I.ev_canvas_mode=mode}if(!mode||I.ev_canvas_mode!==mode||S.target!==N.controls){return false}var P=I.color,R=U/I.chartWidth,Q=T/V;if(mode==="slider"){if(I.ckey_active==="hue"){P[I.ckey_active]=Q}else{if(I.ckey_active_group==="lab"){P[I.ckey_active]=I.abs_max[I.ckey_active]*Q+E.inputValues[I.ckey_active][0]}else{P[I.ckey_active]=1-Q}}return I.update_color(I.ckey_active)}else{if(mode==="chart"){if(R>1){return false}if(I.ckey_active_group==="lab"){R=I.abs_max[I.ckey_adjoint[0]]*R+E.inputValues[I.ckey_adjoint[0]][0];Q=I.abs_max[I.ckey_adjoint[1]]*Q+E.inputValues[I.ckey_adjoint[1]][0]}else{Q=1-Q}P[I.ckey_adjoint[0]]=R;P[I.ckey_adjoint[1]]=Q;return I.update_color(I.ckey_active_group)}}return false};this.draw_chart=function(P){var Q=I.context2d,O,b,S,c;if(P===I.ckey_adjoint[0]||P===I.ckey_adjoint[1]||(I.ev_canvas_mode==="chart"&&P===I.ckey_active_group)){return true}var W=I.chartWidth,e=I.chartHeight;Q.clearRect(0,0,W,e);if(I.ckey_active==="sat"){if(I.color.sat>0){O=Q.createLinearGradient(0,0,W,0);for(c=0;c<=6;c++){b="rgb("+L[c][0]+", "+L[c][1]+", "+L[c][2]+")";O.addColorStop(c*1/6,b)}Q.fillStyle=O;Q.fillRect(0,0,W,e);O=Q.createLinearGradient(0,0,0,e);O.addColorStop(0,"rgba(0, 0, 0, 0)");O.addColorStop(1,"rgba(0, 0, 0, 1)");Q.fillStyle=O;Q.fillRect(0,0,W,e)}if(I.color.sat<1){S=1-I.color.sat;O=Q.createLinearGradient(0,0,0,e);O.addColorStop(0,"rgba(255, 255, 255, "+S+")");O.addColorStop(1,"rgba( 0, 0, 0, "+S+")");Q.fillStyle=O;Q.fillRect(0,0,W,e)}}else{if(I.ckey_active==="val"){if(I.color.val>0){O=Q.createLinearGradient(0,0,W,0);for(c=0;c<=6;c++){b="rgb("+L[c][0]+", "+L[c][1]+", "+L[c][2]+")";O.addColorStop(c*1/6,b)}Q.fillStyle=O;Q.fillRect(0,0,W,e);O=Q.createLinearGradient(0,0,0,e);O.addColorStop(0,"rgba(255, 255, 255, 0)");O.addColorStop(1,"rgba(255, 255, 255, 1)");Q.fillStyle=O;Q.fillRect(0,0,W,e)}if(I.color.val<1){Q.fillStyle="rgba(0, 0, 0, "+(1-I.color.val)+")";Q.fillRect(0,0,W,e)}}else{if(I.ckey_active==="hue"){if(I.color.sat===1&&I.color.val===1){b=[I.color.red,I.color.green,I.color.blue]}else{b=I.hsv2rgb(true,[I.color.hue,1,1])}for(c=0;c<3;c++){b[c]=G(b[c]*255)}Q.fillStyle="rgb("+b[0]+", "+b[1]+", "+b[2]+")";Q.fillRect(0,0,W,e);O=Q.createLinearGradient(0,0,W,0);O.addColorStop(0,"rgba(255, 255, 255, 1)");O.addColorStop(1,"rgba(255, 255, 255, 0)");Q.fillStyle=O;Q.fillRect(0,0,W,e);O=Q.createLinearGradient(0,0,0,e);O.addColorStop(0,"rgba(0, 0, 0, 0)");O.addColorStop(1,"rgba(0, 0, 0, 1)");Q.fillStyle=O;Q.fillRect(0,0,W,e)}else{if(I.ckey_active_group==="rgb"){var f,d;b={red:0,green:0,blue:0};b[I.ckey_active]=G(I.color[I.ckey_active]*255);f={red:0,green:0,blue:0};f[I.ckey_adjoint[1]]=255;d={red:0,green:0,blue:0};d[I.ckey_adjoint[0]]=255;Q.fillStyle="rgb("+b.red+","+b.green+","+b.blue+")";Q.fillRect(0,0,W,e);var V=Q.globalCompositeOperation;Q.globalCompositeOperation="lighter";O=Q.createLinearGradient(0,0,0,e);O.addColorStop(0,"rgba("+f.red+","+f.green+","+f.blue+", 1)");O.addColorStop(1,"rgba("+f.red+","+f.green+","+f.blue+", 0)");Q.fillStyle=O;Q.fillRect(0,0,W,e);O=Q.createLinearGradient(0,0,W,0);O.addColorStop(0,"rgba("+d.red+","+d.green+","+d.blue+", 0)");O.addColorStop(1,"rgba("+d.red+","+d.green+","+d.blue+", 1)");Q.fillStyle=O;Q.fillRect(0,0,W,e);Q.globalCompositeOperation=V}else{if(I.ckey_active_group==="lab"){var g=false;if(Q.createImageData){g=Q.createImageData(W,e)}else{if(Q.getImageData){g=Q.getImageData(0,0,W,e)}else{g={width:W,height:e,data:new Array(W*e*4)}}}var R=g.data,Y=g.data.length-1,c=-1,X=0,a,Z,j=[],N=[],U,T;U=I.ckey_adjoint[0];T=I.ckey_adjoint[1];b={cie_l:I.color.cie_l,cie_a:I.color.cie_a,cie_b:I.color.cie_b};a=I.abs_max[U]/W;Z=I.abs_max[T]/e;b[U]=E.inputValues[U][0];b[T]=E.inputValues[T][0];while(c1){Q=true}if(N.currentPosE.zIndex_){E.zIndex_=f}G.container.className+=" "+Q.classPrefix+"floatingPanel "+Q.classPrefix+"floatingPanel_"+G.id;d.className+=" "+Q.classPrefix+"floatingPanel_content";G.content=d;Z.className+=" "+Q.classPrefix+"floatingPanel_title";Z.replaceChild(X.createTextNode(Y.floatingPanels[G.id]),Z.firstChild);Z.addEventListener("mousedown",A,false);if(G.container.getAttribute("data-pwPanelHide")==="true"){G.hide()}else{G.state=G.STATE_VISIBLE}var a=G.container.parentNode,e=null;while(!e&&a){if(a.nodeName.toLowerCase()==="html"){e=a;break}b=J.getComputedStyle(a,null);if(b&&(b.overflow==="scroll"||b.overflow==="auto")){e=a}else{a=a.parentNode}}G.viewport=e;M=X.createElement("a");M.href="#";M.title=Y.floatingPanelMinimize;M.className=Q.classPrefix+"floatingPanel_minimize";M.addEventListener("click",B,false);M.appendChild(X.createTextNode(M.title));G.container.insertBefore(M,d);R=X.createElement("a");R.href="#";R.title=Y.floatingPanelClose;R.className=Q.classPrefix+"floatingPanel_close";R.addEventListener("click",U,false);R.appendChild(X.createTextNode(R.title));G.container.insertBefore(R,d);if(G.container.getAttribute("data-pwPanelResizable")==="true"){var c=X.createElement("div");c.className=Q.classPrefix+"floatingPanel_resizer";G.container.appendChild(c);G.resizer=new pwlib.guiResizer(Q,c,G.container)}}function B(Z){Z.preventDefault();this.focus();var a=" "+Q.classPrefix+"floatingPanel_minimized";if(G.state===G.STATE_MINIMIZED){G.state=G.STATE_VISIBLE;this.title=Y.floatingPanelMinimize;this.className=Q.classPrefix+"floatingPanel_minimize";this.replaceChild(X.createTextNode(this.title),this.firstChild);if(G.container.className.indexOf(a)!==-1){G.container.className=G.container.className.replace(a,"")}}else{if(G.state===G.STATE_VISIBLE){G.state=G.STATE_MINIMIZED;this.title=Y.floatingPanelRestore;this.className=Q.classPrefix+"floatingPanel_restore";this.replaceChild(X.createTextNode(this.title),this.firstChild);if(G.container.className.indexOf(a)===-1){G.container.className+=a}}}G.events.dispatch(new V.guiFloatingPanelStateChange(G.state));G.bringOnTop()}function U(Z){Z.preventDefault();G.hide();T.focus()}function A(a){G.state=G.STATE_DRAGGING;P=a.clientX;O=a.clientY;var Z=J.getComputedStyle(G.container,null);K=parseInt(Z.top);L=parseInt(Z.left);if(G.viewport){H=G.viewport.scrollLeft;W=G.viewport.scrollTop}G.bringOnTop();X.addEventListener("mousemove",I,false);X.addEventListener("mouseup",F,false);G.events.dispatch(new V.guiFloatingPanelStateChange(G.state));if(a.preventDefault){a.preventDefault()}}function I(a){var Z=L+a.clientX-P,b=K+a.clientY-O;if(G.viewport){if(G.viewport.scrollLeft!==H){Z+=G.viewport.scrollLeft-H}if(G.viewport.scrollTop!==W){b+=G.viewport.scrollTop-W}}C.left=Z+"px";C.top=b+"px"}function F(Z){if(G.container.className.indexOf(" "+Q.classPrefix+"floatingPanel_minimized")!==-1){G.state=G.STATE_MINIMIZED}else{G.state=G.STATE_VISIBLE}X.removeEventListener("mousemove",I,false);X.removeEventListener("mouseup",F,false);T.focus();G.events.dispatch(new V.guiFloatingPanelStateChange(G.state))}this.bringOnTop=function(){E.zIndex_+=D;C.zIndex=E.zIndex_};this.hide=function(){C.display="none";G.state=G.STATE_HIDDEN;G.events.dispatch(new V.guiFloatingPanelStateChange(G.state))};this.show=function(){if(G.state===G.STATE_VISIBLE){return }C.display="block";G.state=G.STATE_VISIBLE;var Z=" "+Q.classPrefix+"floatingPanel_minimized";if(G.container.className.indexOf(Z)!==-1){G.container.className=G.container.className.replace(Z,"");M.className=Q.classPrefix+"floatingPanel_minimize";M.title=Y.floatingPanelMinimize;M.replaceChild(X.createTextNode(M.title),M.firstChild)}G.events.dispatch(new V.guiFloatingPanelStateChange(G.state));G.bringOnTop()};this.toggle=function(){if(G.state===G.STATE_VISIBLE||G.state===G.STATE_MINIMIZED){G.hide()}else{G.show()}};S()};pwlib.appEvent.guiFloatingPanelStateChange=function(A){this.STATE_HIDDEN=0;this.STATE_VISIBLE=1;this.STATE_MINIMIZED=3;this.STATE_DRAGGING=4;this.state=A;pwlib.appEvent.call(this,"guiFloatingPanelStateChange")};pwlib.guiResizer=function(O,J,K){var F=this,B=K.style,R=O.app.doc,D=pwlib.appEvent.guiResizeEnd,L=pwlib.appEvent.guiResizeStart,I=O.app.win;this.events=null;this.resizeHandle=J;this.container=K;this.viewport=null;this.resizing=false;var N=0,M=0;var S=0,C=0;var G=0,Q=0;function P(){F.events=new pwlib.appEvents(F);J.addEventListener("mousedown",A,false);var U,T=F.container.parentNode,V=null;while(!V&&T){if(T.nodeName.toLowerCase()==="html"){V=T;break}U=I.getComputedStyle(T,null);if(U&&(U.overflow==="scroll"||U.overflow==="auto")){V=T}else{T=T.parentNode}}F.viewport=V}function A(V){N=V.clientX;M=V.clientY;var T=I.getComputedStyle(F.container,null);S=parseInt(T.width);C=parseInt(T.height);var U=F.events.dispatch(new L(N,M,S,C));if(U){return }if(F.viewport){G=F.viewport.scrollLeft;Q=F.viewport.scrollTop}F.resizing=true;R.addEventListener("mousemove",H,false);R.addEventListener("mouseup",E,false);if(V.preventDefault){V.preventDefault()}if(V.stopPropagation){V.stopPropagation()}}function H(V){var T=S+V.clientX-N,U=C+V.clientY-M;if(F.viewport){if(F.viewport.scrollLeft!==G){T+=F.viewport.scrollLeft-G}if(F.viewport.scrollTop!==Q){U+=F.viewport.scrollTop-Q}}B.width=T+"px";B.height=U+"px"}function E(U){var T=F.events.dispatch(new D(U.clientX,U.clientY,parseInt(B.width),parseInt(B.height)));if(T){return }F.resizing=false;R.removeEventListener("mousemove",H,false);R.removeEventListener("mouseup",E,false)}P()};pwlib.appEvent.guiResizeStart=function(B,D,C,A){this.x=B;this.y=D;this.width=C;this.height=A;pwlib.appEvent.call(this,"guiResizeStart",true)};pwlib.appEvent.guiResizeEnd=function(B,D,C,A){this.x=B;this.y=D;this.width=C;this.height=A;pwlib.appEvent.call(this,"guiResizeEnd",true)};pwlib.guiTabPanel=function(B,A){var E=this,D=pwlib.appEvent,G=B.app.doc,C=B.app.lang;this.events=null;this.id=null;this.tabs={};this.tabButtons=null;this.container=A;this.tabId=null;var H=null;function I(){E.events=new pwlib.appEvents(E);E.id=E.container.getAttribute("data-pwTabPanel");E.container.className+=" "+B.classPrefix+"tabPanel "+B.classPrefix+"tabPanel_"+E.id;var L=G.createElement("ul"),P=null,O=E.container.getAttribute("data-pwTabDefault")||null,R=E.container.childNodes,Q=Node.ELEMENT_NODE,K=null,J=null,N=null;L.className=B.classPrefix+"tabsList";for(var M=0;K=R[M];M++){if(K.nodeType!==Q){continue}J=K.getAttribute("data-pwTab");if(!J){continue}K.className+=" "+B.classPrefix+"tab "+B.classPrefix+E.id+"_"+J;P=G.createElement("li");P._pwTab=J;N=G.createElement("a");N.href="#";N.addEventListener("click",F,false);if(E.id in C.tabs){N.title=C.tabs[E.id][J+"Title"]||C.tabs[E.id][J];N.appendChild(G.createTextNode(C.tabs[E.id][J]))}if((O&&J===O)||(!O&&!E.tabId)){E.tabId=J;P.className=B.classPrefix+"tabActive"}else{H=J;K.style.display="none"}if(K.getAttribute("data-pwTabHide")==="true"){P.style.display="none"}E.tabs[J]={container:K,button:P};P.appendChild(N);L.appendChild(P)}E.tabButtons=L;E.container.appendChild(L)}function F(J){J.preventDefault();E.tabActivate(this.parentNode._pwTab)}this.tabActivate=function(J){if(!J||!(J in this.tabs)){return false}else{if(J===this.tabId){return true}}var M=new D.guiTabActivate(J,this.tabId),L=this.events.dispatch(M),K=null,N=null;if(L){return false}if(this.tabId in this.tabs){K=this.tabs[this.tabId].container;K.style.display="none";N=this.tabs[this.tabId].button;N.className="";H=this.tabId}K=this.tabs[J].container;K.style.display="";N=this.tabs[J].button;N.className=B.classPrefix+"tabActive";N.style.display="";N.firstChild.focus();this.tabId=J;return true};this.tabHide=function(J){if(!(J in this.tabs)){return false}if(this.tabId===J){this.tabActivate(H)}this.tabs[J].button.style.display="none";return true};this.tabShow=function(J){if(!(J in this.tabs)){return false}this.tabs[J].button.style.display="";return true};I()};pwlib.appEvent.guiTabActivate=function(A,B){this.tabId=A;this.prevTabId=B;pwlib.appEvent.call(this,"guiTabActivate",true)};pwlib.guiColorInput=function(A,J){var I=this,G=null,C=A.app.config,K=A.app.doc,F=Math.round,B=A.app.lang;this.id=null;this.input=J;this.configProperty=null;this.configGroup=null;this.configGroupRef=null;this.color={red:0,green:0,blue:0,alpha:0};function L(){var M=I.input.getAttribute("data-pwColorInput"),X=M.replace(".","_"),S=M.split("."),T=S.pop(),W=S.join("."),U=C,N=B.inputs,V=I.input.parentNode,R=K.createElement("a"),P;for(var Q=0,O=S.length;Q

PaintWeb

  • Undo
  • Redo
  •  
  • Clear image
  • Save image
  • Insert image
  •  
  • Cut selection
  • Copy selection
  • Clipboard paste
  •  
  • Color picker
  •  
  • Selection
  • Hand
  •  
  • Rectangle
  • Ellipse
  • Polygon
  • Line
  • B\u00e9zier curve
  • Text
  • Pencil
  •  
  • Eraser

Fill  

Stroke  

Line cap

Butt
Square
Round

Line join

Miter
Round
Bevel

Shape type

Both
Fill
Stroke

Cut selection

Copy selection

Clipboard paste

Crop selection

Delete selection

Fill selection

Bold
Italic

Text alignment

Left
Center
Right

Color  

About

Resize the image Canvas

WxH

Status

Color mixer

  1.   Active
  2.   Old
  1. Close
  2. Cancel
  3. Save color
  4. Pick color
Your browser does not support Canvas.

About

The project is currently undergoing heavy development for the purpose of integrating it into Moodle.

For user and developer documentation please check out the project site.

';function PaintWeb(win,doc){var _self=this;if(!win){win=window}if(!doc){doc=document}this.version=0.9;this.build=20090724;this.config={showErrors:true};this.lang={noComputedStyle:"Error: window.getComputedStyle is not available.",noXMLHttpRequest:"Error: window.XMLHttpRequest is not available.",noCanvasSupport:"Error: Your browser does not support Canvas.",guiPlaceholderWrong:"Error: The config.guiPlaceholder property must reference a DOM element!",initHandlerMustBeFunction:"The first argument must be a function.",noConfigFile:"Error: You must point to a configuration file by setting the config.configFile property!",failedConfigLoad:"Error: Failed loading the configuration file.",failedLangLoad:"Error: Failed loading the language file."};this.buffer={canvas:null,context:null};this.layer={id:null,canvas:null,context:null};this.tool=null;this.elems={};this.mouse={x:0,y:0,buttonDown:false};this.extensions={};this.commands={};this.gui=null;this.doc=doc;this.win=win;this.image={width:0,height:0,zoom:1,canvasScale:1};this.resolution={elem:null,elemId:"paintweb_resInfo",cssText:"@media screen and (resolution:96dpi){#paintweb_resInfo{width:96px}}@media screen and (resolution:134dpi){#paintweb_resInfo{width:134px}}@media screen and (resolution:200dpi){#paintweb_resInfo{width:200px}}@media screen and (resolution:300dpi){#paintweb_resInfo{width:300px}}#paintweb_resInfo{display:block;height:100%;left:-3000px;position:fixed;top:0;visibility:hidden;z-index:-32}",dpiOptimal:96,dpiLocal:96,browserZoom:1,scale:-1};this.history={pos:0,states:[]};this.shadowSupported=true;this.shadowAllowed=true;this.clipboard=false;this.initialized=PaintWeb.INIT_NOT_STARTED;this.events=null;this.UID=0;this.stateProperties=["strokeStyle","fillStyle","globalAlpha","lineWidth","lineCap","lineJoin","miterLimit","shadowOffsetX","shadowOffsetY","shadowBlur","shadowColor","globalCompositeOperation","font","textAlign","textBaseline"];var kbListener_=null;var temp_={onInit:null,toolsLoadQueue:0,extensionsLoadQueue:0};var MathAbs=Math.abs,MathFloor=Math.floor,MathMax=Math.max,MathMin=Math.min,MathRound=Math.round,pwlib=null,appEvent=null,lang=this.lang;function preInit(){var d=new Date();if(_self.build===-1){var dateArr=[d.getFullYear(),d.getMonth()+1,d.getDate()];if(dateArr[1]<10){dateArr[1]="0"+dateArr[1]}if(dateArr[2]<10){dateArr[2]="0"+dateArr[2]}_self.build=dateArr.join("")}_self.UID=d.getMilliseconds()*MathRound(Math.random()*100);_self.elems.head=doc.getElementsByTagName("head")[0]||doc.body}this.init=function(handler){if(this.initialized===PaintWeb.INIT_DONE){return true}this.initialized=PaintWeb.INIT_STARTED;if(handler&&typeof handler!=="function"){throw new TypeError(lang.initHandlerMustBeFunction)}temp_.onInit=handler;if(!doc.createElement("canvas").getContext){this.initError(lang.noCanvasSupport);return false}if(!window.getComputedStyle){this.initError(lang.noComputedStyle);return false}if(!window.XMLHttpRequest){this.initError(lang.noXMLHttpRequest);return false}if(!this.config.configFile){this.initError(lang.noConfigFile);return false}if(typeof this.config.guiPlaceholder!=="object"||this.config.guiPlaceholder.nodeType!==Node.ELEMENT_NODE){this.initError(lang.guiPlaceholderWrong);return false}if(typeof this.config.imageLoad!=="object"||this.config.imageLoad.nodeType!==Node.ELEMENT_NODE){this.config.imageLoad=null}if(!window.JSON){this.scriptLoad(PaintWeb.baseFolder+"includes/json2.js",this.jsonlibReady)}else{this.jsonlibReady()}return true};this.jsonlibReady=function(){if(window.pwlib){_self.pwlibReady()}else{_self.scriptLoad(PaintWeb.baseFolder+"includes/lib.js",_self.pwlibReady)}};this.pwlibReady=function(){pwlib=window.pwlib;appEvent=pwlib.appEvent;_self.events=new pwlib.appEvents(_self);if(typeof temp_.onInit==="function"){_self.events.add("appInit",temp_.onInit);delete temp_.onInit}_self.configLoad()};this.initError=function(msg){switch(this.initialized){case PaintWeb.INIT_ERROR:case PaintWeb.INIT_DONE:case PaintWeb.INIT_NOT_STARTED:return }this.initialized=PaintWeb.INIT_ERROR;var ev=null;if(this.events&&"dispatch" in this.events&&appEvent&&"appInit" in appEvent){ev=new appEvent.appInit(this.initialized,msg);this.events.dispatch(ev)}else{if(typeof temp_.onInit==="function"){ev={type:"appInit",state:this.initialized,errorMessage:msg};temp_.onInit.call(this,ev)}}if(this.config.showErrors){alert(msg)}else{if(window.console&&console.log){console.log(msg)}}};this.configLoad=function(){pwlib.xhrLoad(PaintWeb.baseFolder+this.config.configFile,this.configReady)};this.configReady=function(xhr){if(!xhr||xhr.readyState!==4){return }if((xhr.status!==304&&xhr.status!==200)||!xhr.responseText){_self.initError(lang.failedConfigLoad);return }var config=pwlib.jsonParse(xhr.responseText);pwlib.extend(_self.config,config);_self.langLoad()};this.langLoad=function(){var id=this.config.lang,file=PaintWeb.baseFolder;if(!(id in this.config.languages)){id=this.config.lang="en"}if("file" in this.config.languages[id]){file+=this.config.languages[id].file}else{file+=this.config.langFolder+"/"+id+".json"}pwlib.xhrLoad(file,this.langReady)};this.langReady=function(xhr){if(!xhr||xhr.readyState!==4){return }if((xhr.status!==304&&xhr.status!==200)||!xhr.responseText){_self.initError(lang.failedLangLoad);return }pwlib.extend(_self.lang,pwlib.jsonParse(xhr.responseText));if(_self.initCanvas()&&_self.initContext()){_self.guiLoad()}else{_self.initError(lang.errorInitCanvas)}};this.initCommands=function(){if(this.commandRegister("historyUndo",this.historyUndo)&&this.commandRegister("historyRedo",this.historyRedo)&&this.commandRegister("selectAll",this.selectAll)&&this.commandRegister("selectionCut",this.selectionCut)&&this.commandRegister("selectionCopy",this.selectionCopy)&&this.commandRegister("clipboardPaste",this.clipboardPaste)&&this.commandRegister("imageSave",this.imageSave)&&this.commandRegister("imageClear",this.imageClear)&&this.commandRegister("swapFillStroke",this.swapFillStroke)&&this.commandRegister("imageZoomIn",this.imageZoomIn)&&this.commandRegister("imageZoomOut",this.imageZoomOut)&&this.commandRegister("imageZoomReset",this.imageZoomReset)){return true}else{this.initError(lang.errorInitCommands);return false}};this.guiLoad=function(){var cfg=this.config,gui=this.config.gui,base=PaintWeb.baseFolder+cfg.interfacesFolder+"/"+gui+"/",style=base+cfg.guiStyle,script=base+cfg.guiScript;this.styleLoad(gui+"style",style);if(pwlib.gui){this.guiScriptReady()}else{this.scriptLoad(script,this.guiScriptReady)}};this.guiScriptReady=function(){var cfg=_self.config,gui=_self.config.gui,base=cfg.interfacesFolder+"/"+gui+"/",markup=base+cfg.guiMarkup;_self.gui=new pwlib.gui(_self);if(markup in pwlib.fileCache){if(_self.gui.init(pwlib.fileCache[markup])){_self.initTools()}else{_self.initError(lang.errorInitGUI)}}else{pwlib.xhrLoad(PaintWeb.baseFolder+markup,_self.guiMarkupReady)}};this.guiMarkupReady=function(xhr){if(!xhr||xhr.readyState!==4){return }if((xhr.status!==304&&xhr.status!==200)||!xhr.responseXML){_self.initError(lang.failedMarkupLoad);return }if(_self.gui.init(xhr.responseXML)){_self.initTools()}else{_self.initError(lang.errorInitGUI)}};this.initCanvas=function(){var cfg=this.config,res=this.resolution,resInfo=doc.getElementById(res.elemId),layerCanvas=doc.createElement("canvas"),bufferCanvas=doc.createElement("canvas"),layerContext=layerCanvas.getContext("2d"),bufferContext=bufferCanvas.getContext("2d"),width=cfg.imageWidth,height=cfg.imageHeight,imageLoad=cfg.imageLoad;if(!resInfo){var style=doc.createElement("style");style.type="text/css";style.appendChild(doc.createTextNode(res.cssText));_self.elems.head.appendChild(style);resInfo=doc.createElement("div");resInfo.id=res.elemId;doc.body.appendChild(resInfo)}if(!resInfo){this.initError(lang.errorInitCanvas);return false}if(!layerCanvas||!bufferCanvas||!layerContext||!bufferContext){this.initError(lang.noCanvasSupport);return false}if(!pwlib.isSameHost(imageLoad.src,win.location.host)){cfg.imageLoad=imageLoad=null;alert(lang.imageLoadDifferentHost)}if(imageLoad){width=parseInt(imageLoad.width);height=parseInt(imageLoad.height)}res.elem=resInfo;this.image.width=layerCanvas.width=bufferCanvas.width=width;this.image.height=layerCanvas.height=bufferCanvas.height=height;this.layer.canvas=layerCanvas;this.layer.context=layerContext;this.buffer.canvas=bufferCanvas;this.buffer.context=bufferContext;if(imageLoad){layerContext.drawImage(imageLoad,0,0)}var events=["dblclick","click","mousedown","mouseup","mousemove","contextmenu"],n=events.length;for(var i=0;imax){val=max}else{if(!isNaN(min)&&valconfig.imageZoomMax){level=config.imageZoomMax}else{if(level=image.width||cropY>=image.height){return false}var cancel=this.events.dispatch(new appEvent.imageCrop(cropX,cropY,cropWidth,cropHeight));if(cancel){return false}if(cropWidth>this.config.imageWidthMax){cropWidth=this.config.imageWidthMax}if(cropHeight>this.config.imageHeightMax){cropHeight=this.config.imageHeightMax}if(cropX===0&&cropY===0&&image.width===cropWidth&&image.height===cropHeight){return true}var scaledWidth=cropWidth*image.canvasScale,scaledHeight=cropHeight*image.canvasScale;bufferCanvas.style.width=layerCanvas.style.width=scaledWidth+"px";bufferCanvas.style.height=layerCanvas.style.height=scaledHeight+"px";var state=this.stateSave(layerContext),dataWidth=MathMin(image.width,cropWidth),dataHeight=MathMin(image.height,cropHeight),sumX=cropX+dataWidth,sumY=cropY+dataHeight;if(sumX>image.width){dataWidth-=sumX-image.width}if(sumY>image.height){dataHeight-=sumY-image.height}var idata=null;if(layerContext.getImageData){try{idata=layerContext.getImageData(cropX,cropY,dataWidth,dataHeight)}catch(err){return false}}layerCanvas.width=cropWidth;layerCanvas.height=cropHeight;if(idata&&layerContext.putImageData){layerContext.putImageData(idata,0,0)}this.stateRestore(layerContext,state);state=this.stateSave(bufferContext);idata=null;if(bufferContext.getImageData){try{idata=bufferContext.getImageData(cropX,cropY,dataWidth,dataHeight)}catch(err){}}bufferCanvas.width=cropWidth;bufferCanvas.height=cropHeight;if(idata&&bufferContext.putImageData){bufferContext.putImageData(idata,0,0)}this.stateRestore(bufferContext,state);image.width=cropWidth;image.height=cropHeight;this.events.dispatch(new appEvent.imageSizeChange(cropWidth,cropHeight));this.events.dispatch(new appEvent.canvasSizeChange(scaledWidth,scaledHeight,image.canvasScale));return true};this.stateSave=function(context){if(!context||!context.canvas||!this.stateProperties){return false}var stateObj={},prop=null,n=this.stateProperties.length;for(var i=0;ithis.config.historyLimit){history.states.splice(0,history.states.length-this.config.historyLimit)}history.pos=history.states.length;this.events.dispatch(new appEvent.historyUpdate(history.pos,prevPos,history.pos));return true};this.historyGoto=function(pos){var layerContext=this.layer.context,image=this.image,history=this.history;if(!history.states.length||!layerContext.putImageData){return false}var cpos=history.pos;if(pos==="undo"){pos=cpos-1}else{if(pos==="redo"){pos=cpos+1}}if(pos===cpos||pos<1||pos>history.states.length){return false}var himg=history.states[pos-1];if(!himg){return false}var w=MathMin(image.width,himg.width),h=MathMin(image.height,himg.height);layerContext.clearRect(0,0,image.width,image.height);try{layerContext.putImageData(himg,0,0,0,0,w,h)}catch(err){var tmp=doc.createElement("canvas");tmp.width=himg.width;tmp.height=himg.height;var tmp2=tmp.getContext("2d");tmp2.putImageData(himg,0,0);layerContext.drawImage(tmp,0,0);delete tmp2,tmp}history.pos=pos;this.events.dispatch(new appEvent.historyUpdate(pos,cpos,history.states.length));return true};this.historyReset=function(){this.history.pos=0;this.history.states=[];this.events.dispatch(new appEvent.historyUpdate(0,0,0))};this.toolSnapXY=function(x,y){var diffx=MathAbs(_self.mouse.x-x),diffy=MathAbs(_self.mouse.y-y);if(diffx>diffy){_self.mouse.y=y}else{_self.mouse.x=x}};this.toolActivate=function(id,ev){if(!id||!(id in pwlib.tools)||typeof pwlib.tools[id]!=="function"){return false}var tool=pwlib.tools[id],prevId=this.tool?this.tool._id:null;if(prevId&&this.tool instanceof pwlib.tools[id]){return true}var cancel=this.events.dispatch(new appEvent.toolPreactivate(id,prevId));if(cancel){return false}var tool_obj=new tool(this,ev);if(!tool_obj){return false}if("preActivate" in tool_obj&&!tool_obj.preActivate(ev)){tool_obj=null;return false}if(this.tool&&"deactivate" in this.tool){this.tool.deactivate(ev)}this.tool=tool_obj;this.mouse.buttonDown=false;if("activate" in this.tool){this.tool.activate(ev)}this.events.dispatch(new appEvent.toolActivate(id,prevId));return true};this.toolRegister=function(id){if(typeof id!=="string"||!id){return false}var tool=pwlib.tools[id];if(typeof tool!=="function"){return false}tool.prototype._id=id;this.events.dispatch(new appEvent.toolRegister(id));if(!this.tool&&id===this.config.toolDefault){return this.toolActivate(id)}else{return true}};this.toolUnregister=function(id){if(typeof id!=="string"||!id||!(id in pwlib.tools)){return false}this.events.dispatch(new appEvent.toolUnregister(id));return true};this.extensionRegister=function(id){if(typeof id!=="string"||!id){return false}var func=pwlib.extensions[id];if(typeof func!=="function"){return false}func.prototype._id=id;var obj=new func(_self);if("extensionRegister" in obj&&!obj.extensionRegister()){return false}this.extensions[id]=obj;this.events.dispatch(new appEvent.extensionRegister(id));return true};this.extensionUnregister=function(id){if(typeof id!=="string"||!id||!(id in this.extensions)){return false}this.events.dispatch(new appEvent.extensionUnregister(id));if("extensionUnregister" in this.extensions[id]){this.extensions[id].extensionUnregister()}delete this.extensions[id];return true};this.commandRegister=function(id,func){if(typeof id!=="string"||!id||typeof func!=="function"||id in this.commands){return false}this.commands[id]=func;this.events.dispatch(new appEvent.commandRegister(id));return true};this.commandUnregister=function(id){if(typeof id!=="string"||!id||!(id in this.commands)){return false}this.events.dispatch(new appEvent.commandUnregister(id));delete this.commands[id];return true};this.scriptLoad=function(url,handler){if(!handler){var elem=doc.createElement("script");elem.type="text/javascript";elem.src=url;this.elems.head.appendChild(elem);return }var xhr=new XMLHttpRequest();xhr.onreadystatechange=function(){if(!xhr||xhr.readyState!==4){return }else{if((xhr.status!==304&&xhr.status!==200)||!xhr.responseText){handler(false,xhr)}else{try{eval.call(win,xhr.responseText)}catch(err){eval(xhr.responseText,win)}handler(true,xhr)}}xhr=null};xhr.open("GET",url);xhr.send("")};this.styleLoad=function(id,url,media,handler){id="paintweb_style_"+id;var elem=doc.getElementById(id);if(elem){return }if(!media){media="screen, projection"}elem=doc.createElement("link");if(handler){elem.addEventListener("load",handler,false)}elem.id=id;elem.rel="stylesheet";elem.type="text/css";elem.media=media;elem.href=url;this.elems.head.appendChild(elem)};this.historyUndo=function(){return _self.historyGoto("undo")};this.historyRedo=function(){return _self.historyGoto("redo")};this.imageLoad=function(importImage){if(!importImage||!importImage.width||!importImage.height||importImage.nodeType!==Node.ELEMENT_NODE||!pwlib.isSameHost(importImage.src,win.location.host)){return false}this.historyReset();var layerContext=this.layer.context,layerCanvas=this.layer.canvas,layerStyle=layerCanvas.style,bufferCanvas=this.buffer.canvas,bufferStyle=bufferCanvas.style,image=this.image,styleWidth=importImage.width*image.canvasScale,styleHeight=importImage.height*image.canvasScale,result=true;bufferCanvas.width=layerCanvas.width=importImage.width;bufferCanvas.height=layerCanvas.height=importImage.height;try{layerContext.drawImage(importImage,0,0)}catch(err){result=false;bufferCanvas.width=layerCanvas.width=image.width;bufferCanvas.height=layerCanvas.height=image.height}if(result){image.width=importImage.width;image.height=importImage.height;bufferStyle.width=layerStyle.width=styleWidth+"px";bufferStyle.height=layerStyle.height=styleHeight+"px";_self.config.imageLoad=importImage;this.events.dispatch(new appEvent.imageSizeChange(image.width,image.height));this.events.dispatch(new appEvent.canvasSizeChange(styleWidth,styleHeight,image.canvasScale))}this.historyAdd();return result};this.imageClear=function(ev){_self.layer.context.clearRect(0,0,_self.image.width,_self.image.height);_self.historyAdd()};this.imageSave=function(){var canvas=_self.layer.canvas,idata=null;if(!canvas.toDataURL){return false}try{idata=canvas.toDataURL()}catch(err){alert(lang.errorImageSave+"\n"+err);return false}if(!idata||idata.toLowerCase()==="data:"){return false}var img=_self.image,ev=new appEvent.imageSave(idata,img.width,img.height),cancel=_self.events.dispatch(ev);if(cancel){return true}var imgwin=_self.win.open();if(!imgwin){return false}imgwin.location=idata;idata=null;_self.events.dispatch(new appEvent.imageSaveResult(true));return true};this.swapFillStroke=function(){var fillStyle=_self.config.fillStyle,strokeStyle=_self.config.strokeStyle;_self.config.fillStyle=strokeStyle;_self.config.strokeStyle=fillStyle;var ev=new appEvent.configChange(strokeStyle,fillStyle,"fillStyle","",_self.config);_self.events.dispatch(ev);ev=new appEvent.configChange(fillStyle,strokeStyle,"strokeStyle","",_self.config);_self.events.dispatch(ev)};this.selectAll=function(ev){if(_self.toolActivate("selection",ev)){return _self.tool.selectAll(ev)}else{return false}};this.selectionCut=function(ev){if(!_self.tool||_self.tool._id!=="selection"){return false}else{return _self.tool.selectionCut(ev)}};this.selectionCopy=function(ev){if(!_self.tool||_self.tool._id!=="selection"){return false}else{return _self.tool.selectionCopy(ev)}};this.clipboardPaste=function(ev){if(!_self.clipboard||!_self.toolActivate("selection",ev)){return false}else{return _self.tool.clipboardPaste(ev)}};this.configChangeHandler=function(ev){if(ev.group==="shadow"&&_self.shadowSupported&&_self.shadowAllowed){var context=_self.layer.context,cfg=ev.groupRef;if(ev.config==="enable"){if(ev.value){context.shadowColor=cfg.shadowColor;context.shadowOffsetX=cfg.shadowOffsetX;context.shadowOffsetY=cfg.shadowOffsetY;context.shadowBlur=cfg.shadowBlur}else{context.shadowColor="rgba(0,0,0,0)";context.shadowOffsetX=0;context.shadowOffsetY=0;context.shadowBlur=0}return }if(!cfg.enable){return }switch(ev.config){case"shadowBlur":case"shadowOffsetX":case"shadowOffsetY":ev.value=parseInt(ev.value);case"shadowColor":context[ev.config]=ev.value}}else{if(ev.group==="line"){switch(ev.config){case"lineWidth":case"miterLimit":ev.value=parseInt(ev.value);case"lineJoin":case"lineCap":_self.buffer.context[ev.config]=ev.value}}else{if(ev.group==="text"){switch(ev.config){case"textAlign":case"textBaseline":_self.buffer.context[ev.config]=ev.value}}else{if(!ev.group){switch(ev.config){case"fillStyle":case"strokeStyle":_self.buffer.context[ev.config]=ev.value}}}}}};this.destroy=function(){this.events.dispatch(new appEvent.appDestroy());for(var cmd in this.commands){this.commandUnregister(cmd)}for(var ext in this.extensions){this.extensionUnregister(ext)}for(var tool in this.gui.tools){this.toolUnregister(tool)}this.gui.destroy();this.initialized=PaintWeb.INIT_NOT_STARTED};this.toString=function(){return"PaintWeb v"+this.version+" (build "+this.build+")"};preInit()}PaintWeb.INIT_NOT_STARTED=0;PaintWeb.INIT_STARTED=1;PaintWeb.INIT_DONE=2;PaintWeb.INIT_ERROR=-1;PaintWeb.baseFolder="";(function(){var A=document.getElementsByTagName("script"),E=A.length,D,C;for(var B=0;B. * * $URL: http://code.google.com/p/paintweb $ - * $Date: 2009-07-21 22:37:43 +0300 $ + * $Date: 2009-07-24 21:59:45 +0300 $ */ /** @@ -9408,13 +9408,18 @@ pwlib.extensions.moodle = function (app) { // Holds properties related to Moodle. var moodle = { + // Holds the URL of the image the user is saving. + imageURL: null, + // The class name for the element which holds the textarea buttons (toggle // on/off). textareaButtons: 'textareaicons', // The image save handler script on the server-side. The path is relative to - // the PaintWeb base folder. - imageSaveHandler: '../ext/moodle/imagesave.php' + // the PaintWeb base folder. If the value is set to '-' then the image src + // attribute is updated to hold the generated dataURL. + //imageSaveHandler: '../ext/moodle/imagesave.php' + imageSaveHandler: '-' }; /** @@ -9444,22 +9449,32 @@ pwlib.extensions.moodle = function (app) { * attempts to save an image, this extension handles the event by sending the * image data to the Moodle server, to perform the actual save operation. * + * @private * @param {pwlib.appEvent.imageSave} ev The application event object. */ this.imageSave = function (ev) { if (!ev.dataURL) { return; } + ev.preventDefault(); - var handlerURL = PaintWeb.baseFolder + moodle.imageSaveHandler, - imageURL = config.imageLoad.src, - send = 'url=' + encodeURIComponent(imageURL) + - '&dataURL=' + encodeURIComponent(ev.dataURL); + moodle.imageURL = config.imageLoad.src; + if (!moodle.imageURL || moodle.imageURL.substr(0, 5) === 'data:') { + moodle.imageURL = '-'; + } - pwlib.xhrLoad(handlerURL, imageSaveReady, 'POST', send); - }; + if (moodle.imageSaveHandler === '-') { + app.events.dispatch(new appEvent.imageSaveResult(true, moodle.imageURL, + ev.dataURL)); + } else { + var handlerURL = PaintWeb.baseFolder + moodle.imageSaveHandler, + send = 'url=' + encodeURIComponent(moodle.imageURL) + + '&dataURL=' + encodeURIComponent(ev.dataURL); + pwlib.xhrLoad(handlerURL, imageSaveReady, 'POST', send); + } + }; /** * The image save onreadystatechange event handler for the @@ -9495,7 +9510,7 @@ pwlib.extensions.moodle = function (app) { return; } - var result = {successful: false, url: config.imageLoad.src}; + var result = {successful: false, url: moodle.imageURL}; if ((xhr.status !== 304 && xhr.status !== 200) || !xhr.responseText) { alert(lang.xhrRequestFailed); @@ -9514,9 +9529,9 @@ pwlib.extensions.moodle = function (app) { } if (result.successful) { - if (result.url !== config.imageLoad.src) { + if (result.url !== moodle.imageURL) { alert(pwlib.strf(lang.urlMismatch, { - url: config.imageLoad.src, + url: moodle.imageURL, urlServer: result.url || 'null'})); } } else { @@ -9535,6 +9550,7 @@ pwlib.extensions.moodle = function (app) { * The guiShow application event handler. When the PaintWeb GUI * is shown, we must hide the textarea icons for the current textarea element, * inside a Moodle page. + * @private */ this.guiShow = function () { var pNode = config.guiPlaceholder.parentNode, @@ -9549,6 +9565,7 @@ pwlib.extensions.moodle = function (app) { * The guiHide application event handler. When the PaintWeb GUI * is hidden, we must show again the textarea icons for the current textarea * element, inside a Moodle page. + * @private */ this.guiHide = function () { var pNode = config.guiPlaceholder.parentNode, @@ -9558,7 +9575,6 @@ pwlib.extensions.moodle = function (app) { elem.style.display = ''; } }; - }; // vim:set spell spl=en fo=wan1croqlt tw=80 ts=2 sw=2 sts=2 sta et ai cin fenc=utf-8 ff=unix: diff --git a/lib/paintweb/ext/moodle/gen_moodlelang.php b/lib/paintweb/ext/moodle/gen_moodlelang.php index 767afd55ea9..68ee9b540dd 100644 --- a/lib/paintweb/ext/moodle/gen_moodlelang.php +++ b/lib/paintweb/ext/moodle/gen_moodlelang.php @@ -18,7 +18,7 @@ * along with PaintWeb. If not, see . * * $URL: http://code.google.com/p/paintweb $ - * $Date: 2009-07-22 13:05:53 +0300 $ + * $Date: 2009-07-24 19:55:28 +0300 $ */ // This script allows you to convert PaintWeb JSON language files into Moodle @@ -93,7 +93,7 @@ function convertFile ($file) { continue; } - $output = ""+L+"")}D.firstChild.innerHTML=str}}}function M(b){if(!G){return }if(b.successful&&T){T=false;A();return }T=false;if(D){if(b.successful){D.firstChild.innerHTML=Y.getLang("paintweb.statusImageSaved","Image save was succesful!")}else{D.firstChild.innerHTML=Y.getLang("paintweb.statusImageSaveFailed","Image save failed!")}setTimeout(F,O)}}function F(){if(!D||!G||!L){return }var b="";if(L==="dataURL"){b=Y.getLang("paintweb.statusEditingDataURL")}else{b=Y.getLang("paintweb.statusImageEditing","You are editing {file}.").replace("{file}",""+L+"")}D.firstChild.innerHTML=b}function E(){if(!I(G)){G=null;L=null;return }if(K){clearTimeout(K);K=null}L=G.src;if(L.substr(0,5)==="data:"){L="dataURL"}else{L=L.substr(L.lastIndexOf("/")+1)}if(C&&C.parentNode&&Y){C.title=Y.getLang("paintweb.overlayLoading","Loading PaintWeb...");C.replaceChild(document.createTextNode(C.title),C.firstChild)}if(S){S.imageLoad(G);N()}else{a()}}function N(){S.gui.show();Z.style.display="none";if(!D){return }F();var b=U.guiPlaceholder;if(!D.parentNode){b.parentNode.insertBefore(D,b)}}function A(){S.gui.hide();if(C&&Y){C.title=Y.getLang("paintweb.overlayButton","Edit");C.replaceChild(document.createTextNode(C.title),C.firstChild)}if(D&&D.parentNode){Z.parentNode.removeChild(D)}Z.style.display="";G=null;L=null;Y.focus();if(!K){K=setTimeout(B,W)}}function B(){if(S){S.destroy();var b=U.guiPlaceholder.parentNode;b.removeChild(U.guiPlaceholder);S=null;U=null;K=null}}function X(){if(G){return }Y=this;Z=this.getContainer();G=this.selection.getNode();E()}function I(f){if(!f){return false}var b=f.src;if(f.nodeName.toLowerCase()!=="img"||!b){return false}var e=b.indexOf(":"),d=b.substr(0,e+1).toLowerCase();if(d==="data:"){return true}if(d!=="http:"&&d!=="https:"){return false}var c=b.replace(/^https?:\/\//i,"");e=c.indexOf("/");if(e>-1){c=c.substr(0,e)}if(c!==window.location.host){return false}return true}function R(c){if(!c||!c.getDoc){return }var f=c.getDoc();if(!f||!f.getElementsByClassName){return }var b=f.getElementsByClassName(C.className),e;for(var d=0;d"+L+"")}D.firstChild.innerHTML=str}}}function M(c){if(!G){return }if(D){if(c.successful){D.firstChild.innerHTML=Z.getLang("paintweb.statusImageSaved","Image save was succesful!")}else{D.firstChild.innerHTML=Z.getLang("paintweb.statusImageSaveFailed","Image save failed!")}V=setTimeout(F,O)}if(c.successful){if(c.urlNew){Z.dom.setAttrib(G,"src",c.urlNew)}if(T){T=false;A()}}}function F(){if(!D||!G||!L){return }V=null;var c="";if(L==="dataURL"){c=Z.getLang("paintweb.statusEditingDataURL")}else{c=Z.getLang("paintweb.statusImageEditing","You are editing {file}.").replace("{file}",""+L+"")}D.firstChild.innerHTML=c}function E(){if(!I(G)){G=null;L=null;return }if(K){clearTimeout(K);K=null}L=Z.dom.getAttrib(G,"src");if(L.substr(0,5)==="data:"){L="dataURL"}else{L=L.substr(L.lastIndexOf("/")+1)}if(C&&C.parentNode&&Z){C.title=Z.getLang("paintweb.overlayLoading","Loading PaintWeb...");C.replaceChild(document.createTextNode(C.title),C.firstChild)}if(S){S.imageLoad(G);N()}else{b()}}function N(){S.gui.show();a.style.display="none";if(!D){return }F();var c=U.guiPlaceholder;if(!D.parentNode){c.parentNode.insertBefore(D,c)}}function A(){S.gui.hide();if(C&&Z){C.title=Z.getLang("paintweb.overlayButton","Edit");C.replaceChild(document.createTextNode(C.title),C.firstChild)}if(D&&D.parentNode){a.parentNode.removeChild(D)}a.style.display="";G=null;L=null;Z.focus();if(!K){K=setTimeout(B,X)}}function B(){if(S){S.destroy();var c=U.guiPlaceholder.parentNode;c.removeChild(U.guiPlaceholder);S=null;U=null;K=null}}function Y(){if(G){return }Z=this;a=this.getContainer();G=this.selection.getNode();E()}function I(g){if(!g){return false}var c=g.src;if(g.nodeName.toLowerCase()!=="img"||!c){return false}var f=c.indexOf(":"),e=c.substr(0,f+1).toLowerCase();if(e==="data:"){return true}if(e!=="http:"&&e!=="https:"){return false}var d=c.replace(/^https?:\/\//i,"");f=d.indexOf("/");if(f>-1){d=d.substr(0,f)}if(d!==window.location.host){return false}return true}function R(d){if(!d||!d.getDoc){return }var g=d.getDoc();if(!g||!g.getElementsByClassName){return }var c=g.getElementsByClassName(C.className),f;for(var e=0;e. * * $URL: http://code.google.com/p/paintweb $ - * $Date: 2009-07-21 23:00:39 +0300 $ + * $Date: 2009-07-24 21:53:23 +0300 $ */ /** @@ -31,6 +31,7 @@ var overlayButton = null, paintwebInstance = null, pluginBar = null, pluginBarDelay = 5000, // 5 seconds + pluginBarTimeout = null, pwDestroyDelay = 30000, // 30 seconds pwDestroyTimer = null, pwSaveReturn = false, @@ -161,12 +162,16 @@ function pluginCancelButton (ev) { */ function paintwebSave (ev) { if (paintwebConfig.tinymce.imageSaveDataURL) { - targetImage.src = ev.dataURL; - targetFile = 'dataURL'; ev.preventDefault(); - paintwebInstance.events.dispatch(new pwlib.appEvent.imageSaveResult(true)); - } else if (pluginBar && targetEditor) { + var url = targetFile === 'dataURL' ? '-' + : targetEditor.dom.getAttrib(targetImage, + 'src'); + + paintwebInstance.events.dispatch(new pwlib.appEvent.imageSaveResult(true, + url, ev.dataURL)); + + } else if (pluginBar && targetEditor && !pluginBarTimeout) { if (targetFile === 'dataURL') { str = targetEditor.getLang('paintweb.statusSavingDataURL', 'Saving image data URL...'); @@ -190,14 +195,6 @@ function paintwebSaveResult (ev) { return; } - if (ev.successful && pwSaveReturn) { - pwSaveReturn = false; - paintwebHide(); - return; - } - - pwSaveReturn = false; - if (pluginBar) { if (ev.successful) { pluginBar.firstChild.innerHTML @@ -208,7 +205,19 @@ function paintwebSaveResult (ev) { = targetEditor.getLang('paintweb.statusImageSaveFailed', 'Image save failed!'); } - setTimeout(pluginBarResetContent, pluginBarDelay); + + pluginBarTimeout = setTimeout(pluginBarResetContent, pluginBarDelay); + } + + if (ev.successful) { + if (ev.urlNew) { + targetEditor.dom.setAttrib(targetImage, 'src', ev.urlNew); + } + + if (pwSaveReturn) { + pwSaveReturn = false; + paintwebHide(); + } } }; @@ -220,6 +229,8 @@ function pluginBarResetContent () { return; } + pluginBarTimeout = null; + var str = ''; if (targetFile === 'dataURL') { @@ -248,7 +259,7 @@ function paintwebEditStart () { pwDestroyTimer = null; } - targetFile = targetImage.src; + targetFile = targetEditor.dom.getAttrib(targetImage, 'src'); if (targetFile.substr(0, 5) === 'data:') { targetFile = 'dataURL'; diff --git a/lib/paintweb/src/extensions/moodle.js b/lib/paintweb/src/extensions/moodle.js index bf92677e47d..7a28cf13717 100644 --- a/lib/paintweb/src/extensions/moodle.js +++ b/lib/paintweb/src/extensions/moodle.js @@ -17,7 +17,7 @@ * along with PaintWeb. If not, see . * * $URL: http://code.google.com/p/paintweb $ - * $Date: 2009-07-21 22:37:43 +0300 $ + * $Date: 2009-07-24 21:59:45 +0300 $ */ /** @@ -41,13 +41,18 @@ pwlib.extensions.moodle = function (app) { // Holds properties related to Moodle. var moodle = { + // Holds the URL of the image the user is saving. + imageURL: null, + // The class name for the element which holds the textarea buttons (toggle // on/off). textareaButtons: 'textareaicons', // The image save handler script on the server-side. The path is relative to - // the PaintWeb base folder. - imageSaveHandler: '../ext/moodle/imagesave.php' + // the PaintWeb base folder. If the value is set to '-' then the image src + // attribute is updated to hold the generated dataURL. + //imageSaveHandler: '../ext/moodle/imagesave.php' + imageSaveHandler: '-' }; /** @@ -77,22 +82,32 @@ pwlib.extensions.moodle = function (app) { * attempts to save an image, this extension handles the event by sending the * image data to the Moodle server, to perform the actual save operation. * + * @private * @param {pwlib.appEvent.imageSave} ev The application event object. */ this.imageSave = function (ev) { if (!ev.dataURL) { return; } + ev.preventDefault(); - var handlerURL = PaintWeb.baseFolder + moodle.imageSaveHandler, - imageURL = config.imageLoad.src, - send = 'url=' + encodeURIComponent(imageURL) + - '&dataURL=' + encodeURIComponent(ev.dataURL); + moodle.imageURL = config.imageLoad.src; + if (!moodle.imageURL || moodle.imageURL.substr(0, 5) === 'data:') { + moodle.imageURL = '-'; + } - pwlib.xhrLoad(handlerURL, imageSaveReady, 'POST', send); - }; + if (moodle.imageSaveHandler === '-') { + app.events.dispatch(new appEvent.imageSaveResult(true, moodle.imageURL, + ev.dataURL)); + } else { + var handlerURL = PaintWeb.baseFolder + moodle.imageSaveHandler, + send = 'url=' + encodeURIComponent(moodle.imageURL) + + '&dataURL=' + encodeURIComponent(ev.dataURL); + pwlib.xhrLoad(handlerURL, imageSaveReady, 'POST', send); + } + }; /** * The image save onreadystatechange event handler for the @@ -128,7 +143,7 @@ pwlib.extensions.moodle = function (app) { return; } - var result = {successful: false, url: config.imageLoad.src}; + var result = {successful: false, url: moodle.imageURL}; if ((xhr.status !== 304 && xhr.status !== 200) || !xhr.responseText) { alert(lang.xhrRequestFailed); @@ -147,9 +162,9 @@ pwlib.extensions.moodle = function (app) { } if (result.successful) { - if (result.url !== config.imageLoad.src) { + if (result.url !== moodle.imageURL) { alert(pwlib.strf(lang.urlMismatch, { - url: config.imageLoad.src, + url: moodle.imageURL, urlServer: result.url || 'null'})); } } else { @@ -168,6 +183,7 @@ pwlib.extensions.moodle = function (app) { * The guiShow application event handler. When the PaintWeb GUI * is shown, we must hide the textarea icons for the current textarea element, * inside a Moodle page. + * @private */ this.guiShow = function () { var pNode = config.guiPlaceholder.parentNode, @@ -182,6 +198,7 @@ pwlib.extensions.moodle = function (app) { * The guiHide application event handler. When the PaintWeb GUI * is hidden, we must show again the textarea icons for the current textarea * element, inside a Moodle page. + * @private */ this.guiHide = function () { var pNode = config.guiPlaceholder.parentNode, @@ -191,7 +208,6 @@ pwlib.extensions.moodle = function (app) { elem.style.display = ''; } }; - }; // vim:set spell spl=en fo=wan1croqlt tw=80 ts=2 sw=2 sts=2 sta et ai cin fenc=utf-8 ff=unix: -- 2.11.4.GIT