(function(){window.$jit=function(w){w=w||window;for(var k in $jit){if($jit[k].$extend){w[k]=$jit[k];}}};$jit.version='2.0.0b';var $=function(d){return document.getElementById(d);};$.empty=function(){};$.extend=function(original,extended){for(var key in(extended||{}))
original[key]=extended[key];return original;};$.lambda=function(value){return(typeof value=='function')?value:function(){return value;};};$.time=Date.now||function(){return+new Date;};$.splat=function(obj){var type=$.type(obj);return type?((type!='array')?[obj]:obj):[];};$.type=function(elem){var type=$.type.s.call(elem).match(/^\[object\s(.*)\]$/)[1].toLowerCase();if(type!='object')return type;if(elem&&elem.$$family)return elem.$$family;return(elem&&elem.nodeName&&elem.nodeType==1)?'element':type;};$.type.s=Object.prototype.toString;$.each=function(iterable,fn){var type=$.type(iterable);if(type=='object'){for(var key in iterable)
fn(iterable[key],key);}else{for(var i=0,l=iterable.length;i<l;i++)
fn(iterable[i],i);}};$.indexOf=function(array,item){if(Array.indexOf)return array.indexOf(item);for(var i=0,l=array.length;i<l;i++){if(array[i]===item)return i;}
return-1;};$.map=function(array,f){var ans=[];$.each(array,function(elem,i){ans.push(f(elem,i));});return ans;};$.reduce=function(array,f,opt){var l=array.length;if(l==0)return opt;var acum=arguments.length==3?opt:array[--l];while(l--){acum=f(acum,array[l]);}
return acum;};$.merge=function(){var mix={};for(var i=0,l=arguments.length;i<l;i++){var object=arguments[i];if($.type(object)!='object')
continue;for(var key in object){var op=object[key],mp=mix[key];mix[key]=(mp&&$.type(op)=='object'&&$.type(mp)=='object')?$.merge(mp,op):$.unlink(op);}}
return mix;};$.unlink=function(object){var unlinked;switch($.type(object)){case'object':unlinked={};for(var p in object)
unlinked[p]=$.unlink(object[p]);break;case'array':unlinked=[];for(var i=0,l=object.length;i<l;i++)
unlinked[i]=$.unlink(object[i]);break;default:return object;}
return unlinked;};$.zip=function(){if(arguments.length===0)return[];for(var j=0,ans=[],l=arguments.length,ml=arguments[0].length;j<ml;j++){for(var i=0,row=[];i<l;i++){row.push(arguments[i][j]);}
ans.push(row);}
return ans;};$.rgbToHex=function(srcArray,array){if(srcArray.length<3)
return null;if(srcArray.length==4&&srcArray[3]==0&&!array)
return'transparent';var hex=[];for(var i=0;i<3;i++){var bit=(srcArray[i]-0).toString(16);hex.push(bit.length==1?'0'+bit:bit);}
return array?hex:'#'+hex.join('');};$.hexToRgb=function(hex){if(hex.length!=7){hex=hex.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);hex.shift();if(hex.length!=3)
return null;var rgb=[];for(var i=0;i<3;i++){var value=hex[i];if(value.length==1)
value+=value;rgb.push(parseInt(value,16));}
return rgb;}else{hex=parseInt(hex.slice(1),16);return[hex>>16,hex>>8&0xff,hex&0xff];}};$.destroy=function(elem){$.clean(elem);if(elem.parentNode)
elem.parentNode.removeChild(elem);if(elem.clearAttributes)
elem.clearAttributes();};$.clean=function(elem){for(var ch=elem.childNodes,i=0,l=ch.length;i<l;i++){$.destroy(ch[i]);}};$.addEvent=function(obj,type,fn){if(obj.addEventListener)
obj.addEventListener(type,fn,false);else
obj.attachEvent('on'+type,fn);};$.addEvents=function(obj,typeObj){for(var type in typeObj){$.addEvent(obj,type,typeObj[type]);}};$.hasClass=function(obj,klass){return(' '+obj.className+' ').indexOf(' '+klass+' ')>-1;};$.addClass=function(obj,klass){if(!$.hasClass(obj,klass))
obj.className=(obj.className+" "+klass);};$.removeClass=function(obj,klass){obj.className=obj.className.replace(new RegExp('(^|\\s)'+klass+'(?:\\s|$)'),'$1');};$.getPos=function(elem){var offset=getOffsets(elem);var scroll=getScrolls(elem);return{x:offset.x-scroll.x,y:offset.y-scroll.y};function getOffsets(elem){var position={x:0,y:0};while(elem&&!isBody(elem)){position.x+=elem.offsetLeft;position.y+=elem.offsetTop;elem=elem.offsetParent;}
return position;}
function getScrolls(elem){var position={x:0,y:0};while(elem&&!isBody(elem)){position.x+=elem.scrollLeft;position.y+=elem.scrollTop;elem=elem.parentNode;}
return position;}
function isBody(element){return(/^(?:body|html)$/i).test(element.tagName);}};$.event={get:function(e,win){win=win||window;return e||win.event;},getWheel:function(e){return e.wheelDelta?e.wheelDelta/120:-(e.detail||0)/3;},isRightClick:function(e){return(e.which==3||e.button==2);},getPos:function(e,win){win=win||window;e=e||win.event;var doc=win.document;doc=doc.documentElement||doc.body;if(e.touches&&e.touches.length){e=e.touches[0];}
var page={x:e.pageX||(e.clientX+doc.scrollLeft),y:e.pageY||(e.clientY+doc.scrollTop)};return page;},stop:function(e){if(e.stopPropagation)e.stopPropagation();e.cancelBubble=true;if(e.preventDefault)e.preventDefault();else e.returnValue=false;}};$jit.util=$jit.id=$;var Class=function(properties){properties=properties||{};var klass=function(){for(var key in this){if(typeof this[key]!='function')
this[key]=$.unlink(this[key]);}
this.constructor=klass;if(Class.prototyping)
return this;var instance=this.initialize?this.initialize.apply(this,arguments):this;this.$$family='class';return instance;};for(var mutator in Class.Mutators){if(!properties[mutator])
continue;properties=Class.Mutators[mutator](properties,properties[mutator]);delete properties[mutator];}
$.extend(klass,this);klass.constructor=Class;klass.prototype=properties;return klass;};Class.Mutators={Implements:function(self,klasses){$.each($.splat(klasses),function(klass){Class.prototyping=klass;var instance=(typeof klass=='function')?new klass:klass;for(var prop in instance){if(!(prop in self)){self[prop]=instance[prop];}}
delete Class.prototyping;});return self;}};$.extend(Class,{inherit:function(object,properties){for(var key in properties){var override=properties[key];var previous=object[key];var type=$.type(override);if(previous&&type=='function'){if(override!=previous){Class.override(object,key,override);}}else if(type=='object'){object[key]=$.merge(previous,override);}else{object[key]=override;}}
return object;},override:function(object,name,method){var parent=Class.prototyping;if(parent&&object[name]!=parent[name])
parent=null;var override=function(){var previous=this.parent;this.parent=parent?parent[name]:object[name];var value=method.apply(this,arguments);this.parent=previous;return value;};object[name]=override;}});Class.prototype.implement=function(){var proto=this.prototype;$.each(Array.prototype.slice.call(arguments||[]),function(properties){Class.inherit(proto,properties);});return this;};$jit.Class=Class;$jit.json={prune:function(tree,maxLevel){this.each(tree,function(elem,i){if(i==maxLevel&&elem.children){delete elem.children;elem.children=[];}});},getParent:function(tree,id){if(tree.id==id)
return false;var ch=tree.children;if(ch&&ch.length>0){for(var i=0;i<ch.length;i++){if(ch[i].id==id)
return tree;else{var ans=this.getParent(ch[i],id);if(ans)
return ans;}}}
return false;},getSubtree:function(tree,id){if(tree.id==id)
return tree;for(var i=0,ch=tree.children;i<ch.length;i++){var t=this.getSubtree(ch[i],id);if(t!=null)
return t;}
return null;},eachLevel:function(tree,initLevel,toLevel,action){if(initLevel<=toLevel){action(tree,initLevel);if(!tree.children)return;for(var i=0,ch=tree.children;i<ch.length;i++){this.eachLevel(ch[i],initLevel+1,toLevel,action);}}},each:function(tree,action){this.eachLevel(tree,0,Number.MAX_VALUE,action);}};$jit.Trans={$extend:true,linear:function(p){return p;}};var Trans=$jit.Trans;(function(){var makeTrans=function(transition,params){params=$.splat(params);return $.extend(transition,{easeIn:function(pos){return transition(pos,params);},easeOut:function(pos){return 1-transition(1-pos,params);},easeInOut:function(pos){return(pos<=0.5)?transition(2*pos,params)/2:(2-transition(2*(1-pos),params))/2;}});};var transitions={Pow:function(p,x){return Math.pow(p,x[0]||6);},Expo:function(p){return Math.pow(2,8*(p-1));},Circ:function(p){return 1-Math.sin(Math.acos(p));},Sine:function(p){return 1-Math.sin((1-p)*Math.PI/2);},Back:function(p,x){x=x[0]||1.618;return Math.pow(p,2)*((x+1)*p-x);},Bounce:function(p){var value;for(var a=0,b=1;1;a+=b,b/=2){if(p>=(7-4*a)/11){value=b*b-Math.pow((11-6*a-11*p)/4,2);break;}}
return value;},Elastic:function(p,x){return Math.pow(2,10*--p)*Math.cos(20*p*Math.PI*(x[0]||1)/3);}};$.each(transitions,function(val,key){Trans[key]=makeTrans(val);});$.each(['Quad','Cubic','Quart','Quint'],function(elem,i){Trans[elem]=makeTrans(function(p){return Math.pow(p,[i+2]);});});})();var Animation=new Class({initialize:function(options){this.setOptions(options);},setOptions:function(options){var opt={duration:2500,fps:40,transition:Trans.Quart.easeInOut,compute:$.empty,complete:$.empty,link:'ignore'};this.opt=$.merge(opt,options||{});return this;},step:function(){var time=$.time(),opt=this.opt;if(time<this.time+opt.duration){var delta=opt.transition((time-this.time)/opt.duration);opt.compute(delta);}else{this.timer=clearInterval(this.timer);opt.compute(1);opt.complete();}},start:function(){if(!this.check())
return this;this.time=0;this.startTimer();return this;},startTimer:function(){var that=this,fps=this.opt.fps;if(this.timer)
return false;this.time=$.time()-this.time;this.timer=setInterval((function(){that.step();}),Math.round(1000/fps));return true;},pause:function(){this.stopTimer();return this;},resume:function(){this.startTimer();return this;},stopTimer:function(){if(!this.timer)
return false;this.time=$.time()-this.time;this.timer=clearInterval(this.timer);return true;},check:function(){if(!this.timer)
return true;if(this.opt.link=='cancel'){this.stopTimer();return true;}
return false;}});var Options=function(){var args=arguments;for(var i=0,l=args.length,ans={};i<l;i++){var opt=Options[args[i]];if(opt.$extend){$.extend(ans,opt);}else{ans[args[i]]=opt;}}
return ans;};Options.Canvas={$extend:true,injectInto:'id',width:false,height:false,useCanvas:false,withLabels:true,background:false};Options.Tree={$extend:true,orientation:"left",subtreeOffset:8,siblingOffset:5,indent:10,multitree:false,align:"center"};Options.Node={$extend:false,overridable:false,type:'circle',color:'#ccb',alpha:1,dim:3,height:20,width:90,autoHeight:false,autoWidth:false,lineWidth:1,transform:true,align:"center",angularWidth:1,span:1,CanvasStyles:{}};Options.Edge={$extend:false,overridable:false,type:'line',color:'#ccb',lineWidth:1,dim:15,alpha:1,epsilon:7,CanvasStyles:{}};Options.Fx={$extend:true,fps:40,duration:2500,transition:$jit.Trans.Quart.easeInOut,clearCanvas:true};Options.Label={$extend:false,overridable:false,type:'HTML',style:' ',size:10,family:'sans-serif',textAlign:'center',textBaseline:'alphabetic',color:'#fff'};Options.Tips={$extend:false,enable:false,type:'auto',offsetX:20,offsetY:20,force:false,onShow:$.empty,onHide:$.empty};Options.NodeStyles={$extend:false,enable:false,type:'auto',stylesHover:false,stylesClick:false};Options.Events={$extend:false,enable:false,enableForEdges:false,type:'auto',onClick:$.empty,onRightClick:$.empty,onMouseMove:$.empty,onMouseEnter:$.empty,onMouseLeave:$.empty,onDragStart:$.empty,onDragMove:$.empty,onDragCancel:$.empty,onDragEnd:$.empty,onTouchStart:$.empty,onTouchMove:$.empty,onTouchEnd:$.empty,onMouseWheel:$.empty};Options.Navigation={$extend:false,enable:false,type:'auto',panning:false,zooming:false};Options.Controller={$extend:true,onBeforeCompute:$.empty,onAfterCompute:$.empty,onCreateLabel:$.empty,onPlaceLabel:$.empty,onComplete:$.empty,onBeforePlotLine:$.empty,onAfterPlotLine:$.empty,onBeforePlotNode:$.empty,onAfterPlotNode:$.empty,request:false};var ExtrasInitializer={initialize:function(className,viz){this.viz=viz;this.canvas=viz.canvas;this.config=viz.config[className];this.nodeTypes=viz.fx.nodeTypes;var type=this.config.type;this.dom=type=='auto'?(viz.config.Label.type!='Native'):(type!='Native');this.labelContainer=this.dom&&viz.labels.getLabelContainer();this.isEnabled()&&this.initializePost();},initializePost:$.empty,setAsProperty:$.lambda(false),isEnabled:function(){return this.config.enable;},isLabel:function(e,win){e=$.event.get(e,win);var labelContainer=this.labelContainer,target=e.target||e.srcElement;if(target&&target.parentNode==labelContainer)
return target;return false;}};var EventsInterface={onMouseUp:$.empty,onMouseDown:$.empty,onMouseMove:$.empty,onMouseOver:$.empty,onMouseOut:$.empty,onMouseWheel:$.empty,onTouchStart:$.empty,onTouchMove:$.empty,onTouchEnd:$.empty,onTouchCancel:$.empty};var MouseEventsManager=new Class({initialize:function(viz){this.viz=viz;this.canvas=viz.canvas;this.node=false;this.edge=false;this.registeredObjects=[];this.attachEvents();},attachEvents:function(){var htmlCanvas=this.canvas.getElement(),that=this;htmlCanvas.oncontextmenu=$.lambda(false);$.addEvents(htmlCanvas,{'mouseup':function(e,win){var event=$.event.get(e,win);that.handleEvent('MouseUp',e,win,that.makeEventObject(e,win),$.event.isRightClick(event));},'mousedown':function(e,win){var event=$.event.get(e,win);that.handleEvent('MouseDown',e,win,that.makeEventObject(e,win),$.event.isRightClick(event));},'mousemove':function(e,win){that.handleEvent('MouseMove',e,win,that.makeEventObject(e,win));},'mouseover':function(e,win){that.handleEvent('MouseOver',e,win,that.makeEventObject(e,win));},'mouseout':function(e,win){that.handleEvent('MouseOut',e,win,that.makeEventObject(e,win));},'touchstart':function(e,win){that.handleEvent('TouchStart',e,win,that.makeEventObject(e,win));},'touchmove':function(e,win){that.handleEvent('TouchMove',e,win,that.makeEventObject(e,win));},'touchend':function(e,win){that.handleEvent('TouchEnd',e,win,that.makeEventObject(e,win));}});var handleMouseWheel=function(e,win){var event=$.event.get(e,win);var wheel=$.event.getWheel(event);that.handleEvent('MouseWheel',e,win,wheel);};if(!document.getBoxObjectFor&&window.mozInnerScreenX==null){$.addEvent(htmlCanvas,'mousewheel',handleMouseWheel);}else{htmlCanvas.addEventListener('DOMMouseScroll',handleMouseWheel,false);}},register:function(obj){this.registeredObjects.push(obj);},handleEvent:function(){var args=Array.prototype.slice.call(arguments),type=args.shift();for(var i=0,regs=this.registeredObjects,l=regs.length;i<l;i++){regs[i]['on'+type].apply(regs[i],args);}},makeEventObject:function(e,win){var that=this,graph=this.viz.graph,fx=this.viz.fx,ntypes=fx.nodeTypes,etypes=fx.edgeTypes;return{pos:false,node:false,edge:false,contains:false,getNodeCalled:false,getEdgeCalled:false,getPos:function(){var canvas=that.viz.canvas,s=canvas.getSize(),p=canvas.getPos(),ox=canvas.translateOffsetX,oy=canvas.translateOffsetY,sx=canvas.scaleOffsetX,sy=canvas.scaleOffsetY,pos=$.event.getPos(e,win);this.pos={x:(pos.x-p.x-s.width/2-ox)*1/sx,y:(pos.y-p.y-s.height/2-oy)*1/sy};return this.pos;},getNode:function(){if(this.getNodeCalled)return this.node;this.getNodeCalled=true;for(var id in graph.nodes){var n=graph.nodes[id],geom=n&&ntypes[n.getData('type')],contains=geom&&geom.contains&&geom.contains.call(fx,n,this.getPos());if(contains){this.contains=contains;return that.node=this.node=n;}}
return that.node=this.node=false;},getEdge:function(){if(this.getEdgeCalled)return this.edge;this.getEdgeCalled=true;var hashset={};for(var id in graph.edges){var edgeFrom=graph.edges[id];hashset[id]=true;for(var edgeId in edgeFrom){if(edgeId in hashset)continue;var e=edgeFrom[edgeId],geom=e&&etypes[e.getData('type')],contains=geom&&geom.contains&&geom.contains.call(fx,e,this.getPos());if(contains){this.contains=contains;return that.edge=this.edge=e;}}}
return that.edge=this.edge=false;},getContains:function(){if(this.getNodeCalled)return this.contains;this.getNode();return this.contains;}};}});var Extras={initializeExtras:function(){var mem=new MouseEventsManager(this),that=this;$.each(['NodeStyles','Tips','Navigation','Events'],function(k){var obj=new Extras.Classes[k](k,that);if(obj.isEnabled()){mem.register(obj);}
if(obj.setAsProperty()){that[k.toLowerCase()]=obj;}});}};Extras.Classes={};Extras.Classes.Events=new Class({Implements:[ExtrasInitializer,EventsInterface],initializePost:function(){this.fx=this.viz.fx;this.ntypes=this.viz.fx.nodeTypes;this.etypes=this.viz.fx.edgeTypes;this.hovered=false;this.pressed=false;this.touched=false;this.touchMoved=false;this.moved=false;},setAsProperty:$.lambda(true),onMouseUp:function(e,win,event,isRightClick){var evt=$.event.get(e,win);if(!this.moved){if(isRightClick){this.config.onRightClick(this.hovered,event,evt);}else{this.config.onClick(this.pressed,event,evt);}}
if(this.pressed){if(this.moved){this.config.onDragEnd(this.pressed,event,evt);}else{this.config.onDragCancel(this.pressed,event,evt);}
this.pressed=this.moved=false;}},onMouseOut:function(e,win,event){var evt=$.event.get(e,win),label;if(this.dom&&(label=this.isLabel(e,win))){this.config.onMouseLeave(this.viz.graph.getNode(label.id),event,evt);this.hovered=false;return;}
var rt=evt.relatedTarget,canvasWidget=this.canvas.getElement();while(rt&&rt.parentNode){if(canvasWidget==rt.parentNode)return;rt=rt.parentNode;}
if(this.hovered){this.config.onMouseLeave(this.hovered,event,evt);this.hovered=false;}},onMouseOver:function(e,win,event){var evt=$.event.get(e,win),label;if(this.dom&&(label=this.isLabel(e,win))){this.hovered=this.viz.graph.getNode(label.id);this.config.onMouseEnter(this.hovered,event,evt);}},onMouseMove:function(e,win,event){var label,evt=$.event.get(e,win);if(this.pressed){this.moved=true;this.config.onDragMove(this.pressed,event,evt);return;}
if(this.dom){this.config.onMouseMove(this.hovered,event,evt);}else{if(this.hovered){var hn=this.hovered;var geom=hn.nodeFrom?this.etypes[hn.getData('type')]:this.ntypes[hn.getData('type')];var contains=geom&&geom.contains&&geom.contains.call(this.fx,hn,event.getPos());if(contains){this.config.onMouseMove(hn,event,evt);return;}else{this.config.onMouseLeave(hn,event,evt);this.hovered=false;}}
if(this.hovered=(event.getNode()||(this.config.enableForEdges&&event.getEdge()))){this.config.onMouseEnter(this.hovered,event,evt);}else{this.config.onMouseMove(false,event,evt);}}},onMouseWheel:function(e,win,delta){this.config.onMouseWheel(delta,$.event.get(e,win));},onMouseDown:function(e,win,event){var evt=$.event.get(e,win);this.pressed=event.getNode()||(this.config.enableForEdges&&event.getEdge());this.config.onDragStart(this.pressed,event,evt);},onTouchStart:function(e,win,event){var evt=$.event.get(e,win);this.touched=event.getNode()||(this.config.enableForEdges&&event.getEdge());this.config.onTouchStart(this.touched,event,evt);},onTouchMove:function(e,win,event){var evt=$.event.get(e,win);if(this.touched){this.touchMoved=true;this.config.onTouchMove(this.touched,event,evt);}},onTouchEnd:function(e,win,event){var evt=$.event.get(e,win);if(this.touched){if(this.touchMoved){this.config.onTouchEnd(this.touched,event,evt);}else{this.config.onTouchCancel(this.touched,event,evt);}
this.touched=this.touchMoved=false;}}});Extras.Classes.Tips=new Class({Implements:[ExtrasInitializer,EventsInterface],initializePost:function(){if(document.body){var tip=$('_tooltip')||document.createElement('div');tip.id='_tooltip';tip.className='tip';$.extend(tip.style,{position:'absolute',display:'none',zIndex:13000});document.body.appendChild(tip);this.tip=tip;this.node=false;}},setAsProperty:$.lambda(true),onMouseOut:function(e,win){if(this.dom&&this.isLabel(e,win)){this.hide(true);return;}
var rt=e.relatedTarget,canvasWidget=this.canvas.getElement();while(rt&&rt.parentNode){if(canvasWidget==rt.parentNode)return;rt=rt.parentNode;}
this.hide(false);},onMouseOver:function(e,win){var label;if(this.dom&&(label=this.isLabel(e,win))){this.node=this.viz.graph.getNode(label.id);this.config.onShow(this.tip,this.node,label);}},onMouseMove:function(e,win,opt){if(this.dom&&this.isLabel(e,win)){this.setTooltipPosition($.event.getPos(e,win));}
if(!this.dom){var node=opt.getNode();if(!node){this.hide(true);return;}
if(this.config.force||!this.node||this.node.id!=node.id){this.node=node;this.config.onShow(this.tip,node,opt.getContains());}
this.setTooltipPosition($.event.getPos(e,win));}},setTooltipPosition:function(pos){var tip=this.tip,style=tip.style,cont=this.config;style.display='';var win={'height':document.body.clientHeight,'width':document.body.clientWidth};var obj={'width':tip.offsetWidth,'height':tip.offsetHeight};var x=cont.offsetX,y=cont.offsetY;style.top=((pos.y+y+obj.height>win.height)?(pos.y-obj.height-y):pos.y+y)+'px';style.left=((pos.x+obj.width+x>win.width)?(pos.x-obj.width-x):pos.x+x)+'px';},hide:function(triggerCallback){this.tip.style.display='none';triggerCallback&&this.config.onHide();}});Extras.Classes.NodeStyles=new Class({Implements:[ExtrasInitializer,EventsInterface],initializePost:function(){this.fx=this.viz.fx;this.types=this.viz.fx.nodeTypes;this.nStyles=this.config;this.nodeStylesOnHover=this.nStyles.stylesHover;this.nodeStylesOnClick=this.nStyles.stylesClick;this.hoveredNode=false;this.fx.nodeFxAnimation=new Animation();this.down=false;this.move=false;},onMouseOut:function(e,win){this.down=this.move=false;if(!this.hoveredNode)return;if(this.dom&&this.isLabel(e,win)){this.toggleStylesOnHover(this.hoveredNode,false);}
var rt=e.relatedTarget,canvasWidget=this.canvas.getElement();while(rt&&rt.parentNode){if(canvasWidget==rt.parentNode)return;rt=rt.parentNode;}
this.toggleStylesOnHover(this.hoveredNode,false);this.hoveredNode=false;},onMouseOver:function(e,win){var label;if(this.dom&&(label=this.isLabel(e,win))){var node=this.viz.graph.getNode(label.id);if(node.selected)return;this.hoveredNode=node;this.toggleStylesOnHover(this.hoveredNode,true);}},onMouseDown:function(e,win,event,isRightClick){if(isRightClick)return;var label;if(this.dom&&(label=this.isLabel(e,win))){this.down=this.viz.graph.getNode(label.id);}else if(!this.dom){this.down=event.getNode();}
this.move=false;},onMouseUp:function(e,win,event,isRightClick){if(isRightClick)return;if(!this.move){this.onClick(event.getNode());}
this.down=this.move=false;},getRestoredStyles:function(node,type){var restoredStyles={},nStyles=this['nodeStylesOn'+type];for(var prop in nStyles){restoredStyles[prop]=node.styles['$'+prop];}
return restoredStyles;},toggleStylesOnHover:function(node,set){if(this.nodeStylesOnHover){this.toggleStylesOn('Hover',node,set);}},toggleStylesOnClick:function(node,set){if(this.nodeStylesOnClick){this.toggleStylesOn('Click',node,set);}},toggleStylesOn:function(type,node,set){var viz=this.viz;var nStyles=this.nStyles;if(set){var that=this;if(!node.styles){node.styles=$.merge(node.data,{});}
for(var s in this['nodeStylesOn'+type]){var $s='$'+s;if(!($s in node.styles)){node.styles[$s]=node.getData(s);}}
viz.fx.nodeFx($.extend({'elements':{'id':node.id,'properties':that['nodeStylesOn'+type]},transition:Trans.Quart.easeOut,duration:300,fps:40},this.config));}else{var restoredStyles=this.getRestoredStyles(node,type);viz.fx.nodeFx($.extend({'elements':{'id':node.id,'properties':restoredStyles},transition:Trans.Quart.easeOut,duration:300,fps:40},this.config));}},onClick:function(node){if(!node)return;var nStyles=this.nodeStylesOnClick;if(!nStyles)return;if(node.selected){this.toggleStylesOnClick(node,false);delete node.selected;}else{this.viz.graph.eachNode(function(n){if(n.selected){for(var s in nStyles){n.setData(s,n.styles['$'+s],'end');}
delete n.selected;}});this.toggleStylesOnClick(node,true);node.selected=true;delete node.hovered;this.hoveredNode=false;}},onMouseMove:function(e,win,event){if(this.down)this.move=true;if(this.dom&&this.isLabel(e,win))return;var nStyles=this.nodeStylesOnHover;if(!nStyles)return;if(!this.dom){if(this.hoveredNode){var geom=this.types[this.hoveredNode.getData('type')];var contains=geom&&geom.contains&&geom.contains.call(this.fx,this.hoveredNode,event.getPos());if(contains)return;}
var node=event.getNode();if(!this.hoveredNode&&!node)return;if(node.hovered)return;if(node&&!node.selected){this.fx.nodeFxAnimation.stopTimer();this.viz.graph.eachNode(function(n){if(n.hovered&&!n.selected){for(var s in nStyles){n.setData(s,n.styles['$'+s],'end');}
delete n.hovered;}});node.hovered=true;this.hoveredNode=node;this.toggleStylesOnHover(node,true);}else if(this.hoveredNode&&!this.hoveredNode.selected){this.fx.nodeFxAnimation.stopTimer();this.toggleStylesOnHover(this.hoveredNode,false);delete this.hoveredNode.hovered;this.hoveredNode=false;}}}});Extras.Classes.Navigation=new Class({Implements:[ExtrasInitializer,EventsInterface],initializePost:function(){this.pos=false;this.pressed=false;},onMouseWheel:function(e,win,scroll){if(!this.config.zooming)return;if(scroll>0)
{counter=counter*1+0.05;}else{counter=counter*1-0.05;}
var val=this.config.zooming/1000,ans=1+scroll*val;counter=counter.toFixed(2);if(counter<0.9)
{counter=0.9;ans=1;}
if(counter>1.5)
{counter=1.5;ans=1;}
$.event.stop($.event.get(e,win));this.canvas.scale(ans,ans);},onMouseDown:function(e,win,eventInfo){if(!this.config.panning)return;if(this.config.panning=='avoid nodes'&&eventInfo.getNode())return;this.pressed=true;this.pos=eventInfo.getPos();var canvas=this.canvas,ox=canvas.translateOffsetX,oy=canvas.translateOffsetY,sx=canvas.scaleOffsetX,sy=canvas.scaleOffsetY;this.pos.x*=sx;this.pos.x+=ox;this.pos.y*=sy;this.pos.y+=oy;},onMouseMove:function(e,win,eventInfo){if(!this.config.panning)return;if(!this.pressed)return;if(this.config.panning=='avoid nodes'&&eventInfo.getNode())return;var thispos=this.pos,currentPos=eventInfo.getPos(),canvas=this.canvas,ox=canvas.translateOffsetX,oy=canvas.translateOffsetY,sx=canvas.scaleOffsetX,sy=canvas.scaleOffsetY;currentPos.x*=sx;currentPos.y*=sy;currentPos.x+=ox;currentPos.y+=oy;var x=currentPos.x-thispos.x,y=currentPos.y-thispos.y;this.pos=currentPos;this.canvas.translate(x*1/sx,y*1/sy);},onMouseUp:function(e,win,eventInfo,isRightClick){if(!this.config.panning)return;this.pressed=false;}});var Canvas;(function(){var canvasType=typeof HTMLCanvasElement,supportsCanvas=(canvasType=='object'||canvasType=='function');function $E(tag,props){var elem=document.createElement(tag);for(var p in props){if(typeof props[p]=="object"){$.extend(elem[p],props[p]);}else{elem[p]=props[p];}}
if(tag=="canvas"&&!supportsCanvas&&G_vmlCanvasManager){elem=G_vmlCanvasManager.initElement(document.body.appendChild(elem));}
return elem;}
$jit.Canvas=Canvas=new Class({canvases:[],pos:false,element:false,labelContainer:false,translateOffsetX:0,translateOffsetY:0,scaleOffsetX:1,scaleOffsetY:1,initialize:function(viz,opt){this.viz=viz;this.opt=opt;var id=$.type(opt.injectInto)=='string'?opt.injectInto:opt.injectInto.id,idLabel=id+"-label",wrapper=$(id),width=opt.width||wrapper.offsetWidth,height=opt.height||wrapper.offsetHeight;this.id=id;var canvasOptions={injectInto:id,width:width,height:height};this.element=$E('div',{'id':id+'-canvaswidget','style':{'position':'relative','width':width+'px','height':height+'px'}});this.labelContainer=this.createLabelContainer(opt.Label.type,idLabel,canvasOptions);this.canvases.push(new Canvas.Base({config:$.extend({idSuffix:'-canvas'},canvasOptions),plot:function(base){viz.fx.plot();},resize:function(){viz.refresh();}}));var back=opt.background;if(back){var backCanvas=new Canvas.Background[back.type](viz,$.extend(back,canvasOptions));this.canvases.push(new Canvas.Base(backCanvas));}
var len=this.canvases.length;while(len--){this.element.appendChild(this.canvases[len].canvas);if(len>0){this.canvases[len].plot();}}
this.element.appendChild(this.labelContainer);wrapper.appendChild(this.element);var timer=null,that=this;$.addEvent(window,'scroll',function(){clearTimeout(timer);timer=setTimeout(function(){that.getPos(true);},500);});},getCtx:function(i){return this.canvases[i||0].getCtx();},getConfig:function(){return this.opt;},getElement:function(){return this.element;},getSize:function(i){return this.canvases[i||0].getSize();},resize:function(width,height){this.getPos(true);this.translateOffsetX=this.translateOffsetY=0;this.scaleOffsetX=this.scaleOffsetY=1;for(var i=0,l=this.canvases.length;i<l;i++){this.canvases[i].resize(width,height);}
var style=this.element.style;style.width=width+'px';style.height=height+'px';if(this.labelContainer)
this.labelContainer.style.width=width+'px';},translate:function(x,y,disablePlot){this.translateOffsetX+=x*this.scaleOffsetX;this.translateOffsetY+=y*this.scaleOffsetY;for(var i=0,l=this.canvases.length;i<l;i++){this.canvases[i].translate(x,y,disablePlot);}},scale:function(x,y,disablePlot){var px=this.scaleOffsetX*x,py=this.scaleOffsetY*y;var dx=this.translateOffsetX*(x-1)/px,dy=this.translateOffsetY*(y-1)/py;this.scaleOffsetX=px.toFixed(2);this.scaleOffsetY=py.toFixed(2);for(var i=0,l=this.canvases.length;i<l;i++){this.canvases[i].scale(x,y,true);}
this.translate(dx,dy,false);},getPos:function(force){if(force||!this.pos){return this.pos=$.getPos(this.getElement());}
return this.pos;},clear:function(i){this.canvases[i||0].clear();},path:function(type,action){var ctx=this.canvases[0].getCtx();ctx.beginPath();action(ctx);ctx[type]();ctx.closePath();},createLabelContainer:function(type,idLabel,dim){var NS='http://www.w3.org/2000/svg';if(type=='HTML'||type=='Native'){return $E('div',{'id':idLabel,'style':{'overflow':'visible','position':'absolute','top':0,'left':0,'width':dim.width+'px','height':0}});}else if(type=='SVG'){var svgContainer=document.createElementNS(NS,'svg:svg');svgContainer.setAttribute("width",dim.width);svgContainer.setAttribute('height',dim.height);var style=svgContainer.style;style.position='absolute';style.left=style.top='0px';var labelContainer=document.createElementNS(NS,'svg:g');labelContainer.setAttribute('width',dim.width);labelContainer.setAttribute('height',dim.height);labelContainer.setAttribute('x',0);labelContainer.setAttribute('y',0);labelContainer.setAttribute('id',idLabel);svgContainer.appendChild(labelContainer);return svgContainer;}}});Canvas.Base=new Class({translateOffsetX:0,translateOffsetY:0,scaleOffsetX:1,scaleOffsetY:1,initialize:function(viz){this.viz=viz;this.opt=viz.config;this.size=false;this.createCanvas();this.translateToCenter();},createCanvas:function(){var opt=this.opt,width=opt.width,height=opt.height;this.canvas=$E('canvas',{'id':opt.injectInto+opt.idSuffix,'width':width,'height':height,'style':{'position':'absolute','top':0,'left':0,'width':width+'px','height':height+'px'}});},getCtx:function(){if(!this.ctx)
return this.ctx=this.canvas.getContext('2d');return this.ctx;},getSize:function(){if(this.size)return this.size;var canvas=this.canvas;return this.size={width:canvas.width,height:canvas.height};},translateToCenter:function(ps){var size=this.getSize(),width=ps?(size.width-ps.width-this.translateOffsetX*2):size.width;height=ps?(size.height-ps.height-this.translateOffsetY*2):size.height;var ctx=this.getCtx();ps&&ctx.scale(1/this.scaleOffsetX,1/this.scaleOffsetY);ctx.translate(width/2,height/2);},resize:function(width,height){var size=this.getSize(),canvas=this.canvas,styles=canvas.style;this.size=false;canvas.width=width;canvas.height=height;styles.width=width+"px";styles.height=height+"px";if(!supportsCanvas){this.translateToCenter(size);}else{this.translateToCenter();}
this.translateOffsetX=this.translateOffsetY=0;this.scaleOffsetX=this.scaleOffsetY=1;this.clear();this.viz.resize(width,height,this);},translate:function(x,y,disablePlot){var sx=this.scaleOffsetX,sy=this.scaleOffsetY;this.translateOffsetX+=x*sx;this.translateOffsetY+=y*sy;this.getCtx().translate(x,y);!disablePlot&&this.plot();},scale:function(x,y,disablePlot){this.scaleOffsetX*=x;this.scaleOffsetY*=y;this.getCtx().scale(x,y);!disablePlot&&this.plot();},clear:function(){var size=this.getSize(),ox=this.translateOffsetX,oy=this.translateOffsetY,sx=this.scaleOffsetX,sy=this.scaleOffsetY;this.getCtx().clearRect((-size.width/2-ox)*1/sx,(-size.height/2-oy)*1/sy,size.width*1/sx,size.height*1/sy);},plot:function(){this.clear();this.viz.plot(this);}});Canvas.Background={};Canvas.Background.Circles=new Class({initialize:function(viz,options){this.viz=viz;this.config=$.merge({idSuffix:'-bkcanvas',levelDistance:100,numberOfCircles:6,CanvasStyles:{},offset:0},options);},resize:function(width,height,base){this.plot(base);},plot:function(base){var canvas=base.canvas,ctx=base.getCtx(),conf=this.config,styles=conf.CanvasStyles;for(var s in styles)ctx[s]=styles[s];var n=conf.numberOfCircles,rho=conf.levelDistance;for(var i=1;i<=n;i++){ctx.beginPath();ctx.arc(0,0,rho*i,0,2*Math.PI,false);ctx.stroke();ctx.closePath();}}});})();var Polar=function(theta,rho){this.theta=theta;this.rho=rho;};$jit.Polar=Polar;Polar.prototype={getc:function(simple){return this.toComplex(simple);},getp:function(){return this;},set:function(v){v=v.getp();this.theta=v.theta;this.rho=v.rho;},setc:function(x,y){this.rho=Math.sqrt(x*x+y*y);this.theta=Math.atan2(y,x);if(this.theta<0)this.theta+=Math.PI*2;},setp:function(theta,rho){this.theta=theta;this.rho=rho;},clone:function(){return new Polar(this.theta,this.rho);},toComplex:function(simple){var x=Math.cos(this.theta)*this.rho;var y=Math.sin(this.theta)*this.rho;if(simple)return{'x':x,'y':y};return new Complex(x,y);},add:function(polar){return new Polar(this.theta+polar.theta,this.rho+polar.rho);},scale:function(number){return new Polar(this.theta,this.rho*number);},equals:function(c){return this.theta==c.theta&&this.rho==c.rho;},$add:function(polar){this.theta=this.theta+polar.theta;this.rho+=polar.rho;return this;},$madd:function(polar){this.theta=(this.theta+polar.theta)%(Math.PI*2);this.rho+=polar.rho;return this;},$scale:function(number){this.rho*=number;return this;},interpolate:function(elem,delta){var pi=Math.PI,pi2=pi*2;var ch=function(t){var a=(t<0)?(t%pi2)+pi2:t%pi2;return a;};var tt=this.theta,et=elem.theta;var sum,diff=Math.abs(tt-et);if(diff==pi){if(tt>et){sum=ch((et+((tt-pi2)-et)*delta));}else{sum=ch((et-pi2+(tt-(et))*delta));}}else if(diff>=pi){if(tt>et){sum=ch((et+((tt-pi2)-et)*delta));}else{sum=ch((et-pi2+(tt-(et-pi2))*delta));}}else{sum=ch((et+(tt-et)*delta));}
var r=(this.rho-elem.rho)*delta+elem.rho;return{'theta':sum,'rho':r};}};var $P=function(a,b){return new Polar(a,b);};Polar.KER=$P(0,0);var Complex=function(x,y){this.x=x;this.y=y;};$jit.Complex=Complex;Complex.prototype={getc:function(){return this;},getp:function(simple){return this.toPolar(simple);},set:function(c){c=c.getc(true);this.x=c.x;this.y=c.y;},setc:function(x,y){this.x=x;this.y=y;},setp:function(theta,rho){this.x=Math.cos(theta)*rho;this.y=Math.sin(theta)*rho;},clone:function(){return new Complex(this.x,this.y);},toPolar:function(simple){var rho=this.norm();var atan=Math.atan2(this.y,this.x);if(atan<0)atan+=Math.PI*2;if(simple)return{'theta':atan,'rho':rho};return new Polar(atan,rho);},norm:function(){return Math.sqrt(this.squaredNorm());},squaredNorm:function(){return this.x*this.x+this.y*this.y;},add:function(pos){return new Complex(this.x+pos.x,this.y+pos.y);},prod:function(pos){return new Complex(this.x*pos.x-this.y*pos.y,this.y*pos.x+this.x*pos.y);},conjugate:function(){return new Complex(this.x,-this.y);},scale:function(factor){return new Complex(this.x*factor,this.y*factor);},equals:function(c){return this.x==c.x&&this.y==c.y;},$add:function(pos){this.x+=pos.x;this.y+=pos.y;return this;},$prod:function(pos){var x=this.x,y=this.y;this.x=x*pos.x-y*pos.y;this.y=y*pos.x+x*pos.y;return this;},$conjugate:function(){this.y=-this.y;return this;},$scale:function(factor){this.x*=factor;this.y*=factor;return this;},$div:function(pos){var x=this.x,y=this.y;var sq=pos.squaredNorm();this.x=x*pos.x+y*pos.y;this.y=y*pos.x-x*pos.y;return this.$scale(1/sq);}};var $C=function(a,b){return new Complex(a,b);};Complex.KER=$C(0,0);$jit.Graph=new Class({initialize:function(opt,Node,Edge,Label){var innerOptions={'complex':false,'Node':{}};this.Node=Node;this.Edge=Edge;this.Label=Label;this.opt=$.merge(innerOptions,opt||{});this.nodes={};this.edges={};var that=this;this.nodeList={};for(var p in Accessors){that.nodeList[p]=(function(p){return function(){var args=Array.prototype.slice.call(arguments);that.eachNode(function(n){n[p].apply(n,args);});};})(p);}},getNode:function(id){if(this.hasNode(id))return this.nodes[id];return false;},getByName:function(name){for(var id in this.nodes){var n=this.nodes[id];if(n.name==name)return n;}
return false;},getAdjacence:function(id,id2){if(id in this.edges){return this.edges[id][id2];}
return false;},addNode:function(obj){if(!this.nodes[obj.id]){var edges=this.edges[obj.id]={};this.nodes[obj.id]=new Graph.Node($.extend({'id':obj.id,'name':obj.name,'data':$.merge(obj.data||{},{}),'adjacencies':edges},this.opt.Node),this.opt.complex,this.Node,this.Edge,this.Label);}
return this.nodes[obj.id];},addAdjacence:function(obj,obj2,data){if(!this.hasNode(obj.id)){this.addNode(obj);}
if(!this.hasNode(obj2.id)){this.addNode(obj2);}
obj=this.nodes[obj.id];obj2=this.nodes[obj2.id];if(!obj.adjacentTo(obj2)){var adjsObj=this.edges[obj.id]=this.edges[obj.id]||{};var adjsObj2=this.edges[obj2.id]=this.edges[obj2.id]||{};adjsObj[obj2.id]=adjsObj2[obj.id]=new Graph.Adjacence(obj,obj2,data,this.Edge,this.Label);return adjsObj[obj2.id];}
return this.edges[obj.id][obj2.id];},removeNode:function(id){if(this.hasNode(id)){delete this.nodes[id];var adjs=this.edges[id];for(var to in adjs){delete this.edges[to][id];}
delete this.edges[id];}},removeAdjacence:function(id1,id2){delete this.edges[id1][id2];delete this.edges[id2][id1];},hasNode:function(id){return id in this.nodes;},empty:function(){this.nodes={};this.edges={};}});var Graph=$jit.Graph;var Accessors;(function(){var getDataInternal=function(prefix,prop,type,force,prefixConfig){var data;type=type||'current';prefix="$"+(prefix?prefix+"-":"");if(type=='current'){data=this.data;}else if(type=='start'){data=this.startData;}else if(type=='end'){data=this.endData;}
var dollar=prefix+prop;if(force){return data[dollar];}
if(!this.Config.overridable)
return prefixConfig[prop]||0;return(dollar in data)?data[dollar]:((dollar in this.data)?this.data[dollar]:(prefixConfig[prop]||0));}
var setDataInternal=function(prefix,prop,value,type){type=type||'current';prefix='$'+(prefix?prefix+'-':'');var data;if(type=='current'){data=this.data;}else if(type=='start'){data=this.startData;}else if(type=='end'){data=this.endData;}
data[prefix+prop]=value;}
var removeDataInternal=function(prefix,properties){prefix='$'+(prefix?prefix+'-':'');var that=this;$.each(properties,function(prop){var pref=prefix+prop;delete that.data[pref];delete that.endData[pref];delete that.startData[pref];});}
Accessors={getData:function(prop,type,force){return getDataInternal.call(this,"",prop,type,force,this.Config);},setData:function(prop,value,type){setDataInternal.call(this,"",prop,value,type);},setDataset:function(types,obj){types=$.splat(types);for(var attr in obj){for(var i=0,val=$.splat(obj[attr]),l=types.length;i<l;i++){this.setData(attr,val[i],types[i]);}}},removeData:function(){removeDataInternal.call(this,"",Array.prototype.slice.call(arguments));},getCanvasStyle:function(prop,type,force){return getDataInternal.call(this,'canvas',prop,type,force,this.Config.CanvasStyles);},setCanvasStyle:function(prop,value,type){setDataInternal.call(this,'canvas',prop,value,type);},setCanvasStyles:function(types,obj){types=$.splat(types);for(var attr in obj){for(var i=0,val=$.splat(obj[attr]),l=types.length;i<l;i++){this.setCanvasStyle(attr,val[i],types[i]);}}},removeCanvasStyle:function(){removeDataInternal.call(this,'canvas',Array.prototype.slice.call(arguments));},getLabelData:function(prop,type,force){return getDataInternal.call(this,'label',prop,type,force,this.Label);},setLabelData:function(prop,value,type){setDataInternal.call(this,'label',prop,value,type);},setLabelDataset:function(types,obj){types=$.splat(types);for(var attr in obj){for(var i=0,val=$.splat(obj[attr]),l=types.length;i<l;i++){this.setLabelData(attr,val[i],types[i]);}}},removeLabelData:function(){removeDataInternal.call(this,'label',Array.prototype.slice.call(arguments));}};})();Graph.Node=new Class({initialize:function(opt,complex,Node,Edge,Label){var innerOptions={'id':'','name':'','data':{},'startData':{},'endData':{},'adjacencies':{},'selected':false,'drawn':false,'exist':false,'angleSpan':{'begin':0,'end':0},'pos':(complex&&$C(0,0))||$P(0,0),'startPos':(complex&&$C(0,0))||$P(0,0),'endPos':(complex&&$C(0,0))||$P(0,0)};$.extend(this,$.extend(innerOptions,opt));this.Config=this.Node=Node;this.Edge=Edge;this.Label=Label;},adjacentTo:function(node){return node.id in this.adjacencies;},getAdjacency:function(id){return this.adjacencies[id];},getPos:function(type){type=type||"current";if(type=="current"){return this.pos;}else if(type=="end"){return this.endPos;}else if(type=="start"){return this.startPos;}},setPos:function(value,type){type=type||"current";var pos;if(type=="current"){pos=this.pos;}else if(type=="end"){pos=this.endPos;}else if(type=="start"){pos=this.startPos;}
pos.set(value);}});Graph.Node.implement(Accessors);Graph.Adjacence=new Class({initialize:function(nodeFrom,nodeTo,data,Edge,Label){this.nodeFrom=nodeFrom;this.nodeTo=nodeTo;this.data=data||{};this.startData={};this.endData={};this.Config=this.Edge=Edge;this.Label=Label;}});Graph.Adjacence.implement(Accessors);Graph.Util={filter:function(param){if(!param||!($.type(param)=='string'))return function(){return true;};var props=param.split(" ");return function(elem){for(var i=0;i<props.length;i++){if(elem[props[i]]){return false;}}
return true;};},getNode:function(graph,id){return graph.nodes[id];},eachNode:function(graph,action,flags){var filter=this.filter(flags);for(var i in graph.nodes){if(filter(graph.nodes[i]))action(graph.nodes[i]);}},eachAdjacency:function(node,action,flags){var adj=node.adjacencies,filter=this.filter(flags);for(var id in adj){var a=adj[id];if(filter(a)){if(a.nodeFrom!=node){var tmp=a.nodeFrom;a.nodeFrom=a.nodeTo;a.nodeTo=tmp;}
action(a,id);}}},computeLevels:function(graph,id,startDepth,flags){startDepth=startDepth||0;var filter=this.filter(flags);this.eachNode(graph,function(elem){elem._flag=false;elem._depth=-1;},flags);var root=graph.getNode(id);root._depth=startDepth;var queue=[root];while(queue.length!=0){var node=queue.pop();node._flag=true;this.eachAdjacency(node,function(adj){var n=adj.nodeTo;if(n._flag==false&&filter(n)){if(n._depth<0)n._depth=node._depth+1+startDepth;queue.unshift(n);}},flags);}},eachBFS:function(graph,id,action,flags){var filter=this.filter(flags);this.clean(graph);var queue=[graph.getNode(id)];while(queue.length!=0){var node=queue.pop();node._flag=true;action(node,node._depth);this.eachAdjacency(node,function(adj){var n=adj.nodeTo;if(n._flag==false&&filter(n)){n._flag=true;queue.unshift(n);}},flags);}},eachLevel:function(node,levelBegin,levelEnd,action,flags){var d=node._depth,filter=this.filter(flags),that=this;levelEnd=levelEnd===false?Number.MAX_VALUE-d:levelEnd;(function loopLevel(node,levelBegin,levelEnd){var d=node._depth;if(d>=levelBegin&&d<=levelEnd&&filter(node))action(node,d);if(d<levelEnd){that.eachAdjacency(node,function(adj){var n=adj.nodeTo;if(n._depth>d)loopLevel(n,levelBegin,levelEnd);});}})(node,levelBegin+d,levelEnd+d);},eachSubgraph:function(node,action,flags){this.eachLevel(node,0,false,action,flags);},eachSubnode:function(node,action,flags){this.eachLevel(node,1,1,action,flags);},anySubnode:function(node,cond,flags){var flag=false;cond=cond||$.lambda(true);var c=$.type(cond)=='string'?function(n){return n[cond];}:cond;this.eachSubnode(node,function(elem){if(c(elem))flag=true;},flags);return flag;},getSubnodes:function(node,level,flags){var ans=[],that=this;level=level||0;var levelStart,levelEnd;if($.type(level)=='array'){levelStart=level[0];levelEnd=level[1];}else{levelStart=level;levelEnd=Number.MAX_VALUE-node._depth;}
this.eachLevel(node,levelStart,levelEnd,function(n){ans.push(n);},flags);return ans;},getParents:function(node){var ans=[];this.eachAdjacency(node,function(adj){var n=adj.nodeTo;if(n._depth<node._depth)ans.push(n);});return ans;},isDescendantOf:function(node,id){if(node.id==id)return true;var pars=this.getParents(node),ans=false;for(var i=0;!ans&&i<pars.length;i++){ans=ans||this.isDescendantOf(pars[i],id);}
return ans;},clean:function(graph){this.eachNode(graph,function(elem){elem._flag=false;});},getClosestNodeToOrigin:function(graph,prop,flags){return this.getClosestNodeToPos(graph,Polar.KER,prop,flags);},getClosestNodeToPos:function(graph,pos,prop,flags){var node=null;prop=prop||'current';pos=pos&&pos.getc(true)||Complex.KER;var distance=function(a,b){var d1=a.x-b.x,d2=a.y-b.y;return d1*d1+d2*d2;};this.eachNode(graph,function(elem){node=(node==null||distance(elem.getPos(prop).getc(true),pos)<distance(node.getPos(prop).getc(true),pos))?elem:node;},flags);return node;}};$.each(['getNode','eachNode','computeLevels','eachBFS','clean','getClosestNodeToPos','getClosestNodeToOrigin'],function(m){Graph.prototype[m]=function(){return Graph.Util[m].apply(Graph.Util,[this].concat(Array.prototype.slice.call(arguments)));};});$.each(['eachAdjacency','eachLevel','eachSubgraph','eachSubnode','anySubnode','getSubnodes','getParents','isDescendantOf'],function(m){Graph.Node.prototype[m]=function(){return Graph.Util[m].apply(Graph.Util,[this].concat(Array.prototype.slice.call(arguments)));};});Graph.Op={options:{type:'nothing',duration:2000,hideLabels:true,fps:30},initialize:function(viz){this.viz=viz;},removeNode:function(node,opt){var viz=this.viz;var options=$.merge(this.options,viz.controller,opt);var n=$.splat(node);var i,that,nodeObj;switch(options.type){case'nothing':for(i=0;i<n.length;i++)viz.graph.removeNode(n[i]);break;case'replot':this.removeNode(n,{type:'nothing'});viz.labels.clearLabels();viz.refresh(true);break;case'fade:seq':case'fade':that=this;for(i=0;i<n.length;i++){nodeObj=viz.graph.getNode(n[i]);nodeObj.setData('alpha',0,'end');}
viz.fx.animate($.merge(options,{modes:['node-property:alpha'],onComplete:function(){that.removeNode(n,{type:'nothing'});viz.labels.clearLabels();viz.reposition();viz.fx.animate($.merge(options,{modes:['linear']}));}}));break;case'fade:con':that=this;for(i=0;i<n.length;i++){nodeObj=viz.graph.getNode(n[i]);nodeObj.setData('alpha',0,'end');nodeObj.ignore=true;}
viz.reposition();viz.fx.animate($.merge(options,{modes:['node-property:alpha','linear'],onComplete:function(){that.removeNode(n,{type:'nothing'});}}));break;case'iter':that=this;viz.fx.sequence({condition:function(){return n.length!=0;},step:function(){that.removeNode(n.shift(),{type:'nothing'});viz.labels.clearLabels();},onComplete:function(){options.onComplete();},duration:Math.ceil(options.duration/n.length)});break;default:this.doError();}},removeEdge:function(vertex,opt){var viz=this.viz;var options=$.merge(this.options,viz.controller,opt);var v=($.type(vertex[0])=='string')?[vertex]:vertex;var i,that,adj;switch(options.type){case'nothing':for(i=0;i<v.length;i++)viz.graph.removeAdjacence(v[i][0],v[i][1]);break;case'replot':this.removeEdge(v,{type:'nothing'});viz.refresh(true);break;case'fade:seq':case'fade':that=this;for(i=0;i<v.length;i++){adj=viz.graph.getAdjacence(v[i][0],v[i][1]);if(adj){adj.setData('alpha',0,'end');}}
viz.fx.animate($.merge(options,{modes:['edge-property:alpha'],onComplete:function(){that.removeEdge(v,{type:'nothing'});viz.reposition();viz.fx.animate($.merge(options,{modes:['linear']}));}}));break;case'fade:con':that=this;for(i=0;i<v.length;i++){adj=viz.graph.getAdjacence(v[i][0],v[i][1]);if(adj){adj.setData('alpha',0,'end');adj.ignore=true;}}
viz.reposition();viz.fx.animate($.merge(options,{modes:['edge-property:alpha','linear'],onComplete:function(){that.removeEdge(v,{type:'nothing'});}}));break;case'iter':that=this;viz.fx.sequence({condition:function(){return v.length!=0;},step:function(){that.removeEdge(v.shift(),{type:'nothing'});viz.labels.clearLabels();},onComplete:function(){options.onComplete();},duration:Math.ceil(options.duration/v.length)});break;default:this.doError();}},sum:function(json,opt){var viz=this.viz;var options=$.merge(this.options,viz.controller,opt),root=viz.root;var graph;viz.root=opt.id||viz.root;switch(options.type){case'nothing':graph=viz.construct(json);graph.eachNode(function(elem){elem.eachAdjacency(function(adj){viz.graph.addAdjacence(adj.nodeFrom,adj.nodeTo,adj.data);});});break;case'replot':viz.refresh(true);this.sum(json,{type:'nothing'});viz.refresh(true);break;case'fade:seq':case'fade':case'fade:con':that=this;graph=viz.construct(json);var fadeEdges=this.preprocessSum(graph);var modes=!fadeEdges?['node-property:alpha']:['node-property:alpha','edge-property:alpha'];viz.reposition();if(options.type!='fade:con'){viz.fx.animate($.merge(options,{modes:['linear'],onComplete:function(){viz.fx.animate($.merge(options,{modes:modes,onComplete:function(){options.onComplete();}}));}}));}else{viz.graph.eachNode(function(elem){if(elem.id!=root&&elem.pos.getp().equals(Polar.KER)){elem.pos.set(elem.endPos);elem.startPos.set(elem.endPos);}});viz.fx.animate($.merge(options,{modes:['linear'].concat(modes)}));}
break;default:this.doError();}},morph:function(json,opt,extraModes){var viz=this.viz;var options=$.merge(this.options,viz.controller,opt),root=viz.root;var graph;viz.root=opt.id||viz.root;switch(options.type){case'nothing':graph=viz.construct(json);graph.eachNode(function(elem){var nodeExists=viz.graph.hasNode(elem.id);elem.eachAdjacency(function(adj){var adjExists=!!viz.graph.getAdjacence(adj.nodeFrom.id,adj.nodeTo.id);viz.graph.addAdjacence(adj.nodeFrom,adj.nodeTo,adj.data);if(adjExists){var addedAdj=viz.graph.getAdjacence(adj.nodeFrom.id,adj.nodeTo.id);for(var prop in(adj.data||{})){addedAdj.data[prop]=adj.data[prop];}}});if(nodeExists){var addedNode=viz.graph.getNode(elem.id);for(var prop in(elem.data||{})){addedNode.data[prop]=elem.data[prop];}}});viz.graph.eachNode(function(elem){elem.eachAdjacency(function(adj){if(!graph.getAdjacence(adj.nodeFrom.id,adj.nodeTo.id)){viz.graph.removeAdjacence(adj.nodeFrom.id,adj.nodeTo.id);}});if(!graph.hasNode(elem.id))viz.graph.removeNode(elem.id);});break;case'replot':viz.labels.clearLabels(true);this.morph(json,{type:'nothing'});viz.refresh(true);viz.refresh(true);break;case'fade:seq':case'fade':case'fade:con':that=this;graph=viz.construct(json);var nodeModes=extraModes&&('node-property'in extraModes)&&$.map($.splat(extraModes['node-property']),function(n){return'$'+n;});viz.graph.eachNode(function(elem){var graphNode=graph.getNode(elem.id);if(!graphNode){elem.setData('alpha',1);elem.setData('alpha',1,'start');elem.setData('alpha',0,'end');elem.ignore=true;}else{var graphNodeData=graphNode.data;for(var prop in graphNodeData){if(nodeModes&&($.indexOf(nodeModes,prop)>-1)){elem.endData[prop]=graphNodeData[prop];}else{elem.data[prop]=graphNodeData[prop];}}}});viz.graph.eachNode(function(elem){if(elem.ignore)return;elem.eachAdjacency(function(adj){if(adj.nodeFrom.ignore||adj.nodeTo.ignore)return;var nodeFrom=graph.getNode(adj.nodeFrom.id);var nodeTo=graph.getNode(adj.nodeTo.id);if(!nodeFrom.adjacentTo(nodeTo)){var adj=viz.graph.getAdjacence(nodeFrom.id,nodeTo.id);fadeEdges=true;adj.setData('alpha',1);adj.setData('alpha',1,'start');adj.setData('alpha',0,'end');}});});var fadeEdges=this.preprocessSum(graph);var modes=!fadeEdges?['node-property:alpha']:['node-property:alpha','edge-property:alpha'];modes[0]=modes[0]+((extraModes&&('node-property'in extraModes))?(':'+$.splat(extraModes['node-property']).join(':')):'');modes[1]=(modes[1]||'edge-property:alpha')+((extraModes&&('edge-property'in extraModes))?(':'+$.splat(extraModes['edge-property']).join(':')):'');if(extraModes&&('label-property'in extraModes)){modes.push('label-property:'+$.splat(extraModes['label-property']).join(':'))}
viz.reposition();viz.graph.eachNode(function(elem){if(elem.id!=root&&elem.pos.getp().equals(Polar.KER)){elem.pos.set(elem.endPos);elem.startPos.set(elem.endPos);}});viz.fx.animate($.merge(options,{modes:['polar'].concat(modes),onComplete:function(){viz.graph.eachNode(function(elem){if(elem.ignore)viz.graph.removeNode(elem.id);});viz.graph.eachNode(function(elem){elem.eachAdjacency(function(adj){if(adj.ignore)viz.graph.removeAdjacence(adj.nodeFrom.id,adj.nodeTo.id);});});options.onComplete();}}));break;default:;}},contract:function(node,opt){var viz=this.viz;if(node.collapsed||!node.anySubnode($.lambda(true)))return;opt=$.merge(this.options,viz.config,opt||{},{'modes':['node-property:alpha:span','linear']});node.collapsed=true;(function subn(n){n.eachSubnode(function(ch){ch.ignore=true;ch.setData('alpha',0,opt.type=='animate'?'end':'current');subn(ch);});})(node);if(opt.type=='animate'){viz.compute('end');if(viz.rotated){viz.rotate(viz.rotated,'none',{'property':'end'});}
(function subn(n){n.eachSubnode(function(ch){ch.setPos(node.getPos('end'),'end');subn(ch);});})(node);viz.fx.animate(opt);}else if(opt.type=='replot'){viz.refresh();}},expand:function(node,opt){if(!('collapsed'in node))return;var viz=this.viz;opt=$.merge(this.options,viz.config,opt||{},{'modes':['node-property:alpha:span','linear']});delete node.collapsed;(function subn(n){n.eachSubnode(function(ch){delete ch.ignore;ch.setData('alpha',1,opt.type=='animate'?'end':'current');subn(ch);});})(node);if(opt.type=='animate'){viz.compute('end');if(viz.rotated){viz.rotate(viz.rotated,'none',{'property':'end'});}
viz.fx.animate(opt);}else if(opt.type=='replot'){viz.refresh();}},preprocessSum:function(graph){var viz=this.viz;graph.eachNode(function(elem){if(!viz.graph.hasNode(elem.id)){viz.graph.addNode(elem);var n=viz.graph.getNode(elem.id);n.setData('alpha',0);n.setData('alpha',0,'start');n.setData('alpha',1,'end');}});var fadeEdges=false;graph.eachNode(function(elem){elem.eachAdjacency(function(adj){var nodeFrom=viz.graph.getNode(adj.nodeFrom.id);var nodeTo=viz.graph.getNode(adj.nodeTo.id);if(!nodeFrom.adjacentTo(nodeTo)){var adj=viz.graph.addAdjacence(nodeFrom,nodeTo,adj.data);if(nodeFrom.startAlpha==nodeFrom.endAlpha&&nodeTo.startAlpha==nodeTo.endAlpha){fadeEdges=true;adj.setData('alpha',0);adj.setData('alpha',0,'start');adj.setData('alpha',1,'end');}}});});return fadeEdges;}};var NodeHelper={'none':{'render':$.empty,'contains':$.lambda(false)},'circle':{'render':function(type,pos,radius,canvas){var ctx=canvas.getCtx();ctx.beginPath();ctx.arc(pos.x,pos.y,radius,0,Math.PI*2,true);ctx.closePath();ctx[type]();},'contains':function(npos,pos,radius){var diffx=npos.x-pos.x,diffy=npos.y-pos.y,diff=diffx*diffx+diffy*diffy;return diff<=radius*radius;}},'ellipse':{'render':function(type,pos,width,height,canvas){var ctx=canvas.getCtx();height/=2;width/=2;ctx.save();ctx.scale(width/height,height/width);ctx.beginPath();ctx.arc(pos.x*(height/width),pos.y*(width/height),height,0,Math.PI*2,true);ctx.closePath();ctx[type]();ctx.restore();},'contains':function(npos,pos,width,height){width/=2;height/=2;var dist=(width+height)/2,diffx=npos.x-pos.x,diffy=npos.y-pos.y,diff=diffx*diffx+diffy*diffy;return diff<=dist*dist;}},'square':{'render':function(type,pos,dim,canvas){canvas.getCtx()[type+"Rect"](pos.x-dim,pos.y-dim,2*dim,2*dim);},'contains':function(npos,pos,dim){return Math.abs(pos.x-npos.x)<=dim&&Math.abs(pos.y-npos.y)<=dim;}},'rectangle':{'render':function(type,pos,width,height,canvas){canvas.getCtx()[type+"Rect"](pos.x-width/2,pos.y-height/2,width,height);},'contains':function(npos,pos,width,height){return Math.abs(pos.x-npos.x)<=width/2&&Math.abs(pos.y-npos.y)<=height/2;}},'triangle':{'render':function(type,pos,dim,canvas){var ctx=canvas.getCtx(),c1x=pos.x,c1y=pos.y-dim,c2x=c1x-dim,c2y=pos.y+dim,c3x=c1x+dim,c3y=c2y;ctx.beginPath();ctx.moveTo(c1x,c1y);ctx.lineTo(c2x,c2y);ctx.lineTo(c3x,c3y);ctx.closePath();ctx[type]();},'contains':function(npos,pos,dim){return NodeHelper.circle.contains(npos,pos,dim);}},'star':{'render':function(type,pos,dim,canvas){var ctx=canvas.getCtx(),pi5=Math.PI/5;ctx.save();ctx.translate(pos.x,pos.y);ctx.beginPath();ctx.moveTo(dim,0);for(var i=0;i<9;i++){ctx.rotate(pi5);if(i%2==0){ctx.lineTo((dim/0.525731)*0.200811,0);}else{ctx.lineTo(dim,0);}}
ctx.closePath();ctx[type]();ctx.restore();},'contains':function(npos,pos,dim){return NodeHelper.circle.contains(npos,pos,dim);}}};var EdgeHelper={'line':{'render':function(from,to,canvas){var ctx=canvas.getCtx();ctx.beginPath();ctx.moveTo(from.x,from.y);ctx.lineTo(to.x,to.y);ctx.stroke();},'contains':function(posFrom,posTo,pos,epsilon){var min=Math.min,max=Math.max,minPosX=min(posFrom.x,posTo.x),maxPosX=max(posFrom.x,posTo.x),minPosY=min(posFrom.y,posTo.y),maxPosY=max(posFrom.y,posTo.y);if(pos.x>=minPosX&&pos.x<=maxPosX&&pos.y>=minPosY&&pos.y<=maxPosY){if(Math.abs(posTo.x-posFrom.x)<=epsilon){return true;}
var dist=(posTo.y-posFrom.y)/(posTo.x-posFrom.x)*(pos.x-posFrom.x)+posFrom.y;return Math.abs(dist-pos.y)<=epsilon;}
return false;}},'arrow':{'render':function(from,to,dim,swap,canvas){var ctx=canvas.getCtx();if(swap){var tmp=from;from=to;to=tmp;}
var vect=new Complex(to.x-from.x,to.y-from.y);vect.$scale(dim/vect.norm());var intermediatePoint=new Complex(to.x-vect.x,to.y-vect.y),normal=new Complex(-vect.y/2,vect.x/2),v1=intermediatePoint.add(normal),v2=intermediatePoint.$add(normal.$scale(-1));ctx.beginPath();ctx.moveTo(from.x,from.y);ctx.lineTo(to.x,to.y);ctx.stroke();ctx.beginPath();ctx.moveTo(v1.x,v1.y);ctx.lineTo(v2.x,v2.y);ctx.lineTo(to.x,to.y);ctx.closePath();ctx.fill();},'contains':function(posFrom,posTo,pos,epsilon){return EdgeHelper.line.contains(posFrom,posTo,pos,epsilon);}},'hyperline':{'render':function(from,to,r,canvas){var ctx=canvas.getCtx();var centerOfCircle=computeArcThroughTwoPoints(from,to);if(centerOfCircle.a>1000||centerOfCircle.b>1000||centerOfCircle.ratio<0){ctx.beginPath();ctx.moveTo(from.x*r,from.y*r);ctx.lineTo(to.x*r,to.y*r);ctx.stroke();}else{var angleBegin=Math.atan2(to.y-centerOfCircle.y,to.x
-centerOfCircle.x);var angleEnd=Math.atan2(from.y-centerOfCircle.y,from.x
-centerOfCircle.x);var sense=sense(angleBegin,angleEnd);ctx.beginPath();ctx.arc(centerOfCircle.x*r,centerOfCircle.y*r,centerOfCircle.ratio*r,angleBegin,angleEnd,sense);ctx.stroke();}
function computeArcThroughTwoPoints(p1,p2){var aDen=(p1.x*p2.y-p1.y*p2.x),bDen=aDen;var sq1=p1.squaredNorm(),sq2=p2.squaredNorm();if(aDen==0)
return{x:0,y:0,ratio:-1};var a=(p1.y*sq2-p2.y*sq1+p1.y-p2.y)/aDen;var b=(p2.x*sq1-p1.x*sq2+p2.x-p1.x)/bDen;var x=-a/2;var y=-b/2;var squaredRatio=(a*a+b*b)/4-1;if(squaredRatio<0)
return{x:0,y:0,ratio:-1};var ratio=Math.sqrt(squaredRatio);var out={x:x,y:y,ratio:ratio>1000?-1:ratio,a:a,b:b};return out;}
function sense(angleBegin,angleEnd){return(angleBegin<angleEnd)?((angleBegin+Math.PI>angleEnd)?false:true):((angleEnd+Math.PI>angleBegin)?true:false);}},'contains':$.lambda(false)}};Graph.Plot={initialize:function(viz,klass){this.viz=viz;this.config=viz.config;this.node=viz.config.Node;this.edge=viz.config.Edge;this.animation=new Animation;this.nodeTypes=new klass.Plot.NodeTypes;this.edgeTypes=new klass.Plot.EdgeTypes;this.labels=viz.labels;},nodeHelper:NodeHelper,edgeHelper:EdgeHelper,Interpolator:{'map':{'border':'color','color':'color','width':'number','height':'number','dim':'number','alpha':'number','lineWidth':'number','angularWidth':'number','span':'number','valueArray':'array-number','dimArray':'array-number'},'canvas':{'globalAlpha':'number','fillStyle':'color','strokeStyle':'color','lineWidth':'number','shadowBlur':'number','shadowColor':'color','shadowOffsetX':'number','shadowOffsetY':'number','miterLimit':'number'},'label':{'size':'number','color':'color'},'compute':function(from,to,delta){return from+(to-from)*delta;},'moebius':function(elem,props,delta,vector){var v=vector.scale(-delta);if(v.norm()<1){var x=v.x,y=v.y;var ans=elem.startPos.getc().moebiusTransformation(v);elem.pos.setc(ans.x,ans.y);v.x=x;v.y=y;}},'linear':function(elem,props,delta){var from=elem.startPos.getc(true);var to=elem.endPos.getc(true);elem.pos.setc(this.compute(from.x,to.x,delta),this.compute(from.y,to.y,delta));},'polar':function(elem,props,delta){var from=elem.startPos.getp(true);var to=elem.endPos.getp();var ans=to.interpolate(from,delta);elem.pos.setp(ans.theta,ans.rho);},'number':function(elem,prop,delta,getter,setter){var from=elem[getter](prop,'start');var to=elem[getter](prop,'end');elem[setter](prop,this.compute(from,to,delta));},'color':function(elem,prop,delta,getter,setter){var from=$.hexToRgb(elem[getter](prop,'start'));var to=$.hexToRgb(elem[getter](prop,'end'));var comp=this.compute;var val=$.rgbToHex([parseInt(comp(from[0],to[0],delta)),parseInt(comp(from[1],to[1],delta)),parseInt(comp(from[2],to[2],delta))]);elem[setter](prop,val);},'array-number':function(elem,prop,delta,getter,setter){var from=elem[getter](prop,'start'),to=elem[getter](prop,'end'),cur=[];for(var i=0,l=from.length;i<l;i++){var fromi=from[i],toi=to[i];if(fromi.length){for(var j=0,len=fromi.length,curi=[];j<len;j++){curi.push(this.compute(fromi[j],toi[j],delta));}
cur.push(curi);}else{cur.push(this.compute(fromi,toi,delta));}}
elem[setter](prop,cur);},'node':function(elem,props,delta,map,getter,setter){map=this[map];if(props){var len=props.length;for(var i=0;i<len;i++){var pi=props[i];this[map[pi]](elem,pi,delta,getter,setter);}}else{for(var pi in map){this[map[pi]](elem,pi,delta,getter,setter);}}},'edge':function(elem,props,delta,mapKey,getter,setter){var adjs=elem.adjacencies;for(var id in adjs)this['node'](adjs[id],props,delta,mapKey,getter,setter);},'node-property':function(elem,props,delta){this['node'](elem,props,delta,'map','getData','setData');},'edge-property':function(elem,props,delta){this['edge'](elem,props,delta,'map','getData','setData');},'label-property':function(elem,props,delta){this['node'](elem,props,delta,'label','getLabelData','setLabelData');},'node-style':function(elem,props,delta){this['node'](elem,props,delta,'canvas','getCanvasStyle','setCanvasStyle');},'edge-style':function(elem,props,delta){this['edge'](elem,props,delta,'canvas','getCanvasStyle','setCanvasStyle');}},sequence:function(options){var that=this;options=$.merge({condition:$.lambda(false),step:$.empty,onComplete:$.empty,duration:200},options||{});var interval=setInterval(function(){if(options.condition()){options.step();}else{clearInterval(interval);options.onComplete();}
that.viz.refresh(true);},options.duration);},prepare:function(modes){var graph=this.viz.graph,accessors={'node-property':{'getter':'getData','setter':'setData'},'edge-property':{'getter':'getData','setter':'setData'},'node-style':{'getter':'getCanvasStyle','setter':'setCanvasStyle'},'edge-style':{'getter':'getCanvasStyle','setter':'setCanvasStyle'}};var m={};if($.type(modes)=='array'){for(var i=0,len=modes.length;i<len;i++){var elems=modes[i].split(':');m[elems.shift()]=elems;}}else{for(var p in modes){if(p=='position'){m[modes.position]=[];}else{m[p]=$.splat(modes[p]);}}}
graph.eachNode(function(node){node.startPos.set(node.pos);$.each(['node-property','node-style'],function(p){if(p in m){var prop=m[p];for(var i=0,l=prop.length;i<l;i++){node[accessors[p].setter](prop[i],node[accessors[p].getter](prop[i]),'start');}}});$.each(['edge-property','edge-style'],function(p){if(p in m){var prop=m[p];node.eachAdjacency(function(adj){for(var i=0,l=prop.length;i<l;i++){adj[accessors[p].setter](prop[i],adj[accessors[p].getter](prop[i]),'start');}});}});});return m;},animate:function(opt,versor){opt=$.merge(this.viz.config,opt||{});var that=this,viz=this.viz,graph=viz.graph,interp=this.Interpolator,animation=opt.type==='nodefx'?this.nodeFxAnimation:this.animation;var m=this.prepare(opt.modes);if(opt.hideLabels)this.labels.hideLabels(true);animation.setOptions($.merge(opt,{$animating:false,compute:function(delta){graph.eachNode(function(node){for(var p in m){interp[p](node,m[p],delta,versor);}});that.plot(opt,this.$animating,delta);this.$animating=true;},complete:function(){if(opt.hideLabels)that.labels.hideLabels(false);that.plot(opt);opt.onComplete();opt.onAfterCompute();}})).start();},nodeFx:function(opt){var viz=this.viz,graph=viz.graph,animation=this.nodeFxAnimation,options=$.merge(this.viz.config,{'elements':{'id':false,'properties':{}},'reposition':false});opt=$.merge(options,opt||{},{onBeforeCompute:$.empty,onAfterCompute:$.empty});animation.stopTimer();var props=opt.elements.properties;if(!opt.elements.id){graph.eachNode(function(n){for(var prop in props){n.setData(prop,props[prop],'end');}});}else{var ids=$.splat(opt.elements.id);$.each(ids,function(id){var n=graph.getNode(id);if(n){for(var prop in props){n.setData(prop,props[prop],'end');}}});}
var propnames=[];for(var prop in props)propnames.push(prop);var modes=['node-property:'+propnames.join(':')];if(opt.reposition){modes.push('linear');viz.compute('end');}
this.animate($.merge(opt,{modes:modes,type:'nodefx'}));},plot:function(opt,animating){var viz=this.viz,aGraph=viz.graph,canvas=viz.canvas,id=viz.root,that=this,ctx=canvas.getCtx(),min=Math.min,opt=opt||this.viz.controller;opt.clearCanvas&&canvas.clear();var root=aGraph.getNode(id);if(!root)return;var T=!!root.visited;aGraph.eachNode(function(node){var nodeAlpha=node.getData('alpha');node.eachAdjacency(function(adj){var nodeTo=adj.nodeTo;if(!!nodeTo.visited===T&&node.drawn&&nodeTo.drawn){!animating&&opt.onBeforePlotLine(adj);ctx.save();ctx.globalAlpha=min(nodeAlpha,nodeTo.getData('alpha'),adj.getData('alpha'));that.plotLine(adj,canvas,animating);ctx.restore();!animating&&opt.onAfterPlotLine(adj);}});ctx.save();if(node.drawn){!animating&&opt.onBeforePlotNode(node);that.plotNode(node,canvas,animating);!animating&&opt.onAfterPlotNode(node);}
if(!that.labelsHidden&&opt.withLabels){if(node.drawn&&nodeAlpha>=0.95){that.labels.plotLabel(canvas,node,opt);}else{that.labels.hideLabel(node,false);}}
ctx.restore();node.visited=!T;});},plotTree:function(node,opt,animating){var that=this,viz=this.viz,canvas=viz.canvas,config=this.config,ctx=canvas.getCtx();var nodeAlpha=node.getData('alpha');node.eachSubnode(function(elem){if(opt.plotSubtree(node,elem)&&elem.exist&&elem.drawn){var adj=node.getAdjacency(elem.id);!animating&&opt.onBeforePlotLine(adj);ctx.globalAlpha=Math.min(nodeAlpha,elem.getData('alpha'));that.plotLine(adj,canvas,animating);!animating&&opt.onAfterPlotLine(adj);that.plotTree(elem,opt,animating);}});if(node.drawn){!animating&&opt.onBeforePlotNode(node);this.plotNode(node,canvas,animating);!animating&&opt.onAfterPlotNode(node);if(!opt.hideLabels&&opt.withLabels&&nodeAlpha>=0.95)
this.labels.plotLabel(canvas,node,opt);else
this.labels.hideLabel(node,false);}else{this.labels.hideLabel(node,true);}},plotNode:function(node,canvas,animating){var f=node.getData('type'),ctxObj=this.node.CanvasStyles;if(f!='none'){var width=node.getData('lineWidth'),color=node.getData('color'),alpha=node.getData('alpha'),ctx=canvas.getCtx();ctx.lineWidth=width;ctx.fillStyle=ctx.strokeStyle=color;ctx.globalAlpha=alpha;for(var s in ctxObj){ctx[s]=node.getCanvasStyle(s);}
this.nodeTypes[f].render.call(this,node,canvas,animating);}},plotLine:function(adj,canvas,animating){var f=adj.getData('type'),ctxObj=this.edge.CanvasStyles;if(f!='none'){var width=adj.getData('lineWidth'),color=adj.getData('color'),ctx=canvas.getCtx();ctx.lineWidth=width;ctx.fillStyle=ctx.strokeStyle=color;for(var s in ctxObj){ctx[s]=adj.getCanvasStyle(s);}
this.edgeTypes[f].render.call(this,adj,canvas,animating);}}};Graph.Label={};Graph.Label.Native=new Class({plotLabel:function(canvas,node,controller){var ctx=canvas.getCtx();var pos=node.pos.getc(true);ctx.font=node.getLabelData('style')+' '+node.getLabelData('size')+'px '+node.getLabelData('family');ctx.textAlign=node.getLabelData('textAlign');ctx.fillStyle=ctx.strokeStyle=node.getLabelData('color');ctx.textBaseline=node.getLabelData('textBaseline');this.renderLabel(canvas,node,controller);},renderLabel:function(canvas,node,controller){var ctx=canvas.getCtx();var pos=node.pos.getc(true);ctx.fillText(node.name,pos.x,pos.y+node.getData("height")/2);},hideLabel:$.empty,hideLabels:$.empty});Graph.Label.DOM=new Class({labelsHidden:false,labelContainer:false,labels:{},getLabelContainer:function(){return this.labelContainer?this.labelContainer:this.labelContainer=document.getElementById(this.viz.config.labelContainer);},getLabel:function(id){return(id in this.labels&&this.labels[id]!=null)?this.labels[id]:this.labels[id]=document.getElementById(id);},hideLabels:function(hide){var container=this.getLabelContainer();if(hide)
container.style.display='none';else
container.style.display='';this.labelsHidden=hide;},clearLabels:function(force){for(var id in this.labels){if(force||!this.viz.graph.hasNode(id)){this.disposeLabel(id);delete this.labels[id];}}},disposeLabel:function(id){var elem=this.getLabel(id);if(elem&&elem.parentNode){elem.parentNode.removeChild(elem);}},hideLabel:function(node,show){node=$.splat(node);var st=show?"":"none",lab,that=this;$.each(node,function(n){var lab=that.getLabel(n.id);if(lab){lab.style.display=st;}});},fitsInCanvas:function(pos,canvas){var size=canvas.getSize();if(pos.x>=size.width||pos.x<0||pos.y>=size.height||pos.y<0)return false;return true;}});Graph.Label.HTML=new Class({Implements:Graph.Label.DOM,plotLabel:function(canvas,node,controller){var id=node.id,tag=this.getLabel(id);if(!tag&&!(tag=document.getElementById(id))){tag=document.createElement('div');var container=this.getLabelContainer();tag.id=id;tag.className='node';tag.style.position='absolute';controller.onCreateLabel(tag,node);container.appendChild(tag);this.labels[node.id]=tag;}
this.placeLabel(tag,node,controller);}});Graph.Label.SVG=new Class({Implements:Graph.Label.DOM,plotLabel:function(canvas,node,controller){var id=node.id,tag=this.getLabel(id);if(!tag&&!(tag=document.getElementById(id))){var ns='http://www.w3.org/2000/svg';tag=document.createElementNS(ns,'svg:text');var tspan=document.createElementNS(ns,'svg:tspan');tag.appendChild(tspan);var container=this.getLabelContainer();tag.setAttribute('id',id);tag.setAttribute('class','node');container.appendChild(tag);controller.onCreateLabel(tag,node);this.labels[node.id]=tag;}
this.placeLabel(tag,node,controller);}});Graph.Geom=new Class({initialize:function(viz){this.viz=viz;this.config=viz.config;this.node=viz.config.Node;this.edge=viz.config.Edge;},translate:function(pos,prop){prop=$.splat(prop);this.viz.graph.eachNode(function(elem){$.each(prop,function(p){elem.getPos(p).$add(pos);});});},setRightLevelToShow:function(node,canvas,callback){var level=this.getRightLevelToShow(node,canvas),fx=this.viz.labels,opt=$.merge({execShow:true,execHide:true,onHide:$.empty,onShow:$.empty},callback||{});node.eachLevel(0,this.config.levelsToShow,function(n){opt.onShow(n);if(opt.execShow){n.exist=true;}});node.drawn=true;},getRightLevelToShow:function(node,canvas){var config=this.config;var level=config.levelsToShow;var constrained=config.constrained;if(!constrained)return level;while(!this.treeFitsInCanvas(node,canvas,level)&&level>1){level--;}
return level;}});var Loader={construct:function(json){var isGraph=($.type(json)=='array');var ans=new Graph(this.graphOptions,this.config.Node,this.config.Edge,this.config.Label);if(!isGraph)
(function(ans,json){ans.addNode(json);if(json.children){for(var i=0,ch=json.children;i<ch.length;i++){ans.addAdjacence(json,ch[i]);arguments.callee(ans,ch[i]);}}})(ans,json);else
(function(ans,json){var getNode=function(id){for(var i=0,l=json.length;i<l;i++){if(json[i].id==id){return json[i];}}
var newNode={"id":id,"name":id};return ans.addNode(newNode);};for(var i=0,l=json.length;i<l;i++){ans.addNode(json[i]);var adj=json[i].adjacencies;if(adj){for(var j=0,lj=adj.length;j<lj;j++){var node=adj[j],data={};if(typeof adj[j]!='string'){data=$.merge(node.data,{});node=node.nodeTo;}
ans.addAdjacence(json[i],getNode(node),data);}}}})(ans,json);return ans;},loadJSON:function(json,i){this.json=json;if(this.labels&&this.labels.clearLabels){this.labels.clearLabels(true);}
this.graph=this.construct(json);if($.type(json)!='array'){this.root=json.id;}else{this.root=json[i?i:0].id;}},toJSON:function(type){type=type||"tree";if(type=='tree'){var ans={};var rootNode=this.graph.getNode(this.root);var ans=(function recTree(node){var ans={};ans.id=node.id;ans.name=node.name;ans.data=node.data;var ch=[];node.eachSubnode(function(n){ch.push(recTree(n));});ans.children=ch;return ans;})(rootNode);return ans;}else{var ans=[];var T=!!this.graph.getNode(this.root).visited;this.graph.eachNode(function(node){var ansNode={};ansNode.id=node.id;ansNode.name=node.name;ansNode.data=node.data;var adjs=[];node.eachAdjacency(function(adj){var nodeTo=adj.nodeTo;if(!!nodeTo.visited===T){var ansAdj={};ansAdj.nodeTo=nodeTo.id;ansAdj.data=adj.data;adjs.push(ansAdj);}});ansNode.adjacencies=adjs;ans.push(ansNode);node.visited=!T;});return ans;}}};var Layouts=$jit.Layouts={};var NodeDim={label:null,compute:function(graph,prop,opt){this.initializeLabel(opt);var label=this.label,style=label.style;graph.eachNode(function(n){var autoWidth=n.getData('autoWidth'),autoHeight=n.getData('autoHeight');if(autoWidth||autoHeight){delete n.data.$width;delete n.data.$height;delete n.data.$dim;var width=n.getData('width'),height=n.getData('height');style.width=autoWidth?'auto':width+'px';style.height=autoHeight?'auto':height+'px';label.innerHTML=n.name;var offsetWidth=label.offsetWidth,offsetHeight=label.offsetHeight;var type=n.getData('type');if($.indexOf(['circle','square','triangle','star'],type)===-1){n.setData('width',offsetWidth);n.setData('height',offsetHeight);}else{var dim=offsetWidth>offsetHeight?offsetWidth:offsetHeight;n.setData('width',dim);n.setData('height',dim);n.setData('dim',dim);}}});},initializeLabel:function(opt){if(!this.label){this.label=document.createElement('div');document.body.appendChild(this.label);}
this.setLabelStyles(opt);},setLabelStyles:function(opt){$.extend(this.label.style,{'visibility':'hidden','position':'absolute','width':'auto','height':'auto'});this.label.className='jit-autoadjust-label';}};Layouts.Tree=(function(){var slice=Array.prototype.slice;function getBoundaries(graph,config,level,orn,prop){var dim=config.Node;var multitree=config.multitree;if(dim.overridable){var w=-1,h=-1;graph.eachNode(function(n){if(n._depth==level&&(!multitree||('$orn'in n.data)&&n.data.$orn==orn)){var dw=n.getData('width',prop);var dh=n.getData('height',prop);w=(w<dw)?dw:w;h=(h<dh)?dh:h;}});return{'width':w<0?dim.width:w,'height':h<0?dim.height:h};}else{return dim;}}
function movetree(node,prop,val,orn){var p=(orn=="left"||orn=="right")?"y":"x";node.getPos(prop)[p]+=val;}
function moveextent(extent,val){var ans=[];$.each(extent,function(elem){elem=slice.call(elem);elem[0]+=val;elem[1]+=val;ans.push(elem);});return ans;}
function merge(ps,qs){if(ps.length==0)
return qs;if(qs.length==0)
return ps;var p=ps.shift(),q=qs.shift();return[[p[0],q[1]]].concat(merge(ps,qs));}
function mergelist(ls,def){def=def||[];if(ls.length==0)
return def;var ps=ls.pop();return mergelist(ls,merge(ps,def));}
function fit(ext1,ext2,subtreeOffset,siblingOffset,i){if(ext1.length<=i||ext2.length<=i)
return 0;var p=ext1[i][1],q=ext2[i][0];return Math.max(fit(ext1,ext2,subtreeOffset,siblingOffset,++i)
+subtreeOffset,p-q+siblingOffset);}
function fitlistl(es,subtreeOffset,siblingOffset){function $fitlistl(acc,es,i){if(es.length<=i)
return[];var e=es[i],ans=fit(acc,e,subtreeOffset,siblingOffset,0);return[ans].concat($fitlistl(merge(acc,moveextent(e,ans)),es,++i));};return $fitlistl([],es,0);}
function fitlistr(es,subtreeOffset,siblingOffset){function $fitlistr(acc,es,i){if(es.length<=i)
return[];var e=es[i],ans=-fit(e,acc,subtreeOffset,siblingOffset,0);return[ans].concat($fitlistr(merge(moveextent(e,ans),acc),es,++i));};es=slice.call(es);var ans=$fitlistr([],es.reverse(),0);return ans.reverse();}
function fitlist(es,subtreeOffset,siblingOffset,align){var esl=fitlistl(es,subtreeOffset,siblingOffset),esr=fitlistr(es,subtreeOffset,siblingOffset);if(align=="left")
esr=esl;else if(align=="right")
esl=esr;for(var i=0,ans=[];i<esl.length;i++){ans[i]=(esl[i]+esr[i])/2;}
return ans;}
function design(graph,node,prop,config,orn){var multitree=config.multitree;var auxp=['x','y'],auxs=['width','height'];var ind=+(orn=="left"||orn=="right");var p=auxp[ind],notp=auxp[1-ind];var cnode=config.Node;var s=auxs[ind],nots=auxs[1-ind];var siblingOffset=config.siblingOffset;var subtreeOffset=config.subtreeOffset;var align=config.align;function $design(node,maxsize,acum){var sval=node.getData(s,prop);var notsval=maxsize||(node.getData(nots,prop));var trees=[],extents=[],chmaxsize=false;var chacum=notsval+config.levelDistance;node.eachSubnode(function(n){if(n.exist&&(!multitree||('$orn'in n.data)&&n.data.$orn==orn)){if(!chmaxsize)
chmaxsize=getBoundaries(graph,config,n._depth,orn,prop);var s=$design(n,chmaxsize[nots],acum+chacum);trees.push(s.tree);extents.push(s.extent);}});var positions=fitlist(extents,subtreeOffset,siblingOffset,align);for(var i=0,ptrees=[],pextents=[];i<trees.length;i++){movetree(trees[i],prop,positions[i],orn);pextents.push(moveextent(extents[i],positions[i]));}
var resultextent=[[-sval/2,sval/2]].concat(mergelist(pextents));node.getPos(prop)[p]=0;if(orn=="top"||orn=="left"){node.getPos(prop)[notp]=acum;}else{node.getPos(prop)[notp]=-acum;}
return{tree:node,extent:resultextent};}
$design(node,false,0);}
return new Class({compute:function(property,computeLevels){var prop=property||'start';var node=this.graph.getNode(this.root);$.extend(node,{'drawn':true,'exist':true,'selected':true});NodeDim.compute(this.graph,prop,this.config);if(!!computeLevels||!("_depth"in node)){this.graph.computeLevels(this.root,0,"ignore");}
this.computePositions(node,prop);},computePositions:function(node,prop){var config=this.config;var multitree=config.multitree;var align=config.align;var indent=align!=='center'&&config.indent;var orn=config.orientation;var orns=multitree?['top','right','bottom','left']:[orn];var that=this;$.each(orns,function(orn){design(that.graph,node,prop,that.config,orn,prop);var i=['x','y'][+(orn=="left"||orn=="right")];(function red(node){node.eachSubnode(function(n){if(n.exist&&(!multitree||('$orn'in n.data)&&n.data.$orn==orn)){n.getPos(prop)[i]+=node.getPos(prop)[i];if(indent){n.getPos(prop)[i]+=align=='left'?indent:-indent;}
red(n);}});})(node);});}});})();$jit.ST=(function(){var nodesInPath=[];function getNodesToHide(node){node=node||this.clickedNode;if(!this.config.constrained){return[];}
var Geom=this.geom;var graph=this.graph;var canvas=this.canvas;var level=node._depth,nodeArray=[];graph.eachNode(function(n){if(n.exist&&!n.selected){if(n.isDescendantOf(node.id)){if(n._depth<=level)nodeArray.push(n);}else{nodeArray.push(n);}}});var leafLevel=Geom.getRightLevelToShow(node,canvas);node.eachLevel(leafLevel,leafLevel,function(n){if(n.exist&&!n.selected)nodeArray.push(n);});for(var i=0;i<nodesInPath.length;i++){var n=this.graph.getNode(nodesInPath[i]);if(!n.isDescendantOf(node.id)){nodeArray.push(n);}}
return nodeArray;};function getNodesToShow(node){var nodeArray=[],config=this.config;node=node||this.clickedNode;this.clickedNode.eachLevel(0,config.levelsToShow,function(n){if(config.multitree&&!('$orn'in n.data)&&n.anySubnode(function(ch){return ch.exist&&!ch.drawn;})){nodeArray.push(n);}else if(n.drawn&&!n.anySubnode("drawn")){nodeArray.push(n);}});return nodeArray;};return new Class({Implements:[Loader,Extras,Layouts.Tree],initialize:function(controller){var $ST=$jit.ST;var config={levelsToShow:2,levelDistance:30,constrained:true,Node:{type:'rectangle'},duration:700,offsetX:0,offsetY:0};this.controller=this.config=$.merge(Options("Canvas","Fx","Tree","Node","Edge","Controller","Tips","NodeStyles","Events","Navigation","Label"),config,controller);var canvasConfig=this.config;if(canvasConfig.useCanvas){this.canvas=canvasConfig.useCanvas;this.config.labelContainer=this.canvas.id+'-label';}else{if(canvasConfig.background){canvasConfig.background=$.merge({type:'Circles'},canvasConfig.background);}
this.canvas=new Canvas(this,canvasConfig);this.config.labelContainer=(typeof canvasConfig.injectInto=='string'?canvasConfig.injectInto:canvasConfig.injectInto.id)+'-label';}
this.graphOptions={'complex':true};this.graph=new Graph(this.graphOptions,this.config.Node,this.config.Edge);this.labels=new $ST.Label[canvasConfig.Label.type](this);this.fx=new $ST.Plot(this,$ST);this.op=new $ST.Op(this);this.group=new $ST.Group(this);this.geom=new $ST.Geom(this);this.clickedNode=null;this.initializeExtras();},plot:function(){this.fx.plot(this.controller);},switchPosition:function(pos,method,onComplete){var Geom=this.geom,Plot=this.fx,that=this;if(!Plot.busy){Plot.busy=true;this.contract({onComplete:function(){Geom.switchOrientation(pos);that.compute('end',false);Plot.busy=false;if(method=='animate'){that.onClick(that.clickedNode.id,onComplete);}else if(method=='replot'){that.select(that.clickedNode.id,onComplete);}}},pos);}},switchAlignment:function(align,method,onComplete){this.config.align=align;if(method=='animate'){this.select(this.clickedNode.id,onComplete);}else if(method=='replot'){this.onClick(this.clickedNode.id,onComplete);}},addNodeInPath:function(id){nodesInPath.push(id);this.select((this.clickedNode&&this.clickedNode.id)||this.root);},clearNodesInPath:function(id){nodesInPath.length=0;this.select((this.clickedNode&&this.clickedNode.id)||this.root);},refresh:function(){this.reposition();this.select((this.clickedNode&&this.clickedNode.id)||this.root);},reposition:function(){this.graph.computeLevels(this.root,0,"ignore");this.geom.setRightLevelToShow(this.clickedNode,this.canvas);this.graph.eachNode(function(n){if(n.exist)n.drawn=true;});this.compute('end');},requestNodes:function(node,onComplete){var handler=$.merge(this.controller,onComplete),lev=this.config.levelsToShow;if(handler.request){var leaves=[],d=node._depth;node.eachLevel(0,lev,function(n){if(n.drawn&&!n.anySubnode()){leaves.push(n);n._level=lev-(n._depth-d);}});this.group.requestNodes(leaves,handler);}
else
handler.onComplete();},contract:function(onComplete,switched){var orn=this.config.orientation;var Geom=this.geom,Group=this.group;if(switched)Geom.switchOrientation(switched);var nodes=getNodesToHide.call(this);if(switched)Geom.switchOrientation(orn);Group.contract(nodes,$.merge(this.controller,onComplete));},move:function(node,onComplete){this.compute('end',false);var move=onComplete.Move,offset={'x':move.offsetX,'y':move.offsetY};if(move.enable){this.geom.translate(node.endPos.add(offset).$scale(-1),"end");}
this.fx.animate($.merge(this.controller,{modes:['linear']},onComplete));},expand:function(node,onComplete){var nodeArray=getNodesToShow.call(this,node);this.group.expand(nodeArray,$.merge(this.controller,onComplete));},selectPath:function(node){var that=this;this.graph.eachNode(function(n){n.selected=false;});function path(node){if(node==null||node.selected)return;node.selected=true;$.each(that.group.getSiblings([node])[node.id],function(n){n.exist=true;n.drawn=true;});var parents=node.getParents();parents=(parents.length>0)?parents[0]:null;path(parents);};for(var i=0,ns=[node.id].concat(nodesInPath);i<ns.length;i++){path(this.graph.getNode(ns[i]));}},setRoot:function(id,method,onComplete){if(this.busy)return;this.busy=true;var that=this,canvas=this.canvas;var rootNode=this.graph.getNode(this.root);var clickedNode=this.graph.getNode(id);function $setRoot(){if(this.config.multitree&&clickedNode.data.$orn){var orn=clickedNode.data.$orn;var opp={'left':'right','right':'left','top':'bottom','bottom':'top'}[orn];rootNode.data.$orn=opp;(function tag(rootNode){rootNode.eachSubnode(function(n){if(n.id!=id){n.data.$orn=opp;tag(n);}});})(rootNode);delete clickedNode.data.$orn;}
this.root=id;this.clickedNode=clickedNode;this.graph.computeLevels(this.root,0,"ignore");this.geom.setRightLevelToShow(clickedNode,canvas,{execHide:false,onShow:function(node){if(!node.drawn){node.drawn=true;node.setData('alpha',1,'end');node.setData('alpha',0);node.pos.setc(clickedNode.pos.x,clickedNode.pos.y);}}});this.compute('end');this.busy=true;this.fx.animate({modes:['linear','node-property:alpha'],onComplete:function(){that.busy=false;that.onClick(id,{onComplete:function(){onComplete&&onComplete.onComplete();}});}});}
delete rootNode.data.$orns;if(method=='animate'){$setRoot.call(this);that.selectPath(clickedNode);}else if(method=='replot'){$setRoot.call(this);this.select(this.root);}},addSubtree:function(subtree,method,onComplete){if(method=='replot'){this.op.sum(subtree,$.extend({type:'replot'},onComplete||{}));}else if(method=='animate'){this.op.sum(subtree,$.extend({type:'fade:seq'},onComplete||{}));}},removeSubtree:function(id,removeRoot,method,onComplete){var node=this.graph.getNode(id),subids=[];node.eachLevel(+!removeRoot,false,function(n){subids.push(n.id);});if(method=='replot'){this.op.removeNode(subids,$.extend({type:'replot'},onComplete||{}));}else if(method=='animate'){this.op.removeNode(subids,$.extend({type:'fade:seq'},onComplete||{}));}},select:function(id,onComplete){var group=this.group,geom=this.geom;var node=this.graph.getNode(id),canvas=this.canvas;var root=this.graph.getNode(this.root);var complete=$.merge(this.controller,onComplete);var that=this;complete.onBeforeCompute(node);this.selectPath(node);this.clickedNode=node;this.requestNodes(node,{onComplete:function(){group.hide(group.prepare(getNodesToHide.call(that)),complete);geom.setRightLevelToShow(node,canvas);that.compute("current");that.graph.eachNode(function(n){var pos=n.pos.getc(true);n.startPos.setc(pos.x,pos.y);n.endPos.setc(pos.x,pos.y);n.visited=false;});var offset={x:complete.offsetX,y:complete.offsetY};that.geom.translate(node.endPos.add(offset).$scale(-1),["start","current","end"]);group.show(getNodesToShow.call(that));that.plot();complete.onAfterCompute(that.clickedNode);complete.onComplete();}});},onClick:function(id,options){var canvas=this.canvas,that=this,Geom=this.geom,config=this.config;var innerController={Move:{enable:true,offsetX:config.offsetX||0,offsetY:config.offsetY||0},setRightLevelToShowConfig:false,onBeforeRequest:$.empty,onBeforeContract:$.empty,onBeforeMove:$.empty,onBeforeExpand:$.empty};var complete=$.merge(this.controller,innerController,options);if(!this.busy){this.busy=true;var node=this.graph.getNode(id);this.selectPath(node,this.clickedNode);this.clickedNode=node;complete.onBeforeCompute(node);complete.onBeforeRequest(node);this.requestNodes(node,{onComplete:function(){complete.onBeforeContract(node);that.contract({onComplete:function(){Geom.setRightLevelToShow(node,canvas,complete.setRightLevelToShowConfig);complete.onBeforeMove(node);that.move(node,{Move:complete.Move,onComplete:function(){complete.onBeforeExpand(node);that.expand(node,{onComplete:function(){that.busy=false;complete.onAfterCompute(id);complete.onComplete();}});}});}});}});}}});})();$jit.ST.$extend=true;$jit.ST.Op=new Class({Implements:Graph.Op});$jit.ST.Group=new Class({initialize:function(viz){this.viz=viz;this.canvas=viz.canvas;this.config=viz.config;this.animation=new Animation;this.nodes=null;},requestNodes:function(nodes,controller){var counter=0,len=nodes.length,nodeSelected={};var complete=function(){controller.onComplete();};var viz=this.viz;if(len==0)complete();for(var i=0;i<len;i++){nodeSelected[nodes[i].id]=nodes[i];controller.request(nodes[i].id,nodes[i]._level,{onComplete:function(nodeId,data){if(data&&data.children){data.id=nodeId;viz.op.sum(data,{type:'nothing'});}
if(++counter==len){viz.graph.computeLevels(viz.root,0);complete();}}});}},contract:function(nodes,controller){var viz=this.viz;var that=this;nodes=this.prepare(nodes);this.animation.setOptions($.merge(controller,{$animating:false,compute:function(delta){if(delta==1)delta=0.99;that.plotStep(1-delta,controller,this.$animating);this.$animating='contract';},complete:function(){that.hide(nodes,controller);}})).start();},hide:function(nodes,controller){var viz=this.viz;for(var i=0;i<nodes.length;i++){if(true||!controller||!controller.request){nodes[i].eachLevel(1,false,function(elem){if(elem.exist){$.extend(elem,{'drawn':false,'exist':false});}});}else{var ids=[];nodes[i].eachLevel(1,false,function(n){ids.push(n.id);});viz.op.removeNode(ids,{'type':'nothing'});viz.labels.clearLabels();}}
controller.onComplete();},expand:function(nodes,controller){var that=this;this.show(nodes);this.animation.setOptions($.merge(controller,{$animating:false,compute:function(delta){that.plotStep(delta,controller,this.$animating);this.$animating='expand';},complete:function(){that.plotStep(undefined,controller,false);controller.onComplete();}})).start();},show:function(nodes){var config=this.config;this.prepare(nodes);$.each(nodes,function(n){if(config.multitree&&!('$orn'in n.data)){delete n.data.$orns;var orns=' ';n.eachSubnode(function(ch){if(('$orn'in ch.data)&&orns.indexOf(ch.data.$orn)<0&&ch.exist&&!ch.drawn){orns+=ch.data.$orn+' ';}});n.data.$orns=orns;}
n.eachLevel(0,config.levelsToShow,function(n){if(n.exist)n.drawn=true;});});},prepare:function(nodes){this.nodes=this.getNodesWithChildren(nodes);return this.nodes;},getNodesWithChildren:function(nodes){var ans=[],config=this.config,root=this.viz.root;nodes.sort(function(a,b){return(a._depth<=b._depth)-(a._depth>=b._depth);});for(var i=0;i<nodes.length;i++){if(nodes[i].anySubnode("exist")){for(var j=i+1,desc=false;!desc&&j<nodes.length;j++){if(!config.multitree||'$orn'in nodes[j].data){desc=desc||nodes[i].isDescendantOf(nodes[j].id);}}
if(!desc)ans.push(nodes[i]);}}
return ans;},plotStep:function(delta,controller,animating){var viz=this.viz,config=this.config,canvas=viz.canvas,ctx=canvas.getCtx(),nodes=this.nodes;var i,node;var nds={};for(i=0;i<nodes.length;i++){node=nodes[i];nds[node.id]=[];var root=config.multitree&&!('$orn'in node.data);var orns=root&&node.data.$orns;node.eachSubgraph(function(n){if(root&&orns&&orns.indexOf(n.data.$orn)>0&&n.drawn){n.drawn=false;nds[node.id].push(n);}else if((!root||!orns)&&n.drawn){n.drawn=false;nds[node.id].push(n);}});node.drawn=true;}
if(nodes.length>0)viz.fx.plot();for(i in nds){$.each(nds[i],function(n){n.drawn=true;});}
for(i=0;i<nodes.length;i++){node=nodes[i];ctx.save();viz.fx.plotSubtree(node,controller,delta,animating);ctx.restore();}},getSiblings:function(nodes){var siblings={};$.each(nodes,function(n){var par=n.getParents();if(par.length==0){siblings[n.id]=[n];}else{var ans=[];par[0].eachSubnode(function(sn){ans.push(sn);});siblings[n.id]=ans;}});return siblings;}});$jit.ST.Geom=new Class({Implements:Graph.Geom,switchOrientation:function(orn){this.config.orientation=orn;},dispatch:function(){var args=Array.prototype.slice.call(arguments);var s=args.shift(),len=args.length;var val=function(a){return typeof a=='function'?a():a;};if(len==2){return(s=="top"||s=="bottom")?val(args[0]):val(args[1]);}else if(len==4){switch(s){case"top":return val(args[0]);case"right":return val(args[1]);case"bottom":return val(args[2]);case"left":return val(args[3]);}}
return undefined;},getSize:function(n,invert){var data=n.data,config=this.config;var siblingOffset=config.siblingOffset;var s=(config.multitree&&('$orn'in data)&&data.$orn)||config.orientation;var w=n.getData('width')+siblingOffset;var h=n.getData('height')+siblingOffset;if(!invert)
return this.dispatch(s,h,w);else
return this.dispatch(s,w,h);},getTreeBaseSize:function(node,level,leaf){var size=this.getSize(node,true),baseHeight=0,that=this;if(leaf(level,node))return size;if(level===0)return 0;node.eachSubnode(function(elem){baseHeight+=that.getTreeBaseSize(elem,level-1,leaf);});return(size>baseHeight?size:baseHeight)+this.config.subtreeOffset;},getEdge:function(node,type,s){var $C=function(a,b){return function(){return node.pos.add(new Complex(a,b));};};var dim=this.node;var w=node.getData('width');var h=node.getData('height');if(type=='begin'){if(dim.align=="center"){return this.dispatch(s,$C(0,h/2),$C(-w/2,0),$C(0,-h/2),$C(w/2,0));}else if(dim.align=="left"){return this.dispatch(s,$C(0,h),$C(0,0),$C(0,0),$C(w,0));}else if(dim.align=="right"){return this.dispatch(s,$C(0,0),$C(-w,0),$C(0,-h),$C(0,0));}else throw"align: not implemented";}else if(type=='end'){if(dim.align=="center"){return this.dispatch(s,$C(0,-h/2),$C(w/2,0),$C(0,h/2),$C(-w/2,0));}else if(dim.align=="left"){return this.dispatch(s,$C(0,0),$C(w,0),$C(0,h),$C(0,0));}else if(dim.align=="right"){return this.dispatch(s,$C(0,-h),$C(0,0),$C(0,0),$C(-w,0));}else throw"align: not implemented";}},getScaledTreePosition:function(node,scale){var dim=this.node;var w=node.getData('width');var h=node.getData('height');var s=(this.config.multitree&&('$orn'in node.data)&&node.data.$orn)||this.config.orientation;var $C=function(a,b){return function(){return node.pos.add(new Complex(a,b)).$scale(1-scale);};};if(dim.align=="left"){return this.dispatch(s,$C(0,h),$C(0,0),$C(0,0),$C(w,0));}else if(dim.align=="center"){return this.dispatch(s,$C(0,h/2),$C(-w/2,0),$C(0,-h/2),$C(w/2,0));}else if(dim.align=="right"){return this.dispatch(s,$C(0,0),$C(-w,0),$C(0,-h),$C(0,0));}else throw"align: not implemented";},treeFitsInCanvas:function(node,canvas,level){var csize=canvas.getSize();var s=(this.config.multitree&&('$orn'in node.data)&&node.data.$orn)||this.config.orientation;var size=this.dispatch(s,csize.width,csize.height);var baseSize=this.getTreeBaseSize(node,level,function(level,node){return level===0||!node.anySubnode();});return(baseSize<size);}});$jit.ST.Plot=new Class({Implements:Graph.Plot,plotSubtree:function(node,opt,scale,animating){var viz=this.viz,canvas=viz.canvas,config=viz.config;scale=Math.min(Math.max(0.001,scale),1);if(scale>=0){node.drawn=false;var ctx=canvas.getCtx();var diff=viz.geom.getScaledTreePosition(node,scale);ctx.translate(diff.x,diff.y);ctx.scale(scale,scale);}
this.plotTree(node,$.merge(opt,{'withLabels':true,'hideLabels':!!scale,'plotSubtree':function(n,ch){var root=config.multitree&&!('$orn'in node.data);var orns=root&&node.getData('orns');return!root||orns.indexOf(elem.getData('orn'))>-1;}}),animating);if(scale>=0)node.drawn=true;},getAlignedPos:function(pos,width,height){var nconfig=this.node;var square,orn;if(nconfig.align=="center"){square={x:pos.x-width/2,y:pos.y-height/2};}else if(nconfig.align=="left"){orn=this.config.orientation;if(orn=="bottom"||orn=="top"){square={x:pos.x-width/2,y:pos.y};}else{square={x:pos.x,y:pos.y-height/2};}}else if(nconfig.align=="right"){orn=this.config.orientation;if(orn=="bottom"||orn=="top"){square={x:pos.x-width/2,y:pos.y-height};}else{square={x:pos.x-width,y:pos.y-height/2};}}else throw"align: not implemented";return square;},getOrientation:function(adj){var config=this.config;var orn=config.orientation;if(config.multitree){var nodeFrom=adj.nodeFrom;var nodeTo=adj.nodeTo;orn=(('$orn'in nodeFrom.data)&&nodeFrom.data.$orn)||(('$orn'in nodeTo.data)&&nodeTo.data.$orn);}
return orn;}});$jit.ST.Label={};$jit.ST.Label.Native=new Class({Implements:Graph.Label.Native,renderLabel:function(canvas,node,controller){var ctx=canvas.getCtx();var coord=node.pos.getc(true);ctx.fillText(node.name,coord.x,coord.y);}});$jit.ST.Label.DOM=new Class({Implements:Graph.Label.DOM,placeLabel:function(tag,node,controller){var pos=node.pos.getc(true),config=this.viz.config,dim=config.Node,canvas=this.viz.canvas,w=node.getData('width'),h=node.getData('height'),radius=canvas.getSize(),labelPos,orn;var ox=canvas.translateOffsetX,oy=canvas.translateOffsetY,sx=canvas.scaleOffsetX,sy=canvas.scaleOffsetY,posx=pos.x*sx+ox,posy=pos.y*sy+oy;if(dim.align=="center"){labelPos={x:Math.round(posx-w/2+radius.width/2),y:Math.round(posy-h/2+radius.height/2)};}else if(dim.align=="left"){orn=config.orientation;if(orn=="bottom"||orn=="top"){labelPos={x:Math.round(posx-w/2+radius.width/2),y:Math.round(posy+radius.height/2)};}else{labelPos={x:Math.round(posx+radius.width/2),y:Math.round(posy-h/2+radius.height/2)};}}else if(dim.align=="right"){orn=config.orientation;if(orn=="bottom"||orn=="top"){labelPos={x:Math.round(posx-w/2+radius.width/2),y:Math.round(posy-h+radius.height/2)};}else{labelPos={x:Math.round(posx-w+radius.width/2),y:Math.round(posy-h/2+radius.height/2)};}}else throw"align: not implemented";var style=tag.style;style.left=labelPos.x+'px';style.top=labelPos.y+'px';style.display=this.fitsInCanvas(labelPos,canvas)?'':'none';controller.onPlaceLabel(tag,node);}});$jit.ST.Label.SVG=new Class({Implements:[$jit.ST.Label.DOM,Graph.Label.SVG],initialize:function(viz){this.viz=viz;}});$jit.ST.Label.HTML=new Class({Implements:[$jit.ST.Label.DOM,Graph.Label.HTML],initialize:function(viz){this.viz=viz;}});$jit.ST.Plot.NodeTypes=new Class({'none':{'render':$.empty,'contains':$.lambda(false)},'circle':{'render':function(node,canvas){var dim=node.getData('dim'),pos=this.getAlignedPos(node.pos.getc(true),dim,dim),dim2=dim/2;this.nodeHelper.circle.render('fill',{x:pos.x+dim2,y:pos.y+dim2},dim2,canvas);},'contains':function(node,pos){var dim=node.getData('dim'),npos=this.getAlignedPos(node.pos.getc(true),dim,dim),dim2=dim/2;this.nodeHelper.circle.contains({x:npos.x+dim2,y:npos.y+dim2},dim2);}},'square':{'render':function(node,canvas){var dim=node.getData('dim'),dim2=dim/2,pos=this.getAlignedPos(node.pos.getc(true),dim,dim);this.nodeHelper.square.render('fill',{x:pos.x+dim2,y:pos.y+dim2},dim2,canvas);},'contains':function(node,pos){var dim=node.getData('dim'),npos=this.getAlignedPos(node.pos.getc(true),dim,dim),dim2=dim/2;this.nodeHelper.square.contains({x:npos.x+dim2,y:npos.y+dim2},dim2);}},'ellipse':{'render':function(node,canvas){var width=node.getData('width'),height=node.getData('height'),pos=this.getAlignedPos(node.pos.getc(true),width,height);this.nodeHelper.ellipse.render('fill',{x:pos.x+width/2,y:pos.y+height/2},width,height,canvas);},'contains':function(node,pos){var width=node.getData('width'),height=node.getData('height'),npos=this.getAlignedPos(node.pos.getc(true),width,height);this.nodeHelper.ellipse.contains({x:npos.x+width/2,y:npos.y+height/2},width,height,canvas);}},'rectangle':{'render':function(node,canvas){var width=node.getData('width'),height=node.getData('height'),pos=this.getAlignedPos(node.pos.getc(true),width,height);this.nodeHelper.rectangle.render('fill',{x:pos.x+width/2,y:pos.y+height/2},width,height,canvas);},'contains':function(node,pos){var width=node.getData('width'),height=node.getData('height'),npos=this.getAlignedPos(node.pos.getc(true),width,height);this.nodeHelper.rectangle.contains({x:npos.x+width/2,y:npos.y+height/2},width,height,canvas);}}});$jit.ST.Plot.EdgeTypes=new Class({'none':$.empty,'line':{'render':function(adj,canvas){var orn=this.getOrientation(adj),nodeFrom=adj.nodeFrom,nodeTo=adj.nodeTo,rel=nodeFrom._depth<nodeTo._depth,from=this.viz.geom.getEdge(rel?nodeFrom:nodeTo,'begin',orn),to=this.viz.geom.getEdge(rel?nodeTo:nodeFrom,'end',orn);this.edgeHelper.line.render(from,to,canvas);},'contains':function(adj,pos){var orn=this.getOrientation(adj),nodeFrom=adj.nodeFrom,nodeTo=adj.nodeTo,rel=nodeFrom._depth<nodeTo._depth,from=this.viz.geom.getEdge(rel?nodeFrom:nodeTo,'begin',orn),to=this.viz.geom.getEdge(rel?nodeTo:nodeFrom,'end',orn);return this.edgeHelper.line.contains(from,to,pos,this.edge.epsilon);}},'arrow':{'render':function(adj,canvas){var orn=this.getOrientation(adj),node=adj.nodeFrom,child=adj.nodeTo,dim=adj.getData('dim'),from=this.viz.geom.getEdge(node,'begin',orn),to=this.viz.geom.getEdge(child,'end',orn),direction=adj.data.$direction,inv=(direction&&direction.length>1&&direction[0]!=node.id);this.edgeHelper.arrow.render(from,to,dim,inv,canvas);},'contains':function(adj,pos){var orn=this.getOrientation(adj),nodeFrom=adj.nodeFrom,nodeTo=adj.nodeTo,rel=nodeFrom._depth<nodeTo._depth,from=this.viz.geom.getEdge(rel?nodeFrom:nodeTo,'begin',orn),to=this.viz.geom.getEdge(rel?nodeTo:nodeFrom,'end',orn);return this.edgeHelper.arrow.contains(from,to,pos,this.edge.epsilon);}},'quadratic:begin':{'render':function(adj,canvas){var orn=this.getOrientation(adj);var nodeFrom=adj.nodeFrom,nodeTo=adj.nodeTo,rel=nodeFrom._depth<nodeTo._depth,begin=this.viz.geom.getEdge(rel?nodeFrom:nodeTo,'begin',orn),end=this.viz.geom.getEdge(rel?nodeTo:nodeFrom,'end',orn),dim=adj.getData('dim'),ctx=canvas.getCtx();ctx.beginPath();ctx.moveTo(begin.x,begin.y);switch(orn){case"left":ctx.quadraticCurveTo(begin.x+dim,begin.y,end.x,end.y);break;case"right":ctx.quadraticCurveTo(begin.x-dim,begin.y,end.x,end.y);break;case"top":ctx.quadraticCurveTo(begin.x,begin.y+dim,end.x,end.y);break;case"bottom":ctx.quadraticCurveTo(begin.x,begin.y-dim,end.x,end.y);break;}
ctx.stroke();}},'quadratic:end':{'render':function(adj,canvas){var orn=this.getOrientation(adj);var nodeFrom=adj.nodeFrom,nodeTo=adj.nodeTo,rel=nodeFrom._depth<nodeTo._depth,begin=this.viz.geom.getEdge(rel?nodeFrom:nodeTo,'begin',orn),end=this.viz.geom.getEdge(rel?nodeTo:nodeFrom,'end',orn),dim=adj.getData('dim'),ctx=canvas.getCtx();ctx.beginPath();ctx.moveTo(begin.x,begin.y);switch(orn){case"left":ctx.quadraticCurveTo(end.x-dim,end.y,end.x,end.y);break;case"right":ctx.quadraticCurveTo(end.x+dim,end.y,end.x,end.y);break;case"top":ctx.quadraticCurveTo(end.x,end.y-dim,end.x,end.y);break;case"bottom":ctx.quadraticCurveTo(end.x,end.y+dim,end.x,end.y);break;}
ctx.stroke();}},'bezier':{'render':function(adj,canvas){var orn=this.getOrientation(adj),nodeFrom=adj.nodeFrom,nodeTo=adj.nodeTo,rel=nodeFrom._depth<nodeTo._depth,begin=this.viz.geom.getEdge(rel?nodeFrom:nodeTo,'begin',orn),end=this.viz.geom.getEdge(rel?nodeTo:nodeFrom,'end',orn),dim=adj.getData('dim'),ctx=canvas.getCtx();ctx.beginPath();ctx.moveTo(begin.x,begin.y);switch(orn){case"left":ctx.bezierCurveTo(begin.x+dim,begin.y,end.x-dim,end.y,end.x,end.y);break;case"right":ctx.bezierCurveTo(begin.x-dim,begin.y,end.x+dim,end.y,end.x,end.y);break;case"top":ctx.bezierCurveTo(begin.x,begin.y+dim,end.x,end.y-dim,end.x,end.y);break;case"bottom":ctx.bezierCurveTo(begin.x,begin.y-dim,end.x,end.y+dim,end.x,end.y);break;}
ctx.stroke();}}});})();
