diff --git a/zoom/build/piskel-packaged-min.js b/zoom/build/piskel-packaged-min.js index 97a968ed..84724a7b 100644 --- a/zoom/build/piskel-packaged-min.js +++ b/zoom/build/piskel-packaged-min.js @@ -2,7 +2,7 @@ }})}),$.attrHooks.contenteditable={get:rb.get,set:function(a,b,c){""===b&&(b="false"),rb.set(a,b,c)}}),$.support.hrefNormalized||$.each(["href","src","width","height"],function(a,c){$.attrHooks[c]=$.extend($.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return null===d?b:d}})}),$.support.style||($.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),$.support.optSelected||($.propHooks.selected=$.extend($.propHooks.selected,{get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}})),$.support.enctype||($.propFix.enctype="encoding"),$.support.checkOn||$.each(["radio","checkbox"],function(){$.valHooks[this]={get:function(a){return null===a.getAttribute("value")?"on":a.value}}}),$.each(["radio","checkbox"],function(){$.valHooks[this]=$.extend($.valHooks[this],{set:function(a,b){return $.isArray(b)?a.checked=$.inArray($(a).val(),b)>=0:void 0}})});var Bb=/^(?:textarea|input|select)$/i,Cb=/^([^\.]*|)(?:\.(.+)|)$/,Db=/(?:^|\s)hover(\.\S+|)\b/,Eb=/^key/,Fb=/^(?:mouse|contextmenu)|click/,Gb=/^(?:focusinfocus|focusoutblur)$/,Hb=function(a){return $.event.special.hover?a:a.replace(Db,"mouseenter$1 mouseleave$1")};$.event={add:function(a,c,d,e,f){var g,h,i,j,k,l,m,n,o,p,q;if(3!==a.nodeType&&8!==a.nodeType&&c&&d&&(g=$._data(a))){for(d.handler&&(o=d,d=o.handler,f=o.selector),d.guid||(d.guid=$.guid++),i=g.events,i||(g.events=i={}),h=g.handle,h||(g.handle=h=function(a){return"undefined"==typeof $||a&&$.event.triggered===a.type?b:$.event.dispatch.apply(h.elem,arguments)},h.elem=a),c=$.trim(Hb(c)).split(" "),j=0;j=0&&(q=q.slice(0,-1),h=!0),q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),e&&!$.event.customEvent[q]||$.event.global[q]))if(c="object"==typeof c?c[$.expando]?c:new $.Event(q,c):new $.Event(q),c.type=q,c.isTrigger=!0,c.exclusive=h,c.namespace=r.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,l=q.indexOf(":")<0?"on"+q:"",e){if(c.result=b,c.target||(c.target=e),d=null!=d?$.makeArray(d):[],d.unshift(c),m=$.event.special[q]||{},!m.trigger||m.trigger.apply(e,d)!==!1){if(o=[[e,m.bindType||q]],!f&&!m.noBubble&&!$.isWindow(e)){for(p=m.delegateType||q,j=Gb.test(p+q)?e:e.parentNode,k=e;j;j=j.parentNode)o.push([j,p]),k=j;k===(e.ownerDocument||P)&&o.push([k.defaultView||k.parentWindow||a,p])}for(i=0;id;d++)l=n[d],m=l.selector,i[m]===b&&(i[m]=g.is(m)),i[m]&&k.push(l);k.length&&s.push({elem:f,matches:k})}for(n.length>o&&s.push({elem:this,matches:n.slice(o)}),d=0;d0?this.on(b,null,a,c):this.trigger(b)},Eb.test(b)&&($.event.fixHooks[b]=$.event.keyHooks),Fb.test(b)&&($.event.fixHooks[b]=$.event.mouseHooks)}),function(a,b){function c(a,b,c,d){for(var e=0,f=b.length;f>e;e++)fb(a,b[e],c,d)}function d(a,b,d,e,f,g){var h,i=gb.setFilters[b.toLowerCase()];return i||fb.error(b),(a||!(h=f))&&c(a||"*",e,h=[],f),h.length>0?i(h,d,g):[]}function e(a,e,f,g,h){for(var i,j,k,l,m,n,o,p,q=0,r=h.length,s=S.POS,t=new RegExp("^"+s.source+"(?!"+y+")","i"),u=function(){for(var a=1,c=arguments.length-2;c>a;a++)arguments[a]===b&&(i[a]=b)};r>q;q++){for(s.exec(""),a=h[q],l=[],k=0,m=g;i=s.exec(a);)p=s.lastIndex=i.index+i[0].length,p>k&&(o=a.slice(k,i.index),k=p,n=[e],I.test(o)&&(m&&(n=m),m=g),(j=O.test(o))&&(o=o.slice(0,-5).replace(I,"$&*")),i.length>1&&i[0].replace(t,u),m=d(o,i[1],i[2],n,m,j));m?(l=l.concat(m),(o=a.slice(k))&&")"!==o?I.test(o)?c(o,l,f,g):fb(o,e,f,g?g.concat(m):m):w.apply(f,l)):fb(a,e,f,g)}return 1===r?f:fb.uniqueSort(f)}function f(a,b,c){for(var d,e,f,g=[],h=0,i=K.exec(a),j=!i.pop()&&!i.pop(),k=j&&a.match(J)||[""],l=gb.preFilter,m=gb.filter,n=!c&&b!==p;null!=(e=k[h])&&j;h++)for(g.push(d=[]),n&&(e=" "+e);e;){j=!1,(i=I.exec(e))&&(e=e.slice(i[0].length),j=d.push({part:i.pop().replace(H," "),captures:i}));for(f in m)!(i=S[f].exec(e))||l[f]&&!(i=l[f](i,b,c))||(e=e.slice(i.shift().length),j=d.push({part:f,captures:i}));if(!j)break}return j||fb.error(a),g}function g(a,b,c){var d=b.dir,e=u++;return a||(a=function(a){return a===c}),b.first?function(b,c){for(;b=b[d];)if(1===b.nodeType)return a(b,c)&&b}:function(b,c){for(var f,g=e+"."+l,h=g+"."+k;b=b[d];)if(1===b.nodeType){if((f=b[x])===h)return b.sizset;if("string"==typeof f&&0===f.indexOf(g)){if(b.sizset)return b}else{if(b[x]=h,a(b,c))return b.sizset=!0,b;b.sizset=!1}}}}function h(a,b){return a?function(c,d){var e=b(c,d);return e&&a(e===!0?c:e,d)}:b}function i(a,b,c){for(var d,e,f=0;d=a[f];f++)gb.relative[d.part]?e=g(e,gb.relative[d.part],b):(d.captures.push(b,c),e=h(e,gb.filter[d.part].apply(null,d.captures)));return e}function j(a){return function(b,c){for(var d,e=0;d=a[e];e++)if(d(b,c))return!0;return!1}}var k,l,m,n,o,p=a.document,q=p.documentElement,r="undefined",s=!1,t=!0,u=0,v=[].slice,w=[].push,x=("sizcache"+Math.random()).replace(".",""),y="[\\x20\\t\\r\\n\\f]",z="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",A=z.replace("w","w#"),B="([*^$|!~]?=)",C="\\["+y+"*("+z+")"+y+"*(?:"+B+y+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+A+")|)|)"+y+"*\\]",D=":("+z+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|((?:[^,]|\\\\,|(?:,(?=[^\\[]*\\]))|(?:,(?=[^\\(]*\\))))*))\\)|)",E=":(nth|eq|gt|lt|first|last|even|odd)(?:\\((\\d*)\\)|)(?=[^-]|$)",F=y+"*([\\x20\\t\\r\\n\\f>+~])"+y+"*",G="(?=[^\\x20\\t\\r\\n\\f])(?:\\\\.|"+C+"|"+D.replace(2,7)+"|[^\\\\(),])+",H=new RegExp("^"+y+"+|((?:^|[^\\\\])(?:\\\\.)*)"+y+"+$","g"),I=new RegExp("^"+F),J=new RegExp(G+"?(?="+y+"*,|$)","g"),K=new RegExp("^(?:(?!,)(?:(?:^|,)"+y+"*"+G+")*?|"+y+"*(.*?))(\\)|$)"),L=new RegExp(G.slice(19,-6)+"\\x20\\t\\r\\n\\f>+~])+|"+F,"g"),M=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,N=/[\x20\t\r\n\f]*[+~]/,O=/:not\($/,P=/h\d/i,Q=/input|select|textarea|button/i,R=/\\(?!\\)/g,S={ID:new RegExp("^#("+z+")"),CLASS:new RegExp("^\\.("+z+")"),NAME:new RegExp("^\\[name=['\"]?("+z+")['\"]?\\]"),TAG:new RegExp("^("+z.replace("[-","[-\\*")+")"),ATTR:new RegExp("^"+C),PSEUDO:new RegExp("^"+D),CHILD:new RegExp("^:(only|nth|last|first)-child(?:\\("+y+"*(even|odd|(([+-]|)(\\d*)n|)"+y+"*(?:([+-]|)"+y+"*(\\d+)|))"+y+"*\\)|)","i"),POS:new RegExp(E,"ig"),needsContext:new RegExp("^"+y+"*[>+~]|"+E,"i")},T={},U=[],V={},W=[],X=function(a){return a.sizzleFilter=!0,a},Y=function(a){return function(b){return"input"===b.nodeName.toLowerCase()&&b.type===a}},Z=function(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}},_=function(a){var b=!1,c=p.createElement("div");try{b=a(c)}catch(d){}return c=null,b},ab=_(function(a){a.innerHTML="";var b=typeof a.lastChild.getAttribute("multiple");return"boolean"!==b&&"string"!==b}),bb=_(function(a){a.id=x+0,a.innerHTML="
",q.insertBefore(a,q.firstChild);var b=p.getElementsByName&&p.getElementsByName(x).length===2+p.getElementsByName(x+0).length;return o=!p.getElementById(x),q.removeChild(a),b}),cb=_(function(a){return a.appendChild(p.createComment("")),0===a.getElementsByTagName("*").length}),db=_(function(a){return a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!==r&&"#"===a.firstChild.getAttribute("href")}),eb=_(function(a){return a.innerHTML="",a.getElementsByClassName&&0!==a.getElementsByClassName("e").length?(a.lastChild.className="e",1!==a.getElementsByClassName("e").length):!1}),fb=function(a,b,c,d){c=c||[],b=b||p;var e,f,g,h,i=b.nodeType;if(1!==i&&9!==i)return[];if(!a||"string"!=typeof a)return c;if(g=ib(b),!g&&!d&&(e=M.exec(a)))if(h=e[1]){if(9===i){if(f=b.getElementById(h),!f||!f.parentNode)return c;if(f.id===h)return c.push(f),c}else if(b.ownerDocument&&(f=b.ownerDocument.getElementById(h))&&jb(b,f)&&f.id===h)return c.push(f),c}else{if(e[2])return w.apply(c,v.call(b.getElementsByTagName(a),0)),c;if((h=e[3])&&eb&&b.getElementsByClassName)return w.apply(c,v.call(b.getElementsByClassName(h),0)),c}return mb(a,b,c,d,g)},gb=fb.selectors={cacheLength:50,match:S,order:["ID","TAG"],attrHandle:{},createPseudo:X,find:{ID:o?function(a,b,c){if(typeof b.getElementById!==r&&!c){var d=b.getElementById(a);return d&&d.parentNode?[d]:[]}}:function(a,c,d){if(typeof c.getElementById!==r&&!d){var e=c.getElementById(a);return e?e.id===a||typeof e.getAttributeNode!==r&&e.getAttributeNode("id").value===a?[e]:b:[]}},TAG:cb?function(a,b){return typeof b.getElementsByTagName!==r?b.getElementsByTagName(a):void 0}:function(a,b){var c=b.getElementsByTagName(a);if("*"===a){for(var d,e=[],f=0;d=c[f];f++)1===d.nodeType&&e.push(d);return e}return c}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(R,""),a[3]=(a[4]||a[5]||"").replace(R,""),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1]?(a[2]||fb.error(a[0]),a[3]=+(a[3]?a[4]+(a[5]||1):2*("even"===a[2]||"odd"===a[2])),a[4]=+(a[6]+a[7]||"odd"===a[2])):a[2]&&fb.error(a[0]),a},PSEUDO:function(a){var b,c=a[4];return S.CHILD.test(a[0])?null:(c&&(b=K.exec(c))&&b.pop()&&(a[0]=a[0].slice(0,b[0].length-c.length-1),c=b[0].slice(0,-1)),a.splice(2,3,c||a[3]),a)}},filter:{ID:o?function(a){return a=a.replace(R,""),function(b){return b.getAttribute("id")===a}}:function(a){return a=a.replace(R,""),function(b){var c=typeof b.getAttributeNode!==r&&b.getAttributeNode("id");return c&&c.value===a}},TAG:function(a){return"*"===a?function(){return!0}:(a=a.replace(R,"").toLowerCase(),function(b){return b.nodeName&&b.nodeName.toLowerCase()===a})},CLASS:function(a){var b=T[a];return b||(b=T[a]=new RegExp("(^|"+y+")"+a+"("+y+"|$)"),U.push(a),U.length>gb.cacheLength&&delete T[U.shift()]),function(a){return b.test(a.className||typeof a.getAttribute!==r&&a.getAttribute("class")||"")}},ATTR:function(a,b,c){return b?function(d){var e=fb.attr(d,a),f=e+"";if(null==e)return"!="===b;switch(b){case"=":return f===c;case"!=":return f!==c;case"^=":return c&&0===f.indexOf(c);case"*=":return c&&f.indexOf(c)>-1;case"$=":return c&&f.substr(f.length-c.length)===c;case"~=":return(" "+f+" ").indexOf(c)>-1;case"|=":return f===c||f.substr(0,c.length+1)===c+"-"}}:function(b){return null!=fb.attr(b,a)}},CHILD:function(a,b,c,d){if("nth"===a){var e=u++;return function(a){var b,f,g=0,h=a;if(1===c&&0===d)return!0;if(b=a.parentNode,b&&(b[x]!==e||!a.sizset)){for(h=b.firstChild;h&&(1!==h.nodeType||(h.sizset=++g,h!==a));h=h.nextSibling);b[x]=e}return f=a.sizset-d,0===c?0===f:0===f%c&&f/c>=0}}return function(b){var c=b;switch(a){case"only":case"first":for(;c=c.previousSibling;)if(1===c.nodeType)return!1;if("first"===a)return!0;c=b;case"last":for(;c=c.nextSibling;)if(1===c.nodeType)return!1;return!0}}},PSEUDO:function(a,b,c,d){var e=gb.pseudos[a]||gb.pseudos[a.toLowerCase()];return e||fb.error("unsupported pseudo: "+a),e.sizzleFilter?e(b,c,d):e}},pseudos:{not:X(function(a,b,c){var d=lb(a.replace(H,"$1"),b,c);return function(a){return!d(a)}}),enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},parent:function(a){return!gb.pseudos.empty(a)},empty:function(a){var b;for(a=a.firstChild;a;){if(a.nodeName>"@"||3===(b=a.nodeType)||4===b)return!1;a=a.nextSibling}return!0},contains:X(function(a){return function(b){return(b.textContent||b.innerText||kb(b)).indexOf(a)>-1}}),has:X(function(a){return function(b){return fb(a,b).length>0}}),header:function(a){return P.test(a.nodeName)},text:function(a){var b,c;return"input"===a.nodeName.toLowerCase()&&"text"===(b=a.type)&&(null==(c=a.getAttribute("type"))||c.toLowerCase()===b)},radio:Y("radio"),checkbox:Y("checkbox"),file:Y("file"),password:Y("password"),image:Y("image"),submit:Z("submit"),reset:Z("reset"),button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},input:function(a){return Q.test(a.nodeName)},focus:function(a){var b=a.ownerDocument;return!(a!==b.activeElement||b.hasFocus&&!b.hasFocus()||!a.type&&!a.href)},active:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b,c){return c?a.slice(1):[a[0]]},last:function(a,b,c){var d=a.pop();return c?a:[d]},even:function(a,b,c){for(var d=[],e=c?1:0,f=a.length;f>e;e+=2)d.push(a[e]);return d},odd:function(a,b,c){for(var d=[],e=c?0:1,f=a.length;f>e;e+=2)d.push(a[e]);return d},lt:function(a,b,c){return c?a.slice(+b):a.slice(0,+b)},gt:function(a,b,c){return c?a.slice(0,+b+1):a.slice(+b+1)},eq:function(a,b,c){var d=a.splice(+b,1);return c?a:d}}};gb.setFilters.nth=gb.setFilters.eq,gb.filters=gb.pseudos,db||(gb.attrHandle={href:function(a){return a.getAttribute("href",2)},type:function(a){return a.getAttribute("type")}}),bb&&(gb.order.push("NAME"),gb.find.NAME=function(a,b){return typeof b.getElementsByName!==r?b.getElementsByName(a):void 0}),eb&&(gb.order.splice(1,0,"CLASS"),gb.find.CLASS=function(a,b,c){return typeof b.getElementsByClassName===r||c?void 0:b.getElementsByClassName(a)});try{v.call(q.childNodes,0)[0].nodeType}catch(hb){v=function(a){for(var b,c=[];b=this[a];a++)c.push(b);return c}}var ib=fb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},jb=fb.contains=q.compareDocumentPosition?function(a,b){return!!(16&a.compareDocumentPosition(b))}:q.contains?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b.parentNode;return a===d||!!(d&&1===d.nodeType&&c.contains&&c.contains(d))}:function(a,b){for(;b=b.parentNode;)if(b===a)return!0;return!1},kb=fb.getText=function(a){var b,c="",d=0,e=a.nodeType;if(e){if(1===e||9===e||11===e){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=kb(a)}else if(3===e||4===e)return a.nodeValue}else for(;b=a[d];d++)c+=kb(b);return c};fb.attr=function(a,b){var c,d=ib(a);return d||(b=b.toLowerCase()),gb.attrHandle[b]?gb.attrHandle[b](a):ab||d?a.getAttribute(b):(c=a.getAttributeNode(b),c?"boolean"==typeof a[b]?a[b]?b:null:c.specified?c.value:null:null)},fb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},[0,0].sort(function(){return t=0}),q.compareDocumentPosition?m=function(a,b){return a===b?(s=!0,0):(a.compareDocumentPosition&&b.compareDocumentPosition?4&a.compareDocumentPosition(b):a.compareDocumentPosition)?-1:1}:(m=function(a,b){if(a===b)return s=!0,0;if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],g=a.parentNode,h=b.parentNode,i=g;if(g===h)return n(a,b);if(!g)return-1;if(!h)return 1;for(;i;)e.unshift(i),i=i.parentNode;for(i=h;i;)f.unshift(i),i=i.parentNode;c=e.length,d=f.length;for(var j=0;c>j&&d>j;j++)if(e[j]!==f[j])return n(e[j],f[j]);return j===c?n(a,f[j],-1):n(e[j],b,1)},n=function(a,b,c){if(a===b)return c;for(var d=a.nextSibling;d;){if(d===b)return-1;d=d.nextSibling}return 1}),fb.uniqueSort=function(a){var b,c=1;if(m&&(s=t,a.sort(m),s))for(;b=a[c];c++)b===a[c-1]&&a.splice(c--,1);return a};var lb=fb.compile=function(a,b,c){var d,e,g,h=V[a];if(h&&h.context===b)return h;for(e=f(a,b,c),g=0;d=e[g];g++)e[g]=i(d,b,c);return h=V[a]=j(e),h.context=b,h.runs=h.dirruns=0,W.push(a),W.length>gb.cacheLength&&delete V[W.shift()],h};fb.matches=function(a,b){return fb(a,null,null,b)},fb.matchesSelector=function(a,b){return fb(b,null,null,[a]).length>0};var mb=function(a,b,c,d,f){a=a.replace(H,"$1");var g,h,i,j,m,n,o,p,q,r=a.match(J),s=a.match(L),t=b.nodeType;if(S.POS.test(a))return e(a,b,c,d,r);if(d)g=v.call(d,0);else if(r&&1===r.length){if(s.length>1&&9===t&&!f&&(r=S.ID.exec(s[0]))){if(b=gb.find.ID(r[1],b,f)[0],!b)return c;a=a.slice(s.shift().length)}for(p=(r=N.exec(s[0]))&&!r.index&&b.parentNode||b,q=s.pop(),n=q.split(":not")[0],i=0,j=gb.order.length;j>i;i++)if(o=gb.order[i],r=S[o].exec(n)){if(g=gb.find[o]((r[1]||"").replace(R,""),p,f),null==g)continue;n===q&&(a=a.slice(0,a.length-q.length)+n.replace(S[o],""),a||w.apply(c,v.call(g,0)));break}}if(a)for(h=lb(a,b,f),l=h.dirruns++,null==g&&(g=gb.find.TAG("*",N.test(a)&&b.parentNode||b)),i=0;m=g[i];i++)k=h.runs++,h(m,b)&&c.push(m);return c};p.querySelectorAll&&function(){var a,b=mb,c=/'|\\/g,d=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,e=[],f=[":active"],g=q.matchesSelector||q.mozMatchesSelector||q.webkitMatchesSelector||q.oMatchesSelector||q.msMatchesSelector;_(function(a){a.innerHTML="",a.querySelectorAll("[selected]").length||e.push("\\["+y+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),a.querySelectorAll(":checked").length||e.push(":checked")}),_(function(a){a.innerHTML="

",a.querySelectorAll("[test^='']").length&&e.push("[*^$]="+y+"*(?:\"\"|'')"),a.innerHTML="",a.querySelectorAll(":enabled").length||e.push(":enabled",":disabled")}),e=e.length&&new RegExp(e.join("|")),mb=function(a,d,f,g,h){if(!(g||h||e&&e.test(a)))if(9===d.nodeType)try{return w.apply(f,v.call(d.querySelectorAll(a),0)),f}catch(i){}else if(1===d.nodeType&&"object"!==d.nodeName.toLowerCase()){var j=d.getAttribute("id"),k=j||x,l=N.test(a)&&d.parentNode||d;j?k=k.replace(c,"\\$&"):d.setAttribute("id",k);try{return w.apply(f,v.call(l.querySelectorAll(a.replace(J,"[id='"+k+"'] $&")),0)),f}catch(i){}finally{j||d.removeAttribute("id")}}return b(a,d,f,g,h)},g&&(_(function(b){a=g.call(b,"div");try{g.call(b,"[test!='']:sizzle"),f.push(gb.match.PSEUDO)}catch(c){}}),f=new RegExp(f.join("|")),fb.matchesSelector=function(b,c){if(c=c.replace(d,"='$1']"),!(ib(b)||f.test(c)||e&&e.test(c)))try{var h=g.call(b,c);if(h||a||b.document&&11!==b.document.nodeType)return h}catch(i){}return fb(c,null,null,[b]).length>0})}(),fb.attr=$.attr,$.find=fb,$.expr=fb.selectors,$.expr[":"]=$.expr.pseudos,$.unique=fb.uniqueSort,$.text=fb.getText,$.isXMLDoc=fb.isXML,$.contains=fb.contains}(a);var Ib=/Until$/,Jb=/^(?:parents|prev(?:Until|All))/,Kb=/^.[^:#\[\.,]*$/,Lb=$.expr.match.needsContext,Mb={children:!0,contents:!0,next:!0,prev:!0};$.fn.extend({find:function(a){var b,c,d,e,f,g,h=this;if("string"!=typeof a)return $(a).filter(function(){for(b=0,c=h.length;c>b;b++)if($.contains(h[b],this))return!0});for(g=this.pushStack("","find",a),b=0,c=this.length;c>b;b++)if(d=g.length,$.find(a,this[b],g),b>0)for(e=d;ef;f++)if(g[f]===g[e]){g.splice(e--,1);break}return g},has:function(a){var b,c=$(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if($.contains(this,c[b]))return!0})},not:function(a){return this.pushStack(j(this,a,!1),"not",a)},filter:function(a){return this.pushStack(j(this,a,!0),"filter",a)},is:function(a){return!!a&&("string"==typeof a?Lb.test(a)?$(a,this.context).index(this[0])>=0:$.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=Lb.test(a)||"string"!=typeof a?$(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c.ownerDocument&&c!==b&&11!==c.nodeType;){if(g?g.index(c)>-1:$.find.matchesSelector(c,a)){f.push(c);break}c=c.parentNode}return f=f.length>1?$.unique(f):f,this.pushStack(f,"closest",a)},index:function(a){return a?"string"==typeof a?$.inArray(this[0],$(a)):$.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(a,b){var c="string"==typeof a?$(a,b):$.makeArray(a&&a.nodeType?[a]:a),d=$.merge(this.get(),c);return this.pushStack(h(c[0])||h(d[0])?d:$.unique(d))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}}),$.fn.andSelf=$.fn.addBack,$.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return $.dir(a,"parentNode")},parentsUntil:function(a,b,c){return $.dir(a,"parentNode",c)},next:function(a){return i(a,"nextSibling")},prev:function(a){return i(a,"previousSibling")},nextAll:function(a){return $.dir(a,"nextSibling")},prevAll:function(a){return $.dir(a,"previousSibling")},nextUntil:function(a,b,c){return $.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return $.dir(a,"previousSibling",c)},siblings:function(a){return $.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return $.sibling(a.firstChild)},contents:function(a){return $.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:$.merge([],a.childNodes)}},function(a,b){$.fn[a]=function(c,d){var e=$.map(this,b,c);return Ib.test(a)||(d=c),d&&"string"==typeof d&&(e=$.filter(d,e)),e=this.length>1&&!Mb[a]?$.unique(e):e,this.length>1&&Jb.test(a)&&(e=e.reverse()),this.pushStack(e,a,V.call(arguments).join(","))}}),$.extend({filter:function(a,b,c){return c&&(a=":not("+a+")"),1===b.length?$.find.matchesSelector(b[0],a)?[b[0]]:[]:$.find.matches(a,b)},dir:function(a,c,d){for(var e=[],f=a[c];f&&9!==f.nodeType&&(d===b||1!==f.nodeType||!$(f).is(d));)1===f.nodeType&&e.push(f),f=f[c];return e},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}});var Nb="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",Ob=/ jQuery\d+="(?:null|\d+)"/g,Pb=/^\s+/,Qb=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,Rb=/<([\w:]+)/,Sb=/]","i"),Xb=/^(?:checkbox|radio)$/,Yb=/checked\s*(?:[^=]|=\s*.checked.)/i,Zb=/\/(java|ecma)script/i,$b=/^\s*\s*$/g,_b={option:[1,""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},ac=k(P),bc=ac.appendChild(P.createElement("div")); _b.optgroup=_b.option,_b.tbody=_b.tfoot=_b.colgroup=_b.caption=_b.thead,_b.th=_b.td,$.support.htmlSerialize||(_b._default=[1,"X
","
"]),$.fn.extend({text:function(a){return $.access(this,function(a){return a===b?$.text(this):this.empty().append((this[0]&&this[0].ownerDocument||P).createTextNode(a))},null,a,arguments.length)},wrapAll:function(a){if($.isFunction(a))return this.each(function(b){$(this).wrapAll(a.call(this,b))});if(this[0]){var b=$(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){for(var a=this;a.firstChild&&1===a.firstChild.nodeType;)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return $.isFunction(a)?this.each(function(b){$(this).wrapInner(a.call(this,b))}):this.each(function(){var b=$(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=$.isFunction(a);return this.each(function(c){$(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){$.nodeName(this,"body")||$(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){(1===this.nodeType||11===this.nodeType)&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){(1===this.nodeType||11===this.nodeType)&&this.insertBefore(a,this.firstChild)})},before:function(){if(!h(this[0]))return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=$.clean(arguments);return this.pushStack($.merge(a,this),"before",this.selector)}},after:function(){if(!h(this[0]))return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=$.clean(arguments);return this.pushStack($.merge(this,a),"after",this.selector)}},remove:function(a,b){for(var c,d=0;null!=(c=this[d]);d++)(!a||$.filter(a,[c]).length)&&(b||1!==c.nodeType||($.cleanData(c.getElementsByTagName("*")),$.cleanData([c])),c.parentNode&&c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)for(1===a.nodeType&&$.cleanData(a.getElementsByTagName("*"));a.firstChild;)a.removeChild(a.firstChild);return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return $.clone(this,a,b)})},html:function(a){return $.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b)return 1===c.nodeType?c.innerHTML.replace(Ob,""):b;if(!("string"!=typeof a||Ub.test(a)||!$.support.htmlSerialize&&Wb.test(a)||!$.support.leadingWhitespace&&Pb.test(a)||_b[(Rb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(Qb,"<$1>");try{for(;e>d;d++)c=this[d]||{},1===c.nodeType&&($.cleanData(c.getElementsByTagName("*")),c.innerHTML=a);c=0}catch(f){}}c&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(a){return h(this[0])?this.length?this.pushStack($($.isFunction(a)?a():a),"replaceWith",a):this:$.isFunction(a)?this.each(function(b){var c=$(this),d=c.html();c.replaceWith(a.call(this,b,d))}):("string"!=typeof a&&(a=$(a).detach()),this.each(function(){var b=this.nextSibling,c=this.parentNode;$(this).remove(),b?$(b).before(a):$(c).append(a)}))},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){a=[].concat.apply([],a);var e,f,g,h,i=0,j=a[0],k=[],m=this.length;if(!$.support.checkClone&&m>1&&"string"==typeof j&&Yb.test(j))return this.each(function(){$(this).domManip(a,c,d)});if($.isFunction(j))return this.each(function(e){var f=$(this);a[0]=j.call(this,e,c?f.html():b),f.domManip(a,c,d)});if(this[0]){if(e=$.buildFragment(a,this,k),g=e.fragment,f=g.firstChild,1===g.childNodes.length&&(g=f),f)for(c=c&&$.nodeName(f,"tr"),h=e.cacheable||m-1;m>i;i++)d.call(c&&$.nodeName(this[i],"table")?l(this[i],"tbody"):this[i],i===h?g:$.clone(g,!0,!0));g=f=null,k.length&&$.each(k,function(a,b){b.src?$.ajax?$.ajax({url:b.src,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0}):$.error("no ajax"):$.globalEval((b.text||b.textContent||b.innerHTML||"").replace($b,"")),b.parentNode&&b.parentNode.removeChild(b)})}return this}}),$.buildFragment=function(a,c,d){var e,f,g,h=a[0];return c=c||P,c=(c[0]||c).ownerDocument||c[0]||c,"undefined"==typeof c.createDocumentFragment&&(c=P),!(1===a.length&&"string"==typeof h&&h.length<512&&c===P&&"<"===h.charAt(0))||Vb.test(h)||!$.support.checkClone&&Yb.test(h)||!$.support.html5Clone&&Wb.test(h)||(f=!0,e=$.fragments[h],g=e!==b),e||(e=c.createDocumentFragment(),$.clean(a,c,e,d),f&&($.fragments[h]=g&&e)),{fragment:e,cacheable:f}},$.fragments={},$.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){$.fn[a]=function(c){var d,e=0,f=[],g=$(c),h=g.length,i=1===this.length&&this[0].parentNode;if((null==i||i&&11===i.nodeType&&1===i.childNodes.length)&&1===h)return g[b](this[0]),this;for(;h>e;e++)d=(e>0?this.clone(!0):this).get(),$(g[e])[b](d),f=f.concat(d);return this.pushStack(f,a,g.selector)}}),$.extend({clone:function(a,b,c){var d,e,f,g;if($.support.html5Clone||$.isXMLDoc(a)||!Wb.test("<"+a.nodeName+">")?g=a.cloneNode(!0):(bc.innerHTML=a.outerHTML,bc.removeChild(g=bc.firstChild)),!($.support.noCloneEvent&&$.support.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||$.isXMLDoc(a)))for(n(a,g),d=o(a),e=o(g),f=0;d[f];++f)e[f]&&n(d[f],e[f]);if(b&&(m(a,g),c))for(d=o(a),e=o(g),f=0;d[f];++f)m(d[f],e[f]);return d=e=null,g},clean:function(a,b,c,d){var e,f,g,h,i,j,l,m,n,o,q,r=0,s=[];for(b&&"undefined"!=typeof b.createDocumentFragment||(b=P),f=b===P&∾null!=(g=a[r]);r++)if("number"==typeof g&&(g+=""),g){if("string"==typeof g)if(Tb.test(g)){for(f=f||k(b),l=l||f.appendChild(b.createElement("div")),g=g.replace(Qb,"<$1>"),h=(Rb.exec(g)||["",""])[1].toLowerCase(),i=_b[h]||_b._default,j=i[0],l.innerHTML=i[1]+g+i[2];j--;)l=l.lastChild;if(!$.support.tbody)for(m=Sb.test(g),n="table"!==h||m?""!==i[1]||m?[]:l.childNodes:l.firstChild&&l.firstChild.childNodes,e=n.length-1;e>=0;--e)$.nodeName(n[e],"tbody")&&!n[e].childNodes.length&&n[e].parentNode.removeChild(n[e]);!$.support.leadingWhitespace&&Pb.test(g)&&l.insertBefore(b.createTextNode(Pb.exec(g)[0]),l.firstChild),g=l.childNodes,l=f.lastChild}else g=b.createTextNode(g);g.nodeType?s.push(g):s=$.merge(s,g)}if(l&&(f.removeChild(l),g=l=f=null),!$.support.appendChecked)for(r=0;null!=(g=s[r]);r++)$.nodeName(g,"input")?p(g):"undefined"!=typeof g.getElementsByTagName&&$.grep(g.getElementsByTagName("input"),p);if(c)for(o=function(a){return!a.type||Zb.test(a.type)?d?d.push(a.parentNode?a.parentNode.removeChild(a):a):c.appendChild(a):void 0},r=0;null!=(g=s[r]);r++)$.nodeName(g,"script")&&o(g)||(c.appendChild(g),"undefined"!=typeof g.getElementsByTagName&&(q=$.grep($.merge([],g.getElementsByTagName("script")),o),s.splice.apply(s,[r+1,0].concat(q)),r+=q.length));return s},cleanData:function(a,b){for(var c,d,e,f,g=0,h=$.expando,i=$.cache,j=$.support.deleteExpando,k=$.event.special;null!=(e=a[g]);g++)if((b||$.acceptData(e))&&(d=e[h],c=d&&i[d])){if(c.events)for(f in c.events)k[f]?$.event.remove(e,f):$.removeEvent(e,f,c.handle);i[d]&&(delete i[d],j?delete e[h]:e.removeAttribute?e.removeAttribute(h):e[h]=null,$.deletedIds.push(d))}}}),function(){var a,b;$.uaMatch=function(a){a=a.toLowerCase();var b=/(chrome)[ \/]([\w.]+)/.exec(a)||/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||a.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},a=$.uaMatch(R.userAgent),b={},a.browser&&(b[a.browser]=!0,b.version=a.version),b.webkit&&(b.safari=!0),$.browser=b,$.sub=function(){function a(b,c){return new a.fn.init(b,c)}$.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(c,d){return d&&d instanceof $&&!(d instanceof a)&&(d=a(d)),$.fn.init.call(this,c,d,b)},a.fn.init.prototype=a.fn;var b=a(P);return a}}();var cc,dc,ec,fc=/alpha\([^)]*\)/i,gc=/opacity=([^)]*)/,hc=/^(top|right|bottom|left)$/,ic=/^margin/,jc=new RegExp("^("+_+")(.*)$","i"),kc=new RegExp("^("+_+")(?!px)[a-z%]+$","i"),lc=new RegExp("^([-+])=("+_+")","i"),mc={},nc={position:"absolute",visibility:"hidden",display:"block"},oc={letterSpacing:0,fontWeight:400,lineHeight:1},pc=["Top","Right","Bottom","Left"],qc=["Webkit","O","Moz","ms"],rc=$.fn.toggle;$.fn.extend({css:function(a,c){return $.access(this,function(a,c,d){return d!==b?$.style(a,c,d):$.css(a,c)},a,c,arguments.length>1)},show:function(){return s(this,!0)},hide:function(){return s(this)},toggle:function(a,b){var c="boolean"==typeof a;return $.isFunction(a)&&$.isFunction(b)?rc.apply(this,arguments):this.each(function(){(c?a:r(this))?$(this).show():$(this).hide()})}}),$.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=cc(a,"opacity");return""===c?"1":c}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":$.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var f,g,h,i=$.camelCase(c),j=a.style;if(c=$.cssProps[i]||($.cssProps[i]=q(j,i)),h=$.cssHooks[c]||$.cssHooks[i],d===b)return h&&"get"in h&&(f=h.get(a,!1,e))!==b?f:j[c];if(g=typeof d,"string"===g&&(f=lc.exec(d))&&(d=(f[1]+1)*f[2]+parseFloat($.css(a,c)),g="number"),!(null==d||"number"===g&&isNaN(d)||("number"!==g||$.cssNumber[i]||(d+="px"),h&&"set"in h&&(d=h.set(a,d,e))===b)))try{j[c]=d}catch(k){}}},css:function(a,c,d,e){var f,g,h,i=$.camelCase(c);return c=$.cssProps[i]||($.cssProps[i]=q(a.style,i)),h=$.cssHooks[c]||$.cssHooks[i],h&&"get"in h&&(f=h.get(a,!0,e)),f===b&&(f=cc(a,c)),"normal"===f&&c in oc&&(f=oc[c]),d||e!==b?(g=parseFloat(f),d||$.isNumeric(g)?g||0:f):f},swap:function(a,b,c){var d,e,f={};for(e in b)f[e]=a.style[e],a.style[e]=b[e];d=c.call(a);for(e in b)a.style[e]=f[e];return d}}),a.getComputedStyle?cc=function(a,b){var c,d,e,f,g=getComputedStyle(a,null),h=a.style;return g&&(c=g[b],""!==c||$.contains(a.ownerDocument.documentElement,a)||(c=$.style(a,b)),kc.test(c)&&ic.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=c,c=g.width,h.width=d,h.minWidth=e,h.maxWidth=f)),c}:P.documentElement.currentStyle&&(cc=function(a,b){var c,d,e=a.currentStyle&&a.currentStyle[b],f=a.style;return null==e&&f&&f[b]&&(e=f[b]),kc.test(e)&&!hc.test(b)&&(c=f.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),f.left="fontSize"===b?"1em":e,e=f.pixelLeft+"px",f.left=c,d&&(a.runtimeStyle.left=d)),""===e?"auto":e}),$.each(["height","width"],function(a,b){$.cssHooks[b]={get:function(a,c,d){return c?0!==a.offsetWidth||"none"!==cc(a,"display")?v(a,b,d):$.swap(a,nc,function(){return v(a,b,d)}):void 0},set:function(a,c,d){return t(a,c,d?u(a,b,d,$.support.boxSizing&&"border-box"===$.css(a,"boxSizing")):0)}}}),$.support.opacity||($.cssHooks.opacity={get:function(a,b){return gc.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=$.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,b>=1&&""===$.trim(f.replace(fc,""))&&c.removeAttribute&&(c.removeAttribute("filter"),d&&!d.filter)||(c.filter=fc.test(f)?f.replace(fc,e):f+" "+e)}}),$(function(){$.support.reliableMarginRight||($.cssHooks.marginRight={get:function(a,b){return $.swap(a,{display:"inline-block"},function(){return b?cc(a,"marginRight"):void 0})}}),!$.support.pixelPosition&&$.fn.position&&$.each(["top","left"],function(a,b){$.cssHooks[b]={get:function(a,c){if(c){var d=cc(a,b);return kc.test(d)?$(a).position()[b]+"px":d}}}})}),$.expr&&$.expr.filters&&($.expr.filters.hidden=function(a){return 0===a.offsetWidth&&0===a.offsetHeight||!$.support.reliableHiddenOffsets&&"none"===(a.style&&a.style.display||cc(a,"display"))},$.expr.filters.visible=function(a){return!$.expr.filters.hidden(a)}),$.each({margin:"",padding:"",border:"Width"},function(a,b){$.cssHooks[a+b]={expand:function(c){var d,e="string"==typeof c?c.split(" "):[c],f={};for(d=0;4>d;d++)f[a+pc[d]+b]=e[d]||e[d-2]||e[0];return f}},ic.test(a)||($.cssHooks[a+b].set=t)});var sc=/%20/g,tc=/\[\]$/,uc=/\r?\n/g,vc=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,wc=/^(?:select|textarea)/i;$.fn.extend({serialize:function(){return $.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?$.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||wc.test(this.nodeName)||vc.test(this.type))}).map(function(a,b){var c=$(this).val();return null==c?null:$.isArray(c)?$.map(c,function(a){return{name:b.name,value:a.replace(uc,"\r\n")}}):{name:b.name,value:c.replace(uc,"\r\n")}}).get()}}),$.param=function(a,c){var d,e=[],f=function(a,b){b=$.isFunction(b)?b():null==b?"":b,e[e.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(c===b&&(c=$.ajaxSettings&&$.ajaxSettings.traditional),$.isArray(a)||a.jquery&&!$.isPlainObject(a))$.each(a,function(){f(this.name,this.value)});else for(d in a)x(d,a[d],c,f);return e.join("&").replace(sc,"+")};var xc,yc,zc=/#.*$/,Ac=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Bc=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,Cc=/^(?:GET|HEAD)$/,Dc=/^\/\//,Ec=/\?/,Fc=/)<[^<]*)*<\/script>/gi,Gc=/([?&])_=[^&]*/,Hc=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,Ic=$.fn.load,Jc={},Kc={},Lc=["*/"]+["*"];try{xc=Q.href}catch(Mc){xc=P.createElement("a"),xc.href="",xc=xc.href}yc=Hc.exec(xc.toLowerCase())||[],$.fn.load=function(a,c,d){if("string"!=typeof a&&Ic)return Ic.apply(this,arguments);if(!this.length)return this;var e,f,g,h=this,i=a.indexOf(" ");return i>=0&&(e=a.slice(i,a.length),a=a.slice(0,i)),$.isFunction(c)?(d=c,c=b):"object"==typeof c&&(f="POST"),$.ajax({url:a,type:f,dataType:"html",data:c,complete:function(a,b){d&&h.each(d,g||[a.responseText,b,a])}}).done(function(a){g=arguments,h.html(e?$("
").append(a.replace(Fc,"")).find(e):a)}),this},$.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){$.fn[b]=function(a){return this.on(b,a)}}),$.each(["get","post"],function(a,c){$[c]=function(a,d,e,f){return $.isFunction(d)&&(f=f||e,e=d,d=b),$.ajax({type:c,url:a,data:d,success:e,dataType:f})}}),$.extend({getScript:function(a,c){return $.get(a,b,c,"script")},getJSON:function(a,b,c){return $.get(a,b,c,"json")},ajaxSetup:function(a,b){return b?A(a,$.ajaxSettings):(b=a,a=$.ajaxSettings),A(a,b),a},ajaxSettings:{url:xc,isLocal:Bc.test(yc[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":Lc},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":$.parseJSON,"text xml":$.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:y(Jc),ajaxTransport:y(Kc),ajax:function(a,c){function d(a,c,d,g){var j,l,s,t,v,x=c;2!==u&&(u=2,i&&clearTimeout(i),h=b,f=g||"",w.readyState=a>0?4:0,d&&(t=B(m,w,d)),a>=200&&300>a||304===a?(m.ifModified&&(v=w.getResponseHeader("Last-Modified"),v&&($.lastModified[e]=v),v=w.getResponseHeader("Etag"),v&&($.etag[e]=v)),304===a?(x="notmodified",j=!0):(j=C(m,t),x=j.state,l=j.data,s=j.error,j=!s)):(s=x,(!x||a)&&(x="error",0>a&&(a=0))),w.status=a,w.statusText=""+(c||x),j?p.resolveWith(n,[l,x,w]):p.rejectWith(n,[w,x,s]),w.statusCode(r),r=b,k&&o.trigger("ajax"+(j?"Success":"Error"),[w,m,j?l:s]),q.fireWith(n,[w,x]),k&&(o.trigger("ajaxComplete",[w,m]),--$.active||$.event.trigger("ajaxStop")))}"object"==typeof a&&(c=a,a=b),c=c||{};var e,f,g,h,i,j,k,l,m=$.ajaxSetup({},c),n=m.context||m,o=n!==m&&(n.nodeType||n instanceof $)?$(n):$.event,p=$.Deferred(),q=$.Callbacks("once memory"),r=m.statusCode||{},s={},t={},u=0,v="canceled",w={readyState:0,setRequestHeader:function(a,b){if(!u){var c=a.toLowerCase();a=t[c]=t[c]||a,s[a]=b}return this},getAllResponseHeaders:function(){return 2===u?f:null},getResponseHeader:function(a){var c;if(2===u){if(!g)for(g={};c=Ac.exec(f);)g[c[1].toLowerCase()]=c[2];c=g[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){return u||(m.mimeType=a),this},abort:function(a){return a=a||v,h&&h.abort(a),d(0,a),this}};if(p.promise(w),w.success=w.done,w.error=w.fail,w.complete=q.add,w.statusCode=function(a){if(a){var b;if(2>u)for(b in a)r[b]=[r[b],a[b]];else b=a[w.status],w.always(b)}return this},m.url=((a||m.url)+"").replace(zc,"").replace(Dc,yc[1]+"//"),m.dataTypes=$.trim(m.dataType||"*").toLowerCase().split(bb),null==m.crossDomain&&(j=Hc.exec(m.url.toLowerCase()),m.crossDomain=!(!j||j[1]==yc[1]&&j[2]==yc[2]&&(j[3]||("http:"===j[1]?80:443))==(yc[3]||("http:"===yc[1]?80:443)))),m.data&&m.processData&&"string"!=typeof m.data&&(m.data=$.param(m.data,m.traditional)),z(Jc,m,c,w),2===u)return w;if(k=m.global,m.type=m.type.toUpperCase(),m.hasContent=!Cc.test(m.type),k&&0===$.active++&&$.event.trigger("ajaxStart"),!m.hasContent&&(m.data&&(m.url+=(Ec.test(m.url)?"&":"?")+m.data,delete m.data),e=m.url,m.cache===!1)){var x=$.now(),y=m.url.replace(Gc,"$1_="+x);m.url=y+(y===m.url?(Ec.test(m.url)?"&":"?")+"_="+x:"")}(m.data&&m.hasContent&&m.contentType!==!1||c.contentType)&&w.setRequestHeader("Content-Type",m.contentType),m.ifModified&&(e=e||m.url,$.lastModified[e]&&w.setRequestHeader("If-Modified-Since",$.lastModified[e]),$.etag[e]&&w.setRequestHeader("If-None-Match",$.etag[e])),w.setRequestHeader("Accept",m.dataTypes[0]&&m.accepts[m.dataTypes[0]]?m.accepts[m.dataTypes[0]]+("*"!==m.dataTypes[0]?", "+Lc+"; q=0.01":""):m.accepts["*"]);for(l in m.headers)w.setRequestHeader(l,m.headers[l]);if(m.beforeSend&&(m.beforeSend.call(n,w,m)===!1||2===u))return w.abort();v="abort";for(l in{success:1,error:1,complete:1})w[l](m[l]);if(h=z(Kc,m,c,w)){w.readyState=1,k&&o.trigger("ajaxSend",[w,m]),m.async&&m.timeout>0&&(i=setTimeout(function(){w.abort("timeout")},m.timeout));try{u=1,h.send(s,d)}catch(A){if(!(2>u))throw A;d(-1,A)}}else d(-1,"No Transport");return w},active:0,lastModified:{},etag:{}});var Nc=[],Oc=/\?/,Pc=/(=)\?(?=&|$)|\?\?/,Qc=$.now();$.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Nc.pop()||$.expando+"_"+Qc++;return this[a]=!0,a}}),$.ajaxPrefilter("json jsonp",function(c,d,e){var f,g,h,i=c.data,j=c.url,k=c.jsonp!==!1,l=k&&Pc.test(j),m=k&&!l&&"string"==typeof i&&!(c.contentType||"").indexOf("application/x-www-form-urlencoded")&&Pc.test(i);return"jsonp"===c.dataTypes[0]||l||m?(f=c.jsonpCallback=$.isFunction(c.jsonpCallback)?c.jsonpCallback():c.jsonpCallback,g=a[f],l?c.url=j.replace(Pc,"$1"+f):m?c.data=i.replace(Pc,"$1"+f):k&&(c.url+=(Oc.test(j)?"&":"?")+c.jsonp+"="+f),c.converters["script json"]=function(){return h||$.error(f+" was not called"),h[0]},c.dataTypes[0]="json",a[f]=function(){h=arguments},e.always(function(){a[f]=g,c[f]&&(c.jsonpCallback=d.jsonpCallback,Nc.push(f)),h&&$.isFunction(g)&&g(h[0]),h=g=b}),"script"):void 0}),$.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){return $.globalEval(a),a}}}),$.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),$.ajaxTransport("script",function(a){if(a.crossDomain){var c,d=P.head||P.getElementsByTagName("head")[0]||P.documentElement;return{send:function(e,f){c=P.createElement("script"),c.async="async",a.scriptCharset&&(c.charset=a.scriptCharset),c.src=a.url,c.onload=c.onreadystatechange=function(a,e){(e||!c.readyState||/loaded|complete/.test(c.readyState))&&(c.onload=c.onreadystatechange=null,d&&c.parentNode&&d.removeChild(c),c=b,e||f(200,"success"))},d.insertBefore(c,d.firstChild)},abort:function(){c&&c.onload(0,1)}}}});var Rc,Sc=a.ActiveXObject?function(){for(var a in Rc)Rc[a](0,1)}:!1,Tc=0;$.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&D()||E()}:D,function(a){$.extend($.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}($.ajaxSettings.xhr()),$.support.ajax&&$.ajaxTransport(function(c){if(!c.crossDomain||$.support.cors){var d;return{send:function(e,f){var g,h,i=c.xhr();if(c.username?i.open(c.type,c.url,c.async,c.username,c.password):i.open(c.type,c.url,c.async),c.xhrFields)for(h in c.xhrFields)i[h]=c.xhrFields[h];c.mimeType&&i.overrideMimeType&&i.overrideMimeType(c.mimeType),c.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");try{for(h in e)i.setRequestHeader(h,e[h])}catch(j){}i.send(c.hasContent&&c.data||null),d=function(a,e){var h,j,k,l,m;try{if(d&&(e||4===i.readyState))if(d=b,g&&(i.onreadystatechange=$.noop,Sc&&delete Rc[g]),e)4!==i.readyState&&i.abort();else{h=i.status,k=i.getAllResponseHeaders(),l={},m=i.responseXML,m&&m.documentElement&&(l.xml=m);try{l.text=i.responseText}catch(a){}try{j=i.statusText}catch(n){j=""}h||!c.isLocal||c.crossDomain?1223===h&&(h=204):h=l.text?200:404}}catch(o){e||f(-1,o)}l&&f(h,j,l,k)},c.async?4===i.readyState?setTimeout(d,0):(g=++Tc,Sc&&(Rc||(Rc={},$(a).unload(Sc)),Rc[g]=d),i.onreadystatechange=d):d()},abort:function(){d&&d(0,1)}}}});var Uc,Vc,Wc=/^(?:toggle|show|hide)$/,Xc=new RegExp("^(?:([-+])=|)("+_+")([a-z%]*)$","i"),Yc=/queueHooks$/,Zc=[J],$c={"*":[function(a,b){var c,d,e,f=this.createTween(a,b),g=Xc.exec(b),h=f.cur(),i=+h||0,j=1;if(g){if(c=+g[2],d=g[3]||($.cssNumber[a]?"":"px"),"px"!==d&&i){i=$.css(f.elem,a,!0)||c||1;do e=j=j||".5",i/=j,$.style(f.elem,a,i+d),j=f.cur()/h;while(1!==j&&j!==e)}f.unit=d,f.start=i,f.end=g[1]?i+(g[1]+1)*c:c}return f}]};$.Animation=$.extend(H,{tweener:function(a,b){$.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],$c[c]=$c[c]||[],$c[c].unshift(b)},prefilter:function(a,b){b?Zc.unshift(a):Zc.push(a)}}),$.Tween=K,K.prototype={constructor:K,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||($.cssNumber[c]?"":"px")},cur:function(){var a=K.propHooks[this.prop];return a&&a.get?a.get(this):K.propHooks._default.get(this)},run:function(a){var b,c=K.propHooks[this.prop];return this.pos=b=$.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration),this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):K.propHooks._default.set(this),this}},K.prototype.init.prototype=K.prototype,K.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=$.css(a.elem,a.prop,!1,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){$.fx.step[a.prop]?$.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[$.cssProps[a.prop]]||$.cssHooks[a.prop])?$.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},K.propHooks.scrollTop=K.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},$.each(["toggle","show","hide"],function(a,b){var c=$.fn[b];$.fn[b]=function(d,e,f){return null==d||"boolean"==typeof d||!a&&$.isFunction(d)&&$.isFunction(e)?c.apply(this,arguments):this.animate(L(b,!0),d,e,f)}}),$.fn.extend({fadeTo:function(a,b,c,d){return this.filter(r).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=$.isEmptyObject(a),f=$.speed(b,c,d),g=function(){var b=H(this,$.extend({},a),f);e&&b.stop(!0)};return e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,c,d){var e=function(a){var b=a.stop;delete a.stop,b(d)};return"string"!=typeof a&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,c=null!=a&&a+"queueHooks",f=$.timers,g=$._data(this);if(c)g[c]&&g[c].stop&&e(g[c]);else for(c in g)g[c]&&g[c].stop&&Yc.test(c)&&e(g[c]);for(c=f.length;c--;)f[c].elem!==this||null!=a&&f[c].queue!==a||(f[c].anim.stop(d),b=!1,f.splice(c,1));(b||!d)&&$.dequeue(this,a)})}}),$.each({slideDown:L("show"),slideUp:L("hide"),slideToggle:L("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){$.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),$.speed=function(a,b,c){var d=a&&"object"==typeof a?$.extend({},a):{complete:c||!c&&b||$.isFunction(a)&&a,duration:a,easing:c&&b||b&&!$.isFunction(b)&&b};return d.duration=$.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in $.fx.speeds?$.fx.speeds[d.duration]:$.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){$.isFunction(d.old)&&d.old.call(this),d.queue&&$.dequeue(this,d.queue)},d},$.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},$.timers=[],$.fx=K.prototype.init,$.fx.tick=function(){for(var a,b=$.timers,c=0;c-1,l={},m={};k?(m=g.position(),e=m.top,f=m.left):(e=parseFloat(i)||0,f=parseFloat(j)||0),$.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(l.top=b.top-h.top+e),null!=b.left&&(l.left=b.left-h.left+f),"using"in b?b.using.call(a,l):g.css(l)}},$.fn.extend({position:function(){if(this[0]){var a=this[0],b=this.offsetParent(),c=this.offset(),d=_c.test(b[0].nodeName)?{top:0,left:0}:b.offset();return c.top-=parseFloat($.css(a,"marginTop"))||0,c.left-=parseFloat($.css(a,"marginLeft"))||0,d.top+=parseFloat($.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat($.css(b[0],"borderLeftWidth"))||0,{top:c.top-d.top,left:c.left-d.left}}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||P.body;a&&!_c.test(a.nodeName)&&"static"===$.css(a,"position");)a=a.offsetParent;return a||P.body})}}),$.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,c){var d=/Y/.test(c);$.fn[a]=function(e){return $.access(this,function(a,e,f){var g=M(a);return f===b?g?c in g?g[c]:g.document.documentElement[e]:a[e]:(g?g.scrollTo(d?$(g).scrollLeft():f,d?f:$(g).scrollTop()):a[e]=f,void 0)},a,e,arguments.length,null)}}),$.each({Height:"height",Width:"width"},function(a,c){$.each({padding:"inner"+a,content:c,"":"outer"+a},function(d,e){$.fn[e]=function(e,f){var g=arguments.length&&(d||"boolean"!=typeof e),h=d||(e===!0||f===!0?"margin":"border");return $.access(this,function(c,d,e){var f;return $.isWindow(c)?c.document.documentElement["client"+a]:9===c.nodeType?(f=c.documentElement,Math.max(c.body["scroll"+a],f["scroll"+a],c.body["offset"+a],f["offset"+a],f["client"+a])):e===b?$.css(c,d,e,h):$.style(c,d,e,h)},c,g?e:b,g)}})}),a.jQuery=a.$=$,"function"==typeof define&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return $})}(window),function(a,b){function c(b,c){var e,f,g,h=b.nodeName.toLowerCase();return"area"===h?(e=b.parentNode,f=e.name,b.href&&f&&"map"===e.nodeName.toLowerCase()?(g=a("img[usemap=#"+f+"]")[0],!!g&&d(g)):!1):(/input|select|textarea|button|object/.test(h)?!b.disabled:"a"===h?b.href||c:c)&&d(b)}function d(b){return a.expr.filters.visible(b)&&!a(b).parents().addBack().filter(function(){return"hidden"===a.css(this,"visibility")}).length}var e=0,f=/^ui-id-\d+$/;a.ui=a.ui||{},a.extend(a.ui,{version:"1.10.3",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),a.fn.extend({focus:function(b){return function(c,d){return"number"==typeof c?this.each(function(){var b=this;setTimeout(function(){a(b).focus(),d&&d.call(b)},c)}):b.apply(this,arguments)}}(a.fn.focus),scrollParent:function(){var b;return b=a.ui.ie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(a.css(this,"position"))&&/(auto|scroll)/.test(a.css(this,"overflow")+a.css(this,"overflow-y")+a.css(this,"overflow-x"))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(a.css(this,"overflow")+a.css(this,"overflow-y")+a.css(this,"overflow-x"))}).eq(0),/fixed/.test(this.css("position"))||!b.length?a(document):b},zIndex:function(c){if(c!==b)return this.css("zIndex",c);if(this.length)for(var d,e,f=a(this[0]);f.length&&f[0]!==document;){if(d=f.css("position"),("absolute"===d||"relative"===d||"fixed"===d)&&(e=parseInt(f.css("zIndex"),10),!isNaN(e)&&0!==e))return e;f=f.parent()}return 0},uniqueId:function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++e)})},removeUniqueId:function(){return this.each(function(){f.test(this.id)&&a(this).removeAttr("id")})}}),a.extend(a.expr[":"],{data:a.expr.createPseudo?a.expr.createPseudo(function(b){return function(c){return!!a.data(c,b)}}):function(b,c,d){return!!a.data(b,d[3])},focusable:function(b){return c(b,!isNaN(a.attr(b,"tabindex")))},tabbable:function(b){var d=a.attr(b,"tabindex"),e=isNaN(d);return(e||d>=0)&&c(b,!e)}}),a("").outerWidth(1).jquery||a.each(["Width","Height"],function(c,d){function e(b,c,d,e){return a.each(f,function(){c-=parseFloat(a.css(b,"padding"+this))||0,d&&(c-=parseFloat(a.css(b,"border"+this+"Width"))||0),e&&(c-=parseFloat(a.css(b,"margin"+this))||0)}),c}var f="Width"===d?["Left","Right"]:["Top","Bottom"],g=d.toLowerCase(),h={innerWidth:a.fn.innerWidth,innerHeight:a.fn.innerHeight,outerWidth:a.fn.outerWidth,outerHeight:a.fn.outerHeight};a.fn["inner"+d]=function(c){return c===b?h["inner"+d].call(this):this.each(function(){a(this).css(g,e(this,c)+"px")})},a.fn["outer"+d]=function(b,c){return"number"!=typeof b?h["outer"+d].call(this,b):this.each(function(){a(this).css(g,e(this,b,!0,c)+"px")})}}),a.fn.addBack||(a.fn.addBack=function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}),a("").data("a-b","a").removeData("a-b").data("a-b")&&(a.fn.removeData=function(b){return function(c){return arguments.length?b.call(this,a.camelCase(c)):b.call(this)}}(a.fn.removeData)),a.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),a.support.selectstart="onselectstart"in document.createElement("div"),a.fn.extend({disableSelection:function(){return this.bind((a.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),a.extend(a.ui,{plugin:{add:function(b,c,d){var e,f=a.ui[b].prototype;for(e in d)f.plugins[e]=f.plugins[e]||[],f.plugins[e].push([c,d[e]])},call:function(a,b,c){var d,e=a.plugins[b];if(e&&a.element[0].parentNode&&11!==a.element[0].parentNode.nodeType)for(d=0;d0?!0:(b[d]=1,e=b[d]>0,b[d]=0,e)}})}(jQuery),function(a,b){var c=0,d=Array.prototype.slice,e=a.cleanData;a.cleanData=function(b){for(var c,d=0;null!=(c=b[d]);d++)try{a(c).triggerHandler("remove")}catch(f){}e(b)},a.widget=function(b,c,d){var e,f,g,h,i={},j=b.split(".")[0];b=b.split(".")[1],e=j+"-"+b,d||(d=c,c=a.Widget),a.expr[":"][e.toLowerCase()]=function(b){return!!a.data(b,e)},a[j]=a[j]||{},f=a[j][b],g=a[j][b]=function(a,b){return this._createWidget?(arguments.length&&this._createWidget(a,b),void 0):new g(a,b)},a.extend(g,f,{version:d.version,_proto:a.extend({},d),_childConstructors:[]}),h=new c,h.options=a.widget.extend({},h.options),a.each(d,function(b,d){return a.isFunction(d)?(i[b]=function(){var a=function(){return c.prototype[b].apply(this,arguments)},e=function(a){return c.prototype[b].apply(this,a)};return function(){var b,c=this._super,f=this._superApply;return this._super=a,this._superApply=e,b=d.apply(this,arguments),this._super=c,this._superApply=f,b}}(),void 0):(i[b]=d,void 0)}),g.prototype=a.widget.extend(h,{widgetEventPrefix:f?h.widgetEventPrefix:b},i,{constructor:g,namespace:j,widgetName:b,widgetFullName:e}),f?(a.each(f._childConstructors,function(b,c){var d=c.prototype;a.widget(d.namespace+"."+d.widgetName,g,c._proto)}),delete f._childConstructors):c._childConstructors.push(g),a.widget.bridge(b,g)},a.widget.extend=function(c){for(var e,f,g=d.call(arguments,1),h=0,i=g.length;i>h;h++)for(e in g[h])f=g[h][e],g[h].hasOwnProperty(e)&&f!==b&&(c[e]=a.isPlainObject(f)?a.isPlainObject(c[e])?a.widget.extend({},c[e],f):a.widget.extend({},f):f);return c},a.widget.bridge=function(c,e){var f=e.prototype.widgetFullName||c;a.fn[c]=function(g){var h="string"==typeof g,i=d.call(arguments,1),j=this;return g=!h&&i.length?a.widget.extend.apply(null,[g].concat(i)):g,h?this.each(function(){var d,e=a.data(this,f);return e?a.isFunction(e[g])&&"_"!==g.charAt(0)?(d=e[g].apply(e,i),d!==e&&d!==b?(j=d&&d.jquery?j.pushStack(d.get()):d,!1):void 0):a.error("no such method '"+g+"' for "+c+" widget instance"):a.error("cannot call methods on "+c+" prior to initialization; "+"attempted to call method '"+g+"'")}):this.each(function(){var b=a.data(this,f);b?b.option(g||{})._init():a.data(this,f,new e(g,this))}),j}},a.Widget=function(){},a.Widget._childConstructors=[],a.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
",options:{disabled:!1,create:null},_createWidget:function(b,d){d=a(d||this.defaultElement||this)[0],this.element=a(d),this.uuid=c++,this.eventNamespace="."+this.widgetName+this.uuid,this.options=a.widget.extend({},this.options,this._getCreateOptions(),b),this.bindings=a(),this.hoverable=a(),this.focusable=a(),d!==this&&(a.data(d,this.widgetFullName,this),this._on(!0,this.element,{remove:function(a){a.target===d&&this.destroy()}}),this.document=a(d.style?d.ownerDocument:d.document||d),this.window=a(this.document[0].defaultView||this.document[0].parentWindow)),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:a.noop,_getCreateEventData:a.noop,_create:a.noop,_init:a.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetName).removeData(this.widgetFullName).removeData(a.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:a.noop,widget:function(){return this.element},option:function(c,d){var e,f,g,h=c;if(0===arguments.length)return a.widget.extend({},this.options);if("string"==typeof c)if(h={},e=c.split("."),c=e.shift(),e.length){for(f=h[c]=a.widget.extend({},this.options[c]),g=0;g=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}})}(jQuery),function(a){function b(a,b,c){return a>b&&b+c>a}function c(a){return/left|right/.test(a.css("float"))||/inline|table-cell/.test(a.css("display"))}a.widget("ui.sortable",a.ui.mouse,{version:"1.10.3",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_create:function(){var a=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?"x"===a.axis||c(this.items[0].item):!1,this.offset=this.element.offset(),this._mouseInit(),this.ready=!0},_destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled"),this._mouseDestroy();for(var a=this.items.length-1;a>=0;a--)this.items[a].item.removeData(this.widgetName+"-item");return this},_setOption:function(b,c){"disabled"===b?(this.options[b]=c,this.widget().toggleClass("ui-sortable-disabled",!!c)):a.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(b,c){var d=null,e=!1,f=this;return this.reverting?!1:this.options.disabled||"static"===this.options.type?!1:(this._refreshItems(b),a(b.target).parents().each(function(){return a.data(this,f.widgetName+"-item")===f?(d=a(this),!1):void 0}),a.data(b.target,f.widgetName+"-item")===f&&(d=a(b.target)),d?!this.options.handle||c||(a(this.options.handle,d).find("*").addBack().each(function(){this===b.target&&(e=!0)}),e)?(this.currentItem=d,this._removeCurrentsFromItems(),!0):!1:!1)},_mouseStart:function(b,c,d){var e,f,g=this.options;if(this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(b),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},a.extend(this.offset,{click:{left:b.pageX-this.offset.left,top:b.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(b),this.originalPageX=b.pageX,this.originalPageY=b.pageY,g.cursorAt&&this._adjustOffsetFromHelper(g.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!==this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),g.containment&&this._setContainment(),g.cursor&&"auto"!==g.cursor&&(f=this.document.find("body"),this.storedCursor=f.css("cursor"),f.css("cursor",g.cursor),this.storedStylesheet=a("").appendTo(f)),g.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",g.opacity)),g.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",g.zIndex)),this.scrollParent[0]!==document&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",b,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!d)for(e=this.containers.length-1;e>=0;e--)this.containers[e]._trigger("activate",b,this._uiHash(this));return a.ui.ddmanager&&(a.ui.ddmanager.current=this),a.ui.ddmanager&&!g.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,b),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(b),!0},_mouseDrag:function(b){var c,d,e,f,g=this.options,h=!1;for(this.position=this._generatePosition(b),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==document&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-b.pageY=0;c--)if(d=this.items[c],e=d.item[0],f=this._intersectsWithPointer(d),f&&d.instance===this.currentContainer&&e!==this.currentItem[0]&&this.placeholder[1===f?"next":"prev"]()[0]!==e&&!a.contains(this.placeholder[0],e)&&("semi-dynamic"===this.options.type?!a.contains(this.element[0],e):!0)){if(this.direction=1===f?"down":"up","pointer"!==this.options.tolerance&&!this._intersectsWithSides(d))break;this._rearrange(b,d),this._trigger("change",b,this._uiHash());break}return this._contactContainers(b),a.ui.ddmanager&&a.ui.ddmanager.drag(this,b),this._trigger("sort",b,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(b,c){if(b){if(a.ui.ddmanager&&!this.options.dropBehaviour&&a.ui.ddmanager.drop(this,b),this.options.revert){var d=this,e=this.placeholder.offset(),f=this.options.axis,g={};f&&"x"!==f||(g.left=e.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===document.body?0:this.offsetParent[0].scrollLeft)),f&&"y"!==f||(g.top=e.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===document.body?0:this.offsetParent[0].scrollTop)),this.reverting=!0,a(this.helper).animate(g,parseInt(this.options.revert,10)||500,function(){d._clear(b)})}else this._clear(b,c);return!1}},cancel:function(){if(this.dragging){this._mouseUp({target:null}),"original"===this.options.helper?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var b=this.containers.length-1;b>=0;b--)this.containers[b]._trigger("deactivate",null,this._uiHash(this)),this.containers[b].containerCache.over&&(this.containers[b]._trigger("out",null,this._uiHash(this)),this.containers[b].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),"original"!==this.options.helper&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),a.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?a(this.domPosition.prev).after(this.currentItem):a(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(b){var c=this._getItemsAsjQuery(b&&b.connected),d=[];return b=b||{},a(c).each(function(){var c=(a(b.item||this).attr(b.attribute||"id")||"").match(b.expression||/(.+)[\-=_](.+)/);c&&d.push((b.key||c[1]+"[]")+"="+(b.key&&b.expression?c[1]:c[2]))}),!d.length&&b.key&&d.push(b.key+"="),d.join("&")},toArray:function(b){var c=this._getItemsAsjQuery(b&&b.connected),d=[];return b=b||{},c.each(function(){d.push(a(b.item||this).attr(b.attribute||"id")||"")}),d},_intersectsWith:function(a){var b=this.positionAbs.left,c=b+this.helperProportions.width,d=this.positionAbs.top,e=d+this.helperProportions.height,f=a.left,g=f+a.width,h=a.top,i=h+a.height,j=this.offset.click.top,k=this.offset.click.left,l="x"===this.options.axis||d+j>h&&i>d+j,m="y"===this.options.axis||b+k>f&&g>b+k,n=l&&m;return"pointer"===this.options.tolerance||this.options.forcePointerForContainers||"pointer"!==this.options.tolerance&&this.helperProportions[this.floating?"width":"height"]>a[this.floating?"width":"height"]?n:f0?"down":"up")},_getDragHorizontalDirection:function(){var a=this.positionAbs.left-this.lastPositionAbs.left;return 0!==a&&(a>0?"right":"left")},refresh:function(a){return this._refreshItems(a),this.refreshPositions(),this},_connectWith:function(){var a=this.options;return a.connectWith.constructor===String?[a.connectWith]:a.connectWith},_getItemsAsjQuery:function(b){var c,d,e,f,g=[],h=[],i=this._connectWith();if(i&&b)for(c=i.length-1;c>=0;c--)for(e=a(i[c]),d=e.length-1;d>=0;d--)f=a.data(e[d],this.widgetFullName),f&&f!==this&&!f.options.disabled&&h.push([a.isFunction(f.options.items)?f.options.items.call(f.element):a(f.options.items,f.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),f]);for(h.push([a.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):a(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]),c=h.length-1;c>=0;c--)h[c][0].each(function(){g.push(this)});return a(g)},_removeCurrentsFromItems:function(){var b=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=a.grep(this.items,function(a){for(var c=0;c=0;c--)for(e=a(m[c]),d=e.length-1;d>=0;d--)f=a.data(e[d],this.widgetFullName),f&&f!==this&&!f.options.disabled&&(l.push([a.isFunction(f.options.items)?f.options.items.call(f.element[0],b,{item:this.currentItem}):a(f.options.items,f.element),f]),this.containers.push(f));for(c=l.length-1;c>=0;c--)for(g=l[c][1],h=l[c][0],d=0,j=h.length;j>d;d++)i=a(h[d]),i.data(this.widgetName+"-item",g),k.push({item:i,instance:g,width:0,height:0,left:0,top:0})},refreshPositions:function(b){this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());var c,d,e,f;for(c=this.items.length-1;c>=0;c--)d=this.items[c],d.instance!==this.currentContainer&&this.currentContainer&&d.item[0]!==this.currentItem[0]||(e=this.options.toleranceElement?a(this.options.toleranceElement,d.item):d.item,b||(d.width=e.outerWidth(),d.height=e.outerHeight()),f=e.offset(),d.left=f.left,d.top=f.top);if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(c=this.containers.length-1;c>=0;c--)f=this.containers[c].element.offset(),this.containers[c].containerCache.left=f.left,this.containers[c].containerCache.top=f.top,this.containers[c].containerCache.width=this.containers[c].element.outerWidth(),this.containers[c].containerCache.height=this.containers[c].element.outerHeight();return this},_createPlaceholder:function(b){b=b||this;var c,d=b.options;d.placeholder&&d.placeholder.constructor!==String||(c=d.placeholder,d.placeholder={element:function(){var d=b.currentItem[0].nodeName.toLowerCase(),e=a("<"+d+">",b.document[0]).addClass(c||b.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper");return"tr"===d?b.currentItem.children().each(function(){a("
",b.document[0]).attr("colspan",a(this).attr("colspan")||1).appendTo(e)}):"img"===d&&e.attr("src",b.currentItem.attr("src")),c||e.css("visibility","hidden"),e},update:function(a,e){(!c||d.forcePlaceholderSize)&&(e.height()||e.height(b.currentItem.innerHeight()-parseInt(b.currentItem.css("paddingTop")||0,10)-parseInt(b.currentItem.css("paddingBottom")||0,10)),e.width()||e.width(b.currentItem.innerWidth()-parseInt(b.currentItem.css("paddingLeft")||0,10)-parseInt(b.currentItem.css("paddingRight")||0,10)))}}),b.placeholder=a(d.placeholder.element.call(b.element,b.currentItem)),b.currentItem.after(b.placeholder),d.placeholder.update(b,b.placeholder)},_contactContainers:function(d){var e,f,g,h,i,j,k,l,m,n,o=null,p=null;for(e=this.containers.length-1;e>=0;e--)if(!a.contains(this.currentItem[0],this.containers[e].element[0]))if(this._intersectsWith(this.containers[e].containerCache)){if(o&&a.contains(this.containers[e].element[0],o.element[0]))continue;o=this.containers[e],p=e}else this.containers[e].containerCache.over&&(this.containers[e]._trigger("out",d,this._uiHash(this)),this.containers[e].containerCache.over=0);if(o)if(1===this.containers.length)this.containers[p].containerCache.over||(this.containers[p]._trigger("over",d,this._uiHash(this)),this.containers[p].containerCache.over=1);else{for(g=1e4,h=null,n=o.floating||c(this.currentItem),i=n?"left":"top",j=n?"width":"height",k=this.positionAbs[i]+this.offset.click[i],f=this.items.length-1;f>=0;f--)a.contains(this.containers[p].element[0],this.items[f].item[0])&&this.items[f].item[0]!==this.currentItem[0]&&(!n||b(this.positionAbs.top+this.offset.click.top,this.items[f].top,this.items[f].height))&&(l=this.items[f].item.offset()[i],m=!1,Math.abs(l-k)>Math.abs(l+this.items[f][j]-k)&&(m=!0,l+=this.items[f][j]),Math.abs(l-k)this.containment[2]&&(f=this.containment[2]+this.offset.click.left),b.pageY-this.offset.click.top>this.containment[3]&&(g=this.containment[3]+this.offset.click.top)),e.grid&&(c=this.originalPageY+Math.round((g-this.originalPageY)/e.grid[1])*e.grid[1],g=this.containment?c-this.offset.click.top>=this.containment[1]&&c-this.offset.click.top<=this.containment[3]?c:c-this.offset.click.top>=this.containment[1]?c-e.grid[1]:c+e.grid[1]:c,d=this.originalPageX+Math.round((f-this.originalPageX)/e.grid[0])*e.grid[0],f=this.containment?d-this.offset.click.left>=this.containment[0]&&d-this.offset.click.left<=this.containment[2]?d:d-this.offset.click.left>=this.containment[0]?d-e.grid[0]:d+e.grid[0]:d)),{top:g-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():i?0:h.scrollTop()),left:f-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():i?0:h.scrollLeft())}},_rearrange:function(a,b,c,d){c?c[0].appendChild(this.placeholder[0]):b.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?b.item[0]:b.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var e=this.counter;this._delay(function(){e===this.counter&&this.refreshPositions(!d)})},_clear:function(a,b){this.reverting=!1;var c,d=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(c in this._storedCSS)("auto"===this._storedCSS[c]||"static"===this._storedCSS[c])&&(this._storedCSS[c]="");this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();for(this.fromOutside&&!b&&d.push(function(a){this._trigger("receive",a,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||b||d.push(function(a){this._trigger("update",a,this._uiHash())}),this!==this.currentContainer&&(b||(d.push(function(a){this._trigger("remove",a,this._uiHash())}),d.push(function(a){return function(b){a._trigger("receive",b,this._uiHash(this))}}.call(this,this.currentContainer)),d.push(function(a){return function(b){a._trigger("update",b,this._uiHash(this))}}.call(this,this.currentContainer)))),c=this.containers.length-1;c>=0;c--)b||d.push(function(a){return function(b){a._trigger("deactivate",b,this._uiHash(this))}}.call(this,this.containers[c])),this.containers[c].containerCache.over&&(d.push(function(a){return function(b){a._trigger("out",b,this._uiHash(this)) -}}.call(this,this.containers[c])),this.containers[c].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,this.cancelHelperRemoval){if(!b){for(this._trigger("beforeStop",a,this._uiHash()),c=0;c
',trigger:"hover",title:"",delay:0,html:!0}}(window.jQuery),function(){var a=function(){!function(){function a(b,c){if({}.hasOwnProperty.call(a.cache,b))return a.cache[b];var d=a.resolve(b);if(!d)throw new Error("Failed to resolve module "+b);var e={id:b,require:a,filename:b,exports:{},loaded:!1,parent:c,children:[]};c&&c.children.push(e);var f=b.slice(0,b.lastIndexOf("/")+1);return a.cache[b]=e.exports,d.call(e.exports,e,e.exports,f,b),e.loaded=!0,a.cache[b]=e.exports}a.modules={},a.cache={},a.resolve=function(b){return{}.hasOwnProperty.call(a.modules,b)?a.modules[b]:void 0},a.define=function(b,c){a.modules[b]=c},a.define("/gif.worker.coffee",function(b){var c,d;c=a("/GIFEncoder.js",b),d=function(a){var b,d,e;return b=new c(a.width,a.height),0===a.index?b.writeHeader():b.firstFrame=!1,b.setRepeat(a.repeat),b.setDelay(a.delay),b.setQuality(a.quality),b.addFrame(a.data),a.last&&b.finish(),d=b.stream(),a.data=d.pages,a.cursor=d.cursor,a.pageSize=d.constructor.pageSize,a.canTransfer?(e=function(b){for(var c,d=0,e=a.data.length;e>d;++d)c=a.data[d],b.push(c.buffer);return b}.call(this,[]),self.postMessage(a,e)):self.postMessage(a)},self.onmessage=function(a){return d(a.data)}}),a.define("/GIFEncoder.js",function(b){function c(){this.page=-1,this.pages=[],this.newPage()}function d(a,b){this.width=~~a,this.height=~~b,this.transparent=null,this.transIndex=0,this.repeat=-1,this.delay=0,this.image=null,this.pixels=null,this.indexedPixels=null,this.colorDepth=null,this.colorTab=null,this.usedEntry=new Array,this.palSize=7,this.dispose=-1,this.firstFrame=!0,this.sample=10,this.out=new c}var e=a("/TypedNeuQuant.js",b),f=a("/LZWEncoder.js",b);c.pageSize=4096,c.charMap={};for(var g=0;256>g;g++)c.charMap[g]=String.fromCharCode(g);c.prototype.newPage=function(){this.pages[++this.page]=new Uint8Array(c.pageSize),this.cursor=0},c.prototype.getData=function(){for(var a="",b=0;b=c.pageSize&&this.newPage(),this.pages[this.page][this.cursor++]=a},c.prototype.writeUTFBytes=function(a){for(var b=a.length,c=0;b>c;c++)this.writeByte(a.charCodeAt(c))},c.prototype.writeBytes=function(a,b,c){for(var d=c||a.length,e=b||0;d>e;e++)this.writeByte(a[e])},d.prototype.setDelay=function(a){this.delay=Math.round(a/10)},d.prototype.setFrameRate=function(a){this.delay=Math.round(100/a)},d.prototype.setDispose=function(a){a>=0&&(this.dispose=a)},d.prototype.setRepeat=function(a){this.repeat=a},d.prototype.setTransparent=function(a){this.transparent=a},d.prototype.addFrame=function(a){this.image=a,this.getImagePixels(),this.analyzePixels(),this.firstFrame&&(this.writeLSD(),this.writePalette(),this.repeat>=0&&this.writeNetscapeExt()),this.writeGraphicCtrlExt(),this.writeImageDesc(),this.firstFrame||this.writePalette(),this.writePixels(),this.firstFrame=!1},d.prototype.finish=function(){this.out.writeByte(59)},d.prototype.setQuality=function(a){1>a&&(a=1),this.sample=a},d.prototype.writeHeader=function(){this.out.writeUTFBytes("GIF89a")},d.prototype.analyzePixels=function(){var a=this.pixels.length,b=a/3;this.indexedPixels=new Uint8Array(b);var c=new e(this.pixels,this.sample);c.buildColormap(),this.colorTab=c.getColormap();for(var d=0,f=0;b>f;f++){var g=c.lookupRGB(255&this.pixels[d++],255&this.pixels[d++],255&this.pixels[d++]);this.usedEntry[g]=!0,this.indexedPixels[f]=g}this.pixels=null,this.colorDepth=8,this.palSize=7,null!==this.transparent&&(this.transIndex=this.findClosest(this.transparent))},d.prototype.findClosest=function(a){if(null===this.colorTab)return-1;for(var b=(16711680&a)>>16,c=(65280&a)>>8,d=255&a,e=0,f=16777216,g=this.colorTab.length,h=0;g>h;){var i=b-(255&this.colorTab[h++]),j=c-(255&this.colorTab[h++]),k=d-(255&this.colorTab[h]),l=i*i+j*j+k*k,m=h/3;this.usedEntry[m]&&f>l&&(f=l,e=m),h++}return e},d.prototype.getImagePixels=function(){var a=this.width,b=this.height;this.pixels=new Uint8Array(3*a*b);for(var c=this.image,d=0,e=0;b>e;e++)for(var f=0;a>f;f++){var g=4*e*a+4*f;this.pixels[d++]=c[g],this.pixels[d++]=c[g+1],this.pixels[d++]=c[g+2]}},d.prototype.writeGraphicCtrlExt=function(){this.out.writeByte(33),this.out.writeByte(249),this.out.writeByte(4);var a,b;null===this.transparent?(a=0,b=0):(a=1,b=2),this.dispose>=0&&(b=7&dispose),b<<=2,this.out.writeByte(0|(0|b)|a),this.writeShort(this.delay),this.out.writeByte(this.transIndex),this.out.writeByte(0)},d.prototype.writeImageDesc=function(){this.out.writeByte(44),this.writeShort(0),this.writeShort(0),this.writeShort(this.width),this.writeShort(this.height),this.firstFrame?this.out.writeByte(0):this.out.writeByte(128|this.palSize)},d.prototype.writeLSD=function(){this.writeShort(this.width),this.writeShort(this.height),this.out.writeByte(240|this.palSize),this.out.writeByte(0),this.out.writeByte(0)},d.prototype.writeNetscapeExt=function(){this.out.writeByte(33),this.out.writeByte(255),this.out.writeByte(11),this.out.writeUTFBytes("NETSCAPE2.0"),this.out.writeByte(3),this.out.writeByte(1),this.writeShort(this.repeat),this.out.writeByte(0)},d.prototype.writePalette=function(){this.out.writeBytes(this.colorTab);for(var a=768-this.colorTab.length,b=0;a>b;b++)this.out.writeByte(0)},d.prototype.writeShort=function(a){this.out.writeByte(255&a),this.out.writeByte(255&a>>8)},d.prototype.writePixels=function(){var a=new f(this.width,this.height,this.indexedPixels,this.colorDepth);a.encode(this.out)},d.prototype.stream=function(){return this.out},b.exports=d}),a.define("/LZWEncoder.js",function(a){function b(a,b,g,h){function i(a,b){y[s++]=a,s>=254&&n(b)}function j(a){k(e),C=v+2,D=!0,q(v,a)}function k(a){for(var b=0;a>b;++b)z[b]=-1}function l(a,b){var f,g,h,i,l,m,n;for(u=a,D=!1,n_bits=u,t=o(n_bits),v=1<f;f*=2)++n;n=8-n,m=e,k(m),q(v,b);a:for(;(g=p())!=c;)if(f=(g<=0){l=m-h,0===h&&(l=1);do if((h-=l)<0&&(h+=m),z[h]===f){i=A[h];continue a}while(z[h]>=0)}q(i,b),i=g,1<C?(A[h]=C++,z[h]=f):j(b)}else i=A[h];q(i,b),q(w,b)}function m(c){c.writeByte(x),remaining=a*b,curPixel=0,l(x+1,c),c.writeByte(0)}function n(a){s>0&&(a.writeByte(s),a.writeBytes(y,0,s),s=0)}function o(a){return(1<0?r|=a<=8;)i(255&r,b),r>>=8,B-=8;if((C>t||D)&&(D?(t=o(n_bits=u),D=!1):(++n_bits,t=n_bits==d?1<0;)i(255&r,b),r>>=8,B-=8;n(b)}}var r,s,t,u,v,w,x=Math.max(2,h),y=new Uint8Array(256),z=new Int32Array(e),A=new Int32Array(e),B=0,C=0,D=!1;this.encode=m}var c=-1,d=12,e=5003,f=[0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535];a.exports=b}),a.define("/TypedNeuQuant.js",function(a){function b(a,b){function m(){H=[],I=new Int32Array(256),J=new Int32Array(d),K=new Int32Array(d),L=new Int32Array(d>>3);var a,b;for(a=0;d>a;a++)b=(a<a;a++)H[a][0]>>=f,H[a][1]>>=f,H[a][2]>>=f,H[a][3]=a}function r(a,b,c,d,e){H[b][0]-=a*(H[b][0]-c)/s,H[b][1]-=a*(H[b][1]-d)/s,H[b][2]-=a*(H[b][2]-e)/s}function t(a,b,c,e,f){for(var g,h,i=Math.abs(b-a),j=Math.min(b+a,d),k=b+1,l=b-1,m=1;j>k||l>i;)h=L[m++],j>k&&(g=H[k++],g[0]-=h*(g[0]-c)/w,g[1]-=h*(g[1]-e)/w,g[2]-=h*(g[2]-f)/w),l>i&&(g=H[l--],g[0]-=h*(g[0]-c)/w,g[1]-=h*(g[1]-e)/w,g[2]-=h*(g[2]-f)/w)}function v(a,b,c){var e,h,m,n,o,p=2147483647,q=p,r=-1,s=r;for(e=0;d>e;e++)h=H[e],m=Math.abs(h[0]-a)+Math.abs(h[1]-b)+Math.abs(h[2]-c),p>m&&(p=m,r=e),n=m-(J[e]>>g-f),q>n&&(q=n,s=e),o=K[e]>>j,K[e]-=o,J[e]+=o<a;a++){for(c=H[a],g=a,h=c[1],b=a+1;d>b;b++)f=H[b],f[1]>1,b=i+1;h>b;b++)I[b]=a;i=h,j=a}}for(I[i]=j+e>>1,b=i+1;256>b;b++)I[b]=e}function D(a,b,c){for(var e,f,g,h=1e3,i=-1,j=I[b],k=j-1;d>j||k>=0;)d>j&&(f=H[j],g=f[1]-b,g>=h?j=d:(j++,0>g&&(g=-g),e=f[0]-a,0>e&&(e=-e),g+=e,h>g&&(e=f[2]-c,0>e&&(e=-e),g+=e,h>g&&(h=g,i=f[3])))),k>=0&&(f=H[k],g=b-f[1],g>=h?k=-1:(k--,0>g&&(g=-g),e=f[0]-a,0>e&&(e=-e),g+=e,h>g&&(e=f[2]-c,0>e&&(e=-e),g+=e,h>g&&(h=g,i=f[3]))));return i}function E(){var d,e=a.length,g=30+(b-1)/3,h=e/(3*b),i=~~(h/c),j=s,k=p,l=k>>n;for(1>=l&&(l=0),d=0;l>d;d++)L[d]=j*((l*l-d*d)*u/(l*l));var m;B>e?(b=1,m=3):m=0!==e%x?3*x:0!==e%y?3*y:0!==e%z?3*z:3*A;var o,w,C,D,E=0;for(d=0;h>d;)if(o=(255&a[E])<=e&&(E-=e),d++,0===i&&(i=1),0===d%i)for(j-=j/g,k-=k/q,l=k>>n,1>=l&&(l=0),D=0;l>D;D++)L[D]=j*((l*l-D*D)*u/(l*l))}function F(){m(),E(),o(),C()}function G(){for(var a=[],b=[],c=0;d>c;c++)b[H[c][3]]=c;for(var e=0,f=0;d>f;f++){var g=b[f];a[e++]=H[g][0],a[e++]=H[g][1],a[e++]=H[g][2]}return a}var H,I,J,K,L;this.buildColormap=F,this.getColormap=G,this.lookupRGB=D}var c=100,d=256,e=d-1,f=4,g=16,h=1<>j,l=h<>3,n=6,o=1<c;++c)if(c in b&&b[c]===a)return!0;return!1}function e(a,b){function d(){this.constructor=a}for(var e in b)c(b,e)&&(a[e]=b[e]);return d.prototype=b.prototype,a.prototype=new d,a.__super__=b.prototype,a}var f,g,h;g=b("events",a).EventEmitter,f=b("/browser.coffee",a),h=function(a,b,g){function h(a){var c,d;this.running=!1,this.options={},this.frames=[],this.freeWorkers=[],this.activeWorkers=[],this.setOptions(a);for(c in b)d=b[c],null!=this.options[c]?this.options[c]:this.options[c]=d}return e(h,a),b={workerScript:window.GifWorkerURL,workers:2,repeat:0,background:"#fff",quality:10,width:null,height:null},g={delay:500,copy:!1},h.prototype.setOption=function(a,b){return this.options[a]=b,null==this._canvas||"width"!==a&&"height"!==a?void 0:this._canvas[a]=b},h.prototype.setOptions=function(a){return function(b){var d,e;for(d in a)c(a,d)&&(e=a[d],b.push(this.setOption(d,e)));return b}.call(this,[])},h.prototype.addFrame=function(a,b){var c,d;null==b&&(b={}),c={};for(d in g)c[d]=b[d]||g[d];if(null!=this.options.width||this.setOption("width",a.width),null!=this.options.height||this.setOption("height",a.height),"undefined"!=typeof ImageData&&null!=ImageData&&a instanceof ImageData)c.data=a.data;else if("undefined"!=typeof CanvasRenderingContext2D&&null!=CanvasRenderingContext2D&&a instanceof CanvasRenderingContext2D||"undefined"!=typeof WebGLRenderingContext&&null!=WebGLRenderingContext&&a instanceof WebGLRenderingContext)b.copy?c.data=this.getContextData(a):c.context=a;else{if(null==a.childNodes)throw new Error("Invalid image");b.copy?c.data=this.getImageData(a):c.image=a}return this.frames.push(c)},h.prototype.render=function(){var a,b;if(this.running)throw new Error("Already running");if(null==this.options.width||null==this.options.height)throw new Error("Width and height must be set prior to rendering");this.running=!0,this.nextFrame=0,this.finishedFrames=0,this.imageParts=function(a){for(var b,c=0,d=function(){var a,a;a=[];for(var b=0;0<=this.frames.length?bthis.frames.length;0<=this.frames.length?++b:--b)a.push(b);return a}.apply(this,arguments).length;d>c;++c)b=function(){var a,a;a=[];for(var b=0;0<=this.frames.length?bthis.frames.length;0<=this.frames.length?++b:--b)a.push(b);return a}.apply(this,arguments)[c],a.push(null);return a}.call(this,[]),b=this.spawnWorkers();for(var c=0,d=function(){var a,a;a=[];for(var c=0;b>=0?b>c:c>b;b>=0?++c:--c)a.push(c);return a}.apply(this,arguments).length;d>c;++c)a=function(){var a,a;a=[];for(var c=0;b>=0?b>c:c>b;b>=0?++c:--c)a.push(c);return a}.apply(this,arguments)[c],this.renderNextFrame();return this.emit("start"),this.emit("progress",0)},h.prototype.abort=function(){for(var a;;){if(a=this.activeWorkers.shift(),!(null!=a))break;console.log("killing active worker"),a.terminate()}return this.running=!1,this.emit("abort")},h.prototype.spawnWorkers=function(){var a,b;return a=Math.min(this.options.workers,this.frames.length),function(){var b;b=[];for(var c=this.freeWorkers.length;this.freeWorkers.length<=a?a>c:c>a;this.freeWorkers.length<=a?++c:--c)b.push(c);return b}.apply(this,arguments).forEach((b=this,function(a){var c,d;return console.log("spawning worker "+a),d=new Worker(b.options.workerScript),c=b,d.onmessage=function(a){return c.activeWorkers.splice(c.activeWorkers.indexOf(d),1),c.freeWorkers.push(d),c.frameFinished(a.data)},b.freeWorkers.push(d)})),a},h.prototype.frameFinished=function(a){return console.log("frame "+a.index+" finished - "+this.activeWorkers.length+" active"),this.finishedFrames++,this.emit("progress",this.finishedFrames/this.frames.length),this.imageParts[a.index]=a,d(null,this.imageParts)?this.renderNextFrame():this.finishRendering()},h.prototype.finishRendering=function(){var a,b,c,d,e,f,g;e=0;for(var h=0,i=this.imageParts.length;i>h;++h)b=this.imageParts[h],e+=(b.data.length-1)*b.pageSize+b.cursor;e+=b.pageSize-b.cursor,console.log("rendering finished - filesize "+Math.round(e/1e3)+"kb"),a=new Uint8Array(e),f=0;for(var j=0,k=this.imageParts.length;k>j;++j){b=this.imageParts[j];for(var l=0,m=b.data.length;m>l;++l)g=b.data[l],c=l,a.set(g,f),f+=c===b.data.length-1?b.cursor:b.pageSize}return d=new Blob([a],{type:"image/gif"}),this.emit("finished",d,a)},h.prototype.renderNextFrame=function(){var a,b,c;if(0===this.freeWorkers.length)throw new Error("No free workers");return this.nextFrame>=this.frames.length?void 0:(a=this.frames[this.nextFrame++],c=this.freeWorkers.shift(),b=this.getTask(a),console.log("starting frame "+(b.index+1)+" of "+this.frames.length),this.activeWorkers.push(c),c.postMessage(b))},h.prototype.getContextData=function(a){return a.getImageData(0,0,this.options.width,this.options.height).data},h.prototype.getImageData=function(a){var b;return null!=this._canvas||(this._canvas=document.createElement("canvas"),this._canvas.width=this.options.width,this._canvas.height=this.options.height),b=this._canvas.getContext("2d"),b.setFill=this.options.background,b.fillRect(0,0,this.options.width,this.options.height),b.drawImage(a,0,0),this.getContextData(b)},h.prototype.getTask=function(a){var b,c;if(b=this.frames.indexOf(a),c={index:b,last:b===this.frames.length-1,delay:a.delay,width:this.options.width,height:this.options.height,quality:this.options.quality,repeat:this.options.repeat,canTransfer:"chrome"===f.name},null!=a.data)c.data=a.data;else if(null!=a.context)c.data=this.getContextData(a.context);else{if(null==a.image)throw new Error("Invalid frame");c.data=this.getImageData(a.image)}return c},h}(g),a.exports=h}),b.define("/browser.coffee",function(a){var b,c,d,e,f;e=navigator.userAgent.toLowerCase(),d=navigator.platform.toLowerCase(),f=e.match(/(opera|ie|firefox|chrome|version)[\s\/:]([\w\d\.]+)?.*?(safari|version[\s\/:]([\w\d\.]+)|$)/)||[null,"unknown",0],c="ie"===f[1]&&document.documentMode,b={name:"version"===f[1]?f[3]:f[1],version:c||parseFloat("opera"===f[1]&&f[4]?f[4]:f[2]),platform:{name:e.match(/ip(?:ad|od|hone)/)?"ios":(e.match(/(?:webos|android)/)||d.match(/mac|win|linux/)||["other"])[0]}},b[b.name]=!0,b[b.name+parseInt(b.version,10)]=!0,b.platform[b.platform.name]=!0,a.exports=b}),b.define("events",function(a,b){c.EventEmitter||(c.EventEmitter=function(){});var d=b.EventEmitter=c.EventEmitter,e="function"==typeof Array.isArray?Array.isArray:function(a){return"[object Array]"===Object.prototype.toString.call(a)},f=10;d.prototype.setMaxListeners=function(a){this._events||(this._events={}),this._events.maxListeners=a},d.prototype.emit=function(a){if("error"===a&&(!this._events||!this._events.error||e(this._events.error)&&!this._events.error.length))throw arguments[1]instanceof Error?arguments[1]:new Error("Uncaught, unspecified 'error' event.");if(!this._events)return!1;var b=this._events[a];if(!b)return!1;if("function"!=typeof b){if(e(b)){for(var c=Array.prototype.slice.call(arguments,1),d=b.slice(),f=0,g=d.length;g>f;f++)d[f].apply(this,c);return!0}return!1}switch(arguments.length){case 1:b.call(this);break;case 2:b.call(this,arguments[1]);break;case 3:b.call(this,arguments[1],arguments[2]);break;default:var c=Array.prototype.slice.call(arguments,1);b.apply(this,c)}return!0},d.prototype.addListener=function(a,b){if("function"!=typeof b)throw new Error("addListener only takes instances of Function");if(this._events||(this._events={}),this.emit("newListener",a,b),this._events[a])if(e(this._events[a])){if(!this._events[a].warned){var c;c=void 0!==this._events.maxListeners?this._events.maxListeners:f,c&&c>0&&this._events[a].length>c&&(this._events[a].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[a].length),console.trace())}this._events[a].push(b)}else this._events[a]=[this._events[a],b];else this._events[a]=b;return this},d.prototype.on=d.prototype.addListener,d.prototype.once=function(a,b){var c=this;return c.on(a,function d(){c.removeListener(a,d),b.apply(this,arguments)}),this},d.prototype.removeListener=function(a,b){if("function"!=typeof b)throw new Error("removeListener only takes instances of Function");if(!this._events||!this._events[a])return this;var c=this._events[a];if(e(c)){var d=c.indexOf(b);if(0>d)return this;c.splice(d,1),0==c.length&&delete this._events[a]}else this._events[a]===b&&delete this._events[a];return this},d.prototype.removeAllListeners=function(a){return a&&this._events&&this._events[a]&&(this._events[a]=null),this},d.prototype.listeners=function(a){return this._events||(this._events={}),this._events[a]||(this._events[a]=[]),e(this._events[a])||(this._events[a]=[this._events[a]]),this._events[a]}}),a.GIF=b("/gif.coffee")}.call(this,this);var Constants={DEFAULT:{HEIGHT:32,WIDTH:32,FPS:12},MODEL_VERSION:1,MAX_HEIGHT:1024,MAX_WIDTH:1024,PREVIEW_FILM_SIZE:120,DEFAULT_PEN_COLOR:"#000000",TRANSPARENT_COLOR:"TRANSPARENT",SELECTION_TRANSPARENT_COLOR:"rgba(255, 255, 255, 0.6)",TOOL_TARGET_HIGHLIGHT_COLOR:"rgba(255, 255, 255, 0.2)",STATIC:{URL:{SAVE:"http://3.piskel-app.appspot.com/store",GET:"http://3.piskel-app.appspot.com/get"}},APPENGINE:{URL:{SAVE:"save"}},IMAGE_SERVICE_UPLOAD_URL:"http://screenletstore.appspot.com/__/upload",IMAGE_SERVICE_GET_URL:"http://screenletstore.appspot.com/img/",GRID_STROKE_WIDTH:1,LEFT_BUTTON:"left_button_1",RIGHT_BUTTON:"right_button_2"},Events={TOOL_SELECTED:"TOOL_SELECTED",TOOL_RELEASED:"TOOL_RELEASED",PRIMARY_COLOR_SELECTED:"PRIMARY_COLOR_SELECTED",PRIMARY_COLOR_UPDATED:"PRIMARY_COLOR_UPDATED",SECONDARY_COLOR_SELECTED:"SECONDARY_COLOR_SELECTED",SECONDARY_COLOR_UPDATED:"SECONDARY_COLOR_UPDATED",LOCALSTORAGE_REQUEST:"LOCALSTORAGE_REQUEST",CANVAS_RIGHT_CLICKED:"CANVAS_RIGHT_CLICKED",REFRESH:"REFRESH",REDRAW_PREVIEWFILM:"REDRAW_PREVIEWFILM",USER_SETTINGS_CHANGED:"USER_SETTINGS_CHANGED",PISKEL_RESET:"PISKEL_RESET",FRAME_SIZE_CHANGED:"FRAME_SIZE_CHANGED",CURRENT_FRAME_SET:"CURRENT_FRAME_SET",SELECTION_CREATED:"SELECTION_CREATED",SELECTION_MOVE_REQUEST:"SELECTION_MOVE_REQUEST",SELECTION_DISMISSED:"SELECTION_DISMISSED",SHOW_NOTIFICATION:"SHOW_NOTIFICATION",HIDE_NOTIFICATION:"HIDE_NOTIFICATION",UNDO:"UNDO",REDO:"REDO",CUT:"CUT",COPY:"COPY",PASTE:"PASTE"};jQuery.namespace=function(){var a,b,c,d=arguments,e=null;for(a=0;a255||b>255||c>255)throw"Invalid color component";return(a<<16|b<<8|c).toString(16)},a.inherit=function(a,b){a.prototype=Object.create(b.prototype),a.prototype.constructor=a,a.prototype.superclass=b.prototype}}(),function(){var a=$.namespace("pskl");a.CanvasUtils={createCanvas:function(a,b,c){var d=document.createElement("canvas");if(d.setAttribute("width",a),d.setAttribute("height",b),"string"==typeof c&&(c=[c]),Array.isArray(c))for(var e=0;e0;){k++;var m=g.pop();a.setPixel(m.col,m.row,d),f.push({col:m.col,row:m.row});for(var n=0;4>n;n++){var o=m.col+i[n],p=m.row+h[n];try{a.containsPixel(o,p)&&a.getPixel(o,p)==e&&g.push({col:o,row:p})}catch(j){}}if(k>10*l){console.log("loop breaker called");break}}return f}},calculateDPIForContainer:function(a,b,c){return this.calculateDPI(a.height(),a.width(),b,c)},calculateDPI:function(a,b,c,d){var e=Math.floor(a/c),f=Math.floor(b/d);return Math.min(e,f)}}}(),function(){var a=$.namespace("pskl.utils");a.Serializer={serializePiskel:function(a){var b=a.getLayers().map(function(a){return pskl.utils.Serializer.serializeLayer(a)});return JSON.stringify({modelVersion:Constants.MODEL_VERSION,piskel:{height:a.getHeight(),width:a.getWidth(),layers:b}})},serializeLayer:function(a){var b=a.getFrames().map(function(a){return a.serialize()});return JSON.stringify({name:a.getName(),frames:b})},deserializePiskel:function(a){var b=JSON.parse(a);return this.createPiskelFromData(b)},createPiskel:function(a){var b=null;if(a.modelVersion==Constants.MODEL_VERSION){var c=a.piskel;b=new pskl.model.Piskel(c.width,c.height),c.layers.forEach(function(a){var c=pskl.utils.Serializer.deserializeLayer(a);b.addLayer(c)})}else b=pskl.utils.Serializer.backwardDeserializer_(a);return b},deserializeLayer:function(a){var b=JSON.parse(a),c=new pskl.model.Layer(b.name);return b.frames.forEach(function(a){var b=pskl.utils.Serializer.deserializeFrame(a);c.addFrame(b)}),c},deserializeFrame:function(a){var b=JSON.parse(a);return pskl.model.Frame.fromPixelGrid(b)},backwardDeserializer_:function(a){var b=new pskl.model.Layer("Layer 1");a.forEach(function(a){b.addFrame(pskl.model.Frame.fromPixelGrid(a))});var c=b.getFrameAt(0).getWidth(),d=b.getFrameAt(0).getHeight(),e=new pskl.model.Piskel(c,d);return e.addLayer(b),e}}}(),function(){var a=$.namespace("pskl");a.utils.Template={get:function(a){var b=document.getElementById(a);return b?b.innerHTML:(console.error("Could not find template for id :",a),void 0)},createFromHTML:function(a){var b=document.createElement("div");return b.innerHTML=a,b.children[0]},replace:function(a,b){for(var c in b)if(b.hasOwnProperty(c)){var d=b[c];a=a.replace(new RegExp("\\{\\{"+c+"\\}\\}","g"),d)}return a}}}(),function(){var a=$.namespace("pskl");a.UserSettings={SHOW_GRID:"SHOW_GRID",CANVAS_BACKGROUND:"CANVAS_BACKGROUND",KEY_TO_DEFAULT_VALUE_MAP_:{SHOW_GRID:!1,CANVAS_BACKGROUND:"medium-canvas-background"},cache_:{},get:function(a){return this.checkKeyValidity_(a),a in this.cache_||(this.cache_[a]=this.readFromLocalStorage_(a)||this.readFromDefaults_(a)),this.cache_[a]},set:function(a,b){this.checkKeyValidity_(a),this.cache_[a]=b,this.writeToLocalStorage_(a,b),$.publish(Events.USER_SETTINGS_CHANGED,[a,b])},readFromLocalStorage_:function(a){var b=window.localStorage[a];return"undefined"!=typeof b&&(b=JSON.parse(b)),b},writeToLocalStorage_:function(a,b){window.localStorage[a]=JSON.stringify(b)},readFromDefaults_:function(a){return this.KEY_TO_DEFAULT_VALUE_MAP_[a]},checkKeyValidity_:function(a){a in this.KEY_TO_DEFAULT_VALUE_MAP_||console.log("UserSettings key <"+a+"> not find in supported keys.")}}}();var jscolor={dir:"",bindClass:"color",binding:!0,preloading:!0,install:function(){"complete"===document.readyState?jscolor.init():jscolor.addEvent(window,"load",jscolor.init)},init:function(){jscolor.binding&&jscolor.bind(),jscolor.preloading&&jscolor.preload()},getDir:function(){return"/"+window.location.pathname.split("/")[1]+"/js/lib/jsColor_1_4_0/"},bind:function(){for(var a=new RegExp("(^|\\s)("+jscolor.bindClass+")\\s*(\\{[^}]*\\})?","i"),b=document.getElementsByTagName("input"),c=0;ck[b]?-i[b]+e[b]+h[b]/2>k[b]/2&&e[b]+h[b]-l[b]>=0?e[b]+h[b]-l[b]:e[b]:e[b],-i[c]+e[c]+h[c]+l[c]-m+m*d>k[c]?-i[c]+e[c]+h[c]/2>k[c]/2&&e[c]+h[c]-m-m*d>=0?e[c]+h[c]-m-m*d:e[c]+h[c]-m+m*d:e[c]+h[c]-m+m*d>=0?e[c]+h[c]-m+m*d:e[c]+h[c]-m-m*d];else var n=[e[b],e[c]+h[c]-m+m*d];f(n[b],n[c])}},this.importColor=function(){t?this.adjust?!this.required&&/^\s*$/.test(t.value)?(t.value="",u.style.backgroundImage=u.jscStyle.backgroundImage,u.style.backgroundColor=u.jscStyle.backgroundColor,u.style.color=u.jscStyle.color,this.exportColor(x|y)):this.fromString(t.value)||this.exportColor():this.fromString(t.value,x)||(u.style.backgroundImage=u.jscStyle.backgroundImage,u.style.backgroundColor=u.jscStyle.backgroundColor,u.style.color=u.jscStyle.color,this.exportColor(x|y)):this.exportColor()},this.exportColor=function(a){if(!(a&x)&&t){var b=this.toString();this.caps&&(b=b.toUpperCase()),this.hash&&(b="#"+b),t.value=b}a&y||!u||(u.style.backgroundImage="none",u.style.backgroundColor="#"+this.toString(),u.style.color=.213*this.rgb[0]+.715*this.rgb[1]+.072*this.rgb[2]<.5?"#FFF":"#000"),a&z||!j()||h(),a&A||!j()||i()},this.fromHSV=function(a,b,c,e){null!==a&&(a=Math.max(0,this.minH,Math.min(6,this.maxH,a))),null!==b&&(b=Math.max(0,this.minS,Math.min(1,this.maxS,b))),null!==c&&(c=Math.max(0,this.minV,Math.min(1,this.maxV,c))),this.rgb=d(null===a?this.hsv[0]:this.hsv[0]=a,null===b?this.hsv[1]:this.hsv[1]=b,null===c?this.hsv[2]:this.hsv[2]=c),this.exportColor(e)},this.fromRGB=function(a,b,e,f){null!==a&&(a=Math.max(0,Math.min(1,a))),null!==b&&(b=Math.max(0,Math.min(1,b))),null!==e&&(e=Math.max(0,Math.min(1,e)));var g=c(null===a?this.rgb[0]:a,null===b?this.rgb[1]:b,null===e?this.rgb[2]:e);null!==g[0]&&(this.hsv[0]=Math.max(0,this.minH,Math.min(6,this.maxH,g[0]))),0!==g[2]&&(this.hsv[1]=null===g[1]?null:Math.max(0,this.minS,Math.min(1,this.maxS,g[1]))),this.hsv[2]=null===g[2]?null:Math.max(0,this.minV,Math.min(1,this.maxV,g[2]));var h=d(this.hsv[0],this.hsv[1],this.hsv[2]);this.rgb[0]=h[0],this.rgb[1]=h[1],this.rgb[2]=h[2],this.exportColor(f)},this.fromString=function(a,b){var c=a.match(/^\W*([0-9A-F]{3}([0-9A-F]{3})?)\W*$/i);return c?(6===c[1].length?this.fromRGB(parseInt(c[1].substr(0,2),16)/255,parseInt(c[1].substr(2,2),16)/255,parseInt(c[1].substr(4,2),16)/255,b):this.fromRGB(parseInt(c[1].charAt(0)+c[1].charAt(0),16)/255,parseInt(c[1].charAt(1)+c[1].charAt(1),16)/255,parseInt(c[1].charAt(2)+c[1].charAt(2),16)/255,b),!0):!1},this.toString=function(){return(256|Math.round(255*this.rgb[0])).toString(16).substr(1)+(256|Math.round(255*this.rgb[1])).toString(16).substr(1)+(256|Math.round(255*this.rgb[2])).toString(16).substr(1)};var q=this,r="hvs"===this.pickerMode.toLowerCase()?1:0,s=!1,t=jscolor.fetchElement(this.valueElement),u=jscolor.fetchElement(this.styleElement),v=!1,w=!1,x=1,y=2,z=4,A=8;if(jscolor.addEvent(a,"focus",function(){q.pickerOnfocus&&q.showPicker()}),jscolor.addEvent(a,"blur",function(){s?s=!1:window.setTimeout(function(){s||k(),s=!1},0)}),t){var B=function(){q.fromString(t.value,x),o()};jscolor.addEvent(t,"keyup",B),jscolor.addEvent(t,"input",B),jscolor.addEvent(t,"blur",l),t.setAttribute("autocomplete","off")}switch(u&&(u.jscStyle={backgroundImage:u.style.backgroundImage,backgroundColor:u.style.backgroundColor,color:u.style.color}),r){case 0:jscolor.requireImage("hs.png");break;case 1:jscolor.requireImage("hv.png")}jscolor.requireImage("cross.gif"),jscolor.requireImage("arrow.gif"),this.importColor()}};!function(){var a=$.namespace("pskl.rendering");a.DrawingLoop=function(){this.requestAnimationFrame=this.getRequestAnimationFrameShim_(),this.isRunning=!1,this.previousTime=0,this.callbacks=[]},a.DrawingLoop.prototype.addCallback=function(a,b,c){var d={fn:a,scope:b,args:c};return this.callbacks.push(d),d},a.DrawingLoop.prototype.removeCallback=function(a){var b=this.callbacks.indexOf(a);-1!=b&&this.callbacks.splice(b,1)},a.DrawingLoop.prototype.start=function(){this.isRunning=!0,this.loop_()},a.DrawingLoop.prototype.loop_=function(){var a=Date.now(),b=a-this.previousTime;this.executeCallbacks_(b),this.previousTime=a,this.requestAnimationFrame.call(window,this.loop_.bind(this))},a.DrawingLoop.prototype.executeCallbacks_=function(a){for(var b=0;bd;d++){for(var e=[],f=0;b>f;f++)e.push(Constants.TRANSPARENT_COLOR);c[d]=e}return c},a.Frame.createEmptyFromFrame=function(b){return new a.Frame(b.getWidth(),b.getHeight())},a.Frame.prototype.clone=function(){var b=new a.Frame(this.width,this.height);return b.setPixels(this.getPixels()),b},a.Frame.prototype.getPixels=function(){return this.clonePixels_(this.pixels)},a.Frame.prototype.setPixels=function(a){this.pixels=this.clonePixels_(a)},a.Frame.prototype.clear=function(){var b=a.Frame.createEmptyPixelGrid_(this.getWidth(),this.getHeight());this.setPixels(b)},a.Frame.prototype.clonePixels_=function(a){for(var b=[],c=0;c=0&&b>=0&&a0&&(this.stateIndex--,this.setPixels(this.previousStates[this.stateIndex]))},a.Frame.prototype.loadNextState=function(){this.stateIndex-1&&b0&&(this.layers[b]=this.layers[b-1],this.layers[b-1]=a)},a.Piskel.prototype.removeLayer=function(a){var b=this.layers.indexOf(a);-1!=b&&this.layers.splice(b,1)},a.Piskel.prototype.removeLayerAt=function(a){this.layers.splice(a,1)}}(),function(){var a=$.namespace("pskl.selection");a.SelectionManager=function(a){this.piskelController=a,this.currentSelection=null},a.SelectionManager.prototype.init=function(){$.subscribe(Events.SELECTION_CREATED,$.proxy(this.onSelectionCreated_,this)),$.subscribe(Events.SELECTION_DISMISSED,$.proxy(this.onSelectionDismissed_,this)),$.subscribe(Events.SELECTION_MOVE_REQUEST,$.proxy(this.onSelectionMoved_,this)),$.subscribe(Events.PASTE,$.proxy(this.onPaste_,this)),$.subscribe(Events.COPY,$.proxy(this.onCopy_,this)),$.subscribe(Events.CUT,$.proxy(this.onCut_,this)),$.subscribe(Events.TOOL_SELECTED,$.proxy(this.onToolSelected_,this))},a.SelectionManager.prototype.cleanSelection_=function(){this.currentSelection&&this.currentSelection.reset()},a.SelectionManager.prototype.onToolSelected_=function(a,b){var c=b instanceof pskl.drawingtools.BaseSelect;c||this.cleanSelection_()},a.SelectionManager.prototype.onSelectionDismissed_=function(){this.cleanSelection_()},a.SelectionManager.prototype.onCut_=function(){if(!this.currentSelection)throw"Bad state for CUT callback in SelectionManager";this.currentSelection.fillSelectionFromFrame(this.piskelController.getCurrentFrame());for(var a=this.currentSelection.pixels,b=this.piskelController.getCurrentFrame(),c=0,d=a.length;d>c;c++)try{b.setPixel(a[c].col,a[c].row,Constants.TRANSPARENT_COLOR)}catch(e){}},a.SelectionManager.prototype.onPaste_=function(){if(this.currentSelection&&this.currentSelection.hasPastedContent)for(var a=this.currentSelection.pixels,b=this.piskelController.getCurrentFrame(),c=0,d=a.length;d>c;c++)try{b.setPixel(a[c].col,a[c].row,a[c].copiedColor)}catch(e){}},a.SelectionManager.prototype.onCopy_=function(){if(!this.currentSelection||!this.piskelController.getCurrentFrame())throw"Bad state for CUT callback in SelectionManager";this.currentSelection.fillSelectionFromFrame(this.piskelController.getCurrentFrame())},a.SelectionManager.prototype.onSelectionCreated_=function(a,b){if(!b)throw"No selection set in SelectionManager";this.currentSelection=b},a.SelectionManager.prototype.onSelectionMoved_=function(a,b,c){if(!this.currentSelection)throw"Bad state: No currentSelection set when trying to move it in SelectionManager";this.currentSelection.move(b,c)}}(),function(){var a=$.namespace("pskl.selection");a.BaseSelection=function(){this.reset()},a.BaseSelection.prototype.reset=function(){this.pixels=[],this.hasPastedContent=!1},a.BaseSelection.prototype.move=function(a,b){for(var c,d=[],e=0,f=this.pixels.length;f>e;e++)c=this.pixels[e],c.col+=a,c.row+=b,d.push(c);this.pixels=d},a.BaseSelection.prototype.fillSelectionFromFrame=function(a){for(var b,c=0,d=this.pixels.length;d>c;c++)b=this.pixels[c],b.copiedColor=a.getPixel(b.col,b.row);this.hasPastedContent=!0}}(),function(){var a=$.namespace("pskl.selection");a.RectangularSelection=function(a,b,c,d){this.pixels=pskl.PixelUtils.getRectanglePixels(a,b,c,d)},pskl.utils.inherit(a.RectangularSelection,a.BaseSelection)}(),function(){var a=$.namespace("pskl.selection");a.ShapeSelection=function(a){this.pixels=a},pskl.utils.inherit(a.ShapeSelection,a.BaseSelection)}(),function(){var a=$.namespace("pskl.rendering");a.CanvasRenderer=function(a,b){this.frame=a,this.dpi=b,this.transparentColor_="white"},a.CanvasRenderer.prototype.drawTransparentAs=function(a){this.transparentColor_=a},a.CanvasRenderer.prototype.render=function(){for(var a=this.createCanvas_(),b=a.getContext("2d"),c=0,d=this.frame.getWidth();d>c;c++)for(var e=0,f=this.frame.getHeight();f>e;e++){var g=this.frame.getPixel(c,e);this.renderPixel_(g,c,e,b)}return b},a.CanvasRenderer.prototype.renderPixel_=function(a,b,c,d){a==Constants.TRANSPARENT_COLOR&&(a=this.transparentColor_),d.fillStyle=a,d.fillRect(b*this.dpi,c*this.dpi,this.dpi,this.dpi)},a.CanvasRenderer.prototype.createCanvas_=function(){var a=this.frame.getWidth()*this.dpi,b=this.frame.getHeight()*this.dpi;return pskl.CanvasUtils.createCanvas(a,b)}}(),function(){var a=$.namespace("pskl.rendering");a.FrameRenderer=function(a,b,c){if(this.defaultRenderingOptions={supportGridRendering:!1,zoom:1,xOffset:0,yOffset:0},b=$.extend(!0,{},this.defaultRenderingOptions,b),void 0===a)throw"Bad FrameRenderer initialization. undefined.";if(isNaN(b.zoom))throw"Bad FrameRenderer initialization. not well defined.";this.container=a,this.zoom=b.zoom,this.xOffset=b.xOffset,this.yOffset=b.yOffset,this.pixelOffsetHeight=0,this.pixelOffsetWidth=0,this.supportGridRendering=b.supportGridRendering,this.classes=c||[],this.classes.push("canvas"),this.canvas=null,this.scaledCanvas=null,this.setDisplaySize(b.width,b.height),this.enableGrid(pskl.UserSettings.get(pskl.UserSettings.SHOW_GRID)),this.updateBackgroundClass_(pskl.UserSettings.get(pskl.UserSettings.CANVAS_BACKGROUND)),$.subscribe(Events.USER_SETTINGS_CHANGED,$.proxy(this.onUserSettingsChange_,this))},a.FrameRenderer.prototype.setZoom=function(a){this.zoom=a},a.FrameRenderer.prototype.isAutoSized_=function(){return"auto"===this.displayHeight&&"auto"===this.displayWidth},a.FrameRenderer.prototype.setDisplaySize=function(a,b){this.displayHeight=b,this.displayWidth=a,this.scaledCanvas&&($(this.scaledCanvas).remove(),this.scaledCanvas=null)},a.FrameRenderer.prototype.updatePixelOffsets_=function(){if(!this.isAutoSized_()){var a=this.displayHeight-this.zoom*this.canvas.height;this.pixelOffsetHeight=Math.max(0,a)/2;var b=this.displayWidth-this.zoom*this.canvas.width;this.pixelOffsetWidth=Math.max(0,b)/2}},a.FrameRenderer.prototype.createScaledCanvas_=function(){var a=this.displayHeight,b=this.displayWidth;this.isAutoSized_()&&(a=this.zoom*this.canvas.height,b=this.zoom*this.canvas.width),this.scaledCanvas=pskl.CanvasUtils.createCanvas(b,a,this.classes),pskl.CanvasUtils.disableImageSmoothing(this.scaledCanvas),this.container.append(this.scaledCanvas)},a.FrameRenderer.prototype.setDisplayOffset=function(a,b){this.xOffset=a,this.yOffset=b},a.FrameRenderer.prototype.onUserSettingsChange_=function(a,b,c){b==pskl.UserSettings.SHOW_GRID?this.enableGrid(c):b==pskl.UserSettings.CANVAS_BACKGROUND&&this.updateBackgroundClass_(c)},a.FrameRenderer.prototype.updateBackgroundClass_=function(a){var b=this.container.data("current-background-class");b&&this.container.removeClass(b),this.container.addClass(a),this.container.data("current-background-class",a)},a.FrameRenderer.prototype.enableGrid=function(a){this.gridStrokeWidth=a&&this.supportGridRendering?Constants.GRID_STROKE_WIDTH:0,this.canvasConfigDirty=!0},a.FrameRenderer.prototype.render=function(a){a&&(this.clear(),this.drawFrameInCanvas_(a),this.lastRenderedFrame=a)},a.FrameRenderer.prototype.clear=function(){pskl.CanvasUtils.clear(this.canvas),pskl.CanvasUtils.clear(this.scaledCanvas)},a.FrameRenderer.prototype.renderPixel_=function(a,b,c,d){a!=Constants.TRANSPARENT_COLOR&&(d.fillStyle=a,d.fillRect(b,c,1,1))},a.FrameRenderer.prototype.convertPixelCoordinatesIntoSpriteCoordinate=function(a){var b=this.zoom+this.gridStrokeWidth,c=a.x-this.pixelOffsetWidth+this.xOffset*b,d=a.y-this.pixelOffsetHeight+this.yOffset*b;return{col:(c-c%b)/b,row:(d-d%b)/b}},a.FrameRenderer.prototype.getFramePos_=function(a){return a*this.dpi+(a-1)*this.gridStrokeWidth},a.FrameRenderer.prototype.drawFrameInCanvas_=function(a){this.canvas||(this.canvas=pskl.CanvasUtils.createCanvas(a.getWidth(),a.getHeight())),this.scaledCanvas||this.createScaledCanvas_(),this.updatePixelOffsets_();for(var b=this.canvas.getContext("2d"),c=0,d=a.getWidth();d>c;c++)for(var e=0,f=a.getHeight();f>e;e++){var g=a.getPixel(c,e);this.renderPixel_(g,c,e,b)}b=this.scaledCanvas.getContext("2d"),b.save(),b.fillStyle="#aaa",b.fillRect(0,0,this.scaledCanvas.width,this.scaledCanvas.height),b.translate(this.pixelOffsetWidth,this.pixelOffsetHeight),b.scale(this.zoom,this.zoom),b.translate(-this.xOffset,-this.yOffset),b.clearRect(0,0,this.canvas.width,this.canvas.height),b.drawImage(this.canvas,0,0),b.restore()}}(),function(){var a=$.namespace("pskl.rendering");a.SpritesheetRenderer=function(a){this.piskelController=a},a.SpritesheetRenderer.prototype.render=function(){for(var a=this.createCanvas_(),b=0;bf;f++)for(var h=0,i=a.getHeight();i>h;h++){var j=a.getPixel(f,h);j!=Constants.TRANSPARENT_COLOR&&(e.fillStyle=j,e.fillRect(f+c,h+d,1,1))}},a.SpritesheetRenderer.prototype.createCanvas_=function(){var a=this.piskelController.getFrameCount();if(a>0){var b=a*this.piskelController.getWidth(),c=this.piskelController.getHeight();return pskl.CanvasUtils.createCanvas(b,c)}throw"Cannot render empty Spritesheet"}}(),function(){var a=$.namespace("pskl.controller");a.PiskelController=function(a){if(!a)throw"A piskel instance is mandatory for instanciating PiskelController";this.setPiskel(a)},a.PiskelController.prototype.setPiskel=function(a){this.piskel=a,this.currentLayerIndex=0,this.currentFrameIndex=0,this.layerIdCounter=1,$.publish(Events.PISKEL_RESET),$.publish(Events.FRAME_SIZE_CHANGED)},a.PiskelController.prototype.getHeight=function(){return this.piskel.getHeight()},a.PiskelController.prototype.getWidth=function(){return this.piskel.getWidth()},a.PiskelController.prototype.getFPS=function(){return pskl.app.animationController.getFPS()},a.PiskelController.prototype.getLayers=function(){return this.piskel.getLayers()},a.PiskelController.prototype.getCurrentLayer=function(){return this.piskel.getLayerAt(this.currentLayerIndex)},a.PiskelController.prototype.getCurrentFrame=function(){var a=this.getCurrentLayer();return a.getFrameAt(this.currentFrameIndex)},a.PiskelController.prototype.getFrameAt=function(a){var b=this.getLayers().map(function(b){return b.getFrameAt(a)});return pskl.utils.FrameUtils.merge(b)},a.PiskelController.prototype.hasFrameAt=function(a){return!!this.getCurrentLayer().getFrameAt(a) -},a.PiskelController.prototype.getFrameByIndex=a.PiskelController.prototype.getMergedFrameAt,a.PiskelController.prototype.addEmptyFrame=function(){var a=this.getLayers();a.forEach(function(a){a.addFrame(this.createEmptyFrame_())}.bind(this))},a.PiskelController.prototype.createEmptyFrame_=function(){var a=this.piskel.getWidth(),b=this.piskel.getHeight();return new pskl.model.Frame(a,b)},a.PiskelController.prototype.removeFrameAt=function(a){var b=this.getLayers();b.forEach(function(b){b.removeFrameAt(a)}),this.currentFrameIndex>=a&&this.setCurrentFrameIndex(this.currentFrameIndex-1),$.publish(Events.PISKEL_RESET)},a.PiskelController.prototype.duplicateFrameAt=function(a){var b=this.getLayers();b.forEach(function(b){b.duplicateFrameAt(a)})},a.PiskelController.prototype.moveFrame=function(a,b){var c=this.getLayers();c.forEach(function(c){c.moveFrame(a,b)})},a.PiskelController.prototype.getFrameCount=function(){var a=this.piskel.getLayerAt(0);return a.length()},a.PiskelController.prototype.setCurrentFrameIndex=function(a){this.currentFrameIndex=a,$.publish(Events.PISKEL_RESET)},a.PiskelController.prototype.setCurrentLayerIndex=function(a){this.currentLayerIndex=a,$.publish(Events.PISKEL_RESET)},a.PiskelController.prototype.selectLayer=function(a){var b=this.getLayers().indexOf(a);-1!=b&&this.setCurrentLayerIndex(b)},a.PiskelController.prototype.selectLayerByName=function(a){if(this.hasLayerForName_(a)){var b=this.piskel.getLayersByName(a)[0];this.selectLayer(b)}},a.PiskelController.prototype.generateLayerName_=function(){for(var a="Layer "+this.layerIdCounter;this.hasLayerForName_(a);)this.layerIdCounter++,a="Layer "+this.layerIdCounter;return a},a.PiskelController.prototype.createLayer=function(a){if(a||(a=this.generateLayerName_()),this.hasLayerForName_(a))throw"Layer name should be unique";for(var b=new pskl.model.Layer(a),c=0;c0},a.PiskelController.prototype.moveLayerUp=function(){var a=this.getCurrentLayer();this.piskel.moveLayerUp(a),this.selectLayer(a)},a.PiskelController.prototype.moveLayerDown=function(){var a=this.getCurrentLayer();this.piskel.moveLayerDown(a),this.selectLayer(a)},a.PiskelController.prototype.removeCurrentLayer=function(){if(this.getLayers().length>1){var a=this.getCurrentLayer();this.piskel.removeLayer(a),this.setCurrentLayerIndex(0)}},a.PiskelController.prototype.serialize=function(){return pskl.utils.Serializer.serializePiskel(this.piskel)},a.PiskelController.prototype.load=function(a){this.deserialize(JSON.stringify(a))}}(),function(){var a=$.namespace("pskl.controller");a.DrawingController=function(a,b){this.piskelController=a,this.overlayFrame=pskl.model.Frame.createEmptyFromFrame(a.getCurrentFrame()),this.container=b,this.zoom=this.calculateZoom_(),this.xOffset=0,this.yOffset=0;var c={zoom:this.zoom,supportGridRendering:!0,height:this.getContainerHeight_(),width:this.getContainerWidth_(),xOffset:this.xOffset,yOffset:this.yOffset};this.overlayRenderer=new pskl.rendering.FrameRenderer(this.container,c,["canvas-overlay"]),this.renderer=new pskl.rendering.FrameRenderer(this.container,c,["drawing-canvas"]),this.layersBelowRenderer=new pskl.rendering.FrameRenderer(this.container,c,["layers-canvas","layers-below-canvas"]),this.layersAboveRenderer=new pskl.rendering.FrameRenderer(this.container,c,["layers-canvas","layers-above-canvas"]),this.isClicked=!1,this.isRightClicked=!1,this.previousMousemoveTime=0,this.currentToolBehavior=null,this.primaryColor=Constants.DEFAULT_PEN_COLOR,this.secondaryColor=Constants.TRANSPARENT_COLOR},a.DrawingController.prototype.init=function(){this.initMouseBehavior(),$.subscribe(Events.TOOL_SELECTED,$.proxy(function(a,b){console.log("Tool selected: ",b),this.currentToolBehavior=b,this.overlayFrame.clear()},this)),$.subscribe(Events.PRIMARY_COLOR_SELECTED,$.proxy(function(a,b){console.log("Primary color selected: ",b),this.primaryColor=b,$.publish(Events.PRIMARY_COLOR_UPDATED,[b])},this)),$.subscribe(Events.SECONDARY_COLOR_SELECTED,$.proxy(function(a,b){console.log("Secondary color selected: ",b),this.secondaryColor=b,$.publish(Events.SECONDARY_COLOR_UPDATED,[b])},this)),$(window).resize($.proxy(this.startDPIUpdateTimer_,this)),$.subscribe(Events.USER_SETTINGS_CHANGED,$.proxy(this.onUserSettingsChange_,this)),$.subscribe(Events.FRAME_SIZE_CHANGED,$.proxy(this.updateZoom_,this)),this.updateZoom_()},a.DrawingController.prototype.initMouseBehavior=function(){var a=$("body");this.container.mousedown($.proxy(this.onMousedown_,this)),this.container.mousemove($.proxy(this.onMousemove_,this)),this.container.on("mousewheel",$.proxy(this.onMousewheel_,this)),a.mouseup($.proxy(this.onMouseup_,this)),a.contextmenu(this.onCanvasContextMenu_)},a.DrawingController.prototype.startDPIUpdateTimer_=function(){this.zoomUpdateTimer&&window.clearInterval(this.zoomUpdateTimer),this.zoomUpdateTimer=window.setTimeout($.proxy(this.updateZoom_,this),200)},a.DrawingController.prototype.onUserSettingsChange_=function(a,b){b==pskl.UserSettings.SHOW_GRID&&this.updateZoom_()},a.DrawingController.prototype.onMousedown_=function(a){this.isClicked=!0,2==a.button&&(this.isRightClicked=!0,$.publish(Events.CANVAS_RIGHT_CLICKED));var b=this.getSpriteCoordinates(a);this.currentToolBehavior.applyToolAt(b.col,b.row,this.getCurrentColor_(),this.piskelController.getCurrentFrame(),this.overlayFrame,this.wrapEvtInfo_(a)),$.publish(Events.LOCALSTORAGE_REQUEST)},a.DrawingController.prototype.onMousemove_=function(a){var b=(new Date).getTime();if(b-this.previousMousemoveTime>40){var c=this.getSpriteCoordinates(a);this.isClicked?(this.currentToolBehavior.moveToolAt(c.col,c.row,this.getCurrentColor_(),this.piskelController.getCurrentFrame(),this.overlayFrame,this.wrapEvtInfo_(a)),$.publish(Events.LOCALSTORAGE_REQUEST)):this.currentToolBehavior.moveUnactiveToolAt(c.col,c.row,this.getCurrentColor_(),this.piskelController.getCurrentFrame(),this.overlayFrame,this.wrapEvtInfo_(a)),this.previousMousemoveTime=b}},a.DrawingController.prototype.onMousewheel_=function(a){var b=a.originalEvent,c=b.wheelDeltaY;c>0?this.setZoom(this.zoom+1):0>c&&this.setZoom(this.zoom-1)},a.DrawingController.prototype.onMouseup_=function(a){if(this.isClicked||this.isRightClicked){this.isClicked=!1,this.isRightClicked=!1;var b=this.getSpriteCoordinates(a);this.currentToolBehavior.releaseToolAt(b.col,b.row,this.getCurrentColor_(),this.piskelController.getCurrentFrame(),this.overlayFrame,this.wrapEvtInfo_(a)),$.publish(Events.TOOL_RELEASED)}},a.DrawingController.prototype.wrapEvtInfo_=function(a){var b={};return 0===a.button?b.button=Constants.LEFT_BUTTON:2==a.button&&(b.button=Constants.RIGHT_BUTTON),b},a.DrawingController.prototype.getRelativeCoordinates=function(a,b){var c=this.container.offset();return{x:a-c.left,y:b-c.top}},a.DrawingController.prototype.getSpriteCoordinates=function(a){var b=this.getRelativeCoordinates(a.clientX,a.clientY);return this.renderer.convertPixelCoordinatesIntoSpriteCoordinate(b)},a.DrawingController.prototype.getCurrentColor_=function(){return this.isRightClicked?this.secondaryColor:this.primaryColor},a.DrawingController.prototype.onCanvasContextMenu_=function(a){return $(a.target).closest("#drawing-canvas-container").length?(a.preventDefault(),a.stopPropagation(),a.cancelBubble=!0,!1):void 0},a.DrawingController.prototype.render=function(){this.renderLayers(),this.renderFrame(),this.renderOverlay()},a.DrawingController.prototype.renderFrame=function(){var a=this.piskelController.getCurrentFrame(),b=[this.zoom,this.xOffset,this.yOffset,a.serialize()].join("-");this.serializedFrame!=b&&(a.isSameSize(this.overlayFrame)||(this.overlayFrame=pskl.model.Frame.createEmptyFromFrame(a)),this.serializedFrame=b,this.renderer.render(a))},a.DrawingController.prototype.renderOverlay=function(){var a=[this.zoom,this.xOffset,this.yOffset,this.overlayFrame.serialize()].join("-");this.serializedOverlay!=a&&(this.serializedOverlay=a,this.overlayRenderer.render(this.overlayFrame))},a.DrawingController.prototype.renderLayers=function(){var a=this.piskelController.getLayers(),b=this.piskelController.currentFrameIndex,c=this.piskelController.currentLayerIndex,d=[this.zoom,b,c,a.length].join("-");if(this.serializedLayerFrame!=d){this.layersAboveRenderer.clear(),this.layersBelowRenderer.clear();var e=a.slice(0,c),f=this.getFrameForLayersAt_(b,e);if(this.layersBelowRenderer.render(f),c+1b){c>e&&(f=!0);var h=d-c-b;h>e&&(g=!0)}var i=$("#preview-list-wrapper");i.toggleClass("top-overflow-visible",f),i.toggleClass("bottom-overflow-visible",g)},a.PreviewFilmController.prototype.createPreviews_=function(){this.container.html(""),$(".tooltip").remove();for(var a=this.piskelController.getFrameCount(),b=0,c=a;c>b;b++)this.container.append(this.createPreviewTile_(b));var d=document.createElement("div");d.id="add-frame-action",d.className="add-frame-action",d.innerHTML="

Add new frame

",this.container.append(d),$(d).click(this.addFrame.bind(this));var e=a>1;e&&this.initDragndropBehavior_(),this.updateScrollerOverflows()},a.PreviewFilmController.prototype.initDragndropBehavior_=function(){$("#preview-list").sortable({placeholder:"preview-tile-drop-proxy",update:$.proxy(this.onUpdate_,this),items:".preview-tile"}),$("#preview-list").disableSelection()},a.PreviewFilmController.prototype.onUpdate_=function(a,b){var c=parseInt(b.item.data("tile-number"),10),d=$(".preview-tile").index(b.item);this.piskelController.moveFrame(c,d),this.piskelController.setCurrentFrameIndex(d),$.publish(Events.LOCALSTORAGE_REQUEST)},a.PreviewFilmController.prototype.createPreviewTile_=function(a){var b=this.piskelController.getCurrentLayer().getFrameAt(a),c=document.createElement("li"),d="preview-tile";c.setAttribute("data-tile-number",a),this.piskelController.getCurrentFrame()==b&&(d+=" selected"),c.className=d;var e=document.createElement("div");e.className="canvas-container";var f=document.createElement("div");f.className="canvas-background",e.appendChild(f),c.addEventListener("click",this.onPreviewClick_.bind(this,a));var g=document.createElement("button");g.setAttribute("rel","tooltip"),g.setAttribute("data-placement","right"),g.setAttribute("title","Duplicate this frame"),g.className="tile-overlay duplicate-frame-action",c.appendChild(g),g.addEventListener("click",this.onAddButtonClick_.bind(this,a));var h={zoom:this.zoom,height:"auto",width:"auto"},i=new pskl.rendering.FrameRenderer($(e),h,["tile-view"]);if(i.render(b),c.appendChild(e),a>0||this.piskelController.getFrameCount()>1){var j=document.createElement("button");j.setAttribute("rel","tooltip"),j.setAttribute("data-placement","right"),j.setAttribute("title","Delete this frame"),j.className="tile-overlay delete-frame-action",j.addEventListener("click",this.onDeleteButtonClick_.bind(this,a)),c.appendChild(j);var k=document.createElement("div");k.className="tile-overlay dnd-action",c.appendChild(k)}var l=document.createElement("div");return l.className="tile-overlay tile-count",l.innerHTML=a,c.appendChild(l),c},a.PreviewFilmController.prototype.onPreviewClick_=function(a,b){b.target.classList.contains("tile-overlay")||this.piskelController.setCurrentFrameIndex(a)},a.PreviewFilmController.prototype.onDeleteButtonClick_=function(a){this.piskelController.removeFrameAt(a),$.publish(Events.LOCALSTORAGE_REQUEST),this.updateScrollerOverflows()},a.PreviewFilmController.prototype.onAddButtonClick_=function(a){this.piskelController.duplicateFrameAt(a),$.publish(Events.LOCALSTORAGE_REQUEST),this.piskelController.setCurrentFrameIndex(a+1),this.updateScrollerOverflows()},a.PreviewFilmController.prototype.calculateZoom_=function(){var a=this.piskelController.getCurrentFrame(),b=a.getHeight(),c=a.getWidth(),d=Math.max(c,b),e=Constants.PREVIEW_FILM_SIZE*b/d,f=Constants.PREVIEW_FILM_SIZE*c/d;return pskl.PixelUtils.calculateDPI(e,f,b,c)||1}}(),function(){var a=$.namespace("pskl.controller");a.LayersListController=function(a){this.piskelController=a},a.LayersListController.prototype.init=function(){this.layerItemTemplate_=pskl.utils.Template.get("layer-item-template"),this.rootEl=document.querySelectorAll(".layers-list-container")[0],this.layersListEl=document.querySelectorAll(".layers-list")[0],this.rootEl.addEventListener("click",this.onClick_.bind(this)),$.subscribe(Events.PISKEL_RESET,this.renderLayerList_.bind(this)),this.renderLayerList_()},a.LayersListController.prototype.renderLayerList_=function(){this.layersListEl.innerHTML="";var a=this.piskelController.getLayers();a.forEach(this.addLayerItem.bind(this))},a.LayersListController.prototype.addLayerItem=function(a){var b=pskl.utils.Template.replace(this.layerItemTemplate_,{layername:a.getName()}),c=pskl.utils.Template.createFromHTML(b);this.piskelController.getCurrentLayer()===a&&c.classList.add("current-layer-item"),this.layersListEl.insertBefore(c,this.layersListEl.firstChild)},a.LayersListController.prototype.onClick_=function(a){var b=a.target||a.srcElement;if("BUTTON"==b.nodeName)this.onButtonClick_(b);else if("LI"==b.nodeName){var c=b.getAttribute("data-layer-name");this.piskelController.selectLayerByName(c)}},a.LayersListController.prototype.onButtonClick_=function(a){var b=a.getAttribute("data-action");"up"==b?this.piskelController.moveLayerUp():"down"==b?this.piskelController.moveLayerDown():"add"==b?this.piskelController.createLayer():"delete"==b&&this.piskelController.removeCurrentLayer()}}(),function(){var a=$.namespace("pskl.controller");a.AnimatedPreviewController=function(a,b){this.piskelController=a,this.container=b,this.elapsedTime=0,this.currentIndex=0,this.setFPS(Constants.DEFAULT.FPS);var c={zoom:this.calculateZoom_(),height:"auto",width:"auto"};this.renderer=new pskl.rendering.FrameRenderer(this.container,c),$.subscribe(Events.FRAME_SIZE_CHANGED,this.updateDPI_.bind(this))},a.AnimatedPreviewController.prototype.init=function(){$("#preview-fps")[0].addEventListener("change",this.onFPSSliderChange.bind(this))},a.AnimatedPreviewController.prototype.onFPSSliderChange=function(){this.setFPS(parseInt($("#preview-fps")[0].value,10))},a.AnimatedPreviewController.prototype.setFPS=function(a){this.fps=a,$("#preview-fps").val(this.fps),$("#display-fps").html(this.fps+" FPS")},a.AnimatedPreviewController.prototype.getFPS=function(){return this.fps},a.AnimatedPreviewController.prototype.render=function(a){this.elapsedTime+=a;var b=Math.floor(this.elapsedTime/(1e3/this.fps));b!=this.currentIndex&&(this.currentIndex=b,this.piskelController.hasFrameAt(this.currentIndex)||(this.currentIndex=0,this.elapsedTime=0),this.renderer.render(this.piskelController.getFrameAt(this.currentIndex)))},a.AnimatedPreviewController.prototype.calculateZoom_=function(){var a=200,b=this.piskelController.getCurrentFrame().getHeight(),c=this.piskelController.getCurrentFrame().getWidth();return pskl.PixelUtils.calculateDPI(a,a,b,c)},a.AnimatedPreviewController.prototype.updateDPI_=function(){this.dpi=this.calculateDPI_(),this.renderer.setDPI(this.dpi)}}(),function(){var a=$.namespace("pskl.controller");a.ToolController=function(){this.toolInstances={simplePen:new pskl.drawingtools.SimplePen,verticalMirrorPen:new pskl.drawingtools.VerticalMirrorPen,eraser:new pskl.drawingtools.Eraser,paintBucket:new pskl.drawingtools.PaintBucket,stroke:new pskl.drawingtools.Stroke,rectangle:new pskl.drawingtools.Rectangle,circle:new pskl.drawingtools.Circle,move:new pskl.drawingtools.Move,rectangleSelect:new pskl.drawingtools.RectangleSelect,shapeSelect:new pskl.drawingtools.ShapeSelect,colorPicker:new pskl.drawingtools.ColorPicker},this.currentSelectedTool=this.toolInstances.simplePen,this.previousSelectedTool=this.toolInstances.simplePen},a.ToolController.prototype.init=function(){this.createToolMarkup_(),this.selectTool_(this.toolInstances.simplePen),$("#tool-section").click($.proxy(this.onToolIconClicked_,this))},a.ToolController.prototype.activateToolOnStage_=function(a){var b=$("body"),c=b.data("selected-tool-class");c&&b.removeClass(c),b.addClass(a.toolId),b.data("selected-tool-class",a.toolId)},a.ToolController.prototype.selectTool_=function(a){console.log("Selecting Tool:",this.currentSelectedTool),this.currentSelectedTool=a,this.activateToolOnStage_(this.currentSelectedTool),$.publish(Events.TOOL_SELECTED,[a])},a.ToolController.prototype.onToolIconClicked_=function(a){var b=$(a.target),c=b.closest(".tool-icon");if(c.length){var d=c.data().toolId,e=this.getToolById_(d);e&&(this.selectTool_(e),$("#tool-section .tool-icon.selected").removeClass("selected"),c.addClass("selected"))}},a.ToolController.prototype.getToolById_=function(a){for(var b in this.toolInstances)if(this.toolInstances[b].toolId==a)return this.toolInstances[b];return null},a.ToolController.prototype.createToolMarkup_=function(){var a,b,c="";for(var d in this.toolInstances)a=this.toolInstances[d],b=a.toolId,this.currentSelectedTool==a&&(b+=" selected"),c+='
  • ';$("#tools-container").html(c)}}(),function(){var a=$.namespace("pskl.controller");a.PaletteController=function(){},a.PaletteController.prototype.init=function(){var a=$(".palette-color[data-color=TRANSPARENT]");a.mouseup($.proxy(this.onPaletteColorClick_,this)),$.subscribe(Events.PRIMARY_COLOR_UPDATED,$.proxy(function(a,b){this.updateColorPicker_(b,$("#color-picker"))},this)),$.subscribe(Events.SECONDARY_COLOR_UPDATED,$.proxy(function(a,b){this.updateColorPicker_(b,$("#secondary-color-picker"))},this));var b=$("#color-picker");b.val(Constants.DEFAULT_PEN_COLOR),b.change({isPrimary:!0},$.proxy(this.onPickerChange_,this));var c=$("#secondary-color-picker");c.val(Constants.TRANSPARENT_COLOR),c.change({isPrimary:!1},$.proxy(this.onPickerChange_,this)),window.jscolor.install()},a.PaletteController.prototype.onPickerChange_=function(a){var b=$(a.target);a.data.isPrimary?$.publish(Events.PRIMARY_COLOR_SELECTED,[b.val()]):$.publish(Events.SECONDARY_COLOR_SELECTED,[b.val()])},a.PaletteController.prototype.onPaletteColorClick_=function(a){var b=$(a.target).data("color"),c=1==a.which,d=3==a.which;c?$.publish(Events.PRIMARY_COLOR_SELECTED,[b]):d&&$.publish(Events.SECONDARY_COLOR_SELECTED,[b])},a.PaletteController.prototype.updateColorPicker_=function(a,b){a==Constants.TRANSPARENT_COLOR?(b[0].color.fromString("#fff"),b.val(Constants.TRANSPARENT_COLOR)):b[0].color.fromString(a)}}(),function(){var a=$.namespace("pskl.controller");a.NotificationController=function(){},a.NotificationController.prototype.init=function(){$.subscribe(Events.SHOW_NOTIFICATION,$.proxy(this.displayMessage_,this)),$.subscribe(Events.HIDE_NOTIFICATION,$.proxy(this.removeMessage_,this))},a.NotificationController.prototype.displayMessage_=function(a,b){var c=document.createElement("div");c.id="user-message",c.className="user-message",c.innerHTML=b.content,c.innerHTML=c.innerHTML+"
    x
    ",document.body.appendChild(c),$(c).find(".close").click($.proxy(this.removeMessage_,this)),b.behavior&&b.behavior(c)},a.NotificationController.prototype.removeMessage_=function(){var a=$("#user-message");a.length&&a.remove()}}(),function(){var a=$.namespace("pskl.controller.settings");a.ApplicationSettingsController=function(){},a.ApplicationSettingsController.prototype.init=function(){var a=pskl.UserSettings.get(pskl.UserSettings.CANVAS_BACKGROUND);$("#background-picker-wrapper").find(".background-picker[data-background-class="+a+"]").addClass("selected");var b=pskl.UserSettings.get(pskl.UserSettings.SHOW_GRID);$("#show-grid").prop("checked",b),$("#show-grid").change($.proxy(function(){var a=$("#show-grid").prop("checked");pskl.UserSettings.set(pskl.UserSettings.SHOW_GRID,a)},this)),$("#background-picker-wrapper").click(function(a){var b=$(a.target).closest(".background-picker");if(b.length){var c=b.data("background-class");pskl.UserSettings.set(pskl.UserSettings.CANVAS_BACKGROUND,c),$(".background-picker").removeClass("selected"),b.addClass("selected")}})}}(),function(){var a=$.namespace("pskl.controller.settings");a.GifExportController=function(a){this.piskelController=a},a.GifExportController.RESOLUTIONS=[{dpi:1},{dpi:5},{dpi:10,"default":!0},{dpi:20}],a.GifExportController.prototype.init=function(){this.radioTemplate_=pskl.utils.Template.get("export-gif-radio-template"),this.previewContainerEl=document.querySelectorAll(".export-gif-preview div")[0],this.radioGroupEl=document.querySelectorAll(".gif-export-radio-group")[0],this.uploadForm=$("[name=gif-export-upload-form]"),this.uploadForm.submit(this.onUploadFormSubmit_.bind(this)),this.createRadioElements_()},a.GifExportController.prototype.onUploadFormSubmit_=function(a){a.originalEvent.preventDefault();var b=this.getSelectedDpi_(),c=this.piskelController.getFPS(),d=b;this.renderAsImageDataAnimatedGIF(d,c,this.onGifRenderingCompleted_.bind(this))},a.GifExportController.prototype.onGifRenderingCompleted_=function(a){this.updatePreview_(a),this.previewContainerEl.classList.add("preview-upload-ongoing"),pskl.app.imageUploadService.upload(a,this.onImageUploadCompleted_.bind(this))},a.GifExportController.prototype.onImageUploadCompleted_=function(a){this.updatePreview_(a),this.previewContainerEl.classList.remove("preview-upload-ongoing")},a.GifExportController.prototype.updatePreview_=function(a){this.previewContainerEl.innerHTML=""},a.GifExportController.prototype.getSelectedDpi_=function(){var a=this.uploadForm.get(0).querySelectorAll("[name=gif-dpi]"),b=Array.prototype.slice.call(a,0),c=b.filter(function(a){return!!a.checked});if(1==c.length)return c[0].value;throw"Unexpected error when retrieving selected dpi"},a.GifExportController.prototype.createRadioElements_=function(){for(var b=a.GifExportController.RESOLUTIONS,c=0;c";this.piskelController=a,this.localStorageThrottler_=null},a.LocalStorageService.prototype.init=function(){$.subscribe(Events.LOCALSTORAGE_REQUEST,$.proxy(this.persistToLocalStorageRequest_,this))},a.LocalStorageService.prototype.persistToLocalStorageRequest_=function(){null!==this.localStorageThrottler_&&window.clearTimeout(this.localStorageThrottler_),this.localStorageThrottler_=window.setTimeout($.proxy(function(){this.persistToLocalStorage_(),this.localStorageThrottler_=null},this),1e3)},a.LocalStorageService.prototype.persistToLocalStorage_=function(){console.log("[LocalStorage service]: Snapshot stored"),window.localStorage.snapShot=this.piskelController.serialize()},a.LocalStorageService.prototype.restoreFromLocalStorage_=function(){this.piskelController.deserialize(window.localStorage.snapShot),this.piskelController.setCurrentFrameIndex(0)},a.LocalStorageService.prototype.cleanLocalStorage_=function(){console.log("[LocalStorage service]: Snapshot removed"),delete window.localStorage.snapShot},a.LocalStorageService.prototype.displayRestoreNotification=function(){if(window.localStorage&&window.localStorage.snapShot){var a="
    reload",b="discard",c="Non saved version found. "+a+" or "+b;$.publish(Events.SHOW_NOTIFICATION,[{content:c,behavior:$.proxy(function(a){a=$(a),a.click($.proxy(function(a){var b=$(a.target);b.hasClass("localstorage-restore")?this.restoreFromLocalStorage_():b.hasClass("localstorage-discard")&&this.cleanLocalStorage_(),$.publish(Events.HIDE_NOTIFICATION)},this))},this)}])}}}(),function(){var a=$.namespace("pskl.service");a.HistoryService=function(a){this.piskelController=a},a.HistoryService.prototype.init=function(){$.subscribe(Events.TOOL_RELEASED,this.saveState.bind(this)),$.subscribe(Events.UNDO,this.undo.bind(this)),$.subscribe(Events.REDO,this.redo.bind(this))},a.HistoryService.prototype.saveState=function(){this.piskelController.getCurrentFrame().saveState()},a.HistoryService.prototype.undo=function(){this.piskelController.getCurrentFrame().loadPreviousState(),$.publish(Events.PISKEL_RESET)},a.HistoryService.prototype.redo=function(){this.piskelController.getCurrentFrame().loadNextState(),$.publish(Events.PISKEL_RESET)}}(),function(){var a=$.namespace("pskl.service");a.KeyboardEventService=function(){},a.KeyboardEventService.prototype.KeyboardActions_={ctrl:{z:Events.UNDO,y:Events.REDO,x:Events.CUT,c:Events.COPY,v:Events.PASTE}},a.KeyboardEventService.prototype.CharCodeToKeyCodeMap_={90:"z",89:"y",88:"x",67:"c",86:"v"},a.KeyboardEventService.prototype.onKeyUp_=function(a){var b=!1;if(-1!=navigator.appVersion.indexOf("Mac")&&(b=!0),b?a.metaKey:a.ctrlKey){var c=this.CharCodeToKeyCodeMap_[a.which];if(c){var d=this.KeyboardActions_.ctrl[c];if(d)return $.publish(d),a.preventDefault(),!1}}},a.KeyboardEventService.prototype.init=function(){$(document.body).keydown($.proxy(this.onKeyUp_,this))}}(),function(){var a=$.namespace("pskl.service");a.ImageUploadService=function(){},a.ImageUploadService.prototype.init=function(){},a.ImageUploadService.prototype.upload=function(a,b,c){var d=new XMLHttpRequest,e=new FormData;e.append("data",a),d.open("POST",Constants.IMAGE_SERVICE_UPLOAD_URL,!0),d.onload=function(){if(200==this.status){var a=Constants.IMAGE_SERVICE_GET_URL+this.responseText;b(a)}else c()},d.send(e)}}(),function(){var a=$.namespace("pskl.drawingtools");a.BaseTool=function(){},a.BaseTool.prototype.applyToolAt=function(){},a.BaseTool.prototype.moveToolAt=function(){},a.BaseTool.prototype.moveUnactiveToolAt=function(a,b,c,d,e){e.containsPixel(a,b)&&(isNaN(this.highlightedPixelCol)||isNaN(this.highlightedPixelRow)||this.highlightedPixelRow==b&&this.highlightedPixelCol==a||e.clear(),e.setPixel(a,b,Constants.TOOL_TARGET_HIGHLIGHT_COLOR),this.highlightedPixelCol=a,this.highlightedPixelRow=b)},a.BaseTool.prototype.releaseToolAt=function(){},a.BaseTool.prototype.getLinePixels_=function(a,b,c,d){for(var e=[],f=Math.abs(b-a),g=Math.abs(d-c),h=b>a?1:-1,i=d>c?1:-1,j=f-g;;){if(e.push({col:a,row:c}),a==b&&c==d)break;var k=2*j;k>-g&&(j-=g,a+=h),f>k&&(j+=f,c+=i)}return e}}(),function(){var a=$.namespace("pskl.drawingtools");a.SimplePen=function(){this.toolId="tool-pen",this.helpText="Pen tool",this.previousCol=null,this.previousRow=null -},pskl.utils.inherit(a.SimplePen,a.BaseTool),a.SimplePen.prototype.applyToolAt=function(a,b,c,d){d.containsPixel(a,b)&&d.setPixel(a,b,c),this.previousCol=a,this.previousRow=b},a.SimplePen.prototype.moveToolAt=function(a,b,c,d,e){if(Math.abs(a-this.previousCol)>1||Math.abs(b-this.previousRow)>1)for(var f=this.getLinePixels_(a,this.previousCol,b,this.previousRow),g=0,h=f.length;h>g;g++){var i=f[g];this.applyToolAt(i.col,i.row,c,d,e)}else this.applyToolAt(a,b,c,d,e);this.previousCol=a,this.previousRow=b}}(),function(){var a=$.namespace("pskl.drawingtools");a.VerticalMirrorPen=function(){this.toolId="tool-vertical-mirror-pen",this.helpText="vertical mirror pen tool",this.swap=null,this.mirroredPreviousCol=null,this.mirroredPreviousRow=null},pskl.utils.inherit(a.VerticalMirrorPen,a.SimplePen),a.VerticalMirrorPen.prototype.setMirrorContext=function(){this.swap=this.previousCol,this.previousCol=this.mirroredPreviousCol},a.VerticalMirrorPen.prototype.unsetMirrorContext=function(){this.mirroredPreviousCol=this.previousCol,this.previousCol=this.swap},a.VerticalMirrorPen.prototype.applyToolAt=function(a,b,c,d,e){this.superclass.applyToolAt.call(this,a,b,c,d,e);var f=this.getSymmetricCol_(a,d);this.mirroredPreviousCol=f,this.setMirrorContext(),this.superclass.applyToolAt.call(this,f,b,c,d,e),this.unsetMirrorContext()},a.VerticalMirrorPen.prototype.getSymmetricCol_=function(a,b){return b.getWidth()-a-1}}(),function(){var a=$.namespace("pskl.drawingtools");a.Eraser=function(){this.toolId="tool-eraser",this.helpText="Eraser tool"},pskl.utils.inherit(a.Eraser,a.SimplePen),a.Eraser.prototype.applyToolAt=function(a,b,c,d,e){this.superclass.applyToolAt.call(this,a,b,Constants.TRANSPARENT_COLOR,d,e)}}(),function(){var a=$.namespace("pskl.drawingtools");a.Stroke=function(){this.toolId="tool-stroke",this.helpText="Stroke tool",this.startCol=null,this.startRow=null},pskl.utils.inherit(a.Stroke,a.BaseTool),a.Stroke.prototype.applyToolAt=function(a,b,c,d,e){this.startCol=a,this.startRow=b,e.setPixel(a,b,c)},a.Stroke.prototype.moveToolAt=function(a,b,c,d,e){e.clear();for(var f=this.getLinePixels_(this.startCol,a,this.startRow,b),g=0;gd;d++)b.setPixel(c[d].col,c[d].row,Constants.SELECTION_TRANSPARENT_COLOR)},a.BaseSelect.prototype.shiftOverlayFrame_=function(a,b,c,d){for(var e,f=0;f
    ',trigger:"hover",title:"",delay:0,html:!0}}(window.jQuery),function(){var a=function(){!function(){function a(b,c){if({}.hasOwnProperty.call(a.cache,b))return a.cache[b];var d=a.resolve(b);if(!d)throw new Error("Failed to resolve module "+b);var e={id:b,require:a,filename:b,exports:{},loaded:!1,parent:c,children:[]};c&&c.children.push(e);var f=b.slice(0,b.lastIndexOf("/")+1);return a.cache[b]=e.exports,d.call(e.exports,e,e.exports,f,b),e.loaded=!0,a.cache[b]=e.exports}a.modules={},a.cache={},a.resolve=function(b){return{}.hasOwnProperty.call(a.modules,b)?a.modules[b]:void 0},a.define=function(b,c){a.modules[b]=c},a.define("/gif.worker.coffee",function(b){var c,d;c=a("/GIFEncoder.js",b),d=function(a){var b,d,e;return b=new c(a.width,a.height),0===a.index?b.writeHeader():b.firstFrame=!1,b.setRepeat(a.repeat),b.setDelay(a.delay),b.setQuality(a.quality),b.addFrame(a.data),a.last&&b.finish(),d=b.stream(),a.data=d.pages,a.cursor=d.cursor,a.pageSize=d.constructor.pageSize,a.canTransfer?(e=function(b){for(var c,d=0,e=a.data.length;e>d;++d)c=a.data[d],b.push(c.buffer);return b}.call(this,[]),self.postMessage(a,e)):self.postMessage(a)},self.onmessage=function(a){return d(a.data)}}),a.define("/GIFEncoder.js",function(b){function c(){this.page=-1,this.pages=[],this.newPage()}function d(a,b){this.width=~~a,this.height=~~b,this.transparent=null,this.transIndex=0,this.repeat=-1,this.delay=0,this.image=null,this.pixels=null,this.indexedPixels=null,this.colorDepth=null,this.colorTab=null,this.usedEntry=new Array,this.palSize=7,this.dispose=-1,this.firstFrame=!0,this.sample=10,this.out=new c}var e=a("/TypedNeuQuant.js",b),f=a("/LZWEncoder.js",b);c.pageSize=4096,c.charMap={};for(var g=0;256>g;g++)c.charMap[g]=String.fromCharCode(g);c.prototype.newPage=function(){this.pages[++this.page]=new Uint8Array(c.pageSize),this.cursor=0},c.prototype.getData=function(){for(var a="",b=0;b=c.pageSize&&this.newPage(),this.pages[this.page][this.cursor++]=a},c.prototype.writeUTFBytes=function(a){for(var b=a.length,c=0;b>c;c++)this.writeByte(a.charCodeAt(c))},c.prototype.writeBytes=function(a,b,c){for(var d=c||a.length,e=b||0;d>e;e++)this.writeByte(a[e])},d.prototype.setDelay=function(a){this.delay=Math.round(a/10)},d.prototype.setFrameRate=function(a){this.delay=Math.round(100/a)},d.prototype.setDispose=function(a){a>=0&&(this.dispose=a)},d.prototype.setRepeat=function(a){this.repeat=a},d.prototype.setTransparent=function(a){this.transparent=a},d.prototype.addFrame=function(a){this.image=a,this.getImagePixels(),this.analyzePixels(),this.firstFrame&&(this.writeLSD(),this.writePalette(),this.repeat>=0&&this.writeNetscapeExt()),this.writeGraphicCtrlExt(),this.writeImageDesc(),this.firstFrame||this.writePalette(),this.writePixels(),this.firstFrame=!1},d.prototype.finish=function(){this.out.writeByte(59)},d.prototype.setQuality=function(a){1>a&&(a=1),this.sample=a},d.prototype.writeHeader=function(){this.out.writeUTFBytes("GIF89a")},d.prototype.analyzePixels=function(){var a=this.pixels.length,b=a/3;this.indexedPixels=new Uint8Array(b);var c=new e(this.pixels,this.sample);c.buildColormap(),this.colorTab=c.getColormap();for(var d=0,f=0;b>f;f++){var g=c.lookupRGB(255&this.pixels[d++],255&this.pixels[d++],255&this.pixels[d++]);this.usedEntry[g]=!0,this.indexedPixels[f]=g}this.pixels=null,this.colorDepth=8,this.palSize=7,null!==this.transparent&&(this.transIndex=this.findClosest(this.transparent))},d.prototype.findClosest=function(a){if(null===this.colorTab)return-1;for(var b=(16711680&a)>>16,c=(65280&a)>>8,d=255&a,e=0,f=16777216,g=this.colorTab.length,h=0;g>h;){var i=b-(255&this.colorTab[h++]),j=c-(255&this.colorTab[h++]),k=d-(255&this.colorTab[h]),l=i*i+j*j+k*k,m=h/3;this.usedEntry[m]&&f>l&&(f=l,e=m),h++}return e},d.prototype.getImagePixels=function(){var a=this.width,b=this.height;this.pixels=new Uint8Array(3*a*b);for(var c=this.image,d=0,e=0;b>e;e++)for(var f=0;a>f;f++){var g=4*e*a+4*f;this.pixels[d++]=c[g],this.pixels[d++]=c[g+1],this.pixels[d++]=c[g+2]}},d.prototype.writeGraphicCtrlExt=function(){this.out.writeByte(33),this.out.writeByte(249),this.out.writeByte(4);var a,b;null===this.transparent?(a=0,b=0):(a=1,b=2),this.dispose>=0&&(b=7&dispose),b<<=2,this.out.writeByte(0|(0|b)|a),this.writeShort(this.delay),this.out.writeByte(this.transIndex),this.out.writeByte(0)},d.prototype.writeImageDesc=function(){this.out.writeByte(44),this.writeShort(0),this.writeShort(0),this.writeShort(this.width),this.writeShort(this.height),this.firstFrame?this.out.writeByte(0):this.out.writeByte(128|this.palSize)},d.prototype.writeLSD=function(){this.writeShort(this.width),this.writeShort(this.height),this.out.writeByte(240|this.palSize),this.out.writeByte(0),this.out.writeByte(0)},d.prototype.writeNetscapeExt=function(){this.out.writeByte(33),this.out.writeByte(255),this.out.writeByte(11),this.out.writeUTFBytes("NETSCAPE2.0"),this.out.writeByte(3),this.out.writeByte(1),this.writeShort(this.repeat),this.out.writeByte(0)},d.prototype.writePalette=function(){this.out.writeBytes(this.colorTab);for(var a=768-this.colorTab.length,b=0;a>b;b++)this.out.writeByte(0)},d.prototype.writeShort=function(a){this.out.writeByte(255&a),this.out.writeByte(255&a>>8)},d.prototype.writePixels=function(){var a=new f(this.width,this.height,this.indexedPixels,this.colorDepth);a.encode(this.out)},d.prototype.stream=function(){return this.out},b.exports=d}),a.define("/LZWEncoder.js",function(a){function b(a,b,g,h){function i(a,b){y[s++]=a,s>=254&&n(b)}function j(a){k(e),C=v+2,D=!0,q(v,a)}function k(a){for(var b=0;a>b;++b)z[b]=-1}function l(a,b){var f,g,h,i,l,m,n;for(u=a,D=!1,n_bits=u,t=o(n_bits),v=1<f;f*=2)++n;n=8-n,m=e,k(m),q(v,b);a:for(;(g=p())!=c;)if(f=(g<=0){l=m-h,0===h&&(l=1);do if((h-=l)<0&&(h+=m),z[h]===f){i=A[h];continue a}while(z[h]>=0)}q(i,b),i=g,1<C?(A[h]=C++,z[h]=f):j(b)}else i=A[h];q(i,b),q(w,b)}function m(c){c.writeByte(x),remaining=a*b,curPixel=0,l(x+1,c),c.writeByte(0)}function n(a){s>0&&(a.writeByte(s),a.writeBytes(y,0,s),s=0)}function o(a){return(1<0?r|=a<=8;)i(255&r,b),r>>=8,B-=8;if((C>t||D)&&(D?(t=o(n_bits=u),D=!1):(++n_bits,t=n_bits==d?1<0;)i(255&r,b),r>>=8,B-=8;n(b)}}var r,s,t,u,v,w,x=Math.max(2,h),y=new Uint8Array(256),z=new Int32Array(e),A=new Int32Array(e),B=0,C=0,D=!1;this.encode=m}var c=-1,d=12,e=5003,f=[0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535];a.exports=b}),a.define("/TypedNeuQuant.js",function(a){function b(a,b){function m(){H=[],I=new Int32Array(256),J=new Int32Array(d),K=new Int32Array(d),L=new Int32Array(d>>3);var a,b;for(a=0;d>a;a++)b=(a<a;a++)H[a][0]>>=f,H[a][1]>>=f,H[a][2]>>=f,H[a][3]=a}function r(a,b,c,d,e){H[b][0]-=a*(H[b][0]-c)/s,H[b][1]-=a*(H[b][1]-d)/s,H[b][2]-=a*(H[b][2]-e)/s}function t(a,b,c,e,f){for(var g,h,i=Math.abs(b-a),j=Math.min(b+a,d),k=b+1,l=b-1,m=1;j>k||l>i;)h=L[m++],j>k&&(g=H[k++],g[0]-=h*(g[0]-c)/w,g[1]-=h*(g[1]-e)/w,g[2]-=h*(g[2]-f)/w),l>i&&(g=H[l--],g[0]-=h*(g[0]-c)/w,g[1]-=h*(g[1]-e)/w,g[2]-=h*(g[2]-f)/w)}function v(a,b,c){var e,h,m,n,o,p=2147483647,q=p,r=-1,s=r;for(e=0;d>e;e++)h=H[e],m=Math.abs(h[0]-a)+Math.abs(h[1]-b)+Math.abs(h[2]-c),p>m&&(p=m,r=e),n=m-(J[e]>>g-f),q>n&&(q=n,s=e),o=K[e]>>j,K[e]-=o,J[e]+=o<a;a++){for(c=H[a],g=a,h=c[1],b=a+1;d>b;b++)f=H[b],f[1]>1,b=i+1;h>b;b++)I[b]=a;i=h,j=a}}for(I[i]=j+e>>1,b=i+1;256>b;b++)I[b]=e}function D(a,b,c){for(var e,f,g,h=1e3,i=-1,j=I[b],k=j-1;d>j||k>=0;)d>j&&(f=H[j],g=f[1]-b,g>=h?j=d:(j++,0>g&&(g=-g),e=f[0]-a,0>e&&(e=-e),g+=e,h>g&&(e=f[2]-c,0>e&&(e=-e),g+=e,h>g&&(h=g,i=f[3])))),k>=0&&(f=H[k],g=b-f[1],g>=h?k=-1:(k--,0>g&&(g=-g),e=f[0]-a,0>e&&(e=-e),g+=e,h>g&&(e=f[2]-c,0>e&&(e=-e),g+=e,h>g&&(h=g,i=f[3]))));return i}function E(){var d,e=a.length,g=30+(b-1)/3,h=e/(3*b),i=~~(h/c),j=s,k=p,l=k>>n;for(1>=l&&(l=0),d=0;l>d;d++)L[d]=j*((l*l-d*d)*u/(l*l));var m;B>e?(b=1,m=3):m=0!==e%x?3*x:0!==e%y?3*y:0!==e%z?3*z:3*A;var o,w,C,D,E=0;for(d=0;h>d;)if(o=(255&a[E])<=e&&(E-=e),d++,0===i&&(i=1),0===d%i)for(j-=j/g,k-=k/q,l=k>>n,1>=l&&(l=0),D=0;l>D;D++)L[D]=j*((l*l-D*D)*u/(l*l))}function F(){m(),E(),o(),C()}function G(){for(var a=[],b=[],c=0;d>c;c++)b[H[c][3]]=c;for(var e=0,f=0;d>f;f++){var g=b[f];a[e++]=H[g][0],a[e++]=H[g][1],a[e++]=H[g][2]}return a}var H,I,J,K,L;this.buildColormap=F,this.getColormap=G,this.lookupRGB=D}var c=100,d=256,e=d-1,f=4,g=16,h=1<>j,l=h<>3,n=6,o=1<c;++c)if(c in b&&b[c]===a)return!0;return!1}function e(a,b){function d(){this.constructor=a}for(var e in b)c(b,e)&&(a[e]=b[e]);return d.prototype=b.prototype,a.prototype=new d,a.__super__=b.prototype,a}var f,g,h;g=b("events",a).EventEmitter,f=b("/browser.coffee",a),h=function(a,b,g){function h(a){var c,d;this.running=!1,this.options={},this.frames=[],this.freeWorkers=[],this.activeWorkers=[],this.setOptions(a);for(c in b)d=b[c],null!=this.options[c]?this.options[c]:this.options[c]=d}return e(h,a),b={workerScript:window.GifWorkerURL,workers:2,repeat:0,background:"#fff",quality:10,width:null,height:null},g={delay:500,copy:!1},h.prototype.setOption=function(a,b){return this.options[a]=b,null==this._canvas||"width"!==a&&"height"!==a?void 0:this._canvas[a]=b},h.prototype.setOptions=function(a){return function(b){var d,e;for(d in a)c(a,d)&&(e=a[d],b.push(this.setOption(d,e)));return b}.call(this,[])},h.prototype.addFrame=function(a,b){var c,d;null==b&&(b={}),c={};for(d in g)c[d]=b[d]||g[d];if(null!=this.options.width||this.setOption("width",a.width),null!=this.options.height||this.setOption("height",a.height),"undefined"!=typeof ImageData&&null!=ImageData&&a instanceof ImageData)c.data=a.data;else if("undefined"!=typeof CanvasRenderingContext2D&&null!=CanvasRenderingContext2D&&a instanceof CanvasRenderingContext2D||"undefined"!=typeof WebGLRenderingContext&&null!=WebGLRenderingContext&&a instanceof WebGLRenderingContext)b.copy?c.data=this.getContextData(a):c.context=a;else{if(null==a.childNodes)throw new Error("Invalid image");b.copy?c.data=this.getImageData(a):c.image=a}return this.frames.push(c)},h.prototype.render=function(){var a,b;if(this.running)throw new Error("Already running");if(null==this.options.width||null==this.options.height)throw new Error("Width and height must be set prior to rendering");this.running=!0,this.nextFrame=0,this.finishedFrames=0,this.imageParts=function(a){for(var b,c=0,d=function(){var a,a;a=[];for(var b=0;0<=this.frames.length?bthis.frames.length;0<=this.frames.length?++b:--b)a.push(b);return a}.apply(this,arguments).length;d>c;++c)b=function(){var a,a;a=[];for(var b=0;0<=this.frames.length?bthis.frames.length;0<=this.frames.length?++b:--b)a.push(b);return a}.apply(this,arguments)[c],a.push(null);return a}.call(this,[]),b=this.spawnWorkers();for(var c=0,d=function(){var a,a;a=[];for(var c=0;b>=0?b>c:c>b;b>=0?++c:--c)a.push(c);return a}.apply(this,arguments).length;d>c;++c)a=function(){var a,a;a=[];for(var c=0;b>=0?b>c:c>b;b>=0?++c:--c)a.push(c);return a}.apply(this,arguments)[c],this.renderNextFrame();return this.emit("start"),this.emit("progress",0)},h.prototype.abort=function(){for(var a;;){if(a=this.activeWorkers.shift(),!(null!=a))break;console.log("killing active worker"),a.terminate()}return this.running=!1,this.emit("abort")},h.prototype.spawnWorkers=function(){var a,b;return a=Math.min(this.options.workers,this.frames.length),function(){var b;b=[];for(var c=this.freeWorkers.length;this.freeWorkers.length<=a?a>c:c>a;this.freeWorkers.length<=a?++c:--c)b.push(c);return b}.apply(this,arguments).forEach((b=this,function(a){var c,d;return console.log("spawning worker "+a),d=new Worker(b.options.workerScript),c=b,d.onmessage=function(a){return c.activeWorkers.splice(c.activeWorkers.indexOf(d),1),c.freeWorkers.push(d),c.frameFinished(a.data)},b.freeWorkers.push(d)})),a},h.prototype.frameFinished=function(a){return console.log("frame "+a.index+" finished - "+this.activeWorkers.length+" active"),this.finishedFrames++,this.emit("progress",this.finishedFrames/this.frames.length),this.imageParts[a.index]=a,d(null,this.imageParts)?this.renderNextFrame():this.finishRendering()},h.prototype.finishRendering=function(){var a,b,c,d,e,f,g;e=0;for(var h=0,i=this.imageParts.length;i>h;++h)b=this.imageParts[h],e+=(b.data.length-1)*b.pageSize+b.cursor;e+=b.pageSize-b.cursor,console.log("rendering finished - filesize "+Math.round(e/1e3)+"kb"),a=new Uint8Array(e),f=0;for(var j=0,k=this.imageParts.length;k>j;++j){b=this.imageParts[j];for(var l=0,m=b.data.length;m>l;++l)g=b.data[l],c=l,a.set(g,f),f+=c===b.data.length-1?b.cursor:b.pageSize}return d=new Blob([a],{type:"image/gif"}),this.emit("finished",d,a)},h.prototype.renderNextFrame=function(){var a,b,c;if(0===this.freeWorkers.length)throw new Error("No free workers");return this.nextFrame>=this.frames.length?void 0:(a=this.frames[this.nextFrame++],c=this.freeWorkers.shift(),b=this.getTask(a),console.log("starting frame "+(b.index+1)+" of "+this.frames.length),this.activeWorkers.push(c),c.postMessage(b))},h.prototype.getContextData=function(a){return a.getImageData(0,0,this.options.width,this.options.height).data},h.prototype.getImageData=function(a){var b;return null!=this._canvas||(this._canvas=document.createElement("canvas"),this._canvas.width=this.options.width,this._canvas.height=this.options.height),b=this._canvas.getContext("2d"),b.setFill=this.options.background,b.fillRect(0,0,this.options.width,this.options.height),b.drawImage(a,0,0),this.getContextData(b)},h.prototype.getTask=function(a){var b,c;if(b=this.frames.indexOf(a),c={index:b,last:b===this.frames.length-1,delay:a.delay,width:this.options.width,height:this.options.height,quality:this.options.quality,repeat:this.options.repeat,canTransfer:"chrome"===f.name},null!=a.data)c.data=a.data;else if(null!=a.context)c.data=this.getContextData(a.context);else{if(null==a.image)throw new Error("Invalid frame");c.data=this.getImageData(a.image)}return c},h}(g),a.exports=h}),b.define("/browser.coffee",function(a){var b,c,d,e,f;e=navigator.userAgent.toLowerCase(),d=navigator.platform.toLowerCase(),f=e.match(/(opera|ie|firefox|chrome|version)[\s\/:]([\w\d\.]+)?.*?(safari|version[\s\/:]([\w\d\.]+)|$)/)||[null,"unknown",0],c="ie"===f[1]&&document.documentMode,b={name:"version"===f[1]?f[3]:f[1],version:c||parseFloat("opera"===f[1]&&f[4]?f[4]:f[2]),platform:{name:e.match(/ip(?:ad|od|hone)/)?"ios":(e.match(/(?:webos|android)/)||d.match(/mac|win|linux/)||["other"])[0]}},b[b.name]=!0,b[b.name+parseInt(b.version,10)]=!0,b.platform[b.platform.name]=!0,a.exports=b}),b.define("events",function(a,b){c.EventEmitter||(c.EventEmitter=function(){});var d=b.EventEmitter=c.EventEmitter,e="function"==typeof Array.isArray?Array.isArray:function(a){return"[object Array]"===Object.prototype.toString.call(a)},f=10;d.prototype.setMaxListeners=function(a){this._events||(this._events={}),this._events.maxListeners=a},d.prototype.emit=function(a){if("error"===a&&(!this._events||!this._events.error||e(this._events.error)&&!this._events.error.length))throw arguments[1]instanceof Error?arguments[1]:new Error("Uncaught, unspecified 'error' event.");if(!this._events)return!1;var b=this._events[a];if(!b)return!1;if("function"!=typeof b){if(e(b)){for(var c=Array.prototype.slice.call(arguments,1),d=b.slice(),f=0,g=d.length;g>f;f++)d[f].apply(this,c);return!0}return!1}switch(arguments.length){case 1:b.call(this);break;case 2:b.call(this,arguments[1]);break;case 3:b.call(this,arguments[1],arguments[2]);break;default:var c=Array.prototype.slice.call(arguments,1);b.apply(this,c)}return!0},d.prototype.addListener=function(a,b){if("function"!=typeof b)throw new Error("addListener only takes instances of Function");if(this._events||(this._events={}),this.emit("newListener",a,b),this._events[a])if(e(this._events[a])){if(!this._events[a].warned){var c;c=void 0!==this._events.maxListeners?this._events.maxListeners:f,c&&c>0&&this._events[a].length>c&&(this._events[a].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[a].length),console.trace())}this._events[a].push(b)}else this._events[a]=[this._events[a],b];else this._events[a]=b;return this},d.prototype.on=d.prototype.addListener,d.prototype.once=function(a,b){var c=this;return c.on(a,function d(){c.removeListener(a,d),b.apply(this,arguments)}),this},d.prototype.removeListener=function(a,b){if("function"!=typeof b)throw new Error("removeListener only takes instances of Function");if(!this._events||!this._events[a])return this;var c=this._events[a];if(e(c)){var d=c.indexOf(b);if(0>d)return this;c.splice(d,1),0==c.length&&delete this._events[a]}else this._events[a]===b&&delete this._events[a];return this},d.prototype.removeAllListeners=function(a){return a&&this._events&&this._events[a]&&(this._events[a]=null),this},d.prototype.listeners=function(a){return this._events||(this._events={}),this._events[a]||(this._events[a]=[]),e(this._events[a])||(this._events[a]=[this._events[a]]),this._events[a]}}),a.GIF=b("/gif.coffee")}.call(this,this);var Constants={DEFAULT:{HEIGHT:32,WIDTH:32,FPS:12},MODEL_VERSION:1,MAX_HEIGHT:1024,MAX_WIDTH:1024,PREVIEW_FILM_SIZE:120,DEFAULT_PEN_COLOR:"#000000",TRANSPARENT_COLOR:"TRANSPARENT",SELECTION_TRANSPARENT_COLOR:"rgba(255, 255, 255, 0.6)",TOOL_TARGET_HIGHLIGHT_COLOR:"rgba(255, 255, 255, 0.2)",STATIC:{URL:{SAVE:"http://3.piskel-app.appspot.com/store",GET:"http://3.piskel-app.appspot.com/get"}},APPENGINE:{URL:{SAVE:"save"}},IMAGE_SERVICE_UPLOAD_URL:"http://screenletstore.appspot.com/__/upload",IMAGE_SERVICE_GET_URL:"http://screenletstore.appspot.com/img/",GRID_STROKE_WIDTH:1,LEFT_BUTTON:"left_button_1",RIGHT_BUTTON:"right_button_2",MOUSEMOVE_THROTTLING:10},Events={TOOL_SELECTED:"TOOL_SELECTED",TOOL_RELEASED:"TOOL_RELEASED",PRIMARY_COLOR_SELECTED:"PRIMARY_COLOR_SELECTED",PRIMARY_COLOR_UPDATED:"PRIMARY_COLOR_UPDATED",SECONDARY_COLOR_SELECTED:"SECONDARY_COLOR_SELECTED",SECONDARY_COLOR_UPDATED:"SECONDARY_COLOR_UPDATED",LOCALSTORAGE_REQUEST:"LOCALSTORAGE_REQUEST",CANVAS_RIGHT_CLICKED:"CANVAS_RIGHT_CLICKED",REFRESH:"REFRESH",REDRAW_PREVIEWFILM:"REDRAW_PREVIEWFILM",USER_SETTINGS_CHANGED:"USER_SETTINGS_CHANGED",PISKEL_RESET:"PISKEL_RESET",FRAME_SIZE_CHANGED:"FRAME_SIZE_CHANGED",CURRENT_FRAME_SET:"CURRENT_FRAME_SET",SELECTION_CREATED:"SELECTION_CREATED",SELECTION_MOVE_REQUEST:"SELECTION_MOVE_REQUEST",SELECTION_DISMISSED:"SELECTION_DISMISSED",SHOW_NOTIFICATION:"SHOW_NOTIFICATION",HIDE_NOTIFICATION:"HIDE_NOTIFICATION",UNDO:"UNDO",REDO:"REDO",CUT:"CUT",COPY:"COPY",PASTE:"PASTE"};jQuery.namespace=function(){var a,b,c,d=arguments,e=null;for(a=0;a255||b>255||c>255)throw"Invalid color component";return(a<<16|b<<8|c).toString(16)},a.inherit=function(a,b){a.prototype=Object.create(b.prototype),a.prototype.constructor=a,a.prototype.superclass=b.prototype}}(),function(){var a=$.namespace("pskl");a.CanvasUtils={createCanvas:function(a,b,c){var d=document.createElement("canvas");if(d.setAttribute("width",a),d.setAttribute("height",b),"string"==typeof c&&(c=[c]),Array.isArray(c))for(var e=0;e0;){k++;var m=g.pop();a.setPixel(m.col,m.row,d),f.push({col:m.col,row:m.row});for(var n=0;4>n;n++){var o=m.col+i[n],p=m.row+h[n];try{a.containsPixel(o,p)&&a.getPixel(o,p)==e&&g.push({col:o,row:p})}catch(j){}}if(k>10*l){console.log("loop breaker called");break}}return f}},calculateDPIForContainer:function(a,b,c){return this.calculateDPI(a.height(),a.width(),b,c)},calculateDPI:function(a,b,c,d){var e=Math.floor(a/c),f=Math.floor(b/d);return Math.min(e,f)}}}(),function(){var a=$.namespace("pskl.utils");a.Serializer={serializePiskel:function(a){var b=a.getLayers().map(function(a){return pskl.utils.Serializer.serializeLayer(a)});return JSON.stringify({modelVersion:Constants.MODEL_VERSION,piskel:{height:a.getHeight(),width:a.getWidth(),layers:b}})},serializeLayer:function(a){var b=a.getFrames().map(function(a){return a.serialize()});return JSON.stringify({name:a.getName(),frames:b})},deserializePiskel:function(a){var b=JSON.parse(a);return this.createPiskelFromData(b)},createPiskel:function(a){var b=null;if(a.modelVersion==Constants.MODEL_VERSION){var c=a.piskel;b=new pskl.model.Piskel(c.width,c.height),c.layers.forEach(function(a){var c=pskl.utils.Serializer.deserializeLayer(a);b.addLayer(c)})}else b=pskl.utils.Serializer.backwardDeserializer_(a);return b},deserializeLayer:function(a){var b=JSON.parse(a),c=new pskl.model.Layer(b.name);return b.frames.forEach(function(a){var b=pskl.utils.Serializer.deserializeFrame(a);c.addFrame(b)}),c},deserializeFrame:function(a){var b=JSON.parse(a);return pskl.model.Frame.fromPixelGrid(b)},backwardDeserializer_:function(a){var b=new pskl.model.Layer("Layer 1");a.forEach(function(a){b.addFrame(pskl.model.Frame.fromPixelGrid(a))});var c=b.getFrameAt(0).getWidth(),d=b.getFrameAt(0).getHeight(),e=new pskl.model.Piskel(c,d);return e.addLayer(b),e}}}(),function(){var a=$.namespace("pskl");a.utils.Template={get:function(a){var b=document.getElementById(a);return b?b.innerHTML:(console.error("Could not find template for id :",a),void 0)},createFromHTML:function(a){var b=document.createElement("div");return b.innerHTML=a,b.children[0]},replace:function(a,b){for(var c in b)if(b.hasOwnProperty(c)){var d=b[c];a=a.replace(new RegExp("\\{\\{"+c+"\\}\\}","g"),d)}return a}}}(),function(){var a=$.namespace("pskl");a.UserSettings={SHOW_GRID:"SHOW_GRID",CANVAS_BACKGROUND:"CANVAS_BACKGROUND",KEY_TO_DEFAULT_VALUE_MAP_:{SHOW_GRID:!1,CANVAS_BACKGROUND:"medium-canvas-background"},cache_:{},get:function(a){return this.checkKeyValidity_(a),a in this.cache_||(this.cache_[a]=this.readFromLocalStorage_(a)||this.readFromDefaults_(a)),this.cache_[a]},set:function(a,b){this.checkKeyValidity_(a),this.cache_[a]=b,this.writeToLocalStorage_(a,b),$.publish(Events.USER_SETTINGS_CHANGED,[a,b]) +},readFromLocalStorage_:function(a){var b=window.localStorage[a];return"undefined"!=typeof b&&(b=JSON.parse(b)),b},writeToLocalStorage_:function(a,b){window.localStorage[a]=JSON.stringify(b)},readFromDefaults_:function(a){return this.KEY_TO_DEFAULT_VALUE_MAP_[a]},checkKeyValidity_:function(a){a in this.KEY_TO_DEFAULT_VALUE_MAP_||console.log("UserSettings key <"+a+"> not find in supported keys.")}}}();var jscolor={dir:"",bindClass:"color",binding:!0,preloading:!0,install:function(){"complete"===document.readyState?jscolor.init():jscolor.addEvent(window,"load",jscolor.init)},init:function(){jscolor.binding&&jscolor.bind(),jscolor.preloading&&jscolor.preload()},getDir:function(){return"/"+window.location.pathname.split("/")[1]+"/js/lib/jsColor_1_4_0/"},bind:function(){for(var a=new RegExp("(^|\\s)("+jscolor.bindClass+")\\s*(\\{[^}]*\\})?","i"),b=document.getElementsByTagName("input"),c=0;ck[b]?-i[b]+e[b]+h[b]/2>k[b]/2&&e[b]+h[b]-l[b]>=0?e[b]+h[b]-l[b]:e[b]:e[b],-i[c]+e[c]+h[c]+l[c]-m+m*d>k[c]?-i[c]+e[c]+h[c]/2>k[c]/2&&e[c]+h[c]-m-m*d>=0?e[c]+h[c]-m-m*d:e[c]+h[c]-m+m*d:e[c]+h[c]-m+m*d>=0?e[c]+h[c]-m+m*d:e[c]+h[c]-m-m*d];else var n=[e[b],e[c]+h[c]-m+m*d];f(n[b],n[c])}},this.importColor=function(){t?this.adjust?!this.required&&/^\s*$/.test(t.value)?(t.value="",u.style.backgroundImage=u.jscStyle.backgroundImage,u.style.backgroundColor=u.jscStyle.backgroundColor,u.style.color=u.jscStyle.color,this.exportColor(x|y)):this.fromString(t.value)||this.exportColor():this.fromString(t.value,x)||(u.style.backgroundImage=u.jscStyle.backgroundImage,u.style.backgroundColor=u.jscStyle.backgroundColor,u.style.color=u.jscStyle.color,this.exportColor(x|y)):this.exportColor()},this.exportColor=function(a){if(!(a&x)&&t){var b=this.toString();this.caps&&(b=b.toUpperCase()),this.hash&&(b="#"+b),t.value=b}a&y||!u||(u.style.backgroundImage="none",u.style.backgroundColor="#"+this.toString(),u.style.color=.213*this.rgb[0]+.715*this.rgb[1]+.072*this.rgb[2]<.5?"#FFF":"#000"),a&z||!j()||h(),a&A||!j()||i()},this.fromHSV=function(a,b,c,e){null!==a&&(a=Math.max(0,this.minH,Math.min(6,this.maxH,a))),null!==b&&(b=Math.max(0,this.minS,Math.min(1,this.maxS,b))),null!==c&&(c=Math.max(0,this.minV,Math.min(1,this.maxV,c))),this.rgb=d(null===a?this.hsv[0]:this.hsv[0]=a,null===b?this.hsv[1]:this.hsv[1]=b,null===c?this.hsv[2]:this.hsv[2]=c),this.exportColor(e)},this.fromRGB=function(a,b,e,f){null!==a&&(a=Math.max(0,Math.min(1,a))),null!==b&&(b=Math.max(0,Math.min(1,b))),null!==e&&(e=Math.max(0,Math.min(1,e)));var g=c(null===a?this.rgb[0]:a,null===b?this.rgb[1]:b,null===e?this.rgb[2]:e);null!==g[0]&&(this.hsv[0]=Math.max(0,this.minH,Math.min(6,this.maxH,g[0]))),0!==g[2]&&(this.hsv[1]=null===g[1]?null:Math.max(0,this.minS,Math.min(1,this.maxS,g[1]))),this.hsv[2]=null===g[2]?null:Math.max(0,this.minV,Math.min(1,this.maxV,g[2]));var h=d(this.hsv[0],this.hsv[1],this.hsv[2]);this.rgb[0]=h[0],this.rgb[1]=h[1],this.rgb[2]=h[2],this.exportColor(f)},this.fromString=function(a,b){var c=a.match(/^\W*([0-9A-F]{3}([0-9A-F]{3})?)\W*$/i);return c?(6===c[1].length?this.fromRGB(parseInt(c[1].substr(0,2),16)/255,parseInt(c[1].substr(2,2),16)/255,parseInt(c[1].substr(4,2),16)/255,b):this.fromRGB(parseInt(c[1].charAt(0)+c[1].charAt(0),16)/255,parseInt(c[1].charAt(1)+c[1].charAt(1),16)/255,parseInt(c[1].charAt(2)+c[1].charAt(2),16)/255,b),!0):!1},this.toString=function(){return(256|Math.round(255*this.rgb[0])).toString(16).substr(1)+(256|Math.round(255*this.rgb[1])).toString(16).substr(1)+(256|Math.round(255*this.rgb[2])).toString(16).substr(1)};var q=this,r="hvs"===this.pickerMode.toLowerCase()?1:0,s=!1,t=jscolor.fetchElement(this.valueElement),u=jscolor.fetchElement(this.styleElement),v=!1,w=!1,x=1,y=2,z=4,A=8;if(jscolor.addEvent(a,"focus",function(){q.pickerOnfocus&&q.showPicker()}),jscolor.addEvent(a,"blur",function(){s?s=!1:window.setTimeout(function(){s||k(),s=!1},0)}),t){var B=function(){q.fromString(t.value,x),o()};jscolor.addEvent(t,"keyup",B),jscolor.addEvent(t,"input",B),jscolor.addEvent(t,"blur",l),t.setAttribute("autocomplete","off")}switch(u&&(u.jscStyle={backgroundImage:u.style.backgroundImage,backgroundColor:u.style.backgroundColor,color:u.style.color}),r){case 0:jscolor.requireImage("hs.png");break;case 1:jscolor.requireImage("hv.png")}jscolor.requireImage("cross.gif"),jscolor.requireImage("arrow.gif"),this.importColor()}};!function(){var a=$.namespace("pskl.rendering");a.DrawingLoop=function(){this.requestAnimationFrame=this.getRequestAnimationFrameShim_(),this.isRunning=!1,this.previousTime=0,this.callbacks=[]},a.DrawingLoop.prototype.addCallback=function(a,b,c){var d={fn:a,scope:b,args:c};return this.callbacks.push(d),d},a.DrawingLoop.prototype.removeCallback=function(a){var b=this.callbacks.indexOf(a);-1!=b&&this.callbacks.splice(b,1)},a.DrawingLoop.prototype.start=function(){this.isRunning=!0,this.loop_()},a.DrawingLoop.prototype.loop_=function(){var a=Date.now(),b=a-this.previousTime;this.executeCallbacks_(b),this.previousTime=a,this.requestAnimationFrame.call(window,this.loop_.bind(this))},a.DrawingLoop.prototype.executeCallbacks_=function(a){for(var b=0;bd;d++){for(var e=[],f=0;b>f;f++)e.push(Constants.TRANSPARENT_COLOR);c[d]=e}return c},a.Frame.createEmptyFromFrame=function(b){return new a.Frame(b.getWidth(),b.getHeight())},a.Frame.prototype.clone=function(){var b=new a.Frame(this.width,this.height);return b.setPixels(this.getPixels()),b},a.Frame.prototype.getPixels=function(){return this.clonePixels_(this.pixels)},a.Frame.prototype.setPixels=function(a){this.pixels=this.clonePixels_(a)},a.Frame.prototype.clear=function(){var b=a.Frame.createEmptyPixelGrid_(this.getWidth(),this.getHeight());this.setPixels(b)},a.Frame.prototype.clonePixels_=function(a){for(var b=[],c=0;c=0&&b>=0&&a0&&(this.stateIndex--,this.setPixels(this.previousStates[this.stateIndex]))},a.Frame.prototype.loadNextState=function(){this.stateIndex-1&&b0&&(this.layers[b]=this.layers[b-1],this.layers[b-1]=a)},a.Piskel.prototype.removeLayer=function(a){var b=this.layers.indexOf(a);-1!=b&&this.layers.splice(b,1)},a.Piskel.prototype.removeLayerAt=function(a){this.layers.splice(a,1)}}(),function(){var a=$.namespace("pskl.selection");a.SelectionManager=function(a){this.piskelController=a,this.currentSelection=null},a.SelectionManager.prototype.init=function(){$.subscribe(Events.SELECTION_CREATED,$.proxy(this.onSelectionCreated_,this)),$.subscribe(Events.SELECTION_DISMISSED,$.proxy(this.onSelectionDismissed_,this)),$.subscribe(Events.SELECTION_MOVE_REQUEST,$.proxy(this.onSelectionMoved_,this)),$.subscribe(Events.PASTE,$.proxy(this.onPaste_,this)),$.subscribe(Events.COPY,$.proxy(this.onCopy_,this)),$.subscribe(Events.CUT,$.proxy(this.onCut_,this)),$.subscribe(Events.TOOL_SELECTED,$.proxy(this.onToolSelected_,this))},a.SelectionManager.prototype.cleanSelection_=function(){this.currentSelection&&this.currentSelection.reset()},a.SelectionManager.prototype.onToolSelected_=function(a,b){var c=b instanceof pskl.drawingtools.BaseSelect;c||this.cleanSelection_()},a.SelectionManager.prototype.onSelectionDismissed_=function(){this.cleanSelection_()},a.SelectionManager.prototype.onCut_=function(){if(!this.currentSelection)throw"Bad state for CUT callback in SelectionManager";this.currentSelection.fillSelectionFromFrame(this.piskelController.getCurrentFrame());for(var a=this.currentSelection.pixels,b=this.piskelController.getCurrentFrame(),c=0,d=a.length;d>c;c++)try{b.setPixel(a[c].col,a[c].row,Constants.TRANSPARENT_COLOR)}catch(e){}},a.SelectionManager.prototype.onPaste_=function(){if(this.currentSelection&&this.currentSelection.hasPastedContent)for(var a=this.currentSelection.pixels,b=this.piskelController.getCurrentFrame(),c=0,d=a.length;d>c;c++)try{b.setPixel(a[c].col,a[c].row,a[c].copiedColor)}catch(e){}},a.SelectionManager.prototype.onCopy_=function(){if(!this.currentSelection||!this.piskelController.getCurrentFrame())throw"Bad state for CUT callback in SelectionManager";this.currentSelection.fillSelectionFromFrame(this.piskelController.getCurrentFrame())},a.SelectionManager.prototype.onSelectionCreated_=function(a,b){if(!b)throw"No selection set in SelectionManager";this.currentSelection=b},a.SelectionManager.prototype.onSelectionMoved_=function(a,b,c){if(!this.currentSelection)throw"Bad state: No currentSelection set when trying to move it in SelectionManager";this.currentSelection.move(b,c)}}(),function(){var a=$.namespace("pskl.selection");a.BaseSelection=function(){this.reset()},a.BaseSelection.prototype.reset=function(){this.pixels=[],this.hasPastedContent=!1},a.BaseSelection.prototype.move=function(a,b){for(var c,d=[],e=0,f=this.pixels.length;f>e;e++)c=this.pixels[e],c.col+=a,c.row+=b,d.push(c);this.pixels=d},a.BaseSelection.prototype.fillSelectionFromFrame=function(a){for(var b,c=0,d=this.pixels.length;d>c;c++)b=this.pixels[c],b.copiedColor=a.getPixel(b.col,b.row);this.hasPastedContent=!0}}(),function(){var a=$.namespace("pskl.selection");a.RectangularSelection=function(a,b,c,d){this.pixels=pskl.PixelUtils.getRectanglePixels(a,b,c,d)},pskl.utils.inherit(a.RectangularSelection,a.BaseSelection)}(),function(){var a=$.namespace("pskl.selection");a.ShapeSelection=function(a){this.pixels=a},pskl.utils.inherit(a.ShapeSelection,a.BaseSelection)}(),function(){var a=$.namespace("pskl.rendering");a.AbstractRenderer=function(){},a.AbstractRenderer.prototype.clear=function(){throw"abstract method should be implemented"},a.AbstractRenderer.prototype.getCoordinates=function(){throw"abstract method should be implemented"},a.AbstractRenderer.prototype.setGridEnabled=function(){throw"abstract method should be implemented"},a.AbstractRenderer.prototype.isGridEnabled=function(){throw"abstract method should be implemented"},a.AbstractRenderer.prototype.setZoom=function(){throw"abstract method should be implemented"},a.AbstractRenderer.prototype.getZoom=function(){throw"abstract method should be implemented"},a.AbstractRenderer.prototype.moveOffset=function(){throw"abstract method should be implemented"},a.AbstractRenderer.prototype.setOffset=function(){throw"abstract method should be implemented"},a.AbstractRenderer.prototype.getOffset=function(){throw"abstract method should be implemented"},a.AbstractRenderer.prototype.setDisplaySize=function(){throw"abstract method should be implemented"},a.AbstractRenderer.prototype.getDisplaySize=function(){throw"abstract method should be implemented"}}(),function(){var a=$.namespace("pskl.rendering");a.CompositeRenderer=function(){this.renderers=[]},pskl.utils.inherit(pskl.rendering.CompositeRenderer,pskl.rendering.AbstractRenderer),a.CompositeRenderer.prototype.add=function(a){return this.renderers.push(a),this},a.CompositeRenderer.prototype.clear=function(){this.renderers.forEach(function(a){a.clear()})},a.CompositeRenderer.prototype.setZoom=function(a){this.renderers.forEach(function(b){b.setZoom(a)})},a.CompositeRenderer.prototype.getZoom=function(){return this.getSampleRenderer_().getZoom()},a.CompositeRenderer.prototype.setDisplaySize=function(a,b){this.renderers.forEach(function(c){c.setDisplaySize(a,b)})},a.CompositeRenderer.prototype.getDisplaySize=function(){return this.getSampleRenderer_().getDisplaySize()},a.CompositeRenderer.prototype.moveOffset=function(a,b){this.renderers.forEach(function(c){c.moveOffset(a,b)})},a.CompositeRenderer.prototype.setOffset=function(a,b){this.renderers.forEach(function(c){c.setOffset(a,b)})},a.CompositeRenderer.prototype.getOffset=function(){return this.getSampleRenderer_().getOffset()},a.CompositeRenderer.prototype.setGridEnabled=function(a){this.renderers.forEach(function(b){b.setGridEnabled(a)})},a.CompositeRenderer.prototype.isGridEnabled=function(){return this.getSampleRenderer_().isGridEnabled()},a.CompositeRenderer.prototype.getSampleRenderer_=function(){if(this.renderers.length>0)return this.renderers[0];throw"Renderer manager is empty"}}(),function(){var a=$.namespace("pskl.rendering.layer");a.LayersRenderer=function(a,b,c){pskl.rendering.CompositeRenderer.call(this),this.piskelController=c,this.belowRenderer=new pskl.rendering.frame.CachedFrameRenderer(a,b,["layers-canvas","layers-below-canvas"]),this.aboveRenderer=new pskl.rendering.frame.CachedFrameRenderer(a,b,["layers-canvas","layers-above-canvas"]),this.add(this.belowRenderer),this.add(this.aboveRenderer),this.serializedRendering=""},pskl.utils.inherit(pskl.rendering.layer.LayersRenderer,pskl.rendering.CompositeRenderer),a.LayersRenderer.prototype.render=function(){var a=this.piskelController.getLayers(),b=this.piskelController.currentFrameIndex,c=this.piskelController.currentLayerIndex,d=[this.getZoom(),b,c,a.length].join("-");if(this.serializedRendering!=d){this.serializedRendering=d,this.clear();var e=a.slice(0,c);if(e.length>0){var f=this.getFrameForLayersAt_(b,e);this.belowRenderer.render(f)}var g=a.slice(c+1,a.length);if(g.length>0){var h=this.getFrameForLayersAt_(b,g);this.aboveRenderer.render(h)}}},a.LayersRenderer.prototype.getFrameForLayersAt_=function(a,b){var c=b.map(function(b){return b.getFrameAt(a)});return pskl.utils.FrameUtils.merge(c)}}(),function(){var a=$.namespace("pskl.rendering.frame");a.FrameRenderer=function(a,b,c){if(this.defaultRenderingOptions={supportGridRendering:!1,zoom:1},b=$.extend(!0,{},this.defaultRenderingOptions,b),void 0===a)throw"Bad FrameRenderer initialization. undefined.";if(isNaN(b.zoom))throw"Bad FrameRenderer initialization. not well defined.";this.container=a,this.zoom=b.zoom,this.offset={x:0,y:0},this.margin={x:0,y:0},this.supportGridRendering=b.supportGridRendering,this.classes=c||[],this.classes.push("canvas"),this.canvas=null,this.displayCanvas=null,this.setDisplaySize(b.width,b.height),this.setGridEnabled(pskl.UserSettings.get(pskl.UserSettings.SHOW_GRID)),this.updateBackgroundClass_(pskl.UserSettings.get(pskl.UserSettings.CANVAS_BACKGROUND)),$.subscribe(Events.USER_SETTINGS_CHANGED,$.proxy(this.onUserSettingsChange_,this))},pskl.utils.inherit(pskl.rendering.frame.FrameRenderer,pskl.rendering.AbstractRenderer),a.FrameRenderer.prototype.render=function(a){a&&(this.clear(),this.renderFrame_(a))},a.FrameRenderer.prototype.clear=function(){pskl.CanvasUtils.clear(this.canvas),pskl.CanvasUtils.clear(this.displayCanvas)},a.FrameRenderer.prototype.setZoom=function(a){var b=this.offset.x+this.displayWidth/(2*this.zoom),c=this.offset.y+this.displayHeight/(2*this.zoom);this.zoom=Math.max(1,a),this.setOffset(b-this.displayWidth/(2*this.zoom),c-this.displayHeight/(2*this.zoom))},a.FrameRenderer.prototype.getZoom=function(){return this.zoom},a.FrameRenderer.prototype.setDisplaySize=function(a,b){this.displayWidth=a,this.displayHeight=b,this.displayCanvas&&($(this.displayCanvas).remove(),this.displayCanvas=null),this.createDisplayCanvas_()},a.FrameRenderer.prototype.getDisplaySize=function(){return{height:this.displayHeight,width:this.displayWidth}},a.FrameRenderer.prototype.getOffset=function(){return{x:this.offset.x,y:this.offset.y}},a.FrameRenderer.prototype.moveOffset=function(a,b){this.setOffset(this.offset.x+a,this.offset.y+b)},a.FrameRenderer.prototype.setOffset=function(a,b){if(this.canvas){var c=this.canvas.width-this.displayWidth/this.zoom; +a=pskl.utils.Math.minmax(a,0,c);var d=this.canvas.height-this.displayHeight/this.zoom;b=pskl.utils.Math.minmax(b,0,d)}this.offset.x=a,this.offset.y=b},a.FrameRenderer.prototype.setGridEnabled=function(a){this.gridStrokeWidth=a&&this.supportGridRendering?Constants.GRID_STROKE_WIDTH:0,this.canvasConfigDirty=!0},a.FrameRenderer.prototype.updateMargins_=function(){var a=this.displayWidth-this.zoom*this.canvas.width;this.margin.x=Math.max(0,a)/2;var b=this.displayHeight-this.zoom*this.canvas.height;this.margin.y=Math.max(0,b)/2},a.FrameRenderer.prototype.createDisplayCanvas_=function(){var a=this.displayHeight,b=this.displayWidth;this.displayCanvas=pskl.CanvasUtils.createCanvas(b,a,this.classes),pskl.CanvasUtils.disableImageSmoothing(this.displayCanvas),this.container.append(this.displayCanvas)},a.FrameRenderer.prototype.onUserSettingsChange_=function(a,b,c){b==pskl.UserSettings.SHOW_GRID?this.setGridEnabled(c):b==pskl.UserSettings.CANVAS_BACKGROUND&&this.updateBackgroundClass_(c)},a.FrameRenderer.prototype.updateBackgroundClass_=function(a){var b=this.container.data("current-background-class");b&&this.container.removeClass(b),this.container.addClass(a),this.container.data("current-background-class",a)},a.FrameRenderer.prototype.renderPixel_=function(a,b,c,d){a!=Constants.TRANSPARENT_COLOR&&(d.fillStyle=a,d.fillRect(b,c,1,1))},a.FrameRenderer.prototype.getCoordinates=function(a,b){var c=this.container.offset();a-=c.left,b-=c.top,a-=this.margin.x,b-=this.margin.y;var d=this.zoom+this.gridStrokeWidth;return a+=this.offset.x*d,b+=this.offset.y*d,{x:0|a/d,y:0|b/d}},a.FrameRenderer.prototype.renderFrame_=function(a){this.canvas||(this.canvas=pskl.CanvasUtils.createCanvas(a.getWidth(),a.getHeight()));for(var b=this.canvas.getContext("2d"),c=0,d=a.getWidth();d>c;c++)for(var e=0,f=a.getHeight();f>e;e++){var g=a.getPixel(c,e);this.renderPixel_(g,c,e,b)}this.updateMargins_(),b=this.displayCanvas.getContext("2d"),b.save(),b.fillStyle="#aaa",b.fillRect(0,0,this.displayCanvas.width,this.displayCanvas.height),b.translate(this.margin.x,this.margin.y),b.scale(this.zoom,this.zoom),b.translate(-this.offset.x,-this.offset.y),b.clearRect(0,0,this.canvas.width,this.canvas.height),b.drawImage(this.canvas,0,0),b.restore()}}(),function(){var a=$.namespace("pskl.rendering.frame");a.CachedFrameRenderer=function(a,b,c){pskl.rendering.frame.FrameRenderer.call(this,a,b,c),this.serializedFrame=""},pskl.utils.inherit(pskl.rendering.frame.CachedFrameRenderer,pskl.rendering.frame.FrameRenderer),a.CachedFrameRenderer.prototype.render=function(a){var b=this.getOffset(),c=this.getDisplaySize(),d=[this.getZoom(),b.x,b.y,c.width,c.height,a.serialize()].join("-");this.serializedFrame!=d&&(this.serializedFrame=d,this.superclass.render.call(this,a))}}(),function(){var a=$.namespace("pskl.rendering");a.CanvasRenderer=function(a,b){this.frame=a,this.dpi=b,this.transparentColor_="white"},a.CanvasRenderer.prototype.drawTransparentAs=function(a){this.transparentColor_=a},a.CanvasRenderer.prototype.render=function(){for(var a=this.createCanvas_(),b=a.getContext("2d"),c=0,d=this.frame.getWidth();d>c;c++)for(var e=0,f=this.frame.getHeight();f>e;e++){var g=this.frame.getPixel(c,e);this.renderPixel_(g,c,e,b)}return b},a.CanvasRenderer.prototype.renderPixel_=function(a,b,c,d){a==Constants.TRANSPARENT_COLOR&&(a=this.transparentColor_),d.fillStyle=a,d.fillRect(b*this.dpi,c*this.dpi,this.dpi,this.dpi)},a.CanvasRenderer.prototype.createCanvas_=function(){var a=this.frame.getWidth()*this.dpi,b=this.frame.getHeight()*this.dpi;return pskl.CanvasUtils.createCanvas(a,b)}}(),function(){var a=$.namespace("pskl.rendering");a.SpritesheetRenderer=function(a){this.piskelController=a},a.SpritesheetRenderer.prototype.render=function(){for(var a=this.createCanvas_(),b=0;bf;f++)for(var h=0,i=a.getHeight();i>h;h++){var j=a.getPixel(f,h);j!=Constants.TRANSPARENT_COLOR&&(e.fillStyle=j,e.fillRect(f+c,h+d,1,1))}},a.SpritesheetRenderer.prototype.createCanvas_=function(){var a=this.piskelController.getFrameCount();if(a>0){var b=a*this.piskelController.getWidth(),c=this.piskelController.getHeight();return pskl.CanvasUtils.createCanvas(b,c)}throw"Cannot render empty Spritesheet"}}(),function(){var a=$.namespace("pskl.controller");a.PiskelController=function(a){if(!a)throw"A piskel instance is mandatory for instanciating PiskelController";this.setPiskel(a)},a.PiskelController.prototype.setPiskel=function(a){this.piskel=a,this.currentLayerIndex=0,this.currentFrameIndex=0,this.layerIdCounter=1,$.publish(Events.PISKEL_RESET),$.publish(Events.FRAME_SIZE_CHANGED)},a.PiskelController.prototype.getHeight=function(){return this.piskel.getHeight()},a.PiskelController.prototype.getWidth=function(){return this.piskel.getWidth()},a.PiskelController.prototype.getFPS=function(){return pskl.app.animationController.getFPS()},a.PiskelController.prototype.getLayers=function(){return this.piskel.getLayers()},a.PiskelController.prototype.getCurrentLayer=function(){return this.piskel.getLayerAt(this.currentLayerIndex)},a.PiskelController.prototype.getCurrentFrame=function(){var a=this.getCurrentLayer();return a.getFrameAt(this.currentFrameIndex)},a.PiskelController.prototype.getFrameAt=function(a){var b=this.getLayers().map(function(b){return b.getFrameAt(a)});return pskl.utils.FrameUtils.merge(b)},a.PiskelController.prototype.hasFrameAt=function(a){return!!this.getCurrentLayer().getFrameAt(a)},a.PiskelController.prototype.getFrameByIndex=a.PiskelController.prototype.getMergedFrameAt,a.PiskelController.prototype.addEmptyFrame=function(){var a=this.getLayers();a.forEach(function(a){a.addFrame(this.createEmptyFrame_())}.bind(this))},a.PiskelController.prototype.createEmptyFrame_=function(){var a=this.piskel.getWidth(),b=this.piskel.getHeight();return new pskl.model.Frame(a,b)},a.PiskelController.prototype.removeFrameAt=function(a){var b=this.getLayers();b.forEach(function(b){b.removeFrameAt(a)}),this.currentFrameIndex>=a&&this.setCurrentFrameIndex(this.currentFrameIndex-1),$.publish(Events.PISKEL_RESET)},a.PiskelController.prototype.duplicateFrameAt=function(a){var b=this.getLayers();b.forEach(function(b){b.duplicateFrameAt(a)})},a.PiskelController.prototype.moveFrame=function(a,b){var c=this.getLayers();c.forEach(function(c){c.moveFrame(a,b)})},a.PiskelController.prototype.getFrameCount=function(){var a=this.piskel.getLayerAt(0);return a.length()},a.PiskelController.prototype.setCurrentFrameIndex=function(a){this.currentFrameIndex=a,$.publish(Events.PISKEL_RESET)},a.PiskelController.prototype.setCurrentLayerIndex=function(a){this.currentLayerIndex=a,$.publish(Events.PISKEL_RESET)},a.PiskelController.prototype.selectLayer=function(a){var b=this.getLayers().indexOf(a);-1!=b&&this.setCurrentLayerIndex(b)},a.PiskelController.prototype.selectLayerByName=function(a){if(this.hasLayerForName_(a)){var b=this.piskel.getLayersByName(a)[0];this.selectLayer(b)}},a.PiskelController.prototype.generateLayerName_=function(){for(var a="Layer "+this.layerIdCounter;this.hasLayerForName_(a);)this.layerIdCounter++,a="Layer "+this.layerIdCounter;return a},a.PiskelController.prototype.createLayer=function(a){if(a||(a=this.generateLayerName_()),this.hasLayerForName_(a))throw"Layer name should be unique";for(var b=new pskl.model.Layer(a),c=0;c0},a.PiskelController.prototype.moveLayerUp=function(){var a=this.getCurrentLayer();this.piskel.moveLayerUp(a),this.selectLayer(a)},a.PiskelController.prototype.moveLayerDown=function(){var a=this.getCurrentLayer();this.piskel.moveLayerDown(a),this.selectLayer(a)},a.PiskelController.prototype.removeCurrentLayer=function(){if(this.getLayers().length>1){var a=this.getCurrentLayer();this.piskel.removeLayer(a),this.setCurrentLayerIndex(0)}},a.PiskelController.prototype.serialize=function(){return pskl.utils.Serializer.serializePiskel(this.piskel)},a.PiskelController.prototype.load=function(a){this.deserialize(JSON.stringify(a))}}(),function(){var a=$.namespace("pskl.controller");a.DrawingController=function(a,b){this.piskelController=a,this.overlayFrame=pskl.model.Frame.createEmptyFromFrame(a.getCurrentFrame()),this.container=b;var c={zoom:this.calculateZoom_(),supportGridRendering:!0,height:this.getContainerHeight_(),width:this.getContainerWidth_(),xOffset:0,yOffset:0};this.overlayRenderer=new pskl.rendering.frame.CachedFrameRenderer(this.container,c,["canvas-overlay"]),this.renderer=new pskl.rendering.frame.CachedFrameRenderer(this.container,c,["drawing-canvas"]),this.layersRenderer=new pskl.rendering.layer.LayersRenderer(this.container,c,a),this.compositeRenderer=new pskl.rendering.CompositeRenderer,this.compositeRenderer.add(this.overlayRenderer).add(this.renderer).add(this.layersRenderer),this.isClicked=!1,this.isRightClicked=!1,this.previousMousemoveTime=0,this.currentToolBehavior=null,this.primaryColor=Constants.DEFAULT_PEN_COLOR,this.secondaryColor=Constants.TRANSPARENT_COLOR},a.DrawingController.prototype.init=function(){this.initMouseBehavior(),$.subscribe(Events.TOOL_SELECTED,$.proxy(function(a,b){console.log("Tool selected: ",b),this.currentToolBehavior=b,this.overlayFrame.clear()},this)),$.subscribe(Events.PRIMARY_COLOR_SELECTED,$.proxy(function(a,b){console.log("Primary color selected: ",b),this.primaryColor=b,$.publish(Events.PRIMARY_COLOR_UPDATED,[b])},this)),$.subscribe(Events.SECONDARY_COLOR_SELECTED,$.proxy(function(a,b){console.log("Secondary color selected: ",b),this.secondaryColor=b,$.publish(Events.SECONDARY_COLOR_UPDATED,[b])},this)),$(window).resize($.proxy(this.startResizeTimer_,this)),$.subscribe(Events.USER_SETTINGS_CHANGED,$.proxy(this.onUserSettingsChange_,this)),$.subscribe(Events.FRAME_SIZE_CHANGED,$.proxy(this.onFrameSizeChanged_,this)),this.centerColumnWrapperHorizontally_()},a.DrawingController.prototype.initMouseBehavior=function(){var a=$("body");this.container.mousedown($.proxy(this.onMousedown_,this)),this.container.mousemove($.proxy(this.onMousemove_,this)),this.container.on("mousewheel",$.proxy(this.onMousewheel_,this)),this.container.on("wheel",$.proxy(this.onMousewheel_,this)),a.mouseup($.proxy(this.onMouseup_,this)),a.contextmenu(this.onCanvasContextMenu_)},a.DrawingController.prototype.startResizeTimer_=function(){this.resizeTimer&&window.clearInterval(this.resizeTimer),this.resizeTimer=window.setTimeout($.proxy(this.afterWindowResize_,this),200)},a.DrawingController.prototype.afterWindowResize_=function(){this.compositeRenderer.setDisplaySize(this.getContainerWidth_(),this.getContainerHeight_())},a.DrawingController.prototype.onUserSettingsChange_=function(a,b){b==pskl.UserSettings.SHOW_GRID&&console.warn("DrawingController:onUserSettingsChange_ not implemented !")},a.DrawingController.prototype.onMousedown_=function(a){this.isClicked=!0,2==a.button&&(this.isRightClicked=!0,$.publish(Events.CANVAS_RIGHT_CLICKED));var b=this.renderer.getCoordinates(a.clientX,a.clientY);this.currentToolBehavior.applyToolAt(b.x,b.y,this.getCurrentColor_(),this.piskelController.getCurrentFrame(),this.overlayFrame,this.wrapEvtInfo_(a)),$.publish(Events.LOCALSTORAGE_REQUEST)},a.DrawingController.prototype.onMousemove_=function(a){var b=(new Date).getTime();if(b-this.previousMousemoveTime>Constants.MOUSEMOVE_THROTTLING){var c=this.renderer.getCoordinates(a.clientX,a.clientY);this.isClicked?(this.currentToolBehavior.moveToolAt(c.x,c.y,this.getCurrentColor_(),this.piskelController.getCurrentFrame(),this.overlayFrame,this.wrapEvtInfo_(a)),$.publish(Events.LOCALSTORAGE_REQUEST)):this.currentToolBehavior.moveUnactiveToolAt(c.x,c.y,this.getCurrentColor_(),this.piskelController.getCurrentFrame(),this.overlayFrame,this.wrapEvtInfo_(a)),this.previousMousemoveTime=b}},a.DrawingController.prototype.onMousewheel_=function(a){var b=a.originalEvent,c=b.wheelDeltaY||-2*b.deltaY,d=this.renderer.getZoom();c>0?this.compositeRenderer.setZoom(d+1):0>c&&this.compositeRenderer.setZoom(d-1),pskl.app.minimapController.onDrawingControllerMove_()},a.DrawingController.prototype.onMouseup_=function(a){if(this.isClicked||this.isRightClicked){this.isClicked=!1,this.isRightClicked=!1;var b=this.renderer.getCoordinates(a.clientX,a.clientY);this.currentToolBehavior.releaseToolAt(b.x,b.y,this.getCurrentColor_(),this.piskelController.getCurrentFrame(),this.overlayFrame,this.wrapEvtInfo_(a)),$.publish(Events.TOOL_RELEASED)}},a.DrawingController.prototype.wrapEvtInfo_=function(a){var b={};return 0===a.button?b.button=Constants.LEFT_BUTTON:2==a.button&&(b.button=Constants.RIGHT_BUTTON),b},a.DrawingController.prototype.getSpriteCoordinates=function(a){return this.renderer.getCoordinates(a.clientX,a.clientY)},a.DrawingController.prototype.getCurrentColor_=function(){return this.isRightClicked?this.secondaryColor:this.primaryColor},a.DrawingController.prototype.onCanvasContextMenu_=function(a){return $(a.target).closest("#drawing-canvas-container").length?(a.preventDefault(),a.stopPropagation(),a.cancelBubble=!0,!1):void 0},a.DrawingController.prototype.render=function(){var a=this.piskelController.getCurrentFrame();a.isSameSize(this.overlayFrame)||(this.overlayFrame=pskl.model.Frame.createEmptyFromFrame(a)),this.layersRenderer.render(),this.renderer.render(a),this.overlayRenderer.render(this.overlayFrame)},a.DrawingController.prototype.calculateZoom_=function(){var a=this.piskelController.getCurrentFrame().getHeight(),b=this.piskelController.getCurrentFrame().getWidth();return Math.min(this.getAvailableWidth_()/b,this.getAvailableHeight_()/a)},a.DrawingController.prototype.getAvailableHeight_=function(){return $("#main-wrapper").height()},a.DrawingController.prototype.getAvailableWidth_=function(){var a=$(".left-column").outerWidth(!0),b=$(".right-column").outerWidth(!0),c=$("#main-wrapper").width()-a-b;return c},a.DrawingController.prototype.getContainerHeight_=function(){return this.calculateZoom_()*this.piskelController.getCurrentFrame().getHeight()},a.DrawingController.prototype.getContainerWidth_=function(){return this.calculateZoom_()*this.piskelController.getCurrentFrame().getWidth()},a.DrawingController.prototype.centerColumnWrapperHorizontally_=function(){var a=this.getContainerHeight_(),b=Math.floor(($("#main-wrapper").height()-a)/2);$("#column-wrapper").css({top:b+"px"})},a.DrawingController.prototype.getRenderer=function(){return this.compositeRenderer},a.DrawingController.prototype.setOffset=function(a,b){this.compositeRenderer.setOffset(a,b),pskl.app.minimapController.onDrawingControllerMove_()}}(),function(){var a=$.namespace("pskl.controller");a.PreviewFilmController=function(a,b){this.piskelController=a,this.container=b,this.refreshZoom_(),this.redrawFlag=!0},a.PreviewFilmController.prototype.init=function(){$.subscribe(Events.TOOL_RELEASED,this.flagForRedraw_.bind(this)),$.subscribe(Events.PISKEL_RESET,this.flagForRedraw_.bind(this)),$.subscribe(Events.PISKEL_RESET,this.refreshZoom_.bind(this)),$("#preview-list-scroller").scroll(this.updateScrollerOverflows.bind(this)),this.updateScrollerOverflows()},a.PreviewFilmController.prototype.addFrame=function(){this.piskelController.addEmptyFrame(),this.piskelController.setCurrentFrameIndex(this.piskelController.getFrameCount()-1),this.updateScrollerOverflows()},a.PreviewFilmController.prototype.flagForRedraw_=function(){this.redrawFlag=!0},a.PreviewFilmController.prototype.refreshZoom_=function(){this.zoom=this.calculateZoom_()},a.PreviewFilmController.prototype.render=function(){this.redrawFlag&&(this.createPreviews_(),this.redrawFlag=!1)},a.PreviewFilmController.prototype.updateScrollerOverflows=function(){var a=$("#preview-list-scroller"),b=a.height(),c=a.scrollTop(),d=$("#preview-list").height(),e=$(".top-overflow").height(),f=!1,g=!1;if(d>b){c>e&&(f=!0);var h=d-c-b;h>e&&(g=!0)}var i=$("#preview-list-wrapper");i.toggleClass("top-overflow-visible",f),i.toggleClass("bottom-overflow-visible",g)},a.PreviewFilmController.prototype.createPreviews_=function(){this.container.html(""),$(".tooltip").remove();for(var a=this.piskelController.getFrameCount(),b=0,c=a;c>b;b++)this.container.append(this.createPreviewTile_(b));var d=document.createElement("div");d.id="add-frame-action",d.className="add-frame-action",d.innerHTML="

    Add new frame

    ",this.container.append(d),$(d).click(this.addFrame.bind(this));var e=a>1;e&&this.initDragndropBehavior_(),this.updateScrollerOverflows()},a.PreviewFilmController.prototype.initDragndropBehavior_=function(){$("#preview-list").sortable({placeholder:"preview-tile-drop-proxy",update:$.proxy(this.onUpdate_,this),items:".preview-tile"}),$("#preview-list").disableSelection()},a.PreviewFilmController.prototype.onUpdate_=function(a,b){var c=parseInt(b.item.data("tile-number"),10),d=$(".preview-tile").index(b.item);this.piskelController.moveFrame(c,d),this.piskelController.setCurrentFrameIndex(d),$.publish(Events.LOCALSTORAGE_REQUEST)},a.PreviewFilmController.prototype.createPreviewTile_=function(a){var b=this.piskelController.getCurrentLayer().getFrameAt(a),c=document.createElement("li"),d="preview-tile";c.setAttribute("data-tile-number",a),this.piskelController.getCurrentFrame()==b&&(d+=" selected"),c.className=d;var e=document.createElement("div");e.className="canvas-container";var f=document.createElement("div");f.className="canvas-background",e.appendChild(f),c.addEventListener("click",this.onPreviewClick_.bind(this,a));var g=document.createElement("button");g.setAttribute("rel","tooltip"),g.setAttribute("data-placement","right"),g.setAttribute("title","Duplicate this frame"),g.className="tile-overlay duplicate-frame-action",c.appendChild(g),g.addEventListener("click",this.onAddButtonClick_.bind(this,a));var h={zoom:this.zoom,height:this.piskelController.getCurrentFrame().getHeight()*this.zoom,width:this.piskelController.getCurrentFrame().getWidth()*this.zoom},i=new pskl.rendering.frame.FrameRenderer($(e),h,["tile-view"]);if(i.render(b),c.appendChild(e),a>0||this.piskelController.getFrameCount()>1){var j=document.createElement("button");j.setAttribute("rel","tooltip"),j.setAttribute("data-placement","right"),j.setAttribute("title","Delete this frame"),j.className="tile-overlay delete-frame-action",j.addEventListener("click",this.onDeleteButtonClick_.bind(this,a)),c.appendChild(j);var k=document.createElement("div");k.className="tile-overlay dnd-action",c.appendChild(k)}var l=document.createElement("div");return l.className="tile-overlay tile-count",l.innerHTML=a,c.appendChild(l),c},a.PreviewFilmController.prototype.onPreviewClick_=function(a,b){b.target.classList.contains("tile-overlay")||this.piskelController.setCurrentFrameIndex(a)},a.PreviewFilmController.prototype.onDeleteButtonClick_=function(a){this.piskelController.removeFrameAt(a),$.publish(Events.LOCALSTORAGE_REQUEST),this.updateScrollerOverflows()},a.PreviewFilmController.prototype.onAddButtonClick_=function(a){this.piskelController.duplicateFrameAt(a),$.publish(Events.LOCALSTORAGE_REQUEST),this.piskelController.setCurrentFrameIndex(a+1),this.updateScrollerOverflows()},a.PreviewFilmController.prototype.calculateZoom_=function(){var a=this.piskelController.getCurrentFrame(),b=a.getHeight(),c=a.getWidth(),d=Math.max(c,b),e=Constants.PREVIEW_FILM_SIZE*b/d,f=Constants.PREVIEW_FILM_SIZE*c/d;return pskl.PixelUtils.calculateDPI(e,f,b,c)||1}}(),function(){var a=$.namespace("pskl.controller");a.LayersListController=function(a){this.piskelController=a},a.LayersListController.prototype.init=function(){this.layerItemTemplate_=pskl.utils.Template.get("layer-item-template"),this.rootEl=document.querySelectorAll(".layers-list-container")[0],this.layersListEl=document.querySelectorAll(".layers-list")[0],this.rootEl.addEventListener("click",this.onClick_.bind(this)),$.subscribe(Events.PISKEL_RESET,this.renderLayerList_.bind(this)),this.renderLayerList_()},a.LayersListController.prototype.renderLayerList_=function(){this.layersListEl.innerHTML="";var a=this.piskelController.getLayers();a.forEach(this.addLayerItem.bind(this))},a.LayersListController.prototype.addLayerItem=function(a){var b=pskl.utils.Template.replace(this.layerItemTemplate_,{layername:a.getName()}),c=pskl.utils.Template.createFromHTML(b);this.piskelController.getCurrentLayer()===a&&c.classList.add("current-layer-item"),this.layersListEl.insertBefore(c,this.layersListEl.firstChild)},a.LayersListController.prototype.onClick_=function(a){var b=a.target||a.srcElement;if("BUTTON"==b.nodeName)this.onButtonClick_(b);else if("LI"==b.nodeName){var c=b.getAttribute("data-layer-name");this.piskelController.selectLayerByName(c)}},a.LayersListController.prototype.onButtonClick_=function(a){var b=a.getAttribute("data-action");"up"==b?this.piskelController.moveLayerUp():"down"==b?this.piskelController.moveLayerDown():"add"==b?this.piskelController.createLayer():"delete"==b&&this.piskelController.removeCurrentLayer()}}(),function(){var a=$.namespace("pskl.controller");a.AnimatedPreviewController=function(a,b){this.piskelController=a,this.container=b,this.elapsedTime=0,this.currentIndex=0,this.setFPS(Constants.DEFAULT.FPS);var c=this.calculateZoom_(),d={zoom:c,height:this.piskelController.getCurrentFrame().getHeight()*c,width:this.piskelController.getCurrentFrame().getWidth()*c};this.renderer=new pskl.rendering.frame.FrameRenderer(this.container,d),$.subscribe(Events.FRAME_SIZE_CHANGED,this.updateZoom_.bind(this))},a.AnimatedPreviewController.prototype.init=function(){$("#preview-fps")[0].addEventListener("change",this.onFPSSliderChange.bind(this))},a.AnimatedPreviewController.prototype.onFPSSliderChange=function(){this.setFPS(parseInt($("#preview-fps")[0].value,10))},a.AnimatedPreviewController.prototype.setFPS=function(a){this.fps=a,$("#preview-fps").val(this.fps),$("#display-fps").html(this.fps+" FPS")},a.AnimatedPreviewController.prototype.getFPS=function(){return this.fps},a.AnimatedPreviewController.prototype.render=function(a){this.elapsedTime+=a;var b=Math.floor(this.elapsedTime/(1e3/this.fps));b!=this.currentIndex&&(this.currentIndex=b,this.piskelController.hasFrameAt(this.currentIndex)||(this.currentIndex=0,this.elapsedTime=0),this.renderer.render(this.piskelController.getFrameAt(this.currentIndex)))},a.AnimatedPreviewController.prototype.calculateZoom_=function(){var a=200,b=a/this.piskelController.getCurrentFrame().getHeight(),c=a/this.piskelController.getCurrentFrame().getWidth();return Math.min(b,c)},a.AnimatedPreviewController.prototype.updateZoom_=function(){var a=this.calculateZoom_();this.renderer.setZoom(a)}}(),function(){var a=$.namespace("pskl.controller");a.MinimapController=function(a,b,c,d){this.piskelController=a,this.animationController=b,this.drawingController=c,this.container=d,this.isClicked=!1},a.MinimapController.prototype.init=function(){this.cropFrame=document.createElement("DIV"),this.cropFrame.className="minimap-crop-frame",this.cropFrame.style.display="none",$(this.container).mousedown(this.onMinimapMousedown_.bind(this)),$(this.container).mousemove(this.onMinimapMousemove_.bind(this)),$(this.container).mouseup(this.onMinimapMouseup_.bind(this)),$(this.container).append(this.cropFrame)},a.MinimapController.prototype.onDrawingControllerMove_=function(){var a=this.getDrawingAreaZoomRatio_();a>1?this.displayCropFrame_(a,this.drawingController.getRenderer().getOffset()):this.hideCropFrame_()},a.MinimapController.prototype.displayCropFrame_=function(a,b){this.cropFrame.style.display="block",this.cropFrame.style.top=b.y*this.animationController.renderer.getZoom()+"px",this.cropFrame.style.left=b.x*this.animationController.renderer.getZoom()+"px";var c=this.getDrawingAreaZoomRatio_();this.cropFrame.style.width=this.container.width()/c+"px",this.cropFrame.style.height=this.container.height()/c+"px"},a.MinimapController.prototype.hideCropFrame_=function(){this.cropFrame.style.display="none"},a.MinimapController.prototype.onMinimapMousemove_=function(a){if(this.isClicked&&this.getDrawingAreaZoomRatio_()>1){var b=this.getCoordinatesCenteredAround_(a.clientX,a.clientY);this.drawingController.setOffset(b.x,b.y)}},a.MinimapController.prototype.onMinimapMousedown_=function(){this.isClicked=!0},a.MinimapController.prototype.onMinimapMouseup_=function(){this.isClicked=!1},a.MinimapController.prototype.getCoordinatesCenteredAround_=function(a,b){var c=this.animationController.renderer.getCoordinates(a,b),d=this.getDrawingAreaZoomRatio_(),e=this.piskelController.getCurrentFrame().getWidth(),f=this.piskelController.getCurrentFrame().getHeight(),g=e/d,h=f/d;return{x:c.x-g/2,y:c.y-h/2}},a.MinimapController.prototype.getDrawingAreaZoomRatio_=function(){var a=this.drawingController.getRenderer().getZoom(),b=this.piskelController.getCurrentFrame().getHeight()*a,c=b/this.drawingController.getRenderer().getDisplaySize().height;return c}}(),function(){var a=$.namespace("pskl.controller");a.ToolController=function(){this.toolInstances={simplePen:new pskl.drawingtools.SimplePen,verticalMirrorPen:new pskl.drawingtools.VerticalMirrorPen,eraser:new pskl.drawingtools.Eraser,paintBucket:new pskl.drawingtools.PaintBucket,stroke:new pskl.drawingtools.Stroke,rectangle:new pskl.drawingtools.Rectangle,circle:new pskl.drawingtools.Circle,move:new pskl.drawingtools.Move,rectangleSelect:new pskl.drawingtools.RectangleSelect,shapeSelect:new pskl.drawingtools.ShapeSelect,colorPicker:new pskl.drawingtools.ColorPicker},this.currentSelectedTool=this.toolInstances.simplePen,this.previousSelectedTool=this.toolInstances.simplePen},a.ToolController.prototype.init=function(){this.createToolMarkup_(),this.selectTool_(this.toolInstances.simplePen),$("#tool-section").click($.proxy(this.onToolIconClicked_,this))},a.ToolController.prototype.activateToolOnStage_=function(a){var b=$("body"),c=b.data("selected-tool-class");c&&b.removeClass(c),b.addClass(a.toolId),b.data("selected-tool-class",a.toolId)},a.ToolController.prototype.selectTool_=function(a){console.log("Selecting Tool:",this.currentSelectedTool),this.currentSelectedTool=a,this.activateToolOnStage_(this.currentSelectedTool),$.publish(Events.TOOL_SELECTED,[a])},a.ToolController.prototype.onToolIconClicked_=function(a){var b=$(a.target),c=b.closest(".tool-icon");if(c.length){var d=c.data().toolId,e=this.getToolById_(d);e&&(this.selectTool_(e),$("#tool-section .tool-icon.selected").removeClass("selected"),c.addClass("selected"))}},a.ToolController.prototype.getToolById_=function(a){for(var b in this.toolInstances)if(this.toolInstances[b].toolId==a)return this.toolInstances[b];return null},a.ToolController.prototype.createToolMarkup_=function(){var a,b,c="";for(var d in this.toolInstances)a=this.toolInstances[d],b=a.toolId,this.currentSelectedTool==a&&(b+=" selected"),c+='
  • ';$("#tools-container").html(c)}}(),function(){var a=$.namespace("pskl.controller");a.PaletteController=function(){},a.PaletteController.prototype.init=function(){var a=$(".palette-color[data-color=TRANSPARENT]");a.mouseup($.proxy(this.onPaletteColorClick_,this)),$.subscribe(Events.PRIMARY_COLOR_UPDATED,$.proxy(function(a,b){this.updateColorPicker_(b,$("#color-picker"))},this)),$.subscribe(Events.SECONDARY_COLOR_UPDATED,$.proxy(function(a,b){this.updateColorPicker_(b,$("#secondary-color-picker"))},this));var b=$("#color-picker");b.val(Constants.DEFAULT_PEN_COLOR),b.change({isPrimary:!0},$.proxy(this.onPickerChange_,this));var c=$("#secondary-color-picker");c.val(Constants.TRANSPARENT_COLOR),c.change({isPrimary:!1},$.proxy(this.onPickerChange_,this)),window.jscolor.install()},a.PaletteController.prototype.onPickerChange_=function(a){var b=$(a.target);a.data.isPrimary?$.publish(Events.PRIMARY_COLOR_SELECTED,[b.val()]):$.publish(Events.SECONDARY_COLOR_SELECTED,[b.val()])},a.PaletteController.prototype.onPaletteColorClick_=function(a){var b=$(a.target).data("color"),c=1==a.which,d=3==a.which;c?$.publish(Events.PRIMARY_COLOR_SELECTED,[b]):d&&$.publish(Events.SECONDARY_COLOR_SELECTED,[b])},a.PaletteController.prototype.updateColorPicker_=function(a,b){a==Constants.TRANSPARENT_COLOR?(b[0].color.fromString("#fff"),b.val(Constants.TRANSPARENT_COLOR)):b[0].color.fromString(a)}}(),function(){var a=$.namespace("pskl.controller");a.NotificationController=function(){},a.NotificationController.prototype.init=function(){$.subscribe(Events.SHOW_NOTIFICATION,$.proxy(this.displayMessage_,this)),$.subscribe(Events.HIDE_NOTIFICATION,$.proxy(this.removeMessage_,this))},a.NotificationController.prototype.displayMessage_=function(a,b){var c=document.createElement("div");c.id="user-message",c.className="user-message",c.innerHTML=b.content,c.innerHTML=c.innerHTML+"
    x
    ",document.body.appendChild(c),$(c).find(".close").click($.proxy(this.removeMessage_,this)),b.behavior&&b.behavior(c)},a.NotificationController.prototype.removeMessage_=function(){var a=$("#user-message");a.length&&a.remove()}}(),function(){var a=$.namespace("pskl.controller.settings");a.ApplicationSettingsController=function(){},a.ApplicationSettingsController.prototype.init=function(){var a=pskl.UserSettings.get(pskl.UserSettings.CANVAS_BACKGROUND);$("#background-picker-wrapper").find(".background-picker[data-background-class="+a+"]").addClass("selected");var b=pskl.UserSettings.get(pskl.UserSettings.SHOW_GRID);$("#show-grid").prop("checked",b),$("#show-grid").change(this.onShowGridClick.bind(this)),$("#background-picker-wrapper").click(this.onBackgroundClick.bind(this))},a.ApplicationSettingsController.prototype.onShowGridClick=function(){var a=$("#show-grid").prop("checked");pskl.UserSettings.set(pskl.UserSettings.SHOW_GRID,a)},a.ApplicationSettingsController.prototype.onBackgroundClick=function(a){var b=$(a.target).closest(".background-picker");if(b.length){var c=b.data("background-class");pskl.UserSettings.set(pskl.UserSettings.CANVAS_BACKGROUND,c),$(".background-picker").removeClass("selected"),b.addClass("selected")}}}(),function(){var a=$.namespace("pskl.controller.settings");a.GifExportController=function(a){this.piskelController=a},a.GifExportController.RESOLUTIONS=[{dpi:1},{dpi:5},{dpi:10,"default":!0},{dpi:20}],a.GifExportController.prototype.init=function(){this.radioTemplate_=pskl.utils.Template.get("export-gif-radio-template"),this.previewContainerEl=document.querySelectorAll(".export-gif-preview div")[0],this.radioGroupEl=document.querySelectorAll(".gif-export-radio-group")[0],this.uploadForm=$("[name=gif-export-upload-form]"),this.uploadForm.submit(this.onUploadFormSubmit_.bind(this)),this.createRadioElements_()},a.GifExportController.prototype.onUploadFormSubmit_=function(a){a.originalEvent.preventDefault();var b=this.getSelectedDpi_(),c=this.piskelController.getFPS(),d=b;this.renderAsImageDataAnimatedGIF(d,c,this.onGifRenderingCompleted_.bind(this))},a.GifExportController.prototype.onGifRenderingCompleted_=function(a){this.updatePreview_(a),this.previewContainerEl.classList.add("preview-upload-ongoing"),pskl.app.imageUploadService.upload(a,this.onImageUploadCompleted_.bind(this))},a.GifExportController.prototype.onImageUploadCompleted_=function(a){this.updatePreview_(a),this.previewContainerEl.classList.remove("preview-upload-ongoing")},a.GifExportController.prototype.updatePreview_=function(a){this.previewContainerEl.innerHTML=""},a.GifExportController.prototype.getSelectedDpi_=function(){var a=this.uploadForm.get(0).querySelectorAll("[name=gif-dpi]"),b=Array.prototype.slice.call(a,0),c=b.filter(function(a){return!!a.checked});if(1==c.length)return c[0].value;throw"Unexpected error when retrieving selected dpi"},a.GifExportController.prototype.createRadioElements_=function(){for(var b=a.GifExportController.RESOLUTIONS,c=0;c";this.piskelController=a,this.localStorageThrottler_=null},a.LocalStorageService.prototype.init=function(){$.subscribe(Events.LOCALSTORAGE_REQUEST,$.proxy(this.persistToLocalStorageRequest_,this))},a.LocalStorageService.prototype.persistToLocalStorageRequest_=function(){null!==this.localStorageThrottler_&&window.clearTimeout(this.localStorageThrottler_),this.localStorageThrottler_=window.setTimeout($.proxy(function(){this.persistToLocalStorage_(),this.localStorageThrottler_=null},this),1e3)},a.LocalStorageService.prototype.persistToLocalStorage_=function(){console.log("[LocalStorage service]: Snapshot stored"),window.localStorage.snapShot=this.piskelController.serialize()},a.LocalStorageService.prototype.restoreFromLocalStorage_=function(){this.piskelController.deserialize(window.localStorage.snapShot),this.piskelController.setCurrentFrameIndex(0)},a.LocalStorageService.prototype.cleanLocalStorage_=function(){console.log("[LocalStorage service]: Snapshot removed"),delete window.localStorage.snapShot},a.LocalStorageService.prototype.displayRestoreNotification=function(){if(window.localStorage&&window.localStorage.snapShot){var a="reload",b="discard",c="Non saved version found. "+a+" or "+b;$.publish(Events.SHOW_NOTIFICATION,[{content:c,behavior:$.proxy(function(a){a=$(a),a.click($.proxy(function(a){var b=$(a.target);b.hasClass("localstorage-restore")?this.restoreFromLocalStorage_():b.hasClass("localstorage-discard")&&this.cleanLocalStorage_(),$.publish(Events.HIDE_NOTIFICATION)},this))},this)}])}}}(),function(){var a=$.namespace("pskl.service");a.HistoryService=function(a){this.piskelController=a},a.HistoryService.prototype.init=function(){$.subscribe(Events.TOOL_RELEASED,this.saveState.bind(this)),$.subscribe(Events.UNDO,this.undo.bind(this)),$.subscribe(Events.REDO,this.redo.bind(this))},a.HistoryService.prototype.saveState=function(){this.piskelController.getCurrentFrame().saveState()},a.HistoryService.prototype.undo=function(){this.piskelController.getCurrentFrame().loadPreviousState(),$.publish(Events.PISKEL_RESET)},a.HistoryService.prototype.redo=function(){this.piskelController.getCurrentFrame().loadNextState(),$.publish(Events.PISKEL_RESET)}}(),function(){var a=$.namespace("pskl.service");a.KeyboardEventService=function(){},a.KeyboardEventService.prototype.KeyboardActions_={ctrl:{z:Events.UNDO,y:Events.REDO,x:Events.CUT,c:Events.COPY,v:Events.PASTE}},a.KeyboardEventService.prototype.CharCodeToKeyCodeMap_={90:"z",89:"y",88:"x",67:"c",86:"v"},a.KeyboardEventService.prototype.onKeyUp_=function(a){var b=!1;if(-1!=navigator.appVersion.indexOf("Mac")&&(b=!0),b?a.metaKey:a.ctrlKey){var c=this.CharCodeToKeyCodeMap_[a.which];if(c){var d=this.KeyboardActions_.ctrl[c];if(d)return $.publish(d),a.preventDefault(),!1}}},a.KeyboardEventService.prototype.init=function(){$(document.body).keydown($.proxy(this.onKeyUp_,this))}}(),function(){var a=$.namespace("pskl.service");a.ImageUploadService=function(){},a.ImageUploadService.prototype.init=function(){},a.ImageUploadService.prototype.upload=function(a,b,c){var d=new XMLHttpRequest,e=new FormData;e.append("data",a),d.open("POST",Constants.IMAGE_SERVICE_UPLOAD_URL,!0),d.onload=function(){if(200==this.status){var a=Constants.IMAGE_SERVICE_GET_URL+this.responseText;b(a)}else c()},d.send(e)}}(),function(){var a=$.namespace("pskl.drawingtools");a.BaseTool=function(){},a.BaseTool.prototype.applyToolAt=function(){},a.BaseTool.prototype.moveToolAt=function(){},a.BaseTool.prototype.moveUnactiveToolAt=function(a,b,c,d,e){e.containsPixel(a,b)&&(isNaN(this.highlightedPixelCol)||isNaN(this.highlightedPixelRow)||this.highlightedPixelRow==b&&this.highlightedPixelCol==a||e.clear(),e.setPixel(a,b,Constants.TOOL_TARGET_HIGHLIGHT_COLOR),this.highlightedPixelCol=a,this.highlightedPixelRow=b)},a.BaseTool.prototype.releaseToolAt=function(){},a.BaseTool.prototype.getLinePixels_=function(a,b,c,d){for(var e=[],f=Math.abs(b-a),g=Math.abs(d-c),h=b>a?1:-1,i=d>c?1:-1,j=f-g;;){if(e.push({col:a,row:c}),a==b&&c==d)break;var k=2*j;k>-g&&(j-=g,a+=h),f>k&&(j+=f,c+=i)}return e}}(),function(){var a=$.namespace("pskl.drawingtools");a.SimplePen=function(){this.toolId="tool-pen",this.helpText="Pen tool",this.previousCol=null,this.previousRow=null},pskl.utils.inherit(a.SimplePen,a.BaseTool),a.SimplePen.prototype.applyToolAt=function(a,b,c,d){d.containsPixel(a,b)&&d.setPixel(a,b,c),this.previousCol=a,this.previousRow=b},a.SimplePen.prototype.moveToolAt=function(a,b,c,d,e){if(Math.abs(a-this.previousCol)>1||Math.abs(b-this.previousRow)>1)for(var f=this.getLinePixels_(a,this.previousCol,b,this.previousRow),g=0,h=f.length;h>g;g++){var i=f[g];this.applyToolAt(i.col,i.row,c,d,e)}else this.applyToolAt(a,b,c,d,e);this.previousCol=a,this.previousRow=b}}(),function(){var a=$.namespace("pskl.drawingtools");a.VerticalMirrorPen=function(){this.toolId="tool-vertical-mirror-pen",this.helpText="vertical mirror pen tool",this.swap=null,this.mirroredPreviousCol=null,this.mirroredPreviousRow=null},pskl.utils.inherit(a.VerticalMirrorPen,a.SimplePen),a.VerticalMirrorPen.prototype.setMirrorContext=function(){this.swap=this.previousCol,this.previousCol=this.mirroredPreviousCol},a.VerticalMirrorPen.prototype.unsetMirrorContext=function(){this.mirroredPreviousCol=this.previousCol,this.previousCol=this.swap},a.VerticalMirrorPen.prototype.applyToolAt=function(a,b,c,d,e){this.superclass.applyToolAt.call(this,a,b,c,d,e);var f=this.getSymmetricCol_(a,d);this.mirroredPreviousCol=f,this.setMirrorContext(),this.superclass.applyToolAt.call(this,f,b,c,d,e),this.unsetMirrorContext()},a.VerticalMirrorPen.prototype.getSymmetricCol_=function(a,b){return b.getWidth()-a-1}}(),function(){var a=$.namespace("pskl.drawingtools");a.Eraser=function(){this.toolId="tool-eraser",this.helpText="Eraser tool"},pskl.utils.inherit(a.Eraser,a.SimplePen),a.Eraser.prototype.applyToolAt=function(a,b,c,d,e){this.superclass.applyToolAt.call(this,a,b,Constants.TRANSPARENT_COLOR,d,e)}}(),function(){var a=$.namespace("pskl.drawingtools");a.Stroke=function(){this.toolId="tool-stroke",this.helpText="Stroke tool",this.startCol=null,this.startRow=null},pskl.utils.inherit(a.Stroke,a.BaseTool),a.Stroke.prototype.applyToolAt=function(a,b,c,d,e){this.startCol=a,this.startRow=b,e.setPixel(a,b,c)},a.Stroke.prototype.moveToolAt=function(a,b,c,d,e){e.clear();for(var f=this.getLinePixels_(this.startCol,a,this.startRow,b),g=0;gd;d++)b.setPixel(c[d].col,c[d].row,Constants.SELECTION_TRANSPARENT_COLOR)},a.BaseSelect.prototype.shiftOverlayFrame_=function(a,b,c,d){for(var e,f=0;f 0) { + return this.renderers[0]; + } else { + throw 'Renderer manager is empty'; + } + }; +})();;(function () { + var ns = $.namespace('pskl.rendering.layer'); + + ns.LayersRenderer = function (container, renderingOptions, piskelController) { + pskl.rendering.CompositeRenderer.call(this); + + this.piskelController = piskelController; + + this.belowRenderer = new pskl.rendering.frame.CachedFrameRenderer(container, renderingOptions, ["layers-canvas", "layers-below-canvas"]); + this.aboveRenderer = new pskl.rendering.frame.CachedFrameRenderer(container, renderingOptions, ["layers-canvas", "layers-above-canvas"]); + + this.add(this.belowRenderer); + this.add(this.aboveRenderer); + + this.serializedRendering = ''; + }; + + pskl.utils.inherit(pskl.rendering.layer.LayersRenderer, pskl.rendering.CompositeRenderer); + + ns.LayersRenderer.prototype.render = function () { + var layers = this.piskelController.getLayers(); + var currentFrameIndex = this.piskelController.currentFrameIndex; + var currentLayerIndex = this.piskelController.currentLayerIndex; + + var serializedRendering = [ + this.getZoom(), + currentFrameIndex, + currentLayerIndex, + layers.length + ].join("-"); + + if (this.serializedRendering != serializedRendering) { + this.serializedRendering = serializedRendering; + + this.clear(); + + var downLayers = layers.slice(0, currentLayerIndex); + if (downLayers.length > 0) { + var downFrame = this.getFrameForLayersAt_(currentFrameIndex, downLayers); + this.belowRenderer.render(downFrame); + } + + var upLayers = layers.slice(currentLayerIndex + 1, layers.length); + if (upLayers.length > 0) { + var upFrame = this.getFrameForLayersAt_(currentFrameIndex, upLayers); + this.aboveRenderer.render(upFrame); + } + + } + }; + + ns.LayersRenderer.prototype.getFrameForLayersAt_ = function (frameIndex, layers) { + var frames = layers.map(function (l) { + return l.getFrameAt(frameIndex); + }); + return pskl.utils.FrameUtils.merge(frames); + }; +})(); +;(function () { + var ns = $.namespace("pskl.rendering.frame"); + + /** + * FrameRenderer will display a given frame inside a canvas element. + * @param {HtmlElement} container HtmlElement to use as parentNode of the Frame + * @param {Object} renderingOptions + * @param {Array} classes array of strings to use for css classes + */ + ns.FrameRenderer = function (container, renderingOptions, classes) { + this.defaultRenderingOptions = { + 'supportGridRendering' : false, + 'zoom' : 1 + }; + + renderingOptions = $.extend(true, {}, this.defaultRenderingOptions, renderingOptions); + + if(container === undefined) { + throw 'Bad FrameRenderer initialization. undefined.'; + } + + if(isNaN(renderingOptions.zoom)) { + throw 'Bad FrameRenderer initialization. not well defined.'; + } + + this.container = container; + + this.zoom = renderingOptions.zoom; + + this.offset = { + x : 0, + y : 0 + }; + + this.margin = { + x : 0, + y : 0 + }; + + this.supportGridRendering = renderingOptions.supportGridRendering; + + this.classes = classes || []; + this.classes.push('canvas'); + + /** + * Off dom canvas, will be used to draw the frame at 1:1 ratio + * @type {HTMLElement} + */ + this.canvas = null; + + /** + * Displayed canvas, scaled-up from the offdom canvas + * @type {HTMLElement} + */ + this.displayCanvas = null; + this.setDisplaySize(renderingOptions.width, renderingOptions.height); + + this.setGridEnabled(pskl.UserSettings.get(pskl.UserSettings.SHOW_GRID)); + + this.updateBackgroundClass_(pskl.UserSettings.get(pskl.UserSettings.CANVAS_BACKGROUND)); + $.subscribe(Events.USER_SETTINGS_CHANGED, $.proxy(this.onUserSettingsChange_, this)); + }; + + pskl.utils.inherit(pskl.rendering.frame.FrameRenderer, pskl.rendering.AbstractRenderer); + + ns.FrameRenderer.prototype.render = function (frame) { + if (frame) { + this.clear(); + this.renderFrame_(frame); + } + }; + + ns.FrameRenderer.prototype.clear = function () { + pskl.CanvasUtils.clear(this.canvas); + pskl.CanvasUtils.clear(this.displayCanvas); + }; + + ns.FrameRenderer.prototype.setZoom = function (zoom) { + // back up center coordinates + var centerX = this.offset.x + (this.displayWidth/(2*this.zoom)); + var centerY = this.offset.y + (this.displayHeight/(2*this.zoom)); + + this.zoom = Math.max(1, zoom); + + // recenter + this.setOffset( + centerX - (this.displayWidth/(2*this.zoom)), + centerY - (this.displayHeight/(2*this.zoom)) + ); + }; + + ns.FrameRenderer.prototype.getZoom = function () { + return this.zoom; + }; + + ns.FrameRenderer.prototype.setDisplaySize = function (width, height) { + this.displayWidth = width; + this.displayHeight = height; + if (this.displayCanvas) { + $(this.displayCanvas).remove(); + this.displayCanvas = null; + } + this.createDisplayCanvas_(); + }; + + ns.FrameRenderer.prototype.getDisplaySize = function () { + return { + height : this.displayHeight, + width : this.displayWidth + }; + }; + + ns.FrameRenderer.prototype.getOffset = function () { + return { + x : this.offset.x, + y : this.offset.y + }; + }, + + ns.FrameRenderer.prototype.moveOffset = function (x, y) { + this.setOffset(this.offset.x + x, this.offset.y + y); + }; + + ns.FrameRenderer.prototype.setOffset = function (x, y) { + // TODO : provide frame size information to the FrameRenderer constructor + // here I first need to verify I have a 'canvas' which I can use to infer the frame information + // and then perform my boundaries checking. This sucks + if (this.canvas) { + var maxX = this.canvas.width - (this.displayWidth/this.zoom); + x = pskl.utils.Math.minmax(x, 0, maxX); + var maxY = this.canvas.height - (this.displayHeight/this.zoom); + y = pskl.utils.Math.minmax(y, 0, maxY); + } + this.offset.x = x; + this.offset.y = y; + }; + + ns.FrameRenderer.prototype.setGridEnabled = function (flag) { + this.gridStrokeWidth = (flag && this.supportGridRendering) ? Constants.GRID_STROKE_WIDTH : 0; + this.canvasConfigDirty = true; + }; + + ns.FrameRenderer.prototype.updateMargins_ = function () { + var deltaX = this.displayWidth - (this.zoom * this.canvas.width); + this.margin.x = Math.max(0, deltaX) / 2; + + var deltaY = this.displayHeight - (this.zoom * this.canvas.height); + this.margin.y = Math.max(0, deltaY) / 2; + }; + + ns.FrameRenderer.prototype.createDisplayCanvas_ = function () { + var height = this.displayHeight; + var width = this.displayWidth; + + this.displayCanvas = pskl.CanvasUtils.createCanvas(width, height, this.classes); + if (true || this.zoom > 2) { + pskl.CanvasUtils.disableImageSmoothing(this.displayCanvas); + } + this.container.append(this.displayCanvas); + }; + + ns.FrameRenderer.prototype.onUserSettingsChange_ = function (evt, settingName, settingValue) { + if(settingName == pskl.UserSettings.SHOW_GRID) { + this.setGridEnabled(settingValue); + } else if (settingName == pskl.UserSettings.CANVAS_BACKGROUND) { + this.updateBackgroundClass_(settingValue); + } + }; + + ns.FrameRenderer.prototype.updateBackgroundClass_ = function (newClass) { + var currentClass = this.container.data('current-background-class'); + if (currentClass) { + this.container.removeClass(currentClass); + } + this.container.addClass(newClass); + this.container.data('current-background-class', newClass); + }; + + ns.FrameRenderer.prototype.renderPixel_ = function (color, x, y, context) { + if(color != Constants.TRANSPARENT_COLOR) { + context.fillStyle = color; + context.fillRect(x, y, 1, 1); + } + }; + + /** + * Transform a screen pixel-based coordinate (relative to the top-left corner of the rendered + * frame) into a sprite coordinate in column and row. + * @public + */ + ns.FrameRenderer.prototype.getCoordinates = function(x, y) { + var containerOffset = this.container.offset(); + x = x - containerOffset.left; + y = y - containerOffset.top; + + // apply margins + x = x - this.margin.x; + y = y - this.margin.y; + + var cellSize = this.zoom + this.gridStrokeWidth; + // apply frame offset + x = x + this.offset.x * cellSize; + y = y + this.offset.y * cellSize; + + return { + x : (x / cellSize) | 0, + y : (y / cellSize) | 0 + }; + }; + + /** + * @private + */ + ns.FrameRenderer.prototype.renderFrame_ = function (frame) { + if (!this.canvas) { + this.canvas = pskl.CanvasUtils.createCanvas(frame.getWidth(), frame.getHeight()); + } + + var context = this.canvas.getContext('2d'); + for(var x = 0, width = frame.getWidth(); x < width; x++) { + for(var y = 0, height = frame.getHeight(); y < height; y++) { + var color = frame.getPixel(x, y); + this.renderPixel_(color, x, y, context); + } + } + + this.updateMargins_(); + + context = this.displayCanvas.getContext('2d'); + context.save(); + // zoom < 1 + context.fillStyle = "#aaa"; + // zoom < 1 + context.fillRect(0,0,this.displayCanvas.width, this.displayCanvas.height); + context.translate(this.margin.x, this.margin.y); + context.scale(this.zoom, this.zoom); + context.translate(-this.offset.x, -this.offset.y); + // zoom < 1 + context.clearRect(0, 0, this.canvas.width, this.canvas.height); + context.drawImage(this.canvas, 0, 0); + context.restore(); + }; +})();;(function () { + var ns = $.namespace('pskl.rendering.frame'); + + /** + * FrameRenderer implementation that prevents unnecessary redraws. + * @param {HtmlElement} container HtmlElement to use as parentNode of the Frame + * @param {Object} renderingOptions + * @param {Array} classes array of strings to use for css classes + */ + ns.CachedFrameRenderer = function (container, renderingOptions, classes) { + pskl.rendering.frame.FrameRenderer.call(this, container, renderingOptions, classes); + this.serializedFrame = ''; + }; + + pskl.utils.inherit(pskl.rendering.frame.CachedFrameRenderer, pskl.rendering.frame.FrameRenderer); + + ns.CachedFrameRenderer.prototype.render = function (frame) { + var offset = this.getOffset(); + var size = this.getDisplaySize(); + var serializedFrame = [this.getZoom(), offset.x, offset.y, size.width, size.height, frame.serialize()].join('-'); + if (this.serializedFrame != serializedFrame) { + this.serializedFrame = serializedFrame; + this.superclass.render.call(this, frame); + } + }; +})(); +;(function () { var ns = $.namespace("pskl.rendering"); ns.CanvasRenderer = function (frame, dpi) { @@ -13888,221 +14390,6 @@ var jscolor = { return pskl.CanvasUtils.createCanvas(width, height); }; })();;(function () { - var ns = $.namespace("pskl.rendering"); - - /** - * FrameRenderer will display a given frame inside a canvas element. - * @param {HtmlElement} container HtmlElement to use as parentNode of the Frame - * @param {Object} renderingOptions - * @param {Array} classes array of strings to use for css classes - */ - ns.FrameRenderer = function (container, renderingOptions, classes) { - this.defaultRenderingOptions = { - 'supportGridRendering' : false, - 'zoom' : 1, - 'xOffset' : 0, - 'yOffset' : 0 - }; - - renderingOptions = $.extend(true, {}, this.defaultRenderingOptions, renderingOptions); - - if(container === undefined) { - throw 'Bad FrameRenderer initialization. undefined.'; - } - - if(isNaN(renderingOptions.zoom)) { - throw 'Bad FrameRenderer initialization. not well defined.'; - } - - this.container = container; - - this.zoom = renderingOptions.zoom; - this.xOffset = renderingOptions.xOffset; - this.yOffset = renderingOptions.yOffset; - - this.pixelOffsetHeight = 0; - this.pixelOffsetWidth = 0; - - this.supportGridRendering = renderingOptions.supportGridRendering; - - this.classes = classes || []; - this.classes.push('canvas'); - - /** - * Off dom canvas, will be used to draw the frame at 1:1 ratio - * @type {HTMLElement} - */ - this.canvas = null; - - /** - * Displayed canvas, scaled-up from the offdom canvas - * @type {HTMLElement} - */ - this.scaledCanvas = null; - this.setDisplaySize(renderingOptions.width, renderingOptions.height); - - this.enableGrid(pskl.UserSettings.get(pskl.UserSettings.SHOW_GRID)); - - this.updateBackgroundClass_(pskl.UserSettings.get(pskl.UserSettings.CANVAS_BACKGROUND)); - $.subscribe(Events.USER_SETTINGS_CHANGED, $.proxy(this.onUserSettingsChange_, this)); - }; - - ns.FrameRenderer.prototype.setZoom = function (zoom) { - this.zoom = zoom; - }; - - ns.FrameRenderer.prototype.isAutoSized_ = function () { - return this.displayHeight === 'auto' && this.displayWidth === 'auto'; - }; - - ns.FrameRenderer.prototype.setDisplaySize = function (width, height) { - this.displayHeight = height; - this.displayWidth = width; - if (this.scaledCanvas) { - $(this.scaledCanvas).remove(); - this.scaledCanvas = null; - } - }; - - ns.FrameRenderer.prototype.updatePixelOffsets_ = function () { - if (!this.isAutoSized_()) { - var deltaH = this.displayHeight - (this.zoom * this.canvas.height); - this.pixelOffsetHeight = Math.max(0, deltaH) / 2; - - var deltaW = this.displayWidth - (this.zoom * this.canvas.width); - this.pixelOffsetWidth = Math.max(0, deltaW) / 2; - } - }; - - ns.FrameRenderer.prototype.createScaledCanvas_ = function () { - var height = this.displayHeight; - var width = this.displayWidth; - - if (this.isAutoSized_()) { - height = this.zoom * this.canvas.height; - width = this.zoom * this.canvas.width; - } - - this.scaledCanvas = pskl.CanvasUtils.createCanvas(width, height, this.classes); - if (true || this.zoom > 2) { - pskl.CanvasUtils.disableImageSmoothing(this.scaledCanvas); - } - this.container.append(this.scaledCanvas); - }; - - ns.FrameRenderer.prototype.setDisplayOffset = function (xOffset, yOffset) { - this.xOffset = xOffset; - this.yOffset = yOffset; - }; - - /** - * @private - */ - ns.FrameRenderer.prototype.onUserSettingsChange_ = function (evt, settingName, settingValue) { - if(settingName == pskl.UserSettings.SHOW_GRID) { - this.enableGrid(settingValue); - } - else if (settingName == pskl.UserSettings.CANVAS_BACKGROUND) { - this.updateBackgroundClass_(settingValue); - } - }; - - /** - * @private - */ - ns.FrameRenderer.prototype.updateBackgroundClass_ = function (newClass) { - var currentClass = this.container.data('current-background-class'); - if (currentClass) { - this.container.removeClass(currentClass); - } - this.container.addClass(newClass); - this.container.data('current-background-class', newClass); - }; - - ns.FrameRenderer.prototype.enableGrid = function (flag) { - this.gridStrokeWidth = (flag && this.supportGridRendering) ? Constants.GRID_STROKE_WIDTH : 0; - this.canvasConfigDirty = true; - }; - - ns.FrameRenderer.prototype.render = function (frame) { - if (frame) { - this.clear(); - this.drawFrameInCanvas_(frame); - this.lastRenderedFrame = frame; - } - }; - - ns.FrameRenderer.prototype.clear = function () { - pskl.CanvasUtils.clear(this.canvas); - pskl.CanvasUtils.clear(this.scaledCanvas); - }; - - ns.FrameRenderer.prototype.renderPixel_ = function (color, col, row, context) { - if(color != Constants.TRANSPARENT_COLOR) { - context.fillStyle = color; - context.fillRect(col, row, 1, 1); - } - }; - - /** - * Transform a screen pixel-based coordinate (relative to the top-left corner of the rendered - * frame) into a sprite coordinate in column and row. - * @public - */ - ns.FrameRenderer.prototype.convertPixelCoordinatesIntoSpriteCoordinate = function(coords) { - var cellSize = this.zoom + this.gridStrokeWidth; - var xCoord = (coords.x - this.pixelOffsetWidth) + (this.xOffset * cellSize), - yCoord = (coords.y - this.pixelOffsetHeight) + (this.yOffset * cellSize); - return { - "col" : (xCoord - xCoord % cellSize) / cellSize, - "row" : (yCoord - yCoord % cellSize) / cellSize - }; - }; - - /** - * @private - */ - ns.FrameRenderer.prototype.getFramePos_ = function(index) { - return index * this.dpi + ((index - 1) * this.gridStrokeWidth); - }; - - /** - * @private - */ - ns.FrameRenderer.prototype.drawFrameInCanvas_ = function (frame) { - if (!this.canvas) { - this.canvas = pskl.CanvasUtils.createCanvas(frame.getWidth(), frame.getHeight()); - } - - if (!this.scaledCanvas) { - this.createScaledCanvas_(); - } - - this.updatePixelOffsets_(); - - var context = this.canvas.getContext('2d'); - for(var col = 0, width = frame.getWidth(); col < width; col++) { - for(var row = 0, height = frame.getHeight(); row < height; row++) { - var color = frame.getPixel(col, row); - this.renderPixel_(color, col, row, context); - } - } - - context = this.scaledCanvas.getContext('2d'); - context.save(); - // zoom < 1 - context.fillStyle = "#aaa"; - // zoom < 1 - context.fillRect(0,0,this.scaledCanvas.width, this.scaledCanvas.height); - context.translate(this.pixelOffsetWidth, this.pixelOffsetHeight); - context.scale(this.zoom, this.zoom); - context.translate(-this.xOffset, -this.yOffset); - // zoom < 1 - context.clearRect(0, 0, this.canvas.width, this.canvas.height); - context.drawImage(this.canvas, 0, 0); - context.restore(); - }; -})();;(function () { var ns = $.namespace("pskl.rendering"); @@ -14356,25 +14643,25 @@ var jscolor = { */ this.container = container; - this.zoom = this.calculateZoom_(); - this.xOffset = 0; - this.yOffset = 0; - // TODO(vincz): Store user prefs in a localstorage string ? var renderingOptions = { - "zoom": this.zoom, + "zoom": this.calculateZoom_(), "supportGridRendering" : true, "height" : this.getContainerHeight_(), "width" : this.getContainerWidth_(), - "xOffset" : this.xOffset, - "yOffset" : this.yOffset + "xOffset" : 0, + "yOffset" : 0 }; - this.overlayRenderer = new pskl.rendering.FrameRenderer(this.container, renderingOptions, ["canvas-overlay"]); - this.renderer = new pskl.rendering.FrameRenderer(this.container, renderingOptions, ["drawing-canvas"]); - this.layersBelowRenderer = new pskl.rendering.FrameRenderer(this.container, renderingOptions, ["layers-canvas", "layers-below-canvas"]); - this.layersAboveRenderer = new pskl.rendering.FrameRenderer(this.container, renderingOptions, ["layers-canvas", "layers-above-canvas"]); + this.overlayRenderer = new pskl.rendering.frame.CachedFrameRenderer(this.container, renderingOptions, ["canvas-overlay"]); + this.renderer = new pskl.rendering.frame.CachedFrameRenderer(this.container, renderingOptions, ["drawing-canvas"]); + this.layersRenderer = new pskl.rendering.layer.LayersRenderer(this.container, renderingOptions, piskelController); + this.compositeRenderer = new pskl.rendering.CompositeRenderer(); + this.compositeRenderer + .add(this.overlayRenderer) + .add(this.renderer) + .add(this.layersRenderer); // State of drawing controller: this.isClicked = false; @@ -14409,12 +14696,12 @@ var jscolor = { $.publish(Events.SECONDARY_COLOR_UPDATED, [color]); }, this)); - $(window).resize($.proxy(this.startDPIUpdateTimer_, this)); + $(window).resize($.proxy(this.startResizeTimer_, this)); $.subscribe(Events.USER_SETTINGS_CHANGED, $.proxy(this.onUserSettingsChange_, this)); - $.subscribe(Events.FRAME_SIZE_CHANGED, $.proxy(this.updateZoom_, this)); + $.subscribe(Events.FRAME_SIZE_CHANGED, $.proxy(this.onFrameSizeChanged_, this)); - this.updateZoom_(); + this.centerColumnWrapperHorizontally_(); }; ns.DrawingController.prototype.initMouseBehavior = function() { @@ -14422,6 +14709,7 @@ var jscolor = { this.container.mousedown($.proxy(this.onMousedown_, this)); this.container.mousemove($.proxy(this.onMousemove_, this)); this.container.on('mousewheel', $.proxy(this.onMousewheel_, this)); + this.container.on('wheel', $.proxy(this.onMousewheel_, this)); body.mouseup($.proxy(this.onMouseup_, this)); @@ -14429,11 +14717,15 @@ var jscolor = { body.contextmenu(this.onCanvasContextMenu_); }; - ns.DrawingController.prototype.startDPIUpdateTimer_ = function () { - if (this.zoomUpdateTimer) { - window.clearInterval(this.zoomUpdateTimer); + ns.DrawingController.prototype.startResizeTimer_ = function () { + if (this.resizeTimer) { + window.clearInterval(this.resizeTimer); } - this.zoomUpdateTimer = window.setTimeout($.proxy(this.updateZoom_, this), 200); + this.resizeTimer = window.setTimeout($.proxy(this.afterWindowResize_, this), 200); + }, + + ns.DrawingController.prototype.afterWindowResize_ = function () { + this.compositeRenderer.setDisplaySize(this.getContainerWidth_(), this.getContainerHeight_()); }, /** @@ -14441,7 +14733,7 @@ var jscolor = { */ ns.DrawingController.prototype.onUserSettingsChange_ = function (evt, settingsName, settingsValue) { if(settingsName == pskl.UserSettings.SHOW_GRID) { - this.updateZoom_(); + console.warn('DrawingController:onUserSettingsChange_ not implemented !'); } }, @@ -14456,10 +14748,11 @@ var jscolor = { $.publish(Events.CANVAS_RIGHT_CLICKED); } - var coords = this.getSpriteCoordinates(event); + var coords = this.renderer.getCoordinates(event.clientX, event.clientY); this.currentToolBehavior.applyToolAt( - coords.col, coords.row, + coords.x, + coords.y, this.getCurrentColor_(), this.piskelController.getCurrentFrame(), this.overlayFrame, @@ -14475,12 +14768,14 @@ var jscolor = { ns.DrawingController.prototype.onMousemove_ = function (event) { var currentTime = new Date().getTime(); // Throttling of the mousemove event: - if ((currentTime - this.previousMousemoveTime) > 40 ) { - var coords = this.getSpriteCoordinates(event); + if ((currentTime - this.previousMousemoveTime) > Constants.MOUSEMOVE_THROTTLING ) { + var coords = this.renderer.getCoordinates(event.clientX, event.clientY); + if (this.isClicked) { this.currentToolBehavior.moveToolAt( - coords.col, coords.row, + coords.x, + coords.y, this.getCurrentColor_(), this.piskelController.getCurrentFrame(), this.overlayFrame, @@ -14494,7 +14789,8 @@ var jscolor = { } else { this.currentToolBehavior.moveUnactiveToolAt( - coords.col, coords.row, + coords.x, + coords.y, this.getCurrentColor_(), this.piskelController.getCurrentFrame(), this.overlayFrame, @@ -14507,12 +14803,14 @@ var jscolor = { ns.DrawingController.prototype.onMousewheel_ = function (jQueryEvent) { var event = jQueryEvent.originalEvent; - var delta = event.wheelDeltaY; + var delta = event.wheelDeltaY || (-2 * event.deltaY); + var currentZoom = this.renderer.getZoom(); if (delta > 0) { - this.setZoom(this.zoom + 1); + this.compositeRenderer.setZoom(currentZoom + 1); } else if (delta < 0) { - this.setZoom(this.zoom - 1); + this.compositeRenderer.setZoom(currentZoom - 1); } + pskl.app.minimapController.onDrawingControllerMove_(); }; /** @@ -14528,10 +14826,11 @@ var jscolor = { this.isClicked = false; this.isRightClicked = false; - var coords = this.getSpriteCoordinates(event); + var coords = this.renderer.getCoordinates(event.clientX, event.clientY); //console.log("mousemove: col: " + spriteCoordinate.col + " - row: " + spriteCoordinate.row); this.currentToolBehavior.releaseToolAt( - coords.col, coords.row, + coords.x, + coords.y, this.getCurrentColor_(), this.piskelController.getCurrentFrame(), this.overlayFrame, @@ -14555,23 +14854,12 @@ var jscolor = { return evtInfo; }; - /** - * @private - */ - ns.DrawingController.prototype.getRelativeCoordinates = function (clientX, clientY) { - var canvasPageOffset = this.container.offset(); - return { - x : clientX - canvasPageOffset.left, - y : clientY - canvasPageOffset.top - }; - }; /** * @private */ ns.DrawingController.prototype.getSpriteCoordinates = function(event) { - var coords = this.getRelativeCoordinates(event.clientX, event.clientY); - return this.renderer.convertPixelCoordinatesIntoSpriteCoordinate(coords); + return this.renderer.getCoordinates(event.clientX, event.clientY); }; /** @@ -14599,66 +14887,14 @@ var jscolor = { }; ns.DrawingController.prototype.render = function () { - this.renderLayers(); - this.renderFrame(); - this.renderOverlay(); - }; - - ns.DrawingController.prototype.renderFrame = function () { - var frame = this.piskelController.getCurrentFrame(); - var serializedFrame = [this.zoom, this.xOffset, this.yOffset, frame.serialize()].join('-'); - if (this.serializedFrame != serializedFrame) { - if (!frame.isSameSize(this.overlayFrame)) { - this.overlayFrame = pskl.model.Frame.createEmptyFromFrame(frame); - } - this.serializedFrame = serializedFrame; - this.renderer.render(frame); + var currentFrame = this.piskelController.getCurrentFrame(); + if (!currentFrame.isSameSize(this.overlayFrame)) { + this.overlayFrame = pskl.model.Frame.createEmptyFromFrame(currentFrame); } - }; - ns.DrawingController.prototype.renderOverlay = function () { - var serializedOverlay = [this.zoom, this.xOffset, this.yOffset, this.overlayFrame.serialize()].join('-'); - if (this.serializedOverlay != serializedOverlay) { - this.serializedOverlay = serializedOverlay; - this.overlayRenderer.render(this.overlayFrame); - } - }; - - ns.DrawingController.prototype.renderLayers = function () { - var layers = this.piskelController.getLayers(); - var currentFrameIndex = this.piskelController.currentFrameIndex; - var currentLayerIndex = this.piskelController.currentLayerIndex; - - var serializedLayerFrame = [ - this.zoom, - currentFrameIndex, - currentLayerIndex, - layers.length - ].join("-"); - - if (this.serializedLayerFrame != serializedLayerFrame) { - this.layersAboveRenderer.clear(); - this.layersBelowRenderer.clear(); - - var downLayers = layers.slice(0, currentLayerIndex); - var downFrame = this.getFrameForLayersAt_(currentFrameIndex, downLayers); - this.layersBelowRenderer.render(downFrame); - - if (currentLayerIndex + 1 < layers.length) { - var upLayers = layers.slice(currentLayerIndex + 1, layers.length); - var upFrame = this.getFrameForLayersAt_(currentFrameIndex, upLayers); - this.layersAboveRenderer.render(upFrame); - } - - this.serializedLayerFrame = serializedLayerFrame; - } - }; - - ns.DrawingController.prototype.getFrameForLayersAt_ = function (frameIndex, layers) { - var frames = layers.map(function (l) { - return l.getFrameAt(frameIndex); - }); - return pskl.utils.FrameUtils.merge(frames); + this.layersRenderer.render(); + this.renderer.render(currentFrame); + this.overlayRenderer.render(this.overlayFrame); }; /** @@ -14689,40 +14925,25 @@ var jscolor = { ns.DrawingController.prototype.getContainerWidth_ = function () { return this.calculateZoom_() * this.piskelController.getCurrentFrame().getWidth(); }; + /** * @private */ - ns.DrawingController.prototype.updateZoom_ = function() { - this.setZoom(this.calculateZoom_()); - - var currentFrameHeight = this.piskelController.getCurrentFrame().getHeight(); - var canvasHeight = currentFrameHeight * this.zoom; - if (pskl.UserSettings.get(pskl.UserSettings.SHOW_GRID)) { - canvasHeight += Constants.GRID_STROKE_WIDTH * currentFrameHeight; - } - - var verticalGapInPixel = Math.floor(($('#main-wrapper').height() - canvasHeight) / 2); + ns.DrawingController.prototype.centerColumnWrapperHorizontally_ = function() { + var containerHeight = this.getContainerHeight_(); + var verticalGapInPixel = Math.floor(($('#main-wrapper').height() - containerHeight) / 2); $('#column-wrapper').css({ - 'top': verticalGapInPixel + 'px', - 'height': canvasHeight + 'px' + 'top': verticalGapInPixel + 'px' }); }; - ns.DrawingController.prototype.setZoom = function (zoom) { - this.zoom = zoom; - this.overlayRenderer.setZoom(this.zoom); - this.renderer.setZoom(this.zoom); - this.layersAboveRenderer.setZoom(this.zoom); - this.layersBelowRenderer.setZoom(this.zoom); + ns.DrawingController.prototype.getRenderer = function () { + return this.compositeRenderer; }; - ns.DrawingController.prototype.moveOffset = function (xOffset, yOffset) { - this.xOffset = xOffset; - this.yOffset = yOffset; - this.overlayRenderer.setDisplayOffset(xOffset, yOffset); - this.renderer.setDisplayOffset(xOffset, yOffset); - this.layersAboveRenderer.setDisplayOffset(xOffset, yOffset); - this.layersBelowRenderer.setDisplayOffset(xOffset, yOffset); + ns.DrawingController.prototype.setOffset = function (x, y) { + this.compositeRenderer.setOffset(x, y); + pskl.app.minimapController.onDrawingControllerMove_(); }; })();;(function () { var ns = $.namespace("pskl.controller"); @@ -14881,10 +15102,10 @@ var jscolor = { // is to make this update function (#createPreviewTile) less aggressive. var renderingOptions = { "zoom" : this.zoom, - "height" : "auto", - "width" : "auto" + "height" : this.piskelController.getCurrentFrame().getHeight() * this.zoom, + "width" : this.piskelController.getCurrentFrame().getWidth() * this.zoom }; - var currentFrameRenderer = new pskl.rendering.FrameRenderer($(canvasContainer), renderingOptions, ["tile-view"]); + var currentFrameRenderer = new pskl.rendering.frame.FrameRenderer($(canvasContainer), renderingOptions, ["tile-view"]); currentFrameRenderer.render(currentFrame); previewTileRoot.appendChild(canvasContainer); @@ -15016,14 +15237,15 @@ var jscolor = { this.setFPS(Constants.DEFAULT.FPS); + var zoom = this.calculateZoom_(); var renderingOptions = { - "zoom": this.calculateZoom_(), - "height" : "auto", - "width" : "auto" + "zoom": zoom, + "height" : this.piskelController.getCurrentFrame().getHeight() * zoom, + "width" : this.piskelController.getCurrentFrame().getWidth() * zoom }; - this.renderer = new pskl.rendering.FrameRenderer(this.container, renderingOptions); + this.renderer = new pskl.rendering.frame.FrameRenderer(this.container, renderingOptions); - $.subscribe(Events.FRAME_SIZE_CHANGED, this.updateDPI_.bind(this)); + $.subscribe(Events.FRAME_SIZE_CHANGED, this.updateZoom_.bind(this)); }; ns.AnimatedPreviewController.prototype.init = function () { @@ -15065,17 +15287,99 @@ var jscolor = { */ ns.AnimatedPreviewController.prototype.calculateZoom_ = function () { var previewSize = 200, - framePixelHeight = this.piskelController.getCurrentFrame().getHeight(), - framePixelWidth = this.piskelController.getCurrentFrame().getWidth(); - // TODO (julz) : should have a utility to get a Size from framesheet easily (what about empty framesheets though ?) + hZoom = previewSize / this.piskelController.getCurrentFrame().getHeight(), + wZoom = previewSize / this.piskelController.getCurrentFrame().getWidth(); - //return pskl.PixelUtils.calculateDPIForContainer($(".preview-container"), framePixelHeight, framePixelWidth); - return pskl.PixelUtils.calculateDPI(previewSize, previewSize, framePixelHeight, framePixelWidth); + return Math.min(hZoom, wZoom); }; - ns.AnimatedPreviewController.prototype.updateDPI_ = function () { - this.dpi = this.calculateDPI_(); - this.renderer.setDPI(this.dpi); + ns.AnimatedPreviewController.prototype.updateZoom_ = function () { + var zoom = this.calculateZoom_(); + this.renderer.setZoom(zoom); + }; +})();;(function () { + var ns = $.namespace('pskl.controller'); + + ns.MinimapController = function (piskelController, animationController, drawingController, container) { + this.piskelController = piskelController; + this.animationController = animationController; + this.drawingController = drawingController; + this.container = container; + + this.isClicked = false; + }; + + ns.MinimapController.prototype.init = function () { + this.cropFrame = document.createElement('DIV'); + this.cropFrame.className = 'minimap-crop-frame'; + this.cropFrame.style.display = 'none'; + $(this.container).mousedown(this.onMinimapMousedown_.bind(this)); + $(this.container).mousemove(this.onMinimapMousemove_.bind(this)); + $(this.container).mouseup(this.onMinimapMouseup_.bind(this)); + $(this.container).append(this.cropFrame); + }; + + ns.MinimapController.prototype.onDrawingControllerMove_ = function () { + var zoomRatio = this.getDrawingAreaZoomRatio_(); + if (zoomRatio > 1) { + this.displayCropFrame_(zoomRatio, this.drawingController.getRenderer().getOffset()); + } else { + this.hideCropFrame_(); + } + }; + + ns.MinimapController.prototype.displayCropFrame_ = function (ratio, offset) { + this.cropFrame.style.display = 'block'; + this.cropFrame.style.top = (offset.y * this.animationController.renderer.getZoom()) + 'px'; + this.cropFrame.style.left = (offset.x * this.animationController.renderer.getZoom()) + 'px'; + var zoomRatio = this.getDrawingAreaZoomRatio_(); + this.cropFrame.style.width = (this.container.width() / zoomRatio) + 'px'; + this.cropFrame.style.height = (this.container.height() / zoomRatio) + 'px'; + + }; + + ns.MinimapController.prototype.hideCropFrame_ = function () { + this.cropFrame.style.display = 'none'; + }; + + ns.MinimapController.prototype.onMinimapMousemove_ = function (evt) { + if (this.isClicked) { + if (this.getDrawingAreaZoomRatio_() > 1) { + var coords = this.getCoordinatesCenteredAround_(evt.clientX, evt.clientY); + this.drawingController.setOffset(coords.x, coords.y); + } + } + }; + + ns.MinimapController.prototype.onMinimapMousedown_ = function (evt) { + this.isClicked = true; + }; + + ns.MinimapController.prototype.onMinimapMouseup_ = function (evt) { + this.isClicked = false; + }; + + ns.MinimapController.prototype.getCoordinatesCenteredAround_ = function (x, y) { + var frameCoords = this.animationController.renderer.getCoordinates(x, y); + var zoomRatio = this.getDrawingAreaZoomRatio_(); + var frameWidth = this.piskelController.getCurrentFrame().getWidth(); + var frameHeight = this.piskelController.getCurrentFrame().getHeight(); + + var width = frameWidth / zoomRatio; + var height = frameHeight / zoomRatio; + + return { + x : frameCoords.x - (width/2), + y : frameCoords.y - (height/2) + }; + }; + + ns.MinimapController.prototype.getDrawingAreaZoomRatio_ = function () { + var drawingAreaZoom = this.drawingController.getRenderer().getZoom(); + var drawingAreaFullHeight = this.piskelController.getCurrentFrame().getHeight() * drawingAreaZoom; + var zoomRatio = drawingAreaFullHeight / this.drawingController.getRenderer().getDisplaySize().height; + + return zoomRatio; }; })();;(function () { var ns = $.namespace("pskl.controller"); @@ -15307,7 +15611,7 @@ var jscolor = { })(); ;(function () { var ns = $.namespace("pskl.controller.settings"); - + ns.ApplicationSettingsController = function () {}; /** @@ -15325,23 +15629,28 @@ var jscolor = { $('#show-grid').prop('checked', show_grid); // Handle grid display changes: - $('#show-grid').change($.proxy(function(evt) { - var checked = $('#show-grid').prop('checked'); - pskl.UserSettings.set(pskl.UserSettings.SHOW_GRID, checked); - }, this)); + $('#show-grid').change(this.onShowGridClick.bind(this)); // Handle canvas background changes: - $('#background-picker-wrapper').click(function(evt) { - var target = $(evt.target).closest('.background-picker'); - if (target.length) { - var backgroundClass = target.data('background-class'); - pskl.UserSettings.set(pskl.UserSettings.CANVAS_BACKGROUND, backgroundClass); - - $('.background-picker').removeClass('selected'); - target.addClass('selected'); - } - }); + $('#background-picker-wrapper').click(this.onBackgroundClick.bind(this)); }; + + ns.ApplicationSettingsController.prototype.onShowGridClick = function (evt) { + var checked = $('#show-grid').prop('checked'); + pskl.UserSettings.set(pskl.UserSettings.SHOW_GRID, checked); + }; + + ns.ApplicationSettingsController.prototype.onBackgroundClick = function (evt) { + var target = $(evt.target).closest('.background-picker'); + if (target.length) { + var backgroundClass = target.data('background-class'); + pskl.UserSettings.set(pskl.UserSettings.CANVAS_BACKGROUND, backgroundClass); + + $('.background-picker').removeClass('selected'); + target.addClass('selected'); + } + }; + })();;(function () { var ns = $.namespace("pskl.controller.settings"); @@ -16556,6 +16865,9 @@ var jscolor = { this.animationController = new pskl.controller.AnimatedPreviewController(this.piskelController, $('#preview-canvas-container')); this.animationController.init(); + this.minimapController = new pskl.controller.MinimapController(this.piskelController, this.animationController, this.drawingController, $('#preview-canvas-container')); + this.minimapController.init(); + this.previewsController = new pskl.controller.PreviewFilmController(this.piskelController, $('#preview-list')); this.previewsController.init(); @@ -16761,9 +17073,9 @@ var jscolor = { getFirstFrameAsPng : function () { var firstFrame = this.piskelController.getFrameAt(0); - var frameRenderer = new pskl.rendering.CanvasRenderer(firstFrame, 1); - frameRenderer.drawTransparentAs('rgba(0,0,0,0)'); - var firstFrameCanvas = frameRenderer.render().canvas; + var canvasRenderer = new pskl.rendering.CanvasRenderer(firstFrame, 1); + canvasRenderer.drawTransparentAs('rgba(0,0,0,0)'); + var firstFrameCanvas = canvasRenderer.render().canvas; return firstFrameCanvas.toDataURL("image/png"); }, diff --git a/zoom/css/minimap.css b/zoom/css/minimap.css new file mode 100644 index 00000000..0383e127 --- /dev/null +++ b/zoom/css/minimap.css @@ -0,0 +1,8 @@ +.minimap-crop-frame { + position:absolute; + border:1px solid red; + z-index:9999; + box-sizing : border-box; + -moz-box-sizing : border-box; + cursor : pointer; +} \ No newline at end of file diff --git a/zoom/css/style.css b/zoom/css/style.css index 1b810419..6fc8e490 100644 --- a/zoom/css/style.css +++ b/zoom/css/style.css @@ -174,6 +174,10 @@ body { font-size: 0; } +.preview-container .canvas-container { + overflow : hidden; +} + .preview-container canvas { border : 0px Solid transparent; } @@ -189,6 +193,7 @@ body { .range-fps { overflow: hidden; + width: 120px; } /** diff --git a/zoom/index.html b/zoom/index.html index 50c1ddd6..cb8f278c 100644 --- a/zoom/index.html +++ b/zoom/index.html @@ -14,6 +14,7 @@ + diff --git a/zoom/js/Constants.js b/zoom/js/Constants.js index abf2726c..6ca8844e 100644 --- a/zoom/js/Constants.js +++ b/zoom/js/Constants.js @@ -48,5 +48,6 @@ var Constants = { GRID_STROKE_WIDTH: 1, LEFT_BUTTON : 'left_button_1', - RIGHT_BUTTON : 'right_button_2' + RIGHT_BUTTON : 'right_button_2', + MOUSEMOVE_THROTTLING : 10 }; \ No newline at end of file diff --git a/zoom/js/app.js b/zoom/js/app.js index def736df..b783d785 100644 --- a/zoom/js/app.js +++ b/zoom/js/app.js @@ -27,6 +27,9 @@ this.animationController = new pskl.controller.AnimatedPreviewController(this.piskelController, $('#preview-canvas-container')); this.animationController.init(); + this.minimapController = new pskl.controller.MinimapController(this.piskelController, this.animationController, this.drawingController, $('#preview-canvas-container')); + this.minimapController.init(); + this.previewsController = new pskl.controller.PreviewFilmController(this.piskelController, $('#preview-list')); this.previewsController.init(); @@ -232,9 +235,9 @@ getFirstFrameAsPng : function () { var firstFrame = this.piskelController.getFrameAt(0); - var frameRenderer = new pskl.rendering.CanvasRenderer(firstFrame, 1); - frameRenderer.drawTransparentAs('rgba(0,0,0,0)'); - var firstFrameCanvas = frameRenderer.render().canvas; + var canvasRenderer = new pskl.rendering.CanvasRenderer(firstFrame, 1); + canvasRenderer.drawTransparentAs('rgba(0,0,0,0)'); + var firstFrameCanvas = canvasRenderer.render().canvas; return firstFrameCanvas.toDataURL("image/png"); }, diff --git a/zoom/js/controller/AnimatedPreviewController.js b/zoom/js/controller/AnimatedPreviewController.js index e03154c1..14749608 100644 --- a/zoom/js/controller/AnimatedPreviewController.js +++ b/zoom/js/controller/AnimatedPreviewController.js @@ -9,14 +9,15 @@ this.setFPS(Constants.DEFAULT.FPS); + var zoom = this.calculateZoom_(); var renderingOptions = { - "zoom": this.calculateZoom_(), - "height" : "auto", - "width" : "auto" + "zoom": zoom, + "height" : this.piskelController.getCurrentFrame().getHeight() * zoom, + "width" : this.piskelController.getCurrentFrame().getWidth() * zoom }; - this.renderer = new pskl.rendering.FrameRenderer(this.container, renderingOptions); + this.renderer = new pskl.rendering.frame.FrameRenderer(this.container, renderingOptions); - $.subscribe(Events.FRAME_SIZE_CHANGED, this.updateDPI_.bind(this)); + $.subscribe(Events.FRAME_SIZE_CHANGED, this.updateZoom_.bind(this)); }; ns.AnimatedPreviewController.prototype.init = function () { @@ -58,16 +59,14 @@ */ ns.AnimatedPreviewController.prototype.calculateZoom_ = function () { var previewSize = 200, - framePixelHeight = this.piskelController.getCurrentFrame().getHeight(), - framePixelWidth = this.piskelController.getCurrentFrame().getWidth(); - // TODO (julz) : should have a utility to get a Size from framesheet easily (what about empty framesheets though ?) + hZoom = previewSize / this.piskelController.getCurrentFrame().getHeight(), + wZoom = previewSize / this.piskelController.getCurrentFrame().getWidth(); - //return pskl.PixelUtils.calculateDPIForContainer($(".preview-container"), framePixelHeight, framePixelWidth); - return pskl.PixelUtils.calculateDPI(previewSize, previewSize, framePixelHeight, framePixelWidth); + return Math.min(hZoom, wZoom); }; - ns.AnimatedPreviewController.prototype.updateDPI_ = function () { - this.dpi = this.calculateDPI_(); - this.renderer.setDPI(this.dpi); + ns.AnimatedPreviewController.prototype.updateZoom_ = function () { + var zoom = this.calculateZoom_(); + this.renderer.setZoom(zoom); }; })(); \ No newline at end of file diff --git a/zoom/js/controller/DrawingController.js b/zoom/js/controller/DrawingController.js index 637cd670..98efb7f4 100644 --- a/zoom/js/controller/DrawingController.js +++ b/zoom/js/controller/DrawingController.js @@ -16,25 +16,25 @@ */ this.container = container; - this.zoom = this.calculateZoom_(); - this.xOffset = 0; - this.yOffset = 0; - // TODO(vincz): Store user prefs in a localstorage string ? var renderingOptions = { - "zoom": this.zoom, + "zoom": this.calculateZoom_(), "supportGridRendering" : true, "height" : this.getContainerHeight_(), "width" : this.getContainerWidth_(), - "xOffset" : this.xOffset, - "yOffset" : this.yOffset + "xOffset" : 0, + "yOffset" : 0 }; - this.overlayRenderer = new pskl.rendering.FrameRenderer(this.container, renderingOptions, ["canvas-overlay"]); - this.renderer = new pskl.rendering.FrameRenderer(this.container, renderingOptions, ["drawing-canvas"]); - this.layersBelowRenderer = new pskl.rendering.FrameRenderer(this.container, renderingOptions, ["layers-canvas", "layers-below-canvas"]); - this.layersAboveRenderer = new pskl.rendering.FrameRenderer(this.container, renderingOptions, ["layers-canvas", "layers-above-canvas"]); + this.overlayRenderer = new pskl.rendering.frame.CachedFrameRenderer(this.container, renderingOptions, ["canvas-overlay"]); + this.renderer = new pskl.rendering.frame.CachedFrameRenderer(this.container, renderingOptions, ["drawing-canvas"]); + this.layersRenderer = new pskl.rendering.layer.LayersRenderer(this.container, renderingOptions, piskelController); + this.compositeRenderer = new pskl.rendering.CompositeRenderer(); + this.compositeRenderer + .add(this.overlayRenderer) + .add(this.renderer) + .add(this.layersRenderer); // State of drawing controller: this.isClicked = false; @@ -69,12 +69,12 @@ $.publish(Events.SECONDARY_COLOR_UPDATED, [color]); }, this)); - $(window).resize($.proxy(this.startDPIUpdateTimer_, this)); + $(window).resize($.proxy(this.startResizeTimer_, this)); $.subscribe(Events.USER_SETTINGS_CHANGED, $.proxy(this.onUserSettingsChange_, this)); - $.subscribe(Events.FRAME_SIZE_CHANGED, $.proxy(this.updateZoom_, this)); + $.subscribe(Events.FRAME_SIZE_CHANGED, $.proxy(this.onFrameSizeChanged_, this)); - this.updateZoom_(); + this.centerColumnWrapperHorizontally_(); }; ns.DrawingController.prototype.initMouseBehavior = function() { @@ -82,6 +82,7 @@ this.container.mousedown($.proxy(this.onMousedown_, this)); this.container.mousemove($.proxy(this.onMousemove_, this)); this.container.on('mousewheel', $.proxy(this.onMousewheel_, this)); + this.container.on('wheel', $.proxy(this.onMousewheel_, this)); body.mouseup($.proxy(this.onMouseup_, this)); @@ -89,11 +90,15 @@ body.contextmenu(this.onCanvasContextMenu_); }; - ns.DrawingController.prototype.startDPIUpdateTimer_ = function () { - if (this.zoomUpdateTimer) { - window.clearInterval(this.zoomUpdateTimer); + ns.DrawingController.prototype.startResizeTimer_ = function () { + if (this.resizeTimer) { + window.clearInterval(this.resizeTimer); } - this.zoomUpdateTimer = window.setTimeout($.proxy(this.updateZoom_, this), 200); + this.resizeTimer = window.setTimeout($.proxy(this.afterWindowResize_, this), 200); + }, + + ns.DrawingController.prototype.afterWindowResize_ = function () { + this.compositeRenderer.setDisplaySize(this.getContainerWidth_(), this.getContainerHeight_()); }, /** @@ -101,7 +106,7 @@ */ ns.DrawingController.prototype.onUserSettingsChange_ = function (evt, settingsName, settingsValue) { if(settingsName == pskl.UserSettings.SHOW_GRID) { - this.updateZoom_(); + console.warn('DrawingController:onUserSettingsChange_ not implemented !'); } }, @@ -116,10 +121,11 @@ $.publish(Events.CANVAS_RIGHT_CLICKED); } - var coords = this.getSpriteCoordinates(event); + var coords = this.renderer.getCoordinates(event.clientX, event.clientY); this.currentToolBehavior.applyToolAt( - coords.col, coords.row, + coords.x, + coords.y, this.getCurrentColor_(), this.piskelController.getCurrentFrame(), this.overlayFrame, @@ -135,12 +141,14 @@ ns.DrawingController.prototype.onMousemove_ = function (event) { var currentTime = new Date().getTime(); // Throttling of the mousemove event: - if ((currentTime - this.previousMousemoveTime) > 40 ) { - var coords = this.getSpriteCoordinates(event); + if ((currentTime - this.previousMousemoveTime) > Constants.MOUSEMOVE_THROTTLING ) { + var coords = this.renderer.getCoordinates(event.clientX, event.clientY); + if (this.isClicked) { this.currentToolBehavior.moveToolAt( - coords.col, coords.row, + coords.x, + coords.y, this.getCurrentColor_(), this.piskelController.getCurrentFrame(), this.overlayFrame, @@ -154,7 +162,8 @@ } else { this.currentToolBehavior.moveUnactiveToolAt( - coords.col, coords.row, + coords.x, + coords.y, this.getCurrentColor_(), this.piskelController.getCurrentFrame(), this.overlayFrame, @@ -167,12 +176,14 @@ ns.DrawingController.prototype.onMousewheel_ = function (jQueryEvent) { var event = jQueryEvent.originalEvent; - var delta = event.wheelDeltaY; + var delta = event.wheelDeltaY || (-2 * event.deltaY); + var currentZoom = this.renderer.getZoom(); if (delta > 0) { - this.setZoom(this.zoom + 1); + this.compositeRenderer.setZoom(currentZoom + 1); } else if (delta < 0) { - this.setZoom(this.zoom - 1); + this.compositeRenderer.setZoom(currentZoom - 1); } + pskl.app.minimapController.onDrawingControllerMove_(); }; /** @@ -188,10 +199,11 @@ this.isClicked = false; this.isRightClicked = false; - var coords = this.getSpriteCoordinates(event); + var coords = this.renderer.getCoordinates(event.clientX, event.clientY); //console.log("mousemove: col: " + spriteCoordinate.col + " - row: " + spriteCoordinate.row); this.currentToolBehavior.releaseToolAt( - coords.col, coords.row, + coords.x, + coords.y, this.getCurrentColor_(), this.piskelController.getCurrentFrame(), this.overlayFrame, @@ -215,23 +227,12 @@ return evtInfo; }; - /** - * @private - */ - ns.DrawingController.prototype.getRelativeCoordinates = function (clientX, clientY) { - var canvasPageOffset = this.container.offset(); - return { - x : clientX - canvasPageOffset.left, - y : clientY - canvasPageOffset.top - }; - }; /** * @private */ ns.DrawingController.prototype.getSpriteCoordinates = function(event) { - var coords = this.getRelativeCoordinates(event.clientX, event.clientY); - return this.renderer.convertPixelCoordinatesIntoSpriteCoordinate(coords); + return this.renderer.getCoordinates(event.clientX, event.clientY); }; /** @@ -259,66 +260,14 @@ }; ns.DrawingController.prototype.render = function () { - this.renderLayers(); - this.renderFrame(); - this.renderOverlay(); - }; - - ns.DrawingController.prototype.renderFrame = function () { - var frame = this.piskelController.getCurrentFrame(); - var serializedFrame = [this.zoom, this.xOffset, this.yOffset, frame.serialize()].join('-'); - if (this.serializedFrame != serializedFrame) { - if (!frame.isSameSize(this.overlayFrame)) { - this.overlayFrame = pskl.model.Frame.createEmptyFromFrame(frame); - } - this.serializedFrame = serializedFrame; - this.renderer.render(frame); + var currentFrame = this.piskelController.getCurrentFrame(); + if (!currentFrame.isSameSize(this.overlayFrame)) { + this.overlayFrame = pskl.model.Frame.createEmptyFromFrame(currentFrame); } - }; - ns.DrawingController.prototype.renderOverlay = function () { - var serializedOverlay = [this.zoom, this.xOffset, this.yOffset, this.overlayFrame.serialize()].join('-'); - if (this.serializedOverlay != serializedOverlay) { - this.serializedOverlay = serializedOverlay; - this.overlayRenderer.render(this.overlayFrame); - } - }; - - ns.DrawingController.prototype.renderLayers = function () { - var layers = this.piskelController.getLayers(); - var currentFrameIndex = this.piskelController.currentFrameIndex; - var currentLayerIndex = this.piskelController.currentLayerIndex; - - var serializedLayerFrame = [ - this.zoom, - currentFrameIndex, - currentLayerIndex, - layers.length - ].join("-"); - - if (this.serializedLayerFrame != serializedLayerFrame) { - this.layersAboveRenderer.clear(); - this.layersBelowRenderer.clear(); - - var downLayers = layers.slice(0, currentLayerIndex); - var downFrame = this.getFrameForLayersAt_(currentFrameIndex, downLayers); - this.layersBelowRenderer.render(downFrame); - - if (currentLayerIndex + 1 < layers.length) { - var upLayers = layers.slice(currentLayerIndex + 1, layers.length); - var upFrame = this.getFrameForLayersAt_(currentFrameIndex, upLayers); - this.layersAboveRenderer.render(upFrame); - } - - this.serializedLayerFrame = serializedLayerFrame; - } - }; - - ns.DrawingController.prototype.getFrameForLayersAt_ = function (frameIndex, layers) { - var frames = layers.map(function (l) { - return l.getFrameAt(frameIndex); - }); - return pskl.utils.FrameUtils.merge(frames); + this.layersRenderer.render(); + this.renderer.render(currentFrame); + this.overlayRenderer.render(this.overlayFrame); }; /** @@ -349,39 +298,24 @@ ns.DrawingController.prototype.getContainerWidth_ = function () { return this.calculateZoom_() * this.piskelController.getCurrentFrame().getWidth(); }; + /** * @private */ - ns.DrawingController.prototype.updateZoom_ = function() { - this.setZoom(this.calculateZoom_()); - - var currentFrameHeight = this.piskelController.getCurrentFrame().getHeight(); - var canvasHeight = currentFrameHeight * this.zoom; - if (pskl.UserSettings.get(pskl.UserSettings.SHOW_GRID)) { - canvasHeight += Constants.GRID_STROKE_WIDTH * currentFrameHeight; - } - - var verticalGapInPixel = Math.floor(($('#main-wrapper').height() - canvasHeight) / 2); + ns.DrawingController.prototype.centerColumnWrapperHorizontally_ = function() { + var containerHeight = this.getContainerHeight_(); + var verticalGapInPixel = Math.floor(($('#main-wrapper').height() - containerHeight) / 2); $('#column-wrapper').css({ - 'top': verticalGapInPixel + 'px', - 'height': canvasHeight + 'px' + 'top': verticalGapInPixel + 'px' }); }; - ns.DrawingController.prototype.setZoom = function (zoom) { - this.zoom = zoom; - this.overlayRenderer.setZoom(this.zoom); - this.renderer.setZoom(this.zoom); - this.layersAboveRenderer.setZoom(this.zoom); - this.layersBelowRenderer.setZoom(this.zoom); + ns.DrawingController.prototype.getRenderer = function () { + return this.compositeRenderer; }; - ns.DrawingController.prototype.moveOffset = function (xOffset, yOffset) { - this.xOffset = xOffset; - this.yOffset = yOffset; - this.overlayRenderer.setDisplayOffset(xOffset, yOffset); - this.renderer.setDisplayOffset(xOffset, yOffset); - this.layersAboveRenderer.setDisplayOffset(xOffset, yOffset); - this.layersBelowRenderer.setDisplayOffset(xOffset, yOffset); + ns.DrawingController.prototype.setOffset = function (x, y) { + this.compositeRenderer.setOffset(x, y); + pskl.app.minimapController.onDrawingControllerMove_(); }; })(); \ No newline at end of file diff --git a/zoom/js/controller/MinimapController.js b/zoom/js/controller/MinimapController.js new file mode 100644 index 00000000..8128790b --- /dev/null +++ b/zoom/js/controller/MinimapController.js @@ -0,0 +1,85 @@ +(function () { + var ns = $.namespace('pskl.controller'); + + ns.MinimapController = function (piskelController, animationController, drawingController, container) { + this.piskelController = piskelController; + this.animationController = animationController; + this.drawingController = drawingController; + this.container = container; + + this.isClicked = false; + }; + + ns.MinimapController.prototype.init = function () { + this.cropFrame = document.createElement('DIV'); + this.cropFrame.className = 'minimap-crop-frame'; + this.cropFrame.style.display = 'none'; + $(this.container).mousedown(this.onMinimapMousedown_.bind(this)); + $(this.container).mousemove(this.onMinimapMousemove_.bind(this)); + $(this.container).mouseup(this.onMinimapMouseup_.bind(this)); + $(this.container).append(this.cropFrame); + }; + + ns.MinimapController.prototype.onDrawingControllerMove_ = function () { + var zoomRatio = this.getDrawingAreaZoomRatio_(); + if (zoomRatio > 1) { + this.displayCropFrame_(zoomRatio, this.drawingController.getRenderer().getOffset()); + } else { + this.hideCropFrame_(); + } + }; + + ns.MinimapController.prototype.displayCropFrame_ = function (ratio, offset) { + this.cropFrame.style.display = 'block'; + this.cropFrame.style.top = (offset.y * this.animationController.renderer.getZoom()) + 'px'; + this.cropFrame.style.left = (offset.x * this.animationController.renderer.getZoom()) + 'px'; + var zoomRatio = this.getDrawingAreaZoomRatio_(); + this.cropFrame.style.width = (this.container.width() / zoomRatio) + 'px'; + this.cropFrame.style.height = (this.container.height() / zoomRatio) + 'px'; + + }; + + ns.MinimapController.prototype.hideCropFrame_ = function () { + this.cropFrame.style.display = 'none'; + }; + + ns.MinimapController.prototype.onMinimapMousemove_ = function (evt) { + if (this.isClicked) { + if (this.getDrawingAreaZoomRatio_() > 1) { + var coords = this.getCoordinatesCenteredAround_(evt.clientX, evt.clientY); + this.drawingController.setOffset(coords.x, coords.y); + } + } + }; + + ns.MinimapController.prototype.onMinimapMousedown_ = function (evt) { + this.isClicked = true; + }; + + ns.MinimapController.prototype.onMinimapMouseup_ = function (evt) { + this.isClicked = false; + }; + + ns.MinimapController.prototype.getCoordinatesCenteredAround_ = function (x, y) { + var frameCoords = this.animationController.renderer.getCoordinates(x, y); + var zoomRatio = this.getDrawingAreaZoomRatio_(); + var frameWidth = this.piskelController.getCurrentFrame().getWidth(); + var frameHeight = this.piskelController.getCurrentFrame().getHeight(); + + var width = frameWidth / zoomRatio; + var height = frameHeight / zoomRatio; + + return { + x : frameCoords.x - (width/2), + y : frameCoords.y - (height/2) + }; + }; + + ns.MinimapController.prototype.getDrawingAreaZoomRatio_ = function () { + var drawingAreaZoom = this.drawingController.getRenderer().getZoom(); + var drawingAreaFullHeight = this.piskelController.getCurrentFrame().getHeight() * drawingAreaZoom; + var zoomRatio = drawingAreaFullHeight / this.drawingController.getRenderer().getDisplaySize().height; + + return zoomRatio; + }; +})(); \ No newline at end of file diff --git a/zoom/js/controller/PreviewFilmController.js b/zoom/js/controller/PreviewFilmController.js index c231adbb..64aa1925 100644 --- a/zoom/js/controller/PreviewFilmController.js +++ b/zoom/js/controller/PreviewFilmController.js @@ -155,10 +155,10 @@ // is to make this update function (#createPreviewTile) less aggressive. var renderingOptions = { "zoom" : this.zoom, - "height" : "auto", - "width" : "auto" + "height" : this.piskelController.getCurrentFrame().getHeight() * this.zoom, + "width" : this.piskelController.getCurrentFrame().getWidth() * this.zoom }; - var currentFrameRenderer = new pskl.rendering.FrameRenderer($(canvasContainer), renderingOptions, ["tile-view"]); + var currentFrameRenderer = new pskl.rendering.frame.FrameRenderer($(canvasContainer), renderingOptions, ["tile-view"]); currentFrameRenderer.render(currentFrame); previewTileRoot.appendChild(canvasContainer); diff --git a/zoom/js/controller/settings/ApplicationSettingsController.js b/zoom/js/controller/settings/ApplicationSettingsController.js index 7329b596..27183642 100644 --- a/zoom/js/controller/settings/ApplicationSettingsController.js +++ b/zoom/js/controller/settings/ApplicationSettingsController.js @@ -1,6 +1,6 @@ (function () { var ns = $.namespace("pskl.controller.settings"); - + ns.ApplicationSettingsController = function () {}; /** @@ -18,21 +18,26 @@ $('#show-grid').prop('checked', show_grid); // Handle grid display changes: - $('#show-grid').change($.proxy(function(evt) { - var checked = $('#show-grid').prop('checked'); - pskl.UserSettings.set(pskl.UserSettings.SHOW_GRID, checked); - }, this)); + $('#show-grid').change(this.onShowGridClick.bind(this)); // Handle canvas background changes: - $('#background-picker-wrapper').click(function(evt) { - var target = $(evt.target).closest('.background-picker'); - if (target.length) { - var backgroundClass = target.data('background-class'); - pskl.UserSettings.set(pskl.UserSettings.CANVAS_BACKGROUND, backgroundClass); - - $('.background-picker').removeClass('selected'); - target.addClass('selected'); - } - }); + $('#background-picker-wrapper').click(this.onBackgroundClick.bind(this)); }; + + ns.ApplicationSettingsController.prototype.onShowGridClick = function (evt) { + var checked = $('#show-grid').prop('checked'); + pskl.UserSettings.set(pskl.UserSettings.SHOW_GRID, checked); + }; + + ns.ApplicationSettingsController.prototype.onBackgroundClick = function (evt) { + var target = $(evt.target).closest('.background-picker'); + if (target.length) { + var backgroundClass = target.data('background-class'); + pskl.UserSettings.set(pskl.UserSettings.CANVAS_BACKGROUND, backgroundClass); + + $('.background-picker').removeClass('selected'); + target.addClass('selected'); + } + }; + })(); \ No newline at end of file diff --git a/zoom/js/rendering/AbstractRenderer.js b/zoom/js/rendering/AbstractRenderer.js new file mode 100644 index 00000000..a3539402 --- /dev/null +++ b/zoom/js/rendering/AbstractRenderer.js @@ -0,0 +1,22 @@ +(function () { + var ns = $.namespace('pskl.rendering'); + + ns.AbstractRenderer = function () {}; + + ns.AbstractRenderer.prototype.clear = function () {throw 'abstract method should be implemented';}; + + ns.AbstractRenderer.prototype.getCoordinates = function (x, y) {throw 'abstract method should be implemented';}; + + ns.AbstractRenderer.prototype.setGridEnabled = function (b) {throw 'abstract method should be implemented';}; + ns.AbstractRenderer.prototype.isGridEnabled = function () {throw 'abstract method should be implemented';}; + + ns.AbstractRenderer.prototype.setZoom = function (zoom) {throw 'abstract method should be implemented';}; + ns.AbstractRenderer.prototype.getZoom = function () {throw 'abstract method should be implemented';}; + + ns.AbstractRenderer.prototype.moveOffset = function (x, y) {throw 'abstract method should be implemented';}; + ns.AbstractRenderer.prototype.setOffset = function (x, y) {throw 'abstract method should be implemented';}; + ns.AbstractRenderer.prototype.getOffset = function () {throw 'abstract method should be implemented';}; + + ns.AbstractRenderer.prototype.setDisplaySize = function (w, h) {throw 'abstract method should be implemented';}; + ns.AbstractRenderer.prototype.getDisplaySize = function () {throw 'abstract method should be implemented';}; +})(); \ No newline at end of file diff --git a/zoom/js/rendering/CompositeRenderer.js b/zoom/js/rendering/CompositeRenderer.js new file mode 100644 index 00000000..d5a770f4 --- /dev/null +++ b/zoom/js/rendering/CompositeRenderer.js @@ -0,0 +1,75 @@ +(function () { + var ns = $.namespace('pskl.rendering'); + + ns.CompositeRenderer = function () { + this.renderers = []; + }; + + pskl.utils.inherit(pskl.rendering.CompositeRenderer, pskl.rendering.AbstractRenderer); + + ns.CompositeRenderer.prototype.add = function (renderer) { + this.renderers.push(renderer); + return this; + }; + + ns.CompositeRenderer.prototype.clear = function () { + this.renderers.forEach(function (renderer) { + renderer.clear(); + }); + }; + + ns.CompositeRenderer.prototype.setZoom = function (zoom) { + this.renderers.forEach(function (renderer) { + renderer.setZoom(zoom); + }); + }; + + ns.CompositeRenderer.prototype.getZoom = function () { + return this.getSampleRenderer_().getZoom(); + }; + + ns.CompositeRenderer.prototype.setDisplaySize = function (w, h) { + this.renderers.forEach(function (renderer) { + renderer.setDisplaySize(w, h); + }); + }; + + ns.CompositeRenderer.prototype.getDisplaySize = function () { + return this.getSampleRenderer_().getDisplaySize(); + }; + + ns.CompositeRenderer.prototype.moveOffset = function (x, y) { + this.renderers.forEach(function (renderer) { + renderer.moveOffset(x, y); + }); + }; + + ns.CompositeRenderer.prototype.setOffset = function (x, y) { + this.renderers.forEach(function (renderer) { + renderer.setOffset(x, y); + }); + }; + + ns.CompositeRenderer.prototype.getOffset = function () { + return this.getSampleRenderer_().getOffset(); + }; + + + ns.CompositeRenderer.prototype.setGridEnabled = function (b) { + this.renderers.forEach(function (renderer) { + renderer.setGridEnabled(b); + }); + }; + + ns.CompositeRenderer.prototype.isGridEnabled = function () { + return this.getSampleRenderer_().isGridEnabled(); + }; + + ns.CompositeRenderer.prototype.getSampleRenderer_ = function () { + if (this.renderers.length > 0) { + return this.renderers[0]; + } else { + throw 'Renderer manager is empty'; + } + }; +})(); \ No newline at end of file diff --git a/zoom/js/rendering/frame/CachedFrameRenderer.js b/zoom/js/rendering/frame/CachedFrameRenderer.js new file mode 100644 index 00000000..819f66ea --- /dev/null +++ b/zoom/js/rendering/frame/CachedFrameRenderer.js @@ -0,0 +1,26 @@ +(function () { + var ns = $.namespace('pskl.rendering.frame'); + + /** + * FrameRenderer implementation that prevents unnecessary redraws. + * @param {HtmlElement} container HtmlElement to use as parentNode of the Frame + * @param {Object} renderingOptions + * @param {Array} classes array of strings to use for css classes + */ + ns.CachedFrameRenderer = function (container, renderingOptions, classes) { + pskl.rendering.frame.FrameRenderer.call(this, container, renderingOptions, classes); + this.serializedFrame = ''; + }; + + pskl.utils.inherit(pskl.rendering.frame.CachedFrameRenderer, pskl.rendering.frame.FrameRenderer); + + ns.CachedFrameRenderer.prototype.render = function (frame) { + var offset = this.getOffset(); + var size = this.getDisplaySize(); + var serializedFrame = [this.getZoom(), offset.x, offset.y, size.width, size.height, frame.serialize()].join('-'); + if (this.serializedFrame != serializedFrame) { + this.serializedFrame = serializedFrame; + this.superclass.render.call(this, frame); + } + }; +})(); diff --git a/zoom/js/rendering/frame/FrameRenderer.js b/zoom/js/rendering/frame/FrameRenderer.js new file mode 100644 index 00000000..9d3bb57d --- /dev/null +++ b/zoom/js/rendering/frame/FrameRenderer.js @@ -0,0 +1,243 @@ +(function () { + var ns = $.namespace("pskl.rendering.frame"); + + /** + * FrameRenderer will display a given frame inside a canvas element. + * @param {HtmlElement} container HtmlElement to use as parentNode of the Frame + * @param {Object} renderingOptions + * @param {Array} classes array of strings to use for css classes + */ + ns.FrameRenderer = function (container, renderingOptions, classes) { + this.defaultRenderingOptions = { + 'supportGridRendering' : false, + 'zoom' : 1 + }; + + renderingOptions = $.extend(true, {}, this.defaultRenderingOptions, renderingOptions); + + if(container === undefined) { + throw 'Bad FrameRenderer initialization. undefined.'; + } + + if(isNaN(renderingOptions.zoom)) { + throw 'Bad FrameRenderer initialization. not well defined.'; + } + + this.container = container; + + this.zoom = renderingOptions.zoom; + + this.offset = { + x : 0, + y : 0 + }; + + this.margin = { + x : 0, + y : 0 + }; + + this.supportGridRendering = renderingOptions.supportGridRendering; + + this.classes = classes || []; + this.classes.push('canvas'); + + /** + * Off dom canvas, will be used to draw the frame at 1:1 ratio + * @type {HTMLElement} + */ + this.canvas = null; + + /** + * Displayed canvas, scaled-up from the offdom canvas + * @type {HTMLElement} + */ + this.displayCanvas = null; + this.setDisplaySize(renderingOptions.width, renderingOptions.height); + + this.setGridEnabled(pskl.UserSettings.get(pskl.UserSettings.SHOW_GRID)); + + this.updateBackgroundClass_(pskl.UserSettings.get(pskl.UserSettings.CANVAS_BACKGROUND)); + $.subscribe(Events.USER_SETTINGS_CHANGED, $.proxy(this.onUserSettingsChange_, this)); + }; + + pskl.utils.inherit(pskl.rendering.frame.FrameRenderer, pskl.rendering.AbstractRenderer); + + ns.FrameRenderer.prototype.render = function (frame) { + if (frame) { + this.clear(); + this.renderFrame_(frame); + } + }; + + ns.FrameRenderer.prototype.clear = function () { + pskl.CanvasUtils.clear(this.canvas); + pskl.CanvasUtils.clear(this.displayCanvas); + }; + + ns.FrameRenderer.prototype.setZoom = function (zoom) { + // back up center coordinates + var centerX = this.offset.x + (this.displayWidth/(2*this.zoom)); + var centerY = this.offset.y + (this.displayHeight/(2*this.zoom)); + + this.zoom = Math.max(1, zoom); + + // recenter + this.setOffset( + centerX - (this.displayWidth/(2*this.zoom)), + centerY - (this.displayHeight/(2*this.zoom)) + ); + }; + + ns.FrameRenderer.prototype.getZoom = function () { + return this.zoom; + }; + + ns.FrameRenderer.prototype.setDisplaySize = function (width, height) { + this.displayWidth = width; + this.displayHeight = height; + if (this.displayCanvas) { + $(this.displayCanvas).remove(); + this.displayCanvas = null; + } + this.createDisplayCanvas_(); + }; + + ns.FrameRenderer.prototype.getDisplaySize = function () { + return { + height : this.displayHeight, + width : this.displayWidth + }; + }; + + ns.FrameRenderer.prototype.getOffset = function () { + return { + x : this.offset.x, + y : this.offset.y + }; + }, + + ns.FrameRenderer.prototype.moveOffset = function (x, y) { + this.setOffset(this.offset.x + x, this.offset.y + y); + }; + + ns.FrameRenderer.prototype.setOffset = function (x, y) { + // TODO : provide frame size information to the FrameRenderer constructor + // here I first need to verify I have a 'canvas' which I can use to infer the frame information + // and then perform my boundaries checking. This sucks + if (this.canvas) { + var maxX = this.canvas.width - (this.displayWidth/this.zoom); + x = pskl.utils.Math.minmax(x, 0, maxX); + var maxY = this.canvas.height - (this.displayHeight/this.zoom); + y = pskl.utils.Math.minmax(y, 0, maxY); + } + this.offset.x = x; + this.offset.y = y; + }; + + ns.FrameRenderer.prototype.setGridEnabled = function (flag) { + this.gridStrokeWidth = (flag && this.supportGridRendering) ? Constants.GRID_STROKE_WIDTH : 0; + this.canvasConfigDirty = true; + }; + + ns.FrameRenderer.prototype.updateMargins_ = function () { + var deltaX = this.displayWidth - (this.zoom * this.canvas.width); + this.margin.x = Math.max(0, deltaX) / 2; + + var deltaY = this.displayHeight - (this.zoom * this.canvas.height); + this.margin.y = Math.max(0, deltaY) / 2; + }; + + ns.FrameRenderer.prototype.createDisplayCanvas_ = function () { + var height = this.displayHeight; + var width = this.displayWidth; + + this.displayCanvas = pskl.CanvasUtils.createCanvas(width, height, this.classes); + if (true || this.zoom > 2) { + pskl.CanvasUtils.disableImageSmoothing(this.displayCanvas); + } + this.container.append(this.displayCanvas); + }; + + ns.FrameRenderer.prototype.onUserSettingsChange_ = function (evt, settingName, settingValue) { + if(settingName == pskl.UserSettings.SHOW_GRID) { + this.setGridEnabled(settingValue); + } else if (settingName == pskl.UserSettings.CANVAS_BACKGROUND) { + this.updateBackgroundClass_(settingValue); + } + }; + + ns.FrameRenderer.prototype.updateBackgroundClass_ = function (newClass) { + var currentClass = this.container.data('current-background-class'); + if (currentClass) { + this.container.removeClass(currentClass); + } + this.container.addClass(newClass); + this.container.data('current-background-class', newClass); + }; + + ns.FrameRenderer.prototype.renderPixel_ = function (color, x, y, context) { + if(color != Constants.TRANSPARENT_COLOR) { + context.fillStyle = color; + context.fillRect(x, y, 1, 1); + } + }; + + /** + * Transform a screen pixel-based coordinate (relative to the top-left corner of the rendered + * frame) into a sprite coordinate in column and row. + * @public + */ + ns.FrameRenderer.prototype.getCoordinates = function(x, y) { + var containerOffset = this.container.offset(); + x = x - containerOffset.left; + y = y - containerOffset.top; + + // apply margins + x = x - this.margin.x; + y = y - this.margin.y; + + var cellSize = this.zoom + this.gridStrokeWidth; + // apply frame offset + x = x + this.offset.x * cellSize; + y = y + this.offset.y * cellSize; + + return { + x : (x / cellSize) | 0, + y : (y / cellSize) | 0 + }; + }; + + /** + * @private + */ + ns.FrameRenderer.prototype.renderFrame_ = function (frame) { + if (!this.canvas) { + this.canvas = pskl.CanvasUtils.createCanvas(frame.getWidth(), frame.getHeight()); + } + + var context = this.canvas.getContext('2d'); + for(var x = 0, width = frame.getWidth(); x < width; x++) { + for(var y = 0, height = frame.getHeight(); y < height; y++) { + var color = frame.getPixel(x, y); + this.renderPixel_(color, x, y, context); + } + } + + this.updateMargins_(); + + context = this.displayCanvas.getContext('2d'); + context.save(); + // zoom < 1 + context.fillStyle = "#aaa"; + // zoom < 1 + context.fillRect(0,0,this.displayCanvas.width, this.displayCanvas.height); + context.translate(this.margin.x, this.margin.y); + context.scale(this.zoom, this.zoom); + context.translate(-this.offset.x, -this.offset.y); + // zoom < 1 + context.clearRect(0, 0, this.canvas.width, this.canvas.height); + context.drawImage(this.canvas, 0, 0); + context.restore(); + }; +})(); \ No newline at end of file diff --git a/zoom/js/rendering/layer/LayersRenderer.js b/zoom/js/rendering/layer/LayersRenderer.js new file mode 100644 index 00000000..12c8b38d --- /dev/null +++ b/zoom/js/rendering/layer/LayersRenderer.js @@ -0,0 +1,58 @@ +(function () { + var ns = $.namespace('pskl.rendering.layer'); + + ns.LayersRenderer = function (container, renderingOptions, piskelController) { + pskl.rendering.CompositeRenderer.call(this); + + this.piskelController = piskelController; + + this.belowRenderer = new pskl.rendering.frame.CachedFrameRenderer(container, renderingOptions, ["layers-canvas", "layers-below-canvas"]); + this.aboveRenderer = new pskl.rendering.frame.CachedFrameRenderer(container, renderingOptions, ["layers-canvas", "layers-above-canvas"]); + + this.add(this.belowRenderer); + this.add(this.aboveRenderer); + + this.serializedRendering = ''; + }; + + pskl.utils.inherit(pskl.rendering.layer.LayersRenderer, pskl.rendering.CompositeRenderer); + + ns.LayersRenderer.prototype.render = function () { + var layers = this.piskelController.getLayers(); + var currentFrameIndex = this.piskelController.currentFrameIndex; + var currentLayerIndex = this.piskelController.currentLayerIndex; + + var serializedRendering = [ + this.getZoom(), + currentFrameIndex, + currentLayerIndex, + layers.length + ].join("-"); + + if (this.serializedRendering != serializedRendering) { + this.serializedRendering = serializedRendering; + + this.clear(); + + var downLayers = layers.slice(0, currentLayerIndex); + if (downLayers.length > 0) { + var downFrame = this.getFrameForLayersAt_(currentFrameIndex, downLayers); + this.belowRenderer.render(downFrame); + } + + var upLayers = layers.slice(currentLayerIndex + 1, layers.length); + if (upLayers.length > 0) { + var upFrame = this.getFrameForLayersAt_(currentFrameIndex, upLayers); + this.aboveRenderer.render(upFrame); + } + + } + }; + + ns.LayersRenderer.prototype.getFrameForLayersAt_ = function (frameIndex, layers) { + var frames = layers.map(function (l) { + return l.getFrameAt(frameIndex); + }); + return pskl.utils.FrameUtils.merge(frames); + }; +})(); diff --git a/zoom/js/utils/FrameUtils.js b/zoom/js/utils/FrameUtils.js index cb615527..b28d154d 100644 --- a/zoom/js/utils/FrameUtils.js +++ b/zoom/js/utils/FrameUtils.js @@ -1,6 +1,6 @@ (function () { var ns = $.namespace('pskl.utils'); - + var colorCache = {}; ns.FrameUtils = { merge : function (frames) { var merged = null; @@ -20,6 +20,77 @@ frameA.setPixel(col, row, p); } }); + }, + + /** + * Alpha compositing using porter duff algorithm : + * http://en.wikipedia.org/wiki/Alpha_compositing + * http://keithp.com/~keithp/porterduff/p253-porter.pdf + * @param {String} strColor1 color over + * @param {String} strColor2 color under + * @return {String} the composite color + */ + mergePixels : function (strColor1, strColor2, globalOpacity1) { + var col1 = pskl.utils.FrameUtils.toRgba(strColor1); + var col2 = pskl.utils.FrameUtils.toRgba(strColor2); + if (typeof globalOpacity1 == 'number') { + col1 = JSON.parse(JSON.stringify(col1)); + col1.a = globalOpacity1 * col1.a; + } + var a = col1.a + col2.a * (1 - col1.a); + + var r = ((col1.r * col1.a + col2.r * col2.a * (1 - col1.a)) / a)|0; + var g = ((col1.g * col1.a + col2.g * col2.a * (1 - col1.a)) / a)|0; + var b = ((col1.b * col1.a + col2.b * col2.a * (1 - col1.a)) / a)|0; + + return 'rgba('+r+','+g+','+b+','+a+')'; + }, + + /** + * Convert a color defined as a string (hex, rgba, rgb, 'TRANSPARENT') to an Object with r,g,b,a properties. + * r, g and b are integers between 0 and 255, a is a float between 0 and 1 + * @param {String} c color as a string + * @return {Object} {r:Number,g:Number,b:Number,a:Number} + */ + toRgba : function (c) { + if (colorCache[c]) { + return colorCache[c]; + } + var color, matches; + if (c === 'TRANSPARENT') { + color = { + r : 0, + g : 0, + b : 0, + a : 0 + }; + } else if (c.indexOf('rgba(') != -1) { + matches = /rgba\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(1|0\.\d+)\s*\)/.exec(c); + color = { + r : parseInt(matches[1],10), + g : parseInt(matches[2],10), + b : parseInt(matches[3],10), + a : parseFloat(matches[4]) + }; + } else if (c.indexOf('rgb(') != -1) { + matches = /rgb\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/.exec(c); + color = { + r : parseInt(matches[1],10), + g : parseInt(matches[2],10), + b : parseInt(matches[3],10), + a : 1 + }; + } else { + matches = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(c); + color = { + r : parseInt(matches[1], 16), + g : parseInt(matches[2], 16), + b : parseInt(matches[3], 16), + a : 1 + }; + } + colorCache[c] = color; + return color; } }; -})(); \ No newline at end of file +})(); diff --git a/zoom/js/utils/Math.js b/zoom/js/utils/Math.js new file mode 100644 index 00000000..b333a333 --- /dev/null +++ b/zoom/js/utils/Math.js @@ -0,0 +1,9 @@ +(function () { + var ns = $.namespace('pskl.utils'); + + ns.Math = { + minmax : function (val, min, max) { + return Math.max(Math.min(val, max), min); + } + }; +})(); \ No newline at end of file diff --git a/zoom/piskel-script-list.js b/zoom/piskel-script-list.js index a35ebdcf..9f3288d8 100644 --- a/zoom/piskel-script-list.js +++ b/zoom/piskel-script-list.js @@ -14,6 +14,7 @@ exports.scripts = [ // Libraries "js/utils/core.js", "js/utils/CanvasUtils.js", + "js/utils/Math.js", "js/utils/FrameUtils.js", "js/utils/PixelUtils.js", "js/utils/Serializer.js", @@ -36,8 +37,12 @@ exports.scripts = [ "js/selection/ShapeSelection.js", // Rendering + "js/rendering/AbstractRenderer.js", + "js/rendering/CompositeRenderer.js", + "js/rendering/layer/LayersRenderer.js", + "js/rendering/frame/FrameRenderer.js", + "js/rendering/frame/CachedFrameRenderer.js", "js/rendering/CanvasRenderer.js", - "js/rendering/FrameRenderer.js", "js/rendering/SpritesheetRenderer.js", // Controllers @@ -46,6 +51,7 @@ exports.scripts = [ "js/controller/PreviewFilmController.js", "js/controller/LayersListController.js", "js/controller/AnimatedPreviewController.js", + "js/controller/MinimapController.js", "js/controller/ToolController.js", "js/controller/PaletteController.js", "js/controller/NotificationController.js",