var $_={empty:function(){},fn:function(A){return function(){return A}},merge:function(){var E={};for(var D=0,A=arguments.length;D<A;D++){var B=arguments[D];if(typeof B!="object"){continue}for(var C in B){var G=B[C],F=E[C];E[C]=(F&&typeof G=="object"&&typeof F=="object")?this.merge(F,G):this.unlink(G)}}return E},unlink:function(C){var B=null;if(this.isArray(C)){B=[];for(var D=0,A=C.length;D<A;D++){B[D]=this.unlink(C[D])}}else{if(this.isObject(C)){B={};for(var E in C){B[E]=this.unlink(C[E])}}else{return C}}return B},isArray:function(A){return A&&A.constructor&&A.constructor.toString().match(/array/i)},isString:function(A){return A&&A.constructor&&A.constructor.toString().match(/string/i)},isObject:function(A){return A&&A.constructor&&A.constructor.toString().match(/object/i)}};var Canvas=(function(){var K,G,A,J,B,I;var E={injectInto:"id",width:200,height:200,backgroundColor:"#333333",styles:{fillStyle:"#000000",strokeStyle:"#000000"},backgroundCanvas:false};function D(){D.t=D.t||typeof(HTMLCanvasElement);return"function"==D.t||"object"==D.t}function F(L,O,N){var M=document.createElement(L);(function(Q,R){if(R){for(var P in R){Q[P]=R[P]}}return arguments.callee})(M,O)(M.style,N);if(L=="canvas"&&!D()&&G_vmlCanvasManager){M=G_vmlCanvasManager.initElement(document.body.appendChild(M))}return M}function C(L){return document.getElementById(L)}function H(O,N,M,Q){var P=M?(M-O.width):O.width;var L=Q?(Q-O.height):O.height;N.translate(P/2,L/2)}return function(L,N){if(arguments.length<1){throw"Arguments missing"}var M=L+"-label",R=L+"-canvas",O=L+"-bkcanvas";N=$_.merge(E,N||{});var P={width:N.width,height:N.height};A=F("div",{id:L},$_.merge(P,{position:"relative"}));J=F("div",{id:M},{overflow:"visible",position:"absolute",top:0,left:0,width:P.width+"px",height:0});var S={position:"absolute",top:0,left:0,width:P.width+"px",height:P.height+"px"};B=F("canvas",$_.merge({id:R},P),S);var Q=N.backgroundCanvas;if(Q){I=F("canvas",$_.merge({id:O},P),S);A.appendChild(I)}A.appendChild(B);A.appendChild(J);C(N.injectInto).appendChild(A);K=B.getContext("2d");H(B,K);var T=N.styles;for(var U in T){K[U]=T[U]}if(Q){G=I.getContext("2d");var T=Q.styles;for(var U in T){G[U]=T[U]}H(I,G);Q.impl.init(I,G);Q.impl.plot(I,G)}return{id:L,getCtx:function(){return K},getElement:function(){return A},resize:function(W,V){(function(Y,X){H(Y,X,W,V);Y.width=W;Y.height=V;return arguments.callee})(B,K)(I,G)},getSize:function(){return{width:B.width,height:B.height}},path:function(V,W){K.beginPath();W(K);K[V]();K.closePath()},clear:function(){var V=this.getSize();K.clearRect(-V.width/2,-V.height/2,V.width,V.height)},clearRectangle:function(Z,X,W,Y){if(!D()){var V=K.fillStyle;K.fillStyle=N.backgroundColor;K.fillRect(Y,Z,X-Y,W-Z);K.fillStyle=V}else{K.clearRect(Y,Z-2,X-Y+2,Math.abs(W-Z)+5)}},makeRect:function(W,V){if(V=="fill"||V=="stroke"){K[V+"Rect"](W.x1,W.y1,W.x2,W.y2)}else{throw"parameter not recognized "+V}}}}})();var Config={orientation:"left",labelContainer:"label_container",levelsToShow:2,offsetBase:8,Label:{height:26,realHeight:20,width:95,realWidth:90,offsetHeight:30,offsetWidth:30},Node:{mode:"fill"},animationTime:700,fps:25};var Complex=function(){this.x=arguments[0]||0;this.y=arguments[1]||0};Complex.prototype={clone:function(){return new Complex(this.x,this.y)},norm:function(){return Math.sqrt(this.squaredNorm())},squaredNorm:function(){return this.x*this.x+this.y*this.y},add:function(A){return new Complex(this.x+A.x,this.y+A.y)},prod:function(A){return new Complex(this.x*A.x-this.y*A.y,this.y*A.x+this.x*A.y)},conjugate:function(){return new Complex(this.x,-this.y)},scale:function(A){return new Complex(this.x*A,this.y*A)},$add:function(A){this.x+=A.x;this.y+=A.y;return this},$prod:function(C){var A=this.x,B=this.y;this.x=A*C.x-B*C.y;this.y=B*C.x+A*C.y;return this},$conjugate:function(){this.y=-this.y;return this},$scale:function(A){this.x*=A;this.y*=A;return this},$div:function(D){var A=this.x,C=this.y;var B=D.squaredNorm();this.x=A*D.x+C*D.y;this.y=C*D.x-A*D.y;return this.$scale(1/B)}};var Tree=function(A){(function(C,D){Tree.Node(C,D);for(var B=0;B<C.children.length;B++){arguments.callee(C.children[B],C)}})(A,null)};Tree.Node=function(A,B){A.selected=false;A.drawn=false;A.exist=false;A._parent=B;A.pos=new Complex(0,0);A.startPos=new Complex(0,0);A.endPos=new Complex(0,0);A.startAlpha=1;A.endAlpha=1;A.alpha=1};Tree.Util={set:function(A,C,D){if(typeof C=="object"){for(var E in C){A[E]=C[E]}}else{if(typeof C=="array"){for(var B=0;B<C.length;B++){A[C[B]]=D}}else{A[C]=D}}},addSubtree:function(A,D,C){var B=this.getSubtree(A,D);Tree(C);if(D==C.id){B.children=B.children.concat(C.children);Tree.Children.each(B,function(E){E._parent=B})}else{B.children.push(C);C._parent=B}return C},removeSubtree:function(A,F,B){var C=this.getSubtree(A,F);var D=C._parent;if(!B){delete C.children;C.children=[]}else{var E=new Array();Tree.Children.each(D,function(G){if(F!=G.id){E.push(G)}});D.children=E}},each:function(A,B){this.eachLevel(A,0,Number.MAX_VALUE,B)},eachLevel:function(A,B,C,F){if(B<=C){F(A,B);for(var D=0,E=A.children;D<E.length;D++){this.eachLevel(E[D],B+1,C,F)}}},atLevel:function(A,C,B){this.eachLevel(A,0,C,function(E,D){if(D==C){B(E)}})},getLevel:function(A){var B=function(C,D){if(C._parent==null){return D}else{return B(C._parent,D+1)}};return B(A,0)},getRoot:function(A){if(A._parent==null){return A}return this.getRoot(A._parent)},getLeaves:function(A){var B=new Array();this.eachLevel(A,0,Config.levelsToShow,function(D,C){if(D.drawn&&!Tree.Children.children(D,"exist")){B.push(D);D._level=Config.levelsToShow-C}});return B},getSubtree:function(A,C){var B=null;this.each(A,function(D){if(D.id==C){B=D}});return B}};Tree.Children={each:function(A,D){for(var B=0,C=A.children;B<C.length;B++){D(C[B])}},children:function(A,D){for(var B=0,C=A.children;B<C.length;B++){if(!D||C[B][D]){return true}}return false},getChildren:function(A,E){for(var C=0,B=new Array(),D=A.children;C<D.length;C++){if(!E||D[C][E]){B.push(D[C])}}return B},getLength:function(A,E){if(!E){return A.children.length}for(var C=0,B=0,D=A.children;C<D.length;C++){if(D[C][E]){B++}}return B}};Tree.Group={requestNodes:function(E,D){var C=0,A=E.length,G={};var B=function(){D.onComplete()};if(A==0){B()}for(var F=0;F<A;F++){G[E[F].id]=E[F];D.request(E[F].id,E[F]._level,{onComplete:function(K,J){if(J&&J.children){Tree(J);for(var H=0,I=J.children;H<I.length;H++){I[H]._parent=G[K]}G[K].children=J.children}if(++C==A){B()}}})}},hide:function(C,D,B){C=this.getNodesWithChildren(C);var A=D.getCtx();for(var E=0;E<C.length;E++){Tree.Children.each(C[E],function(G){Tree.Plot.hideLabels(G,true)})}A.save();var F={compute:function(J){for(var G=0;G<C.length;G++){A.save();var H=C[G];var I=Tree.Geometry.getBoundingBox(H);D.clearRectangle(I.top,I.right,I.bottom,I.left);if(J==1){J=0.99}Tree.Plot.plot({tree:H,canvas:D},B,1-J);A.restore()}},complete:function(){A.restore();for(var G=0;G<C.length;G++){if(!B||!B.request){if(Tree.Children.children(C[G],"exist")){Tree.Util.each(C[G],function(H){Tree.Util.set(H,{drawn:false,exist:false})});Tree.Util.set(C[G],{drawn:true,exist:true})}}else{delete C[G].children;C[G].children=[]}}B.onComplete()}};Animation.controller=F;Animation.start()},show:function(C,D,B){C=this.getNodesWithChildren(C),newNodes=new Array();var A=D.getCtx();for(var E=0;E<C.length;E++){if(!Tree.Children.children(C[E],"drawn")){newNodes.push(C[E]);Tree.Util.eachLevel(C[E],0,Config.levelsToShow,function(G){if(G.exist){G.drawn=true}})}}C=newNodes;A.save();var F={compute:function(J){for(var G=0;G<C.length;G++){A.save();var H=C[G];var I=Tree.Geometry.getBoundingBox(H);D.clearRectangle(I.top,I.right,I.bottom,I.left);Tree.Plot.plot({tree:H,canvas:D},B,J);A.restore()}},complete:function(){A.restore();for(var G=0;G<C.length;G++){var H=C[G];var I=Tree.Geometry.getBoundingBox(H);D.clearRectangle(I.top,I.right,I.bottom,I.left);Tree.Plot.plot({tree:H,canvas:D},B)}B.onComplete()}};Animation.controller=F;Animation.start()},getNodesWithChildren:function(B){var A=new Array();for(var C=0;C<B.length;C++){if(Tree.Children.children(B[C],"exist")){A.push(B[C])}}return A}};Tree.Plot={Interpolator:{linear:function(A,D){var C=A.startPos.clone();var B=A.endPos.clone();A.pos=(B.$add(C.scale(-1))).$scale(D).$add(C)},"fade:nodes":function(A,D){if(A.endAlpha!=A.alpha){var C=A.startAlpha;var B=A.endAlpha;A.alpha=C+(B-C)*D}},"fade:vertex":function(A,D){var C=A.adjacencies;for(var B in C){this["fade:nodes"](C[B],D)}}},plot:function(B,E,G){var A=B.tree,D=B.canvas;if(G>=0){A.drawn=false;var C=D.getCtx();var F=Tree.Geometry.getScaledTreePosition(A,G);C.translate(F.x,F.y);C.scale(G,G)}this.plotTree(B,!G,E);if(G>=0){A.drawn=true}},plotTree:function(B,E,F){var H=this,D=B.canvas,A=B.tree,C=D.getCtx();var G=Tree.Geometry.getEdge(A.pos,"begin");Tree.Children.each(A,function(K){if(K.exist){var I=Tree.Geometry.getEdge(K.pos,"end");if(K.drawn){var J={nodeFrom:A,nodeTo:K};F.onBeforePlotLine(J);C.globalAlpha=Math.min(A.alpha,K.alpha);H.plotEdge(G,I,D,A.selected&&K.selected);F.onAfterPlotLine(J)}H.plotTree({tree:K,canvas:D},E,F)}});if(A.drawn&&A.exist){C.globalAlpha=A.alpha;F.onBeforePlotNode(A);this.plotNode(A,D);F.onAfterPlotNode(A);if(E&&C.globalAlpha>=0.95){Tree.Label.plotOn(A,D)}else{Tree.Label.hide(A)}}},plotNode:function(B,A){this.plotNodeSquared(B,A)},plotNodeSquared:function(D,B){var F=D.pos,C=D.selected,A=Config.Label;var E={x1:F.x,y1:F.y-A.height+(A.height-A.realHeight)/2,x2:A.realWidth,y2:A.realHeight};B.makeRect(E,Config.Node.mode)},plotEdge:function(D,A,B,C){B.path("stroke",function(E){E.moveTo(D.x,D.y);E.lineTo(A.x,A.y)})},hideLabels:function(C,B){var A=Tree.Label;Tree.Util.each(C,function(D){if(B){A.hide(D)}else{A.show(D)}})},animate:function(J,A){var F=this,B=J.canvas,K=J.tree,H=Animation,E=A.duration||H.duration,C=A.fps||H.fps;var I=H.duration,D=H.fps;H.duration=E;H.fps=C;var G={compute:function(L){B.clear();Tree.Util.each(K,function(N){for(var M=0;M<A.modes.length;M++){F.Interpolator[A.modes[M]](N,L)}});F.plot(J,A)},complete:function(){Tree.Util.each(K,function(L){L.startPos=L.pos;L.startAlpha=L.alpha});H.duration=I;H.fps=D;A.onComplete()}};H.controller=G;H.start()}};Tree.Label={nodeHash:{},container:false,controller:null,chk:function(A){if(!(A.id in this.nodeHash)){this.init(A)}return this.nodeHash[A.id]},init:function(B){if(!(B.id in this.nodeHash)){if(!this.container){this.container=document.getElementById(Config.labelContainer)}var A=document.createElement("a");this.container.appendChild(A);this.controller.onCreateLabel(A,B);this.nodeHash[B.id]=A}this.setClass(B,"node hidden");this.setDimensions(B)},plotOn:function(B,A){var C=B.pos;if(this.fitsInCanvas(C,A)){this.setDivProperties(B,"node",A)}else{this.hide(B)}},fitsInCanvas:function(C,A){var B=A.getSize();return !(Math.abs(C.x+Config.Label.width/2)>=B.width/2||Math.abs(C.y)>=B.height/2)},setDivProperties:function(D,B,C){var A=C.getSize(),G=D.pos;var E={x:Math.round(G.x+A.width/2),y:Math.round(G.y+A.height/2-Config.Label.height)};var F=this.chk(D);F.style.top=E.y+"px";F.style.left=E.x+"px";this.removeClass(D,"hidden");this.setDimensions(D)},addClass:function(C,A){var B=this.chk(C);if(!this.hasClass(C,A)){var D=B.className.split(" ");D.push(A);B.className=D.join(" ")}},setDimensions:function(B){var A=this.chk(B);A.style.width=Config.Label.realWidth+"px";A.style.height=Config.Label.realHeight+"px";this.controller.onPlaceLabel(A,B)},removeClass:function(E,A){var D=this.chk(E);var F=D.className.split(" ");var B=false;for(var C=0;C<F.length&&!B;C++){if(F[C]==A){F.splice(C,1);B=true}}D.className=F.join(" ")},hasClass:function(C,A){var D=this.chk(C).className.split(" ");for(var B=0;B<D.length;B++){if(A==D[B]){return true}}return false},setClass:function(B,A){this.chk(B).className=A},hide:function(A){this.addClass(A,"hidden")},show:function(A){this.removeClass(A,"hidden")}};Tree.Geometry={dispatch:function(){var B=arguments,A=B.length,C=Config.orientation;var D=function(E){return typeof E=="function"?E():E};if(A==2){return(C=="top"||C=="bottom")?D(B[0]):D(B[1])}else{if(A==4){switch(C){case"top":return D(B[0]);case"right":return D(B[1]);case"bottom":return D(B[2]);case"left":return D(B[3])}}}},switchOrientation:function(){var A=arguments;if(A.length>0){Config.orientation=A[0]}else{var B=this.dispatch("bottom","top","left","right");Config.orientation=B}},getSize:function(C){var A=Config.Label.width,B=Config.Label.height;if(!C){return this.dispatch(B,A)}else{return this.dispatch(A,B)}},getOffsetSize:function(){var A=Config.Label;return this.dispatch(A.offsetHeight,A.offsetWidth)},translate:function(A,C,B){Tree.Util.each(A,function(D){D[B].$add(C)})},getBoundingBox:function(A){var C=Config.Label,D=A.pos;var B={top:D.y,bottom:D.y,right:D.x,left:D.x};this.calculateCorners(A,B);return this.dispatch({left:B.left,bottom:B.bottom,top:B.top,right:B.right+C.width},{left:B.left,bottom:B.bottom,top:B.top-C.height,right:B.right-2},{left:B.left,bottom:B.bottom-C.height,top:B.top-C.height,right:B.right+C.width},{left:B.left+C.realWidth,bottom:B.bottom,top:B.top-C.height,right:B.right+C.width})},calculateCorners:function(A,B){var E=A.pos;if(A.exist){if(B.top>E.y){B.top=E.y}if(B.bottom<E.y){B.bottom=E.y}if(B.right<E.x){B.right=E.x}if(B.left>E.x){B.left=E.x}for(var C=0,D=A.children;C<D.length;C++){this.calculateCorners(D[C],B)}}},getBaseSize:function(A,B,D){var C=this.getSize(true);if(B){return(D=="available")?C:Tree.Children.getLength(A,"exist")*C+Config.offsetBase}return this.getTreeBaseSize(A,"expanded")},getTreeBaseSize:function(A,G,H){var E=this.getSize(true),C=function(I,K,J){return K==0||(J=="expanded")?Tree.Children.getLength(I,"exist")==0:I.children.length==0},H=(arguments.length==3)?H:Number.MAX_VALUE;if(C(A,H,G)){return E}for(var D=0,F=A.children,B=0;D<F.length;D++){B+=this.getTreeBaseSize(F[D],G,H-1)}return B+Config.offsetBase},getEdge:function(D,B){var C=Config.Label;var A=function(F,E){return function(){return D.add(new Complex(F,E))}};if(B=="begin"){return this.dispatch(A(C.realWidth/2,(C.realHeight-C.height)/2),A(0,-C.height/2),A(C.realWidth/2,-C.realHeight+(C.realHeight-C.height)/2),A(C.realWidth,-C.height/2))}else{if(B=="end"){return this.dispatch(A(C.realWidth/2,-C.realHeight),A(C.realWidth,-C.height/2),A(C.realWidth/2,(C.realHeight-C.height)/2),A(0,-C.height/2))}}},getScaledTreePosition:function(B,E){var D=Config.Label.width,A=Config.Label.height;var C=function(G,F){return function(){return B.pos.add(new Complex(G,F)).$scale(1-E)}};return this.dispatch(C(D/2,0),C(0,-A/2),C(D/2,-A),C(D,-A/2))},treeFitsInCanvas:function(A,B,F){var D=B.getSize();var C=this.dispatch(D.width,D.height);var E=this.getTreeBaseSize(A,"exist",F);return(E<C)},getFirstPos:function(F,A){var E=function(G,C){return function(){return new Complex(G,C)}};var D=this.getSize()+this.getOffsetSize();var B=-A/2+Config.offsetBase/2;return this.dispatch(E(F.x+B,F.y+D),E(F.x-D,F.y+B),E(F.x+B,F.y-D),E(F.x+D,F.y+B))},nextPosition:function(C,A){var B=function(E,D){return function(){return new Complex(E,D)}};return this.dispatch(B(C.x+A,C.y),B(C.x,C.y+A),B(C.x+A,C.y),B(C.x,C.y+A))},setRightLevelToShow:function(A,B){var C=this.getRightLevelToShow(A,B);Tree.Util.eachLevel(A,0,Config.levelsToShow,function(E,D){if(D>C){E.drawn=false;E.exist=false;Tree.Label.hide(E)}else{E.exist=true}});A.drawn=true},getRightLevelToShow:function(A,B){var C=Config.levelsToShow;while(!this.treeFitsInCanvas(A,B,C)&&C>1){C--}return C}};var ST=function(C,A){var B={onBeforeCompute:$_.empty,onAfterCompute:$_.empty,onCreateLabel:$_.empty,onPlaceLabel:$_.empty,onComplete:$_.empty,onBeforePlotNode:$_.empty,onAfterPlotNode:$_.empty,onBeforePlotLine:$_.empty,onAfterPlotLine:$_.empty,request:false};this.controller=$_.merge(B,A);this.canvas=C;this.tree=null;this.clickedNode=null;Tree.Label.controller=this.controller;Config.labelContainer=C.id+"-label";Animation.fps=Config.fps;Animation.duration=Config.animationTime};ST.prototype={loadFromJSON:function(A){this.tree=A;Tree(A)},compute:function(){Tree.Util.set(this.tree,{drawn:true,exist:true,selected:true});this.calculatePositions(this.tree,new Complex(0,0),"startPos")},calculatePositions:function(O,F,L,G){var C=Tree.Geometry,M=Tree.Children,G=(arguments.length==3)?true:G;if(this.clickedNode&&(O.id==this.clickedNode.id)&&G){G=false}O[L]=F;var A=Tree.Children.getChildren(O,"exist");if(A.length>0){var I=C.getBaseSize(O,G);var K=C.getBaseSize(A[0],G,"available");var D=(A.length==1)?Config.offsetBase:I-K;var B=A[0][L]=C.getFirstPos(F,D);this.calculatePositions(A[0],B,L,G);for(var H=1;H<A.length;H++){var J=!M.children(A[H],"exist")||!M.children(A[H-1],"exist");var N=C.getBaseSize(A[H],G,"available");var E=J?C.getSize(true):(K+N)/2;B=C.nextPosition(B,E);K=N;this.calculatePositions(A[H],B,L,G)}}},plot:function(){Tree.Plot.plot(this.tree,this.canvas,this.controller)},switchPosition:function(F,E){var B=Tree.Geometry,C=Tree.Plot,A=this.tree,D=this;if(!C.busy){C.busy=true;this.contract({onComplete:function(){B.switchOrientation(F);D.calculatePositions(A,new Complex(0,0),"endPos");C.busy=false;D.onClick(D.clickedNode.id,E)}},F)}},requestNodes:function(B,C){var A=$_.merge(this.controller,C);if(A.request){Tree.Group.requestNodes(Tree.Util.getLeaves(B),A)}else{A.onComplete()}},contract:function(D,C){var G=Config.orientation;var B=Tree.Geometry,H=Tree.Util,F=Tree.Group;var I=this.clickedNode;var E=function(J,L){var N=H.getLevel(J),K=H.getRoot(J),M=new Array();H.eachLevel(K,0,N,function(P,O){if(P.exist&&!P.selected){M.push(P)}});N=B.getRightLevelToShow(J,L);H.atLevel(J,N,function(P,O){if(P.exist){M.push(P)}});return M};if(C){B.switchOrientation(C)}var A=E(I,this.canvas);if(C){B.switchOrientation(G)}F.hide(A,this.canvas,$_.merge(this.controller,D))},move:function(A,B){this.calculatePositions(this.tree,new Complex(0,0),"endPos");Tree.Geometry.translate(this.tree,A.endPos.scale(-1),"endPos");Tree.Plot.animate(this,$_.merge(this.controller,B,{modes:["linear"]}))},expand:function(B,C){var A=new Array();Tree.Util.eachLevel(B,0,Config.levelsToShow,function(E,D){if(!Tree.Children.children(E,"drawn")){A.push(E)}});Tree.Group.show(A,this.canvas,$_.merge(this.controller,C))},selectPath:function(B,A){(function(C,D){if(C==null){return arguments.callee}C.selected=D;return arguments.callee(C._parent,D)})(A,false)(B,true)},addSubtree:function(G,C,F,D){var E=Tree.Util,B=this,A=E.addSubtree(this.tree,G,C);if(F=="replot"){this.onClick(this.clickedNode.id,$_.merge({onMoveComplete:function(){E.each(A,function(H){H.drawn=H.exist})},onExpandComplete:function(){B.canvas.clear();B.plot()}},D))}else{if(F=="animate"){this.onClick(this.clickedNode.id,{onMoveComplete:function(){E.each(A,function(H){H.drawn=H.exist})},onExpandComplete:function(){E.each(A,function(H){E.set(H,{drawn:H.exist,startAlpha:H.exist?0:1,endAlpha:1,alpha:H.exist?0:1})});Tree.Plot.animate(B,$_.merge(B.controller,D,{modes:["fade:nodes"]}))}})}}},removeSubtree:function(G,B,F,D){var E=Tree.Util,C=this;if(F=="replot"){this.onClick(this.clickedNode.id,$_.merge({onContractComplete:function(){Tree.Plot.hideLabels(E.getSubtree(C.tree,G),true);E.removeSubtree(C.tree,G,B)}},D))}else{if(F=="animate"){var A=E.getSubtree(this.tree,G);E.each(A,function(H){E.set(H,{drawn:H.exist,startAlpha:1,endAlpha:0,alpha:1})});if(!B){E.set(A,{drawn:elem.exist,startAlpha:1,endAlpha:1,alpha:1})}Tree.Plot.animate(this,$_.merge(C.controller,{onComplete:function(){E.removeSubtree(C.tree,G,B);C.onClick(C.clickedNode.id,D)},modes:["fade:nodes"]}))}}},onClick:function(C,F){var D=this.canvas,H=this,J=Tree.Plot,I=Tree.Util,A=Tree.Geometry;var G={onRequestNodesComplete:$_.empty,onContractComplete:$_.empty,onMoveComplete:$_.empty,onExpandComplete:$_.empty};var B=$_.merge(this.controller,G,F);if(!J.busy){J.busy=true;var E=I.getSubtree(this.tree,C);this.selectPath(E,this.clickedNode);this.clickedNode=E;B.onBeforeCompute(E);this.requestNodes(E,{onComplete:function(){B.onRequestNodesComplete();H.contract({onComplete:function(){A.setRightLevelToShow(E,D);B.onContractComplete();H.move(E,{onComplete:function(){B.onMoveComplete();H.expand(E,{onComplete:function(){B.onExpandComplete();B.onAfterCompute(C);B.onComplete();J.busy=false}})}})}})}})}}};var Trans={linear:function(A){return A},Quart:function(A){return Math.pow(A,4)},easeIn:function(A,B){return A(B)},easeOut:function(A,B){return 1-A(1-B)},easeInOut:function(A,B){return(B<=0.5)?A(2*B)/2:(2-A(2*(1-B)))/2}};var Animation={duration:Config.animationTime,fps:Config.fps,transition:function(A){return Trans.easeInOut(Trans.Quart,A)},controller:false,getTime:function(){var A=(Date.now)?Date.now():new Date().getTime();return A},step:function(){var A=this.getTime();if(A<this.time+this.duration){var B=this.transition((A-this.time)/this.duration);this.controller.compute(B)}else{this.timer=clearInterval(this.timer);this.controller.compute(1);this.controller.complete()}},start:function(){this.time=0;this.startTimer();return this},startTimer:function(){if(this.timer){return false}this.time=this.getTime()-this.time;this.timer=setInterval((function(){Animation.step()}),Math.round(1000/this.fps));return true}};