Change script location.

Split js code.
Added cache and changed loading mechanism for js sources.
This commit is contained in:
Oleg Sh
2023-11-06 19:16:50 +02:00
parent c29ad15e3c
commit 43a4b44a22
86 changed files with 7738 additions and 3383 deletions

View File

@@ -0,0 +1,9 @@
// Global version needs to force reload scripts from server.
globalVersion = 75;
{
let modulDir = "pages/create_graph_by_edge_list/";
doInclude ([
include ("entities/graph/api/index.js")]);
}

View File

@@ -0,0 +1,594 @@
moduleLoader.beginCacheLoading(["/script/entities/graph/api/index.js?v=75","/script/shared/point.js?v=75","/script/entities/edge/api/index.js?v=75","/script/entities/edge/model/BaseEdge.js?v=75","/script/entities/edge/model/EdgeModel.js?v=75","/script/entities/vertex/api/index.js?v=75","/script/entities/vertex/model/BaseVertex.js?v=75","/script/entities/vertex/model/VertexModel.js?v=75","/script/entities/graph/model/Graph.js?v=75",]);globalVersion=75;{let modulDir="pages/create_graph_by_edge_list/";doInclude([include("entities/graph/api/index.js")]);}
{let modulDir="entities/graph/";doInclude([include("shared/point.js"),include("entities/edge/api/index.js"),include("entities/vertex/api/index.js"),include("model/Graph.js",modulDir)])}function Point(x,y){this.x=x||0;this.y=y||0;};Point.prototype.x=null;Point.prototype.y=null;Point.prototype.add=function(v){return new Point(this.x+v.x,this.y+v.y);};Point.prototype.addValue=function(v){return new Point(this.x+v,this.y+v);};Point.prototype.clone=function(){return new Point(this.x,this.y);};Point.prototype.degreesTo=function(v){var dx=this.x-v.x;var dy=this.y-v.y;var angle=Math.atan2(dy,dx);return angle*(180/Math.PI);};Point.prototype.distance=function(v){return Math.sqrt(this.distanceSqr(v));};Point.prototype.distanceSqr=function(v){var x=this.x-v.x;var y=this.y-v.y;return x*x+y*y;};Point.prototype.equals=function(toCompare){return this.x==toCompare.x&&this.y==toCompare.y;};Point.prototype.interpolate=function(v,f){return new Point((this.x+v.x)*f,(this.y+v.y)*f);};Point.prototype.length=function(){return Math.sqrt(this.x*this.x+this.y*this.y);};Point.prototype.normalize=function(thickness){var l=this.length();this.x=this.x/l*thickness;this.y=this.y/l*thickness;return new Point(this.x,this.y);};Point.prototype.normalizeCopy=function(thickness){var l=this.length();return new Point(this.x/l*thickness,this.y/l*thickness);};Point.prototype.orbit=function(origin,arcWidth,arcHeight,degrees){var radians=degrees*(Math.PI/180);this.x=origin.x+arcWidth*Math.cos(radians);this.y=origin.y+arcHeight*Math.sin(radians);};Point.prototype.rotate=function(center,degrees){var radians=degrees*(Math.PI/180);offset=this.subtract(center);this.x=offset.x*Math.cos(radians)-offset.y*Math.sin(radians);this.y=offset.x*Math.sin(radians)+offset.y*Math.cos(radians);this.x=this.x+center.x;this.y=this.y+center.y;return this;};Point.prototype.offset=function(dx,dy){this.x+=dx;this.y+=dy;};Point.prototype.subtract=function(v){return new Point(this.x-v.x,this.y-v.y);};Point.prototype.subtractValue=function(value){return new Point(this.x-value,this.y-value);};Point.prototype.multiply=function(value){return new Point(this.x*value,this.y*value);};Point.prototype.toString=function(){return"(x="+this.x+", y="+this.y+")";};Point.prototype.normal=function(){return new Point(-this.y,this.x);};Point.prototype.min=function(point)
{return new Point(Math.min(this.x,point.x),Math.min(this.y,point.y));};Point.prototype.max=function(point)
{return new Point(Math.max(this.x,point.x),Math.max(this.y,point.y));};Point.prototype.inverse=function()
{return new Point(-this.x,-this.y);};Point.prototype.cross=function(point)
{return this.x*point.y-this.y*point.x;};Point.interpolate=function(pt1,pt2,f){return new Point(pt1.x*(1.0-f)+pt2.x*f,pt1.y*(1.0-f)+pt2.y*f);};Point.polar=function(len,angle){return new Point(len*Math.cos(angle),len*Math.sin(angle));};Point.distance=function(pt1,pt2){var x=pt1.x-pt2.x;var y=pt1.y-pt2.y;return Math.sqrt(x*x+y*y);};Point.center=function(pt1,pt2){return new Point((pt1.x+pt2.x)/2.0,(pt1.y+pt2.y)/2.0);};Point.toString=function(){return x+" "+y;}
Point.projection=function(point,line1,line2)
{var x=line2.y-line1.y;var y=line1.x-line2.x;var l=(line1.cross(line2)+line1.cross(point)+line2.cross(point))/(x*(line2.y-line1.y)+y*(line1.x-line2.x));var res=new Point(point.x+x*l,point.y+y*l);return res;}
Point.hitTest=function(pt11,pt12,pt21,pt22)
{var res=null;var n=0.0;var x1=pt11.x;var y1=pt11.y;var x2=pt12.x;var y2=pt12.y;var x3=pt21.x;var y3=pt21.y;var x4=pt22.x;var y4=pt22.y;if(y2-y1!=0.0)
{var q=(x2-x1)/(y1-y2);var sn=(x3-x4)+(y3-y4)*q;if(sn==0.0)
{return res;}
var fn=(x3-x1)+(y3-y1)*q;n=fn/sn;}
else
{if((y3-y4)==0.0)
{return res;}
n=(y3-y1)/(y3-y4);}
res=new Point(x3+(x4-x3)*n,y3+(y4-y3)*n);var epsilon=1E-5;if(!(res.x>=Math.min(x1,x2)-epsilon&&res.x>=Math.min(x3,x4)-epsilon&&res.x<=Math.max(x1,x2)+epsilon&&res.x<=Math.max(x3,x4)+epsilon&&res.y>=Math.min(y1,y2)-epsilon&&res.y>=Math.min(y3,y4)-epsilon&&res.y<=Math.max(y1,y2)+epsilon&&res.y<=Math.max(y3,y4)+epsilon))
{res=null;}
return res;}
function Rect(minPoint,maxPoint){this.minPoint=minPoint;this.maxPoint=maxPoint;};Rect.prototype.center=function()
{return Point.center(this.minPoint,this.maxPoint);};Rect.prototype.size=function()
{return this.maxPoint.subtract(this.minPoint);};Rect.prototype.left=function()
{return this.minPoint.x;};Rect.prototype.top=function()
{return this.minPoint.y;};Rect.prototype.isIn=function(v)
{return this.minPoint.x<=v.x&&this.minPoint.y<=v.y&&this.maxPoint.x>v.x&&this.maxPoint.y>v.y;};{let modulDir="entities/edge/";doInclude([include("model/BaseEdge.js",modulDir),include("model/EdgeModel.js",modulDir)])}
function BaseEdge(vertex1,vertex2,isDirect,weight,upText)
{this.vertex1=vertex1;this.vertex2=vertex2;this.arrayStyleStart="";this.arrayStyleFinish="";this.isDirect=isDirect;this.weight=0;this.text="";this.useWeight=false;this.id=0;this.model=new EdgeModel();if(upText===undefined)
this.upText="";else
this.upText=upText;if(weight!==undefined)
this.SetWeight(weight);this.ownStyles={};}
BaseEdge.prototype.copyFrom=function(other)
{this.vertex1=other.vertex1;this.vertex2=other.vertex2;this.arrayStyleStart=other.arrayStyleStart;this.arrayStyleFinish=other.arrayStyleFinish;this.isDirect=other.isDirect;this.weight=other.weight;this.text=other.text;this.useWeight=other.useWeight;this.id=other.id;this.model=new EdgeModel();this.model.copyFrom(other.model);this.upText=other.upText;this.ownStyles=FullObjectCopy(other.ownStyles);}
BaseEdge.prototype.SaveToXML=function()
{return"<edge "+"source=\""+this.vertex1.id+"\" "+"target=\""+this.vertex2.id+"\" "+"isDirect=\""+this.isDirect+"\" "+"weight=\""+this.weight+"\" "+"useWeight=\""+this.useWeight+"\" "+"id=\""+this.id+"\" "+"text=\""+gEncodeToHTML(this.text)+"\" "+"upText=\""+gEncodeToHTML(this.upText)+"\" "+"arrayStyleStart=\""+this.arrayStyleStart+"\" "+"arrayStyleFinish=\""+this.arrayStyleFinish+"\" "+
((Object.keys(this.ownStyles).length>0)?"ownStyles = \""+gEncodeToHTML(JSON.stringify(this.ownStyles))+"\" ":"")+
this.model.SaveToXML()+"></edge>";}
BaseEdge.prototype.LoadFromXML=function(xml,graph)
{var attr=xml.attr('vertex1');if(typeof attr==='undefined')
{attr=xml.attr('source');}
this.vertex1=graph.FindVertex(typeof attr!=='undefined'?attr:xml.attr('graph1'));var attr=xml.attr('vertex2');if(typeof attr==='undefined')
{attr=xml.attr('target');}
this.vertex2=graph.FindVertex(typeof attr!=='undefined'?attr:xml.attr('graph2'));this.isDirect=xml.attr('isDirect')=="true";this.weight=parseFloat(xml.attr('weight'));if(isNaN(this.weight))
{this.weight=1;}
this.hasPair=xml.attr('hasPair')=="true";this.useWeight=xml.attr('useWeight')=="true";this.id=xml.attr('id');this.text=xml.attr("text")==null?"":gDecodeFromHTML(xml.attr("text"));this.arrayStyleStart=xml.attr("arrayStyleStart")==null?"":xml.attr("arrayStyleStart");this.arrayStyleFinish=xml.attr("arrayStyleFinish")==null?"":xml.attr("arrayStyleFinish");this.upText=xml.attr('upText');if(typeof this.upText==='undefined')
{this.upText="";}
else
{this.upText=gDecodeFromHTML(this.upText);}
var ownStyle=xml.attr('ownStyles');if(typeof ownStyle!=='undefined')
{var parsedSave=gDecodeFromHTML(JSON.parse(ownStyle));for(var indexField in parsedSave)
{var index=parseInt(indexField);this.ownStyles[index]=FullObjectCopy(this.getStyleFor(index));for(var field in parsedSave[indexField])
{if(this.ownStyles[index].ShouldLoad(field))
this.ownStyles[index][field]=parsedSave[indexField][field];}}}
this.model.LoadFromXML(xml);}
BaseEdge.prototype.GetPixelLength=function()
{if(this.vertex1==this.vertex2)
{return this.model.GetLoopSize()*2*Math.PI;}
else
{return Point.distance(this.vertex1.position,this.vertex2.position);}}
BaseEdge.prototype.GetWeight=function()
{return this.useWeight?this.weight:1;}
BaseEdge.prototype.GetText=function()
{return this.text.length>0?this.text:(this.useWeight?this.weight.toString():"");}
BaseEdge.prototype.GetUpText=function()
{return this.upText;}
BaseEdge.prototype.GetStartEdgeStyle=function()
{return this.arrayStyleStart;}
BaseEdge.prototype.GetFinishEdgeStyle=function()
{return(this.arrayStyleFinish!=""?this.arrayStyleFinish:(this.isDirect?"arrow":""));}
BaseEdge.prototype.HitTest=function(pos)
{var positions=this.GetEdgePositionsShift();return this.model.HitTest(positions[0],positions[1],pos);}
BaseEdge.prototype.GetEdgePositionsShift=function()
{return this.GetEdgePositions();}
BaseEdge.prototype.GetEdgePositions=function()
{var res=[];if(this.vertex1==this.vertex2)
{res.push(this.vertex1.position);res.push(this.vertex2.position);return res;}
var position1=this.vertex1.position;var position2=this.vertex2.position;var diameter1=this.vertex1.model.diameter+parseInt(this.vertex1.currentStyle.GetStyle({},this.vertex1).lineWidth);var diameter2=this.vertex2.model.diameter+parseInt(this.vertex2.currentStyle.GetStyle({},this.vertex2).lineWidth);var direction=position1.subtract(position2);var direction1=direction;var direction2=direction;var d1=diameter1;var d2=diameter2;if(this.model.type==EdgeModels.curve)
{var dist=position1.distance(position2);var point1=this.model.GetCurvePoint(position1,position2,10.0/dist);direction1=position1.subtract(point1);var point2=this.model.GetCurvePoint(position1,position2,1.0-10.0/dist);direction2=position2.subtract(point2);d2=diameter2;}
else
{direction2=direction2.multiply(-1);}
direction1.normalize(1.0);direction2.normalize(1.0);var vertices=[];vertices.push({vertex:this.vertex1,direction:direction1,position:position1,diameter:d1});vertices.push({vertex:this.vertex2,direction:direction2,position:position2,diameter:d2});vertices.forEach(function(data)
{var shape=data.vertex.currentStyle.GetStyle({},data.vertex).shape;if(shape==VertexCircleShape)
{var direction=data.direction.multiply(0.5);res.push(data.position.subtract(direction.multiply(data.diameter)));}
else
{var lineFinish1=data.direction.multiply(-1).multiply(1000.0);var pointsVertex1=GetPointsForShape(shape,data.diameter,data.vertex.mainText);pointsVertex1.push(pointsVertex1[0]);for(var i=0;i<pointsVertex1.length-1;i++)
{var hitText=Point.hitTest(new Point(0,0),lineFinish1,pointsVertex1[i],pointsVertex1[i+1]);if(hitText!=null)
{res.push(data.position.add(hitText));break;}}}});return res;}
BaseEdge.prototype.SetWeight=function(weight)
{var useWeight=false;if(!isNaN(parseInt(weight,10)))
{useWeight=true;}
weight=(!isNaN(parseInt(weight,10))&&weight>=0)?weight:1;this.weight=Number(weight);this.useWeight=useWeight;}
BaseEdge.prototype.SetUpText=function(text)
{this.upText=text;}
BaseEdge.prototype.resetOwnStyle=function(index)
{if(this.ownStyles.hasOwnProperty(index))
{delete this.ownStyles[index];}}
BaseEdge.prototype.setOwnStyle=function(index,style)
{this.ownStyles[index]=style;}
BaseEdge.prototype.getStyleFor=function(index)
{if(this.ownStyles.hasOwnProperty(index))
{return this.ownStyles[index];}
else
{var style=null;if(index==0)
style=globalApplication.GetStyle("edge","common");else
style=globalApplication.GetStyle("edge","selected",undefined,index-1);return style;}}
BaseEdge.prototype.hasOwnStyleFor=function(index)
{return this.ownStyles.hasOwnProperty(index);}
var EdgeModels={"line":0,"curve":1};const defaultEdgeWidth=4;function EdgeModel()
{this.width=globalApplication.GetDefaultEdgeWidth();this.type=EdgeModels.line;this.curveValue=EdgeModel.prototype.defaultCurve;this.default=true;this.sizeOfLoop=24;this.loopShiftAngel=Math.PI/6;}
EdgeModel.prototype.defaultCurve=0.1;EdgeModel.prototype.copyFrom=function(other)
{this.width=other.width;this.type=other.type;this.curveValue=other.curveValue;this.default=other.default;}
EdgeModel.prototype.SaveToXML=function()
{return"model_width=\""+this.width+"\" "+"model_type=\""+this.type+"\" "+"model_curveValue=\""+this.curveValue+"\" "+"model_default=\""+this.default+"\" ";}
EdgeModel.prototype.LoadFromXML=function(xml,graph)
{this.width=xml.attr('model_width')==null?this.width:parseFloat(xml.attr("model_width"));this.type=xml.attr('model_type')==null?this.type:xml.attr("model_type");this.curveValue=xml.attr('model_curveValue')==null?this.curveValue:parseFloat(xml.attr("model_curveValue"));this.default=xml.attr('model_default')==null?this.default:parseFloat(xml.attr("model_default"));}
EdgeModel.prototype.GetCurvePoint=function(position1,position2,t)
{var points=this.GetBezierPoints(position1,position2);var firstBezierPoint=points[0];var secondBezierPoint=points[1];var B0_t=Math.pow(1-t,3);var B1_t=3*t*Math.pow(1-t,2);var B2_t=3*t*t*(1-t)
var B3_t=t*t*t;var ax=position1.x;var ay=position1.y;var dx=position2.x;var dy=position2.y;var bx=firstBezierPoint.x;var by=firstBezierPoint.y;var cx=secondBezierPoint.x;var cy=secondBezierPoint.y;var px_t=(B0_t*ax)+(B1_t*bx)+(B2_t*cx)+(B3_t*dx);var py_t=(B0_t*ay)+(B1_t*by)+(B2_t*cy)+(B3_t*dy);return new Point(px_t,py_t);}
EdgeModel.prototype.GetBezierPoints=function(position1,position2)
{var direction=position2.subtract(position1);var delta=direction.length();direction.normalize(1.0);var normal=direction.normal();var deltaOffsetPixels=delta*this.curveValue;var yOffset=normal.multiply(deltaOffsetPixels);var firstBezierPointShift=(direction.multiply(delta*0.2)).add(yOffset);var secondBezierPointShift=(direction.multiply(-delta*0.2)).add(yOffset);var firstBezierPoint=position1.add(firstBezierPointShift);var secondBezierPoint=position2.add(secondBezierPointShift);return[firstBezierPoint,secondBezierPoint];}
EdgeModel.prototype.HitTest=function(position1,position2,mousePos)
{if(this.type==EdgeModels.line)
return this.HitTestLine(position1,position2,mousePos);else if(this.type==EdgeModels.curve)
return this.HitTestCurve(position1,position2,mousePos);return false;}
EdgeModel.prototype.HitTestLine=function(position1,position2,mousePos,factor)
{if(factor===undefined)
{factor=1.0;}
var pos1=position1;var pos2=position2;var pos0=mousePos;if(pos1.equals(pos2))
{var xCenter=pos1.x-Math.cos(this.GetLoopShiftAngel())*this.GetLoopSize();var yCenter=pos1.y-Math.sin(this.GetLoopShiftAngel())*this.GetLoopSize();return Math.abs((Point.distance(new Point(xCenter,yCenter),pos0))-this.GetLoopSize())<=this.width*1.5*factor;}
var r1=pos0.distance(pos1);var r2=pos0.distance(pos2);var r12=pos1.distance(pos2);if(r1>=(new Point(r2,r12)).length()||r2>=(new Point(r1,r12)).length())
{}
else
{var distance=((pos1.y-pos2.y)*pos0.x+(pos2.x-pos1.x)*pos0.y+(pos1.x*pos2.y-pos2.x*pos1.y))/r12;if(Math.abs(distance)<=this.width*1.5*factor)
{return true;}}
return false;}
EdgeModel.prototype.HitTestCurve=function(position1,position2,mousePos)
{var pos1=position1;var pos2=position2;var pos0=mousePos;if(pos1.equals(pos2))
{var xCenter=pos1.x-Math.cos(this.GetLoopShiftAngel())*this.GetLoopSize();var yCenter=pos1.y-Math.sin(this.GetLoopShiftAngel())*this.GetLoopSize();return Math.abs((Point.distance(new Point(xCenter,yCenter),pos0))-this.GetLoopSize())<=this.width*1.5;}
var interval_count=position1.distance(position2)/100*30;var start=position1;for(var i=0;i<interval_count;i++)
{var finish=this.GetCurvePoint(position1,position2,i/interval_count);if(this.HitTestLine(start,finish,mousePos,2.0))
return true;start=finish;}
return false;}
EdgeModel.prototype.ChangeCurveValue=function(delta)
{if(this.type==EdgeModels.line)
{this.type=EdgeModels.curve;this.curveValue=0.0;}
this.curveValue=this.curveValue+delta;if(Math.abs(this.curveValue)<=0.01)
this.type=EdgeModels.line;this.default=false;}
EdgeModel.prototype.SetCurveValue=function(value)
{if(this.type==EdgeModels.line)
{this.type=EdgeModels.curve;this.curveValue=0.0;}
this.curveValue=value;if(Math.abs(this.curveValue)<=0.01)
this.type=EdgeModels.line;this.default=false;}
EdgeModel.prototype.GetLoopSize=function()
{if(Math.abs(this.curveValue)<=0.01)
{return this.sizeOfLoop;}
else
{let normalCurve=this.curveValue;if(this.type==EdgeModels.line){normalCurve=this.defaultCurve;}
else if(normalCurve>=0.0){normalCurve+=this.defaultCurve}
return this.sizeOfLoop*Math.abs(normalCurve)*(1/this.defaultCurve);}}
EdgeModel.prototype.GetLoopShiftAngel=function()
{if(this.type==EdgeModels.line||this.curveValue>=0.0)
{return this.loopShiftAngel;}
else
{return this.loopShiftAngel+Math.PI;}}
{let modulDir="entities/vertex/";doInclude([include("model/BaseVertex.js",modulDir),include("model/VertexModel.js",modulDir)])}
function BaseVertex(x,y,vertexEnumType)
{this.position=new Point(x,y);this.id=0;this.mainText="";this.upText="";this.vertexEnumType=vertexEnumType;this.model=new VertexModel();this.hasUndefinedPosition=false;this.ownStyles={};};BaseVertex.prototype.position=new Point(0,0);BaseVertex.prototype.copyFrom=function(other)
{this.position=new Point(other.position.x,other.position.y);this.id=other.id;this.mainText=other.mainText;this.upText=other.upText;this.vertexEnumType=other.vertexEnumType;this.model=new VertexModel();this.hasUndefinedPosition=other.hasUndefinedPosition;this.ownStyles=FullObjectCopy(other.ownStyles);}
BaseVertex.prototype.SaveToXML=function()
{return"<node "+"positionX=\""+this.position.x+"\" "+"positionY=\""+this.position.y+"\" "+"id=\""+this.id+"\" "+"mainText=\""+gEncodeToHTML(this.mainText)+"\" "+"upText=\""+gEncodeToHTML(this.upText)+"\" "+
((Object.keys(this.ownStyles).length>0)?"ownStyles = \""+gEncodeToHTML(JSON.stringify(this.ownStyles))+"\" ":"")+"size=\""+this.model.diameter+"\" "+"></node>";}
BaseVertex.prototype.LoadFromXML=function(xml)
{var xmlX=xml.attr('positionX');var xmlY=xml.attr('positionY');this.hasUndefinedPosition=(typeof xmlX==='undefined')||(typeof xmlY==='undefined');this.position=new Point(parseFloat(xmlX),parseFloat(xmlY));this.id=xml.attr('id');this.mainText=xml.attr('mainText');this.upText=xml.attr('upText');if(typeof this.mainText==='undefined')
this.mainText=this.id;else
this.mainText=gDecodeFromHTML(this.mainText);if(typeof this.upText==='undefined')
this.upText="";else
this.upText=gDecodeFromHTML(this.upText);var ownStyle=xml.attr('ownStyles');if(typeof ownStyle!=='undefined')
{var parsedSave=gDecodeFromHTML(JSON.parse(ownStyle));for(var indexField in parsedSave)
{var index=parseInt(indexField);this.ownStyles[index]=FullObjectCopy(this.getStyleFor(index));for(var field in parsedSave[indexField])
{if(this.ownStyles[index].ShouldLoad(field))
this.ownStyles[index][field]=parsedSave[indexField][field];}}}
var size=xml.attr('size');if(typeof size!=='undefined')
this.model.diameter=parseInt(size);}
BaseVertex.prototype.SetId=function(id)
{this.id=id;if(this.vertexEnumType!=null)
this.mainText=this.vertexEnumType.GetVertexText(id);}
BaseVertex.prototype.diameterFactor=function()
{return new Point(1.0+(this.mainText.length?this.mainText.length/8.0:0),1.5);}
BaseVertex.prototype.IsUndefinedPosition=function()
{return this.hasUndefinedPosition;}
BaseVertex.prototype.HitTest=function(pos)
{var shape=this.hasOwnProperty('currentStyle')?this.currentStyle.GetStyle({},this).shape:VertexCircleShape;var width=this.hasOwnProperty('currentStyle')?this.currentStyle.GetStyle({},this).lineWidth:0;if(shape==VertexCircleShape)
{return this.position.distance(pos)<this.model.diameter/2.0+width;}
else
{var relativePos=(new Point(pos.x,pos.y)).subtract(this.position);var lineFinish1=relativePos.add(new Point(1000,0));var lineFinish2=relativePos.add(new Point(-1000,0));var pointsVertex1=GetPointsForShape(shape,this.model.diameter+width,this.mainText);pointsVertex1.push(pointsVertex1[0]);var hitNumber1=0;var hitNumber2=0;for(var i=0;i<pointsVertex1.length-1;i++)
{var hitTest=Point.hitTest(relativePos,lineFinish1,pointsVertex1[i],pointsVertex1[i+1]);if(hitTest!=null)
{hitNumber1++;}
hitTest=Point.hitTest(relativePos,lineFinish2,pointsVertex1[i],pointsVertex1[i+1]);if(hitTest!=null)
{hitNumber2++;}}
return hitNumber1==1&&hitNumber2==1;}
return false;}
BaseVertex.prototype.resetOwnStyle=function(index)
{if(this.ownStyles.hasOwnProperty(index))
{delete this.ownStyles[index];}}
BaseVertex.prototype.setOwnStyle=function(index,style)
{this.ownStyles[index]=FullObjectCopy(style);}
BaseVertex.prototype.getStyleFor=function(index)
{if(this.ownStyles.hasOwnProperty(index))
{return this.ownStyles[index];}
else
{var style=null;if(index==0)
style=globalApplication.GetStyle("vertex","common");else
style=globalApplication.GetStyle("vertex","selected",undefined,index-1);return style;}}
BaseVertex.prototype.hasOwnStyleFor=function(index)
{return this.ownStyles.hasOwnProperty(index);}
const defaultVertexDiameter=30;function VertexModel()
{this.diameter=globalApplication.GetDefaultVertexSize();}
function Graph()
{this.vertices=[];this.edges=[];this.uidGraph=0;this.uidEdge=10000;this.hasDirect=false;this.isMultiGraph=false;};Graph.prototype.infinity=1E8;Graph.prototype.maxVertices=1000;Graph.prototype.edgesOffset=10000;Graph.prototype.AddNewVertex=function(vertex)
{if(this.vertices.length<=this.maxVertices)
{vertex.SetId(this.uidGraph);this.uidGraph=this.uidGraph+1;this.vertices.push(vertex);}
return this.vertices.length-1;}
Graph.prototype.ClearGraph=function(){this.vertices=[];this.edges=[];this.uidGraph=0;this.uidEdge=10000;this.hasDirect=false;this.isMultiGraph=false;}
Graph.prototype.AddNewEdgeSafe=function(graph1,graph2,isDirect,weight,replaceIfExists=true)
{return this.AddNewEdge(new BaseEdge(graph1,graph2,isDirect,weight),replaceIfExists);}
Graph.prototype.AddNewEdge=function(edge,replaceIfExists)
{edge.id=this.uidEdge;this.uidEdge=this.uidEdge+1;var edge1=this.FindEdgeAny(edge.vertex1.id,edge.vertex2.id);var edgeRevert=this.FindEdgeAny(edge.vertex2.id,edge.vertex1.id);if(!edge.isDirect)
{if(edge1!=null&&replaceIfExists)
this.DeleteEdge(edge1);if(edgeRevert!=null&&replaceIfExists)
this.DeleteEdge(edgeRevert);this.edges.push(edge);}
else
{if(edge1!=null&&replaceIfExists)
this.DeleteEdge(edge1);if(edgeRevert!=null&&!edgeRevert.isDirect&&replaceIfExists)
this.DeleteEdge(edgeRevert);this.edges.push(edge);}
this.isMultiGraph=this.checkMutiGraph();return this.edges.length-1;}
Graph.prototype.DeleteEdge=function(edgeObject)
{var index=this.edges.indexOf(edgeObject);if(index>-1)
{this.edges.splice(index,1);}
this.isMultiGraph=this.checkMutiGraph();}
Graph.prototype.DeleteVertex=function(vertexObject)
{var index=this.vertices.indexOf(vertexObject);if(index>-1)
{for(var i=0;i<this.edges.length;i++)
{if(this.edges[i].vertex1==vertexObject||this.edges[i].vertex2==vertexObject)
{this.DeleteEdge(this.edges[i]);i--;}}
this.vertices.splice(index,1);}}
Graph.prototype.HasConnectedNodes=function(vertexObject)
{var res=false;var index=this.vertices.indexOf(vertexObject);if(index>-1)
{for(var i=0;i<this.edges.length;i++)
{if(this.edges[i].vertex1==vertexObject||this.edges[i].vertex2==vertexObject)
{res=true;break;}}}
return res;}
Graph.prototype.FindVertex=function(id)
{var res=null;for(var i=0;i<this.vertices.length;i++)
{if(this.vertices[i].id==id)
{res=this.vertices[i];break;}}
return res;}
Graph.prototype.FindVertexByTitle=function(title)
{var res=null;for(var i=0;i<this.vertices.length;i++)
{if(this.vertices[i].mainText==title)
{res=this.vertices[i];break;}}
return res;}
Graph.prototype.FindEdge=function(id1,id2)
{return this.FindEdgeAny(id1,id2);}
Graph.prototype.FindEdgeById=function(edgeId)
{var res=null;for(var i=0;i<this.edges.length;i++)
{if(this.edges[i].id==edgeId)
{res=this.edges[i];break;}}
return res;}
Graph.prototype.FindEdgeAny=function(id1,id2)
{var res=null;for(var i=0;i<this.edges.length;i++)
{if((this.edges[i].vertex1.id==id1&&this.edges[i].vertex2.id==id2)||(!this.edges[i].isDirect&&this.edges[i].vertex1.id==id2&&this.edges[i].vertex2.id==id1))
{res=this.edges[i];break;}}
return res;}
Graph.prototype.FindEdgeMin=function(id1,id2)
{var res=null;var minWeight=this.infinity;for(var i=0;i<this.edges.length;i++)
{var edge=this.edges[i];if((edge.vertex1.id==id1&&edge.vertex2.id==id2)||(!edge.isDirect&&edge.vertex1.id==id2&&edge.vertex2.id==id1))
{if(edge.weight<minWeight)
{res=edge;minWeight=edge.weight;}}}
return res;}
Graph.prototype.FindEdgeMax=function(id1,id2)
{var res=null;var maxWeight=0;for(var i=0;i<this.edges.length;i++)
{var edge=this.edges[i];if((edge.vertex1.id==id1&&edge.vertex2.id==id2)||(!edge.isDirect&&edge.vertex1.id==id2&&edge.vertex2.id==id1))
{if(edge.weight>maxWeight)
{res=edge;maxWeight=edge.weight;}}}
return res;}
Graph.prototype.FindEdgeMinIgnoreDirection=function(id1,id2)
{var res=null;var minWeight=this.infinity;for(var i=0;i<this.edges.length;i++)
{var edge=this.edges[i];if((edge.vertex1.id==id1&&edge.vertex2.id==id2)||(edge.vertex1.id==id2&&edge.vertex2.id==id1))
{if(edge.weight<minWeight)
{res=edge;minWeight=edge.weight;}}}
return res;}
Graph.prototype.FindAllEdges=function(id1,id2)
{var res=[];for(var i=0;i<this.edges.length;i++)
{var edge=this.edges[i];if((edge.vertex1.id==id1&&edge.vertex2.id==id2)||(!edge.isDirect&&edge.vertex1.id==id2&&edge.vertex2.id==id1))
{res.push(edge);}}
return res;}
Graph.prototype.GetAdjacencyMatrixStr=function()
{var matrix="";for(var i=0;i<this.vertices.length;i++)
{for(var j=0;j<this.vertices.length;j++)
{var edge=this.FindEdgeMin(this.vertices[i].id,this.vertices[j].id);if(edge!=null)
{matrix+=edge.weight;}
else
{matrix+="0";}
if(j!=this.vertices.length)
{matrix+=", ";}}
matrix=matrix+"\n";}
return matrix;}
Graph.prototype.GetAdjacencyMatrix=function()
{var matrix=[];for(var i=0;i<this.vertices.length;i++)
{matrix.push([]);var v1=this.vertices[i];for(var j=0;j<this.vertices.length;j++)
{var v2=this.vertices[j];var edge=this.FindEdgeMin(v1.id,v2.id);if(edge!=null)
{matrix[i][j]=edge.GetWeight();}
else
{matrix[i][j]=this.infinity;}}}
return matrix;}
Graph.prototype.TestAdjacencyMatrix=function(matrix,rowsObj,colsObj,separator)
{if(separator===undefined)
{separator=",";}
var bGoodFormat=true;rowsObj.rows=[];rowsObj.rows=matrix.split("\n");for(j=0;j<rowsObj.rows.length;++j)
{if(rowsObj.rows[j]==="")
{rowsObj.rows.splice(j--,1);}}
colsObj.cols=[];for(var i=0;i<rowsObj.rows.length;i++)
{colsObj.cols[i]=this.SplitMatrixString(rowsObj.rows[i],separator);for(j=0;j<colsObj.cols[i].length;++j)
{if(colsObj.cols[i][j]==="")
{colsObj.cols[i].splice(j--,1);}}
if(colsObj.cols[i].length!=rowsObj.rows.length)
{bGoodFormat=false;break;}}
return bGoodFormat;}
Graph.prototype.TestPair=function(pair)
{let lines=pair.split("\n");let regExp=[/^.+-.+$/g,/^.+\>.+$/g,/^.+<.+$/g,/^.+-\(\d+\.?\d+\)-.+$/g,/^.+-\(\d+\.?\d+\)\>.+$/g,/^.+<\(\d+\.?\d+\)\-.+$/g];let res=true;for(let i=0;i<lines.length;++i)
{let resLine=false;let line=lines[i];if(line==""){continue;}
for(let j=0;j<regExp.length;++j){if(line.match(regExp[j])){resLine=true;}}
res=resLine&&res;}
return res;}
Graph.prototype.IsVerticesHaveSamePosition=function(position,vertexCount)
{var res=false;for(var j=0;j<Math.min(this.vertices.length,vertexCount);j++)
{if(position.distance(this.vertices[j].position)<this.vertices[j].model.diameter*2)
{res=true;break;}}
return res;}
Graph.prototype.GetRandomPosition=function(viewportSize){return new Point(Math.random()*viewportSize.x,Math.random()*viewportSize.y);}
Graph.prototype.GetRandomPositionOfVertex=function(matrix,vertexIndex,viewportSize)
{var point=new Point(0,0);var relatedVertex=[];for(var j=0;j<matrix.length;j++)
{if(j<this.vertices.length&&(cols[vertexIndex][j]>0||cols[j][vertexIndex]>0)&&j!=vertexIndex)
{relatedVertex.push(this.vertices[j]);}}
var diameter=(new VertexModel()).diameter;if(relatedVertex.length>1)
{for(var j=0;j<relatedVertex.length;j++)
{point=point.add(relatedVertex[j].position);}
point=point.multiply(1/relatedVertex.length);point.offset(Math.random()*diameter+(Math.random()?-1:1)*2*diameter,Math.random()*diameter+(Math.random()?-1:1)*2*diameter);}
else
{point=new Point(Math.random()*viewportSize.x,Math.random()*viewportSize.y);}
if(this.IsVerticesHaveSamePosition(point,matrix.length))
{point.offset(Math.random()*diameter+ +(Math.random()?-1:1)*4*diameter,Math.random()*diameter+ +(Math.random()?-1:1)*4*diameter);}
point.x=Math.min(Math.max(point.x,diameter),viewportSize.x);point.y=Math.min(Math.max(point.y,diameter),viewportSize.y);return point;}
Graph.prototype.VerticesReposition=function(viewportSize,newVertices)
{var maxGravityDistanceSqr=Math.max(viewportSize.x,viewportSize.y)/5.0;maxGravityDistanceSqr=maxGravityDistanceSqr*maxGravityDistanceSqr;var velocityDamping=0.85;var diameter=(new VertexModel()).diameter;var maxDistance=diameter*3;var gravityDistanceSqr=10*(maxDistance*maxDistance);var edgeGravityKof=10/(maxDistance);var kCenterForce=10/(maxDistance*10);var centerPoint=viewportSize.multiply(0.5);var velocityMax=maxDistance*10;var edgesMatrix={};for(var i=0;i<this.edges.length;i++)
{edgesMatrix[this.edges[i].vertex1.id+this.edges[i].vertex2.id*1000]=1;edgesMatrix[this.edges[i].vertex2.id+this.edges[i].vertex1.id*1000]=1;}
var startAngel=Math.random()*180.0;for(i=0;i<newVertices.length;i++)
{newVertices[i].position.orbit(new Point(viewportSize.x/2,viewportSize.y/2),(viewportSize.x-diameter*2)/2,(viewportSize.y-diameter*2)/2,360*i/newVertices.length+startAngel);}
var k=0;var bChanged=true;while(k<1000&&bChanged)
{var vertexData=[];for(i=0;i<newVertices.length;i++)
{var currentVertex={};currentVertex.object=newVertices[i];currentVertex.net_force=new Point(0,0);currentVertex.velocity=new Point(0,0);vertexData.push(currentVertex);for(j=0;j<this.vertices.length;j++)
{otherVertex=this.vertices[j];if(otherVertex==currentVertex.object)continue;var rsq=currentVertex.object.position.distanceSqr(otherVertex.position);{var force=(currentVertex.object.position.subtract(otherVertex.position)).normalize(gravityDistanceSqr/rsq);currentVertex.net_force=currentVertex.net_force.add(force);}}
for(j=0;j<this.vertices.length;j++)
{otherVertex=this.vertices[j];if(edgesMatrix.hasOwnProperty(currentVertex.object.id+1000*otherVertex.id))
{var distance=currentVertex.object.position.distance(otherVertex.position);if(distance>maxDistance)
{var force=(otherVertex.position.subtract(currentVertex.object.position)).normalize(edgeGravityKof*(distance-maxDistance));currentVertex.net_force=currentVertex.net_force.add(force);}}}
var distanceToCenter=centerPoint.distance(currentVertex.object.position);var force=centerPoint.subtract(currentVertex.object.position).normalize(distanceToCenter*kCenterForce);currentVertex.net_force=currentVertex.net_force.add(force);currentVertex.velocity=currentVertex.velocity.add(currentVertex.net_force);}
bChanged=false;for(i=0;i<vertexData.length;i++)
{var v=vertexData[i];var velocity=v.velocity;if(velocity.length()>velocityMax)
{velocity=velocity.normalize(velocityMax);}
v.object.position=v.object.position.add(velocity);if(velocity.length()>=1)
{bChanged=true;}}
k++;}
var bbox=this.getGraphBBox();if(bbox.size().length()>viewportSize.length()*1000)
{for(i=0;i<newVertices.length;i++)
{newVertices[i].position.orbit(new Point(viewportSize.x/2,viewportSize.y/2),(viewportSize.x-diameter*2)/2,(viewportSize.y-diameter*2)/2,360*i/newVertices.length+startAngel);}}
else
{var count=10;var angle=360.0/count;var viewportAspect=viewportSize.x/viewportSize.y;var bestIndex=0;var graphSize=bbox.size();var bestAspect=graphSize.x/graphSize.y;var center=bbox.center();for(var i=1;i<count;i++)
{for(j=0;j<newVertices.length;j++)
{newVertices[j].position.rotate(center,angle);}
var newBBox=this.getGraphBBox();var newAspect=newBBox.size().x/newBBox.size().y;if(Math.abs(newAspect-viewportAspect)<Math.abs(bestAspect-viewportAspect))
{bestAspect=newAspect;bestIndex=i;}}
for(j=0;j<newVertices.length;j++)
{newVertices[j].position.rotate(center,-angle*(count-bestIndex-1));}}}
Graph.prototype.SetAdjacencyMatrix=function(matrix,viewportSize,currentEnumVerticesType,separator)
{if(separator===undefined)
{separator=",";}
var rowsObj={};var colsObj={};if(this.TestAdjacencyMatrix(matrix,rowsObj,colsObj,separator))
{rows=rowsObj.rows;cols=colsObj.cols;var clonedEdge=this.edges.slice(0);for(var i=0;i<clonedEdge.length;i++)
{this.DeleteEdge(clonedEdge[i]);}
var newVertices=[];var bWeightGraph=false;for(var i=0;i<rows.length;i++)
{for(var j=0;j<rows.length;j++)
{if(j>=this.vertices.length)
{var newPos=this.GetRandomPositionOfVertex(matrix,j,viewportSize);newVertices.push(new BaseVertex(newPos.x,newPos.y,currentEnumVerticesType));this.AddNewVertex(newVertices[newVertices.length-1]);}
if(cols[i][j]>0)
{var nEdgeIndex=this.AddNewEdgeSafe(this.vertices[i],this.vertices[j],cols[i][j]!=cols[j][i],cols[i][j],true);this.FixEdgeCurve(nEdgeIndex);if(nEdgeIndex>=0)
{bWeightGraph=bWeightGraph||this.edges[nEdgeIndex].weight!=1;}}}}
if(!bWeightGraph)
{this.edges.forEach(function(part,index,theArray){theArray[index].useWeight=false;});}
for(var i=rows.length;i<Math.max(this.vertices.length,rows.length);i++)
{this.DeleteVertex(this.vertices[i]);i--;}
this.VerticesReposition(viewportSize,newVertices);}}
Graph.prototype.SetPair=function(pairs,viewportSize,currentEnumVerticesType)
{if(this.TestPair(pairs))
{this.ClearGraph();let lines=pairs.split("\n");let regExp=[/^(.+)-(.+)$/g,/^(.+)\>(.+)$/g,/^(.+)<(.+)$/g,/^(.+)-\((\d+|\d+\.?\d+)\)-(.+)$/g,/^(.+)-\((\d+|\d+\.?\d+)\)\>(.+)$/g,/^(.+)<\((\d+|\d+\.?\d+)\)\-(.+)$/g,];let bWeightGraph=false;var newVertices=[];for(var i=0;i<lines.length;i++)
{let line=lines[i];if(line==""){continue;}
for(let j=regExp.length-1;j>=0;--j){if(!line.match(regExp[j])){continue;}
let groupes=Array.from(line.matchAll(regExp[j]));let groupe=groupes[0];let vetext1Title=groupe[1];let vertex1=this.FindVertexByTitle(vetext1Title);if(vertex1==null){let newPosition=this.GetRandomPosition(viewportSize);vertex1=this.vertices[this.AddNewVertex(new BaseVertex(newPosition.x,newPosition.y,currentEnumVerticesType))];vertex1.mainText=vetext1Title;newVertices.push(vertex1);}
let vetext2Title=groupe[j<=2?2:3];let vertex2=this.FindVertexByTitle(vetext2Title);if(vertex2==null){let newPosition=this.GetRandomPosition(viewportSize);vertex2=this.vertices[this.AddNewVertex(new BaseVertex(newPosition.x,newPosition.y,currentEnumVerticesType))];vertex2.mainText=vetext2Title;newVertices.push(vertex2);}
let isDirect=j==1||j==2||j==4||j==5;let weight=1;if(j>2){weight=groupe[2];bWeightGraph=true;}
let isRevertEdge=j==2||j==5;let nEdgeIndex=this.AddNewEdgeSafe(isRevertEdge?vertex2:vertex1,isRevertEdge?vertex1:vertex2,isDirect,weight,false);this.FixEdgeCurve(nEdgeIndex);break;}}
if(!bWeightGraph)
{this.edges.forEach(function(part,index,theArray){theArray[index].useWeight=false;});}
this.VerticesReposition(viewportSize,newVertices);}}
Graph.prototype.TestIncidenceMatrix=function(matrix,rowsObj,colsObj,separator)
{if(separator===undefined)
{separator=",";}
var bGoodFormat=true;rowsObj.rows=[];rowsObj.rows=matrix.split("\n");for(j=0;j<rowsObj.rows.length;++j)
{if(rowsObj.rows[j]==="")
{rowsObj.rows.splice(j--,1);}}
colsObj.cols=[];var columnCount=0;for(var i=0;i<rowsObj.rows.length;i++)
{colsObj.cols[i]=this.SplitMatrixString(rowsObj.rows[i],separator);for(j=0;j<colsObj.cols[i].length;++j)
{if(colsObj.cols[i][j]==="")
{colsObj.cols[i].splice(j--,1);}}
if(i==0)
{columnCount=colsObj.cols[i].length;}
if(colsObj.cols[i].length!=columnCount)
{bGoodFormat=false;break;}}
if(bGoodFormat)
{for(var i=0;i<colsObj.cols[0].length;i++)
{var values=[];for(j=0;j<colsObj.cols.length;++j)
{if(colsObj.cols[j][i]!=0)
{values.push(colsObj.cols[j][i]);}}
if(!(values.length<=1||(values.length==2&&(values[0]==values[1]||values[0]==-values[1]))))
{bGoodFormat=false;break;}}}
return bGoodFormat;}
Graph.prototype.SetIncidenceMatrix=function(matrix,viewportSize,currentEnumVerticesType)
{var rowsObj={};var colsObj={};if(this.TestIncidenceMatrix(matrix,rowsObj,colsObj))
{rows=rowsObj.rows;cols=colsObj.cols;var clonedEdge=this.edges.slice(0);for(var i=0;i<clonedEdge.length;i++)
{this.DeleteEdge(clonedEdge[i]);}
var newVertices=[];var bWeightGraph=false;for(var i=0;i<cols[0].length;i++)
{var edgeValue=[];var edgeIndex=[];for(var j=0;j<cols.length;j++)
{if(j>=this.vertices.length)
{var newPos=new Point(0,0);newVertices.push(new BaseVertex(newPos.x,newPos.y,currentEnumVerticesType));this.AddNewVertex(newVertices[newVertices.length-1]);}
if(cols[j][i]!=0)
{edgeValue.push(cols[j][i]);edgeIndex.push(j);}}
if(edgeIndex.length==1)
{edgeValue.push(edgeValue[0]);edgeIndex.push(edgeIndex[0]);}
if(edgeIndex.length==2)
{if(edgeValue[0]!=edgeValue[1])
{if(edgeValue[1]>0)
{edgeValue=edgeValue.swap(0,1);edgeIndex=edgeIndex.swap(0,1);}}
var nEdgeIndex=this.AddNewEdgeSafe(this.vertices[edgeIndex[0]],this.vertices[edgeIndex[1]],edgeValue[0]!=edgeValue[1],Math.abs(edgeValue[1]),false);this.FixEdgeCurve(nEdgeIndex);if(nEdgeIndex>=0)
{bWeightGraph=bWeightGraph||this.edges[nEdgeIndex].weight!=1;}}}
if(!bWeightGraph)
{this.edges.forEach(function(part,index,theArray){theArray[index].useWeight=false;});}
for(var i=cols.length;i<Math.max(this.vertices.length,cols.length);i++)
{this.DeleteVertex(this.vertices[i]);i--;}
this.VerticesReposition(viewportSize,newVertices);}}
Graph.prototype.GetIncidenceMatrix=function()
{var matrix="";for(var i=0;i<this.vertices.length;i++)
{for(var j=0;j<this.edges.length;j++)
{if(this.edges[j].vertex1==this.vertices[i])
{matrix+=this.edges[j].weight;}
else if(this.edges[j].vertex2==this.vertices[i]&&!this.edges[j].isDirect)
{matrix+=this.edges[j].weight;}
else if(this.edges[j].vertex2==this.vertices[i]&&this.edges[j].isDirect)
{matrix+=-this.edges[j].weight;}
else
{matrix+="0";}
if(j!=this.edges.length-1)
{matrix+=", ";}}
matrix=matrix+"\n";}
return matrix;}
Graph.prototype.SplitMatrixString=function(line,separator)
{if(separator===undefined)
{separator=",";}
var res=[];var i=0;var isZeroOneLine=true;for(i=0;i<line.length;i++)
{if(line.charAt(i)!='0'&&line.charAt(i)!='1')
{isZeroOneLine=false;break;}}
if(!isZeroOneLine)
{if(separator!=",")
{line=line.replace(/,/g,".");}
for(i=0;i<line.length;i++)
{if(("0123456789.-e").indexOf(line.charAt(i))<0)
{if(i>0)
{res.push(line.substr(0,i));}
if(i==0)
{i=1;}
line=line.substr(i,line.length-i);i=-1;}}
if(line.length>0)
{res.push(line);}}
else
{for(i=0;i<line.length;i++)
{res.push(line.charAt(i));}}
console.log(res);return res;}
Graph.prototype.SaveToXML=function(additionalData)
{var mainHeader="<?xml version=\"1.0\" encoding=\"UTF-8\"?><graphml>";var header="<graph id=\"Graph\" uidGraph=\""+this.uidGraph+"\""+" uidEdge=\""+this.uidEdge+"\">";var xmlBody="";for(var i=0;i<this.vertices.length;i++)
{xmlBody=xmlBody+this.vertices[i].SaveToXML();}
xmlBody=xmlBody+"";for(var i=0;i<this.edges.length;i++)
{xmlBody=xmlBody+this.edges[i].SaveToXML();}
xmlBody=xmlBody+"";additionalField="";if(additionalData.length>0)
{additionalField="<additional data=\""+additionalData+"\"/>"}
return mainHeader+header+xmlBody+"</graph>"+additionalField+"</graphml>";}
Graph.prototype.LoadFromXML=function(xmlText,additionalData)
{xmlDoc=$.parseXML(xmlText);var $xml=$(xmlDoc);$graphs=$xml.find("graph");var loadedGraphId=0;var loadedEdgeId=0;$graphs.each(function(){loadedGraphId=parseInt($(this).attr('uidGraph'));loadedEdgeId=parseInt($(this).attr('uidEdge'));});if(isNaN(loadedEdgeId))
{loadedEdgeId=this.edgesOffset;}else if(loadedEdgeId<this.edgesOffset)
{loadedEdgeId=this.edgesOffset;}
this.uidGraph=loadedGraphId;this.uidEdge=loadedEdgeId;$nodes=$xml.find("node");var vertices=[];$nodes.each(function(){var vertex=new BaseVertex();vertex.LoadFromXML($(this));vertices.push(vertex);});this.vertices=vertices;$edges=$xml.find("edge");var edges=[];var graph=this;$edges.each(function(){var edge=new BaseEdge();edge.LoadFromXML($(this),graph);if(edge.id<graph.uidEdge){edge.id=graph.uidEdge;graph.uidEdge++;}
edges.push(edge);});this.edges=edges;$additional=$xml.find("additional");if($additional.length!=0&&additionalData!=null)
{additionalData["data"]=$additional.attr('data');}
this.isMultiGraph=this.checkMutiGraph();}
Graph.prototype.hasDirectEdge=function()
{var res=false;for(var i=0;i<this.edges.length;i++)
{if(this.edges[i].isDirect)
{res=true;break;}}
return res;}
Graph.prototype.hasUndirectEdge=function()
{var res=false;for(var i=0;i<this.edges.length;i++)
{if(!this.edges[i].isDirect)
{res=true;break;}}
return res;}
Graph.prototype.hasEdges=function()
{return this.edges.length>0;}
Graph.prototype.clampPositions=function(viewportSize)
{var diameter=(new VertexModel()).diameter;for(i=0;i<this.vertices.length;i++)
{this.vertices[i].position.x=Math.min(Math.max(this.vertices[i].position.x,diameter),viewportSize.x-diameter);this.vertices[i].position.y=Math.min(Math.max(this.vertices[i].position.y,diameter),viewportSize.y-diameter);}}
Graph.prototype.getGraphBBox=function(viewportSize)
{var pointMin=new Point(1e5,1e5);var pointMax=new Point(-1e5,-1e5);var diameter=(new VertexModel()).diameter;for(i=0;i<this.vertices.length;i++)
{var vertex=this.vertices[i];var factor=vertex.diameterFactor();var deltaVector=new Point(factor.x*diameter,factor.y*diameter);pointMin=pointMin.min(vertex.position.subtract(deltaVector));pointMax=pointMax.max(vertex.position.add(deltaVector));}
var max_curve_length=32;for(i=0;i<this.edges.length;i++)
{var edge=this.edges[i];if(edge.model.type==EdgeModels.curve)
{var max_curve=edge.vertex2.position.subtract(edge.vertex1.position).length()/max_curve_length;for(j=0;j<max_curve;j++)
{var point=edge.model.GetCurvePoint(edge.vertex1.position,edge.vertex2.position,j/max_curve);var deltaVector=new Point(max_curve_length,max_curve_length);pointMin=pointMin.min(point.subtract(deltaVector));pointMax=pointMax.max(point.add(deltaVector));}}}
return new Rect(pointMin,pointMax);}
Graph.prototype.hasPair=function(edge)
{return this.FindPairFor(edge)!=null;}
Graph.prototype.FindPairFor=function(edge)
{var res=this.getNeighborEdges(edge);return res.length==1?res[0]:null;}
Graph.prototype.getNeighborEdges=function(edge)
{var res=[];for(var i=0;i<this.edges.length;i++)
{var curEdge=this.edges[i];if(curEdge==edge)
continue;if((curEdge.vertex1.id==edge.vertex1.id&&curEdge.vertex2.id==edge.vertex2.id)||(curEdge.vertex1.id==edge.vertex2.id&&curEdge.vertex2.id==edge.vertex1.id))
{res.push(curEdge);}}
return res;}
Graph.prototype.checkMutiGraph=function()
{var res=false;var start={};for(var i=0;i<this.edges.length;i++)
{var edge=this.edges[i];if(start.hasOwnProperty(edge.vertex1.id)&&start[edge.vertex1.id]==edge.vertex2.id)
{res=true;break;}
start[edge.vertex1.id]=edge.vertex2.id;if(!edge.isDirect)
{if(start.hasOwnProperty(edge.vertex2.id)&&start[edge.vertex2.id]==edge.vertex1.id)
{res=true;break;}
start[edge.vertex2.id]=edge.vertex1.id;}}
return res;}
Graph.prototype.isMulti=function()
{return this.isMultiGraph;}
Graph.prototype.isNeedReposition=function()
{var res=false;for(var i=0;i<this.vertices.length;i++)
{res=res||this.vertices[i].IsUndefinedPosition();}
return res;}
Graph.prototype.FixEdgeCurve=function(edgeIndex)
{var edgeObject=this.edges[edgeIndex];var hasPair=this.hasPair(edgeObject);var neighborEdges=this.getNeighborEdges(edgeObject);if(hasPair)
{if(edgeObject.model.default)
edgeObject.model.type=EdgeModels.curve;var pairEdge=this.FindPairFor(edgeObject);if(pairEdge.model.default)
{pairEdge.model.type=EdgeModels.curve;if(pairEdge.vertex1==edgeObject.vertex1&&pairEdge.vertex2==edgeObject.vertex2)
pairEdge.model.curveValue=-pairEdge.model.curveValue;}}
else if(neighborEdges.length>=2)
{var curve=this.GetAvailableCurveValue(neighborEdges,edgeObject);if(edgeObject.model.default)
{edgeObject.model.type=EdgeModels.curve;edgeObject.model.curveValue=curve;}}}
Graph.prototype.GetAvailableCurveValue=function(neighborEdges,originalEdge)
{var values=[];for(var i=0;i<neighborEdges.length;i++)
{var edge=neighborEdges[i];var sameDirection=(originalEdge.vertex1.id==edge.vertex1.id);if(edge.model.type==EdgeModels.curve)
{values[(sameDirection?edge.model.curveValue:-edge.model.curveValue)]=true;}}
var changeValue=DefaultHandler.prototype.curveValue;var defaultValue=0.0;var maxSearch=10;for(var i=1;i<maxSearch;i++)
{value=i*changeValue;if(!values.hasOwnProperty(value))
return value;value=-i*changeValue;if(!values.hasOwnProperty(value))
return value;}
return defaultValue;}
Graph.prototype.reverseAllEdges=function()
{for(var i=0;i<this.edges.length;i++)
{if(this.edges[i].isDirect)
{let v1=this.edges[i].vertex1;this.edges[i].vertex1=this.edges[i].vertex2;this.edges[i].vertex2=v1;}}
this.isMultiGraph=this.checkMutiGraph();}
Graph.prototype.makeAllEdgesDirected=function()
{for(var i=0;i<this.edges.length;i++)
{if(!this.edges[i].isDirect)
{this.edges[i].isDirect=true;}}
this.isMultiGraph=this.checkMutiGraph();}
Graph.prototype.makeAllEdgesUndirected=function()
{for(var i=0;i<this.edges.length;i++)
{if(this.edges[i].isDirect)
{this.edges[i].isDirect=false;}}
this.isMultiGraph=this.checkMutiGraph();}
moduleLoader.endCacheLoading();

View File

@@ -0,0 +1,11 @@
// Global version needs to force reload scripts from server.
globalVersion = 75;
{
let modulDir = "pages/create_graph_by_matrix/";
doInclude ([
include ("entities/graph/api/index.js")
]);
}

View File

@@ -0,0 +1,594 @@
moduleLoader.beginCacheLoading(["/script/entities/graph/api/index.js?v=75","/script/shared/point.js?v=75","/script/entities/edge/api/index.js?v=75","/script/entities/edge/model/BaseEdge.js?v=75","/script/entities/edge/model/EdgeModel.js?v=75","/script/entities/vertex/api/index.js?v=75","/script/entities/vertex/model/BaseVertex.js?v=75","/script/entities/vertex/model/VertexModel.js?v=75","/script/entities/graph/model/Graph.js?v=75",]);globalVersion=75;{let modulDir="pages/create_graph_by_matrix/";doInclude([include("entities/graph/api/index.js")]);}
{let modulDir="entities/graph/";doInclude([include("shared/point.js"),include("entities/edge/api/index.js"),include("entities/vertex/api/index.js"),include("model/Graph.js",modulDir)])}function Point(x,y){this.x=x||0;this.y=y||0;};Point.prototype.x=null;Point.prototype.y=null;Point.prototype.add=function(v){return new Point(this.x+v.x,this.y+v.y);};Point.prototype.addValue=function(v){return new Point(this.x+v,this.y+v);};Point.prototype.clone=function(){return new Point(this.x,this.y);};Point.prototype.degreesTo=function(v){var dx=this.x-v.x;var dy=this.y-v.y;var angle=Math.atan2(dy,dx);return angle*(180/Math.PI);};Point.prototype.distance=function(v){return Math.sqrt(this.distanceSqr(v));};Point.prototype.distanceSqr=function(v){var x=this.x-v.x;var y=this.y-v.y;return x*x+y*y;};Point.prototype.equals=function(toCompare){return this.x==toCompare.x&&this.y==toCompare.y;};Point.prototype.interpolate=function(v,f){return new Point((this.x+v.x)*f,(this.y+v.y)*f);};Point.prototype.length=function(){return Math.sqrt(this.x*this.x+this.y*this.y);};Point.prototype.normalize=function(thickness){var l=this.length();this.x=this.x/l*thickness;this.y=this.y/l*thickness;return new Point(this.x,this.y);};Point.prototype.normalizeCopy=function(thickness){var l=this.length();return new Point(this.x/l*thickness,this.y/l*thickness);};Point.prototype.orbit=function(origin,arcWidth,arcHeight,degrees){var radians=degrees*(Math.PI/180);this.x=origin.x+arcWidth*Math.cos(radians);this.y=origin.y+arcHeight*Math.sin(radians);};Point.prototype.rotate=function(center,degrees){var radians=degrees*(Math.PI/180);offset=this.subtract(center);this.x=offset.x*Math.cos(radians)-offset.y*Math.sin(radians);this.y=offset.x*Math.sin(radians)+offset.y*Math.cos(radians);this.x=this.x+center.x;this.y=this.y+center.y;return this;};Point.prototype.offset=function(dx,dy){this.x+=dx;this.y+=dy;};Point.prototype.subtract=function(v){return new Point(this.x-v.x,this.y-v.y);};Point.prototype.subtractValue=function(value){return new Point(this.x-value,this.y-value);};Point.prototype.multiply=function(value){return new Point(this.x*value,this.y*value);};Point.prototype.toString=function(){return"(x="+this.x+", y="+this.y+")";};Point.prototype.normal=function(){return new Point(-this.y,this.x);};Point.prototype.min=function(point)
{return new Point(Math.min(this.x,point.x),Math.min(this.y,point.y));};Point.prototype.max=function(point)
{return new Point(Math.max(this.x,point.x),Math.max(this.y,point.y));};Point.prototype.inverse=function()
{return new Point(-this.x,-this.y);};Point.prototype.cross=function(point)
{return this.x*point.y-this.y*point.x;};Point.interpolate=function(pt1,pt2,f){return new Point(pt1.x*(1.0-f)+pt2.x*f,pt1.y*(1.0-f)+pt2.y*f);};Point.polar=function(len,angle){return new Point(len*Math.cos(angle),len*Math.sin(angle));};Point.distance=function(pt1,pt2){var x=pt1.x-pt2.x;var y=pt1.y-pt2.y;return Math.sqrt(x*x+y*y);};Point.center=function(pt1,pt2){return new Point((pt1.x+pt2.x)/2.0,(pt1.y+pt2.y)/2.0);};Point.toString=function(){return x+" "+y;}
Point.projection=function(point,line1,line2)
{var x=line2.y-line1.y;var y=line1.x-line2.x;var l=(line1.cross(line2)+line1.cross(point)+line2.cross(point))/(x*(line2.y-line1.y)+y*(line1.x-line2.x));var res=new Point(point.x+x*l,point.y+y*l);return res;}
Point.hitTest=function(pt11,pt12,pt21,pt22)
{var res=null;var n=0.0;var x1=pt11.x;var y1=pt11.y;var x2=pt12.x;var y2=pt12.y;var x3=pt21.x;var y3=pt21.y;var x4=pt22.x;var y4=pt22.y;if(y2-y1!=0.0)
{var q=(x2-x1)/(y1-y2);var sn=(x3-x4)+(y3-y4)*q;if(sn==0.0)
{return res;}
var fn=(x3-x1)+(y3-y1)*q;n=fn/sn;}
else
{if((y3-y4)==0.0)
{return res;}
n=(y3-y1)/(y3-y4);}
res=new Point(x3+(x4-x3)*n,y3+(y4-y3)*n);var epsilon=1E-5;if(!(res.x>=Math.min(x1,x2)-epsilon&&res.x>=Math.min(x3,x4)-epsilon&&res.x<=Math.max(x1,x2)+epsilon&&res.x<=Math.max(x3,x4)+epsilon&&res.y>=Math.min(y1,y2)-epsilon&&res.y>=Math.min(y3,y4)-epsilon&&res.y<=Math.max(y1,y2)+epsilon&&res.y<=Math.max(y3,y4)+epsilon))
{res=null;}
return res;}
function Rect(minPoint,maxPoint){this.minPoint=minPoint;this.maxPoint=maxPoint;};Rect.prototype.center=function()
{return Point.center(this.minPoint,this.maxPoint);};Rect.prototype.size=function()
{return this.maxPoint.subtract(this.minPoint);};Rect.prototype.left=function()
{return this.minPoint.x;};Rect.prototype.top=function()
{return this.minPoint.y;};Rect.prototype.isIn=function(v)
{return this.minPoint.x<=v.x&&this.minPoint.y<=v.y&&this.maxPoint.x>v.x&&this.maxPoint.y>v.y;};{let modulDir="entities/edge/";doInclude([include("model/BaseEdge.js",modulDir),include("model/EdgeModel.js",modulDir)])}
function BaseEdge(vertex1,vertex2,isDirect,weight,upText)
{this.vertex1=vertex1;this.vertex2=vertex2;this.arrayStyleStart="";this.arrayStyleFinish="";this.isDirect=isDirect;this.weight=0;this.text="";this.useWeight=false;this.id=0;this.model=new EdgeModel();if(upText===undefined)
this.upText="";else
this.upText=upText;if(weight!==undefined)
this.SetWeight(weight);this.ownStyles={};}
BaseEdge.prototype.copyFrom=function(other)
{this.vertex1=other.vertex1;this.vertex2=other.vertex2;this.arrayStyleStart=other.arrayStyleStart;this.arrayStyleFinish=other.arrayStyleFinish;this.isDirect=other.isDirect;this.weight=other.weight;this.text=other.text;this.useWeight=other.useWeight;this.id=other.id;this.model=new EdgeModel();this.model.copyFrom(other.model);this.upText=other.upText;this.ownStyles=FullObjectCopy(other.ownStyles);}
BaseEdge.prototype.SaveToXML=function()
{return"<edge "+"source=\""+this.vertex1.id+"\" "+"target=\""+this.vertex2.id+"\" "+"isDirect=\""+this.isDirect+"\" "+"weight=\""+this.weight+"\" "+"useWeight=\""+this.useWeight+"\" "+"id=\""+this.id+"\" "+"text=\""+gEncodeToHTML(this.text)+"\" "+"upText=\""+gEncodeToHTML(this.upText)+"\" "+"arrayStyleStart=\""+this.arrayStyleStart+"\" "+"arrayStyleFinish=\""+this.arrayStyleFinish+"\" "+
((Object.keys(this.ownStyles).length>0)?"ownStyles = \""+gEncodeToHTML(JSON.stringify(this.ownStyles))+"\" ":"")+
this.model.SaveToXML()+"></edge>";}
BaseEdge.prototype.LoadFromXML=function(xml,graph)
{var attr=xml.attr('vertex1');if(typeof attr==='undefined')
{attr=xml.attr('source');}
this.vertex1=graph.FindVertex(typeof attr!=='undefined'?attr:xml.attr('graph1'));var attr=xml.attr('vertex2');if(typeof attr==='undefined')
{attr=xml.attr('target');}
this.vertex2=graph.FindVertex(typeof attr!=='undefined'?attr:xml.attr('graph2'));this.isDirect=xml.attr('isDirect')=="true";this.weight=parseFloat(xml.attr('weight'));if(isNaN(this.weight))
{this.weight=1;}
this.hasPair=xml.attr('hasPair')=="true";this.useWeight=xml.attr('useWeight')=="true";this.id=xml.attr('id');this.text=xml.attr("text")==null?"":gDecodeFromHTML(xml.attr("text"));this.arrayStyleStart=xml.attr("arrayStyleStart")==null?"":xml.attr("arrayStyleStart");this.arrayStyleFinish=xml.attr("arrayStyleFinish")==null?"":xml.attr("arrayStyleFinish");this.upText=xml.attr('upText');if(typeof this.upText==='undefined')
{this.upText="";}
else
{this.upText=gDecodeFromHTML(this.upText);}
var ownStyle=xml.attr('ownStyles');if(typeof ownStyle!=='undefined')
{var parsedSave=gDecodeFromHTML(JSON.parse(ownStyle));for(var indexField in parsedSave)
{var index=parseInt(indexField);this.ownStyles[index]=FullObjectCopy(this.getStyleFor(index));for(var field in parsedSave[indexField])
{if(this.ownStyles[index].ShouldLoad(field))
this.ownStyles[index][field]=parsedSave[indexField][field];}}}
this.model.LoadFromXML(xml);}
BaseEdge.prototype.GetPixelLength=function()
{if(this.vertex1==this.vertex2)
{return this.model.GetLoopSize()*2*Math.PI;}
else
{return Point.distance(this.vertex1.position,this.vertex2.position);}}
BaseEdge.prototype.GetWeight=function()
{return this.useWeight?this.weight:1;}
BaseEdge.prototype.GetText=function()
{return this.text.length>0?this.text:(this.useWeight?this.weight.toString():"");}
BaseEdge.prototype.GetUpText=function()
{return this.upText;}
BaseEdge.prototype.GetStartEdgeStyle=function()
{return this.arrayStyleStart;}
BaseEdge.prototype.GetFinishEdgeStyle=function()
{return(this.arrayStyleFinish!=""?this.arrayStyleFinish:(this.isDirect?"arrow":""));}
BaseEdge.prototype.HitTest=function(pos)
{var positions=this.GetEdgePositionsShift();return this.model.HitTest(positions[0],positions[1],pos);}
BaseEdge.prototype.GetEdgePositionsShift=function()
{return this.GetEdgePositions();}
BaseEdge.prototype.GetEdgePositions=function()
{var res=[];if(this.vertex1==this.vertex2)
{res.push(this.vertex1.position);res.push(this.vertex2.position);return res;}
var position1=this.vertex1.position;var position2=this.vertex2.position;var diameter1=this.vertex1.model.diameter+parseInt(this.vertex1.currentStyle.GetStyle({},this.vertex1).lineWidth);var diameter2=this.vertex2.model.diameter+parseInt(this.vertex2.currentStyle.GetStyle({},this.vertex2).lineWidth);var direction=position1.subtract(position2);var direction1=direction;var direction2=direction;var d1=diameter1;var d2=diameter2;if(this.model.type==EdgeModels.curve)
{var dist=position1.distance(position2);var point1=this.model.GetCurvePoint(position1,position2,10.0/dist);direction1=position1.subtract(point1);var point2=this.model.GetCurvePoint(position1,position2,1.0-10.0/dist);direction2=position2.subtract(point2);d2=diameter2;}
else
{direction2=direction2.multiply(-1);}
direction1.normalize(1.0);direction2.normalize(1.0);var vertices=[];vertices.push({vertex:this.vertex1,direction:direction1,position:position1,diameter:d1});vertices.push({vertex:this.vertex2,direction:direction2,position:position2,diameter:d2});vertices.forEach(function(data)
{var shape=data.vertex.currentStyle.GetStyle({},data.vertex).shape;if(shape==VertexCircleShape)
{var direction=data.direction.multiply(0.5);res.push(data.position.subtract(direction.multiply(data.diameter)));}
else
{var lineFinish1=data.direction.multiply(-1).multiply(1000.0);var pointsVertex1=GetPointsForShape(shape,data.diameter,data.vertex.mainText);pointsVertex1.push(pointsVertex1[0]);for(var i=0;i<pointsVertex1.length-1;i++)
{var hitText=Point.hitTest(new Point(0,0),lineFinish1,pointsVertex1[i],pointsVertex1[i+1]);if(hitText!=null)
{res.push(data.position.add(hitText));break;}}}});return res;}
BaseEdge.prototype.SetWeight=function(weight)
{var useWeight=false;if(!isNaN(parseInt(weight,10)))
{useWeight=true;}
weight=(!isNaN(parseInt(weight,10))&&weight>=0)?weight:1;this.weight=Number(weight);this.useWeight=useWeight;}
BaseEdge.prototype.SetUpText=function(text)
{this.upText=text;}
BaseEdge.prototype.resetOwnStyle=function(index)
{if(this.ownStyles.hasOwnProperty(index))
{delete this.ownStyles[index];}}
BaseEdge.prototype.setOwnStyle=function(index,style)
{this.ownStyles[index]=style;}
BaseEdge.prototype.getStyleFor=function(index)
{if(this.ownStyles.hasOwnProperty(index))
{return this.ownStyles[index];}
else
{var style=null;if(index==0)
style=globalApplication.GetStyle("edge","common");else
style=globalApplication.GetStyle("edge","selected",undefined,index-1);return style;}}
BaseEdge.prototype.hasOwnStyleFor=function(index)
{return this.ownStyles.hasOwnProperty(index);}
var EdgeModels={"line":0,"curve":1};const defaultEdgeWidth=4;function EdgeModel()
{this.width=globalApplication.GetDefaultEdgeWidth();this.type=EdgeModels.line;this.curveValue=EdgeModel.prototype.defaultCurve;this.default=true;this.sizeOfLoop=24;this.loopShiftAngel=Math.PI/6;}
EdgeModel.prototype.defaultCurve=0.1;EdgeModel.prototype.copyFrom=function(other)
{this.width=other.width;this.type=other.type;this.curveValue=other.curveValue;this.default=other.default;}
EdgeModel.prototype.SaveToXML=function()
{return"model_width=\""+this.width+"\" "+"model_type=\""+this.type+"\" "+"model_curveValue=\""+this.curveValue+"\" "+"model_default=\""+this.default+"\" ";}
EdgeModel.prototype.LoadFromXML=function(xml,graph)
{this.width=xml.attr('model_width')==null?this.width:parseFloat(xml.attr("model_width"));this.type=xml.attr('model_type')==null?this.type:xml.attr("model_type");this.curveValue=xml.attr('model_curveValue')==null?this.curveValue:parseFloat(xml.attr("model_curveValue"));this.default=xml.attr('model_default')==null?this.default:parseFloat(xml.attr("model_default"));}
EdgeModel.prototype.GetCurvePoint=function(position1,position2,t)
{var points=this.GetBezierPoints(position1,position2);var firstBezierPoint=points[0];var secondBezierPoint=points[1];var B0_t=Math.pow(1-t,3);var B1_t=3*t*Math.pow(1-t,2);var B2_t=3*t*t*(1-t)
var B3_t=t*t*t;var ax=position1.x;var ay=position1.y;var dx=position2.x;var dy=position2.y;var bx=firstBezierPoint.x;var by=firstBezierPoint.y;var cx=secondBezierPoint.x;var cy=secondBezierPoint.y;var px_t=(B0_t*ax)+(B1_t*bx)+(B2_t*cx)+(B3_t*dx);var py_t=(B0_t*ay)+(B1_t*by)+(B2_t*cy)+(B3_t*dy);return new Point(px_t,py_t);}
EdgeModel.prototype.GetBezierPoints=function(position1,position2)
{var direction=position2.subtract(position1);var delta=direction.length();direction.normalize(1.0);var normal=direction.normal();var deltaOffsetPixels=delta*this.curveValue;var yOffset=normal.multiply(deltaOffsetPixels);var firstBezierPointShift=(direction.multiply(delta*0.2)).add(yOffset);var secondBezierPointShift=(direction.multiply(-delta*0.2)).add(yOffset);var firstBezierPoint=position1.add(firstBezierPointShift);var secondBezierPoint=position2.add(secondBezierPointShift);return[firstBezierPoint,secondBezierPoint];}
EdgeModel.prototype.HitTest=function(position1,position2,mousePos)
{if(this.type==EdgeModels.line)
return this.HitTestLine(position1,position2,mousePos);else if(this.type==EdgeModels.curve)
return this.HitTestCurve(position1,position2,mousePos);return false;}
EdgeModel.prototype.HitTestLine=function(position1,position2,mousePos,factor)
{if(factor===undefined)
{factor=1.0;}
var pos1=position1;var pos2=position2;var pos0=mousePos;if(pos1.equals(pos2))
{var xCenter=pos1.x-Math.cos(this.GetLoopShiftAngel())*this.GetLoopSize();var yCenter=pos1.y-Math.sin(this.GetLoopShiftAngel())*this.GetLoopSize();return Math.abs((Point.distance(new Point(xCenter,yCenter),pos0))-this.GetLoopSize())<=this.width*1.5*factor;}
var r1=pos0.distance(pos1);var r2=pos0.distance(pos2);var r12=pos1.distance(pos2);if(r1>=(new Point(r2,r12)).length()||r2>=(new Point(r1,r12)).length())
{}
else
{var distance=((pos1.y-pos2.y)*pos0.x+(pos2.x-pos1.x)*pos0.y+(pos1.x*pos2.y-pos2.x*pos1.y))/r12;if(Math.abs(distance)<=this.width*1.5*factor)
{return true;}}
return false;}
EdgeModel.prototype.HitTestCurve=function(position1,position2,mousePos)
{var pos1=position1;var pos2=position2;var pos0=mousePos;if(pos1.equals(pos2))
{var xCenter=pos1.x-Math.cos(this.GetLoopShiftAngel())*this.GetLoopSize();var yCenter=pos1.y-Math.sin(this.GetLoopShiftAngel())*this.GetLoopSize();return Math.abs((Point.distance(new Point(xCenter,yCenter),pos0))-this.GetLoopSize())<=this.width*1.5;}
var interval_count=position1.distance(position2)/100*30;var start=position1;for(var i=0;i<interval_count;i++)
{var finish=this.GetCurvePoint(position1,position2,i/interval_count);if(this.HitTestLine(start,finish,mousePos,2.0))
return true;start=finish;}
return false;}
EdgeModel.prototype.ChangeCurveValue=function(delta)
{if(this.type==EdgeModels.line)
{this.type=EdgeModels.curve;this.curveValue=0.0;}
this.curveValue=this.curveValue+delta;if(Math.abs(this.curveValue)<=0.01)
this.type=EdgeModels.line;this.default=false;}
EdgeModel.prototype.SetCurveValue=function(value)
{if(this.type==EdgeModels.line)
{this.type=EdgeModels.curve;this.curveValue=0.0;}
this.curveValue=value;if(Math.abs(this.curveValue)<=0.01)
this.type=EdgeModels.line;this.default=false;}
EdgeModel.prototype.GetLoopSize=function()
{if(Math.abs(this.curveValue)<=0.01)
{return this.sizeOfLoop;}
else
{let normalCurve=this.curveValue;if(this.type==EdgeModels.line){normalCurve=this.defaultCurve;}
else if(normalCurve>=0.0){normalCurve+=this.defaultCurve}
return this.sizeOfLoop*Math.abs(normalCurve)*(1/this.defaultCurve);}}
EdgeModel.prototype.GetLoopShiftAngel=function()
{if(this.type==EdgeModels.line||this.curveValue>=0.0)
{return this.loopShiftAngel;}
else
{return this.loopShiftAngel+Math.PI;}}
{let modulDir="entities/vertex/";doInclude([include("model/BaseVertex.js",modulDir),include("model/VertexModel.js",modulDir)])}
function BaseVertex(x,y,vertexEnumType)
{this.position=new Point(x,y);this.id=0;this.mainText="";this.upText="";this.vertexEnumType=vertexEnumType;this.model=new VertexModel();this.hasUndefinedPosition=false;this.ownStyles={};};BaseVertex.prototype.position=new Point(0,0);BaseVertex.prototype.copyFrom=function(other)
{this.position=new Point(other.position.x,other.position.y);this.id=other.id;this.mainText=other.mainText;this.upText=other.upText;this.vertexEnumType=other.vertexEnumType;this.model=new VertexModel();this.hasUndefinedPosition=other.hasUndefinedPosition;this.ownStyles=FullObjectCopy(other.ownStyles);}
BaseVertex.prototype.SaveToXML=function()
{return"<node "+"positionX=\""+this.position.x+"\" "+"positionY=\""+this.position.y+"\" "+"id=\""+this.id+"\" "+"mainText=\""+gEncodeToHTML(this.mainText)+"\" "+"upText=\""+gEncodeToHTML(this.upText)+"\" "+
((Object.keys(this.ownStyles).length>0)?"ownStyles = \""+gEncodeToHTML(JSON.stringify(this.ownStyles))+"\" ":"")+"size=\""+this.model.diameter+"\" "+"></node>";}
BaseVertex.prototype.LoadFromXML=function(xml)
{var xmlX=xml.attr('positionX');var xmlY=xml.attr('positionY');this.hasUndefinedPosition=(typeof xmlX==='undefined')||(typeof xmlY==='undefined');this.position=new Point(parseFloat(xmlX),parseFloat(xmlY));this.id=xml.attr('id');this.mainText=xml.attr('mainText');this.upText=xml.attr('upText');if(typeof this.mainText==='undefined')
this.mainText=this.id;else
this.mainText=gDecodeFromHTML(this.mainText);if(typeof this.upText==='undefined')
this.upText="";else
this.upText=gDecodeFromHTML(this.upText);var ownStyle=xml.attr('ownStyles');if(typeof ownStyle!=='undefined')
{var parsedSave=gDecodeFromHTML(JSON.parse(ownStyle));for(var indexField in parsedSave)
{var index=parseInt(indexField);this.ownStyles[index]=FullObjectCopy(this.getStyleFor(index));for(var field in parsedSave[indexField])
{if(this.ownStyles[index].ShouldLoad(field))
this.ownStyles[index][field]=parsedSave[indexField][field];}}}
var size=xml.attr('size');if(typeof size!=='undefined')
this.model.diameter=parseInt(size);}
BaseVertex.prototype.SetId=function(id)
{this.id=id;if(this.vertexEnumType!=null)
this.mainText=this.vertexEnumType.GetVertexText(id);}
BaseVertex.prototype.diameterFactor=function()
{return new Point(1.0+(this.mainText.length?this.mainText.length/8.0:0),1.5);}
BaseVertex.prototype.IsUndefinedPosition=function()
{return this.hasUndefinedPosition;}
BaseVertex.prototype.HitTest=function(pos)
{var shape=this.hasOwnProperty('currentStyle')?this.currentStyle.GetStyle({},this).shape:VertexCircleShape;var width=this.hasOwnProperty('currentStyle')?this.currentStyle.GetStyle({},this).lineWidth:0;if(shape==VertexCircleShape)
{return this.position.distance(pos)<this.model.diameter/2.0+width;}
else
{var relativePos=(new Point(pos.x,pos.y)).subtract(this.position);var lineFinish1=relativePos.add(new Point(1000,0));var lineFinish2=relativePos.add(new Point(-1000,0));var pointsVertex1=GetPointsForShape(shape,this.model.diameter+width,this.mainText);pointsVertex1.push(pointsVertex1[0]);var hitNumber1=0;var hitNumber2=0;for(var i=0;i<pointsVertex1.length-1;i++)
{var hitTest=Point.hitTest(relativePos,lineFinish1,pointsVertex1[i],pointsVertex1[i+1]);if(hitTest!=null)
{hitNumber1++;}
hitTest=Point.hitTest(relativePos,lineFinish2,pointsVertex1[i],pointsVertex1[i+1]);if(hitTest!=null)
{hitNumber2++;}}
return hitNumber1==1&&hitNumber2==1;}
return false;}
BaseVertex.prototype.resetOwnStyle=function(index)
{if(this.ownStyles.hasOwnProperty(index))
{delete this.ownStyles[index];}}
BaseVertex.prototype.setOwnStyle=function(index,style)
{this.ownStyles[index]=FullObjectCopy(style);}
BaseVertex.prototype.getStyleFor=function(index)
{if(this.ownStyles.hasOwnProperty(index))
{return this.ownStyles[index];}
else
{var style=null;if(index==0)
style=globalApplication.GetStyle("vertex","common");else
style=globalApplication.GetStyle("vertex","selected",undefined,index-1);return style;}}
BaseVertex.prototype.hasOwnStyleFor=function(index)
{return this.ownStyles.hasOwnProperty(index);}
const defaultVertexDiameter=30;function VertexModel()
{this.diameter=globalApplication.GetDefaultVertexSize();}
function Graph()
{this.vertices=[];this.edges=[];this.uidGraph=0;this.uidEdge=10000;this.hasDirect=false;this.isMultiGraph=false;};Graph.prototype.infinity=1E8;Graph.prototype.maxVertices=1000;Graph.prototype.edgesOffset=10000;Graph.prototype.AddNewVertex=function(vertex)
{if(this.vertices.length<=this.maxVertices)
{vertex.SetId(this.uidGraph);this.uidGraph=this.uidGraph+1;this.vertices.push(vertex);}
return this.vertices.length-1;}
Graph.prototype.ClearGraph=function(){this.vertices=[];this.edges=[];this.uidGraph=0;this.uidEdge=10000;this.hasDirect=false;this.isMultiGraph=false;}
Graph.prototype.AddNewEdgeSafe=function(graph1,graph2,isDirect,weight,replaceIfExists=true)
{return this.AddNewEdge(new BaseEdge(graph1,graph2,isDirect,weight),replaceIfExists);}
Graph.prototype.AddNewEdge=function(edge,replaceIfExists)
{edge.id=this.uidEdge;this.uidEdge=this.uidEdge+1;var edge1=this.FindEdgeAny(edge.vertex1.id,edge.vertex2.id);var edgeRevert=this.FindEdgeAny(edge.vertex2.id,edge.vertex1.id);if(!edge.isDirect)
{if(edge1!=null&&replaceIfExists)
this.DeleteEdge(edge1);if(edgeRevert!=null&&replaceIfExists)
this.DeleteEdge(edgeRevert);this.edges.push(edge);}
else
{if(edge1!=null&&replaceIfExists)
this.DeleteEdge(edge1);if(edgeRevert!=null&&!edgeRevert.isDirect&&replaceIfExists)
this.DeleteEdge(edgeRevert);this.edges.push(edge);}
this.isMultiGraph=this.checkMutiGraph();return this.edges.length-1;}
Graph.prototype.DeleteEdge=function(edgeObject)
{var index=this.edges.indexOf(edgeObject);if(index>-1)
{this.edges.splice(index,1);}
this.isMultiGraph=this.checkMutiGraph();}
Graph.prototype.DeleteVertex=function(vertexObject)
{var index=this.vertices.indexOf(vertexObject);if(index>-1)
{for(var i=0;i<this.edges.length;i++)
{if(this.edges[i].vertex1==vertexObject||this.edges[i].vertex2==vertexObject)
{this.DeleteEdge(this.edges[i]);i--;}}
this.vertices.splice(index,1);}}
Graph.prototype.HasConnectedNodes=function(vertexObject)
{var res=false;var index=this.vertices.indexOf(vertexObject);if(index>-1)
{for(var i=0;i<this.edges.length;i++)
{if(this.edges[i].vertex1==vertexObject||this.edges[i].vertex2==vertexObject)
{res=true;break;}}}
return res;}
Graph.prototype.FindVertex=function(id)
{var res=null;for(var i=0;i<this.vertices.length;i++)
{if(this.vertices[i].id==id)
{res=this.vertices[i];break;}}
return res;}
Graph.prototype.FindVertexByTitle=function(title)
{var res=null;for(var i=0;i<this.vertices.length;i++)
{if(this.vertices[i].mainText==title)
{res=this.vertices[i];break;}}
return res;}
Graph.prototype.FindEdge=function(id1,id2)
{return this.FindEdgeAny(id1,id2);}
Graph.prototype.FindEdgeById=function(edgeId)
{var res=null;for(var i=0;i<this.edges.length;i++)
{if(this.edges[i].id==edgeId)
{res=this.edges[i];break;}}
return res;}
Graph.prototype.FindEdgeAny=function(id1,id2)
{var res=null;for(var i=0;i<this.edges.length;i++)
{if((this.edges[i].vertex1.id==id1&&this.edges[i].vertex2.id==id2)||(!this.edges[i].isDirect&&this.edges[i].vertex1.id==id2&&this.edges[i].vertex2.id==id1))
{res=this.edges[i];break;}}
return res;}
Graph.prototype.FindEdgeMin=function(id1,id2)
{var res=null;var minWeight=this.infinity;for(var i=0;i<this.edges.length;i++)
{var edge=this.edges[i];if((edge.vertex1.id==id1&&edge.vertex2.id==id2)||(!edge.isDirect&&edge.vertex1.id==id2&&edge.vertex2.id==id1))
{if(edge.weight<minWeight)
{res=edge;minWeight=edge.weight;}}}
return res;}
Graph.prototype.FindEdgeMax=function(id1,id2)
{var res=null;var maxWeight=0;for(var i=0;i<this.edges.length;i++)
{var edge=this.edges[i];if((edge.vertex1.id==id1&&edge.vertex2.id==id2)||(!edge.isDirect&&edge.vertex1.id==id2&&edge.vertex2.id==id1))
{if(edge.weight>maxWeight)
{res=edge;maxWeight=edge.weight;}}}
return res;}
Graph.prototype.FindEdgeMinIgnoreDirection=function(id1,id2)
{var res=null;var minWeight=this.infinity;for(var i=0;i<this.edges.length;i++)
{var edge=this.edges[i];if((edge.vertex1.id==id1&&edge.vertex2.id==id2)||(edge.vertex1.id==id2&&edge.vertex2.id==id1))
{if(edge.weight<minWeight)
{res=edge;minWeight=edge.weight;}}}
return res;}
Graph.prototype.FindAllEdges=function(id1,id2)
{var res=[];for(var i=0;i<this.edges.length;i++)
{var edge=this.edges[i];if((edge.vertex1.id==id1&&edge.vertex2.id==id2)||(!edge.isDirect&&edge.vertex1.id==id2&&edge.vertex2.id==id1))
{res.push(edge);}}
return res;}
Graph.prototype.GetAdjacencyMatrixStr=function()
{var matrix="";for(var i=0;i<this.vertices.length;i++)
{for(var j=0;j<this.vertices.length;j++)
{var edge=this.FindEdgeMin(this.vertices[i].id,this.vertices[j].id);if(edge!=null)
{matrix+=edge.weight;}
else
{matrix+="0";}
if(j!=this.vertices.length)
{matrix+=", ";}}
matrix=matrix+"\n";}
return matrix;}
Graph.prototype.GetAdjacencyMatrix=function()
{var matrix=[];for(var i=0;i<this.vertices.length;i++)
{matrix.push([]);var v1=this.vertices[i];for(var j=0;j<this.vertices.length;j++)
{var v2=this.vertices[j];var edge=this.FindEdgeMin(v1.id,v2.id);if(edge!=null)
{matrix[i][j]=edge.GetWeight();}
else
{matrix[i][j]=this.infinity;}}}
return matrix;}
Graph.prototype.TestAdjacencyMatrix=function(matrix,rowsObj,colsObj,separator)
{if(separator===undefined)
{separator=",";}
var bGoodFormat=true;rowsObj.rows=[];rowsObj.rows=matrix.split("\n");for(j=0;j<rowsObj.rows.length;++j)
{if(rowsObj.rows[j]==="")
{rowsObj.rows.splice(j--,1);}}
colsObj.cols=[];for(var i=0;i<rowsObj.rows.length;i++)
{colsObj.cols[i]=this.SplitMatrixString(rowsObj.rows[i],separator);for(j=0;j<colsObj.cols[i].length;++j)
{if(colsObj.cols[i][j]==="")
{colsObj.cols[i].splice(j--,1);}}
if(colsObj.cols[i].length!=rowsObj.rows.length)
{bGoodFormat=false;break;}}
return bGoodFormat;}
Graph.prototype.TestPair=function(pair)
{let lines=pair.split("\n");let regExp=[/^.+-.+$/g,/^.+\>.+$/g,/^.+<.+$/g,/^.+-\(\d+\.?\d+\)-.+$/g,/^.+-\(\d+\.?\d+\)\>.+$/g,/^.+<\(\d+\.?\d+\)\-.+$/g];let res=true;for(let i=0;i<lines.length;++i)
{let resLine=false;let line=lines[i];if(line==""){continue;}
for(let j=0;j<regExp.length;++j){if(line.match(regExp[j])){resLine=true;}}
res=resLine&&res;}
return res;}
Graph.prototype.IsVerticesHaveSamePosition=function(position,vertexCount)
{var res=false;for(var j=0;j<Math.min(this.vertices.length,vertexCount);j++)
{if(position.distance(this.vertices[j].position)<this.vertices[j].model.diameter*2)
{res=true;break;}}
return res;}
Graph.prototype.GetRandomPosition=function(viewportSize){return new Point(Math.random()*viewportSize.x,Math.random()*viewportSize.y);}
Graph.prototype.GetRandomPositionOfVertex=function(matrix,vertexIndex,viewportSize)
{var point=new Point(0,0);var relatedVertex=[];for(var j=0;j<matrix.length;j++)
{if(j<this.vertices.length&&(cols[vertexIndex][j]>0||cols[j][vertexIndex]>0)&&j!=vertexIndex)
{relatedVertex.push(this.vertices[j]);}}
var diameter=(new VertexModel()).diameter;if(relatedVertex.length>1)
{for(var j=0;j<relatedVertex.length;j++)
{point=point.add(relatedVertex[j].position);}
point=point.multiply(1/relatedVertex.length);point.offset(Math.random()*diameter+(Math.random()?-1:1)*2*diameter,Math.random()*diameter+(Math.random()?-1:1)*2*diameter);}
else
{point=new Point(Math.random()*viewportSize.x,Math.random()*viewportSize.y);}
if(this.IsVerticesHaveSamePosition(point,matrix.length))
{point.offset(Math.random()*diameter+ +(Math.random()?-1:1)*4*diameter,Math.random()*diameter+ +(Math.random()?-1:1)*4*diameter);}
point.x=Math.min(Math.max(point.x,diameter),viewportSize.x);point.y=Math.min(Math.max(point.y,diameter),viewportSize.y);return point;}
Graph.prototype.VerticesReposition=function(viewportSize,newVertices)
{var maxGravityDistanceSqr=Math.max(viewportSize.x,viewportSize.y)/5.0;maxGravityDistanceSqr=maxGravityDistanceSqr*maxGravityDistanceSqr;var velocityDamping=0.85;var diameter=(new VertexModel()).diameter;var maxDistance=diameter*3;var gravityDistanceSqr=10*(maxDistance*maxDistance);var edgeGravityKof=10/(maxDistance);var kCenterForce=10/(maxDistance*10);var centerPoint=viewportSize.multiply(0.5);var velocityMax=maxDistance*10;var edgesMatrix={};for(var i=0;i<this.edges.length;i++)
{edgesMatrix[this.edges[i].vertex1.id+this.edges[i].vertex2.id*1000]=1;edgesMatrix[this.edges[i].vertex2.id+this.edges[i].vertex1.id*1000]=1;}
var startAngel=Math.random()*180.0;for(i=0;i<newVertices.length;i++)
{newVertices[i].position.orbit(new Point(viewportSize.x/2,viewportSize.y/2),(viewportSize.x-diameter*2)/2,(viewportSize.y-diameter*2)/2,360*i/newVertices.length+startAngel);}
var k=0;var bChanged=true;while(k<1000&&bChanged)
{var vertexData=[];for(i=0;i<newVertices.length;i++)
{var currentVertex={};currentVertex.object=newVertices[i];currentVertex.net_force=new Point(0,0);currentVertex.velocity=new Point(0,0);vertexData.push(currentVertex);for(j=0;j<this.vertices.length;j++)
{otherVertex=this.vertices[j];if(otherVertex==currentVertex.object)continue;var rsq=currentVertex.object.position.distanceSqr(otherVertex.position);{var force=(currentVertex.object.position.subtract(otherVertex.position)).normalize(gravityDistanceSqr/rsq);currentVertex.net_force=currentVertex.net_force.add(force);}}
for(j=0;j<this.vertices.length;j++)
{otherVertex=this.vertices[j];if(edgesMatrix.hasOwnProperty(currentVertex.object.id+1000*otherVertex.id))
{var distance=currentVertex.object.position.distance(otherVertex.position);if(distance>maxDistance)
{var force=(otherVertex.position.subtract(currentVertex.object.position)).normalize(edgeGravityKof*(distance-maxDistance));currentVertex.net_force=currentVertex.net_force.add(force);}}}
var distanceToCenter=centerPoint.distance(currentVertex.object.position);var force=centerPoint.subtract(currentVertex.object.position).normalize(distanceToCenter*kCenterForce);currentVertex.net_force=currentVertex.net_force.add(force);currentVertex.velocity=currentVertex.velocity.add(currentVertex.net_force);}
bChanged=false;for(i=0;i<vertexData.length;i++)
{var v=vertexData[i];var velocity=v.velocity;if(velocity.length()>velocityMax)
{velocity=velocity.normalize(velocityMax);}
v.object.position=v.object.position.add(velocity);if(velocity.length()>=1)
{bChanged=true;}}
k++;}
var bbox=this.getGraphBBox();if(bbox.size().length()>viewportSize.length()*1000)
{for(i=0;i<newVertices.length;i++)
{newVertices[i].position.orbit(new Point(viewportSize.x/2,viewportSize.y/2),(viewportSize.x-diameter*2)/2,(viewportSize.y-diameter*2)/2,360*i/newVertices.length+startAngel);}}
else
{var count=10;var angle=360.0/count;var viewportAspect=viewportSize.x/viewportSize.y;var bestIndex=0;var graphSize=bbox.size();var bestAspect=graphSize.x/graphSize.y;var center=bbox.center();for(var i=1;i<count;i++)
{for(j=0;j<newVertices.length;j++)
{newVertices[j].position.rotate(center,angle);}
var newBBox=this.getGraphBBox();var newAspect=newBBox.size().x/newBBox.size().y;if(Math.abs(newAspect-viewportAspect)<Math.abs(bestAspect-viewportAspect))
{bestAspect=newAspect;bestIndex=i;}}
for(j=0;j<newVertices.length;j++)
{newVertices[j].position.rotate(center,-angle*(count-bestIndex-1));}}}
Graph.prototype.SetAdjacencyMatrix=function(matrix,viewportSize,currentEnumVerticesType,separator)
{if(separator===undefined)
{separator=",";}
var rowsObj={};var colsObj={};if(this.TestAdjacencyMatrix(matrix,rowsObj,colsObj,separator))
{rows=rowsObj.rows;cols=colsObj.cols;var clonedEdge=this.edges.slice(0);for(var i=0;i<clonedEdge.length;i++)
{this.DeleteEdge(clonedEdge[i]);}
var newVertices=[];var bWeightGraph=false;for(var i=0;i<rows.length;i++)
{for(var j=0;j<rows.length;j++)
{if(j>=this.vertices.length)
{var newPos=this.GetRandomPositionOfVertex(matrix,j,viewportSize);newVertices.push(new BaseVertex(newPos.x,newPos.y,currentEnumVerticesType));this.AddNewVertex(newVertices[newVertices.length-1]);}
if(cols[i][j]>0)
{var nEdgeIndex=this.AddNewEdgeSafe(this.vertices[i],this.vertices[j],cols[i][j]!=cols[j][i],cols[i][j],true);this.FixEdgeCurve(nEdgeIndex);if(nEdgeIndex>=0)
{bWeightGraph=bWeightGraph||this.edges[nEdgeIndex].weight!=1;}}}}
if(!bWeightGraph)
{this.edges.forEach(function(part,index,theArray){theArray[index].useWeight=false;});}
for(var i=rows.length;i<Math.max(this.vertices.length,rows.length);i++)
{this.DeleteVertex(this.vertices[i]);i--;}
this.VerticesReposition(viewportSize,newVertices);}}
Graph.prototype.SetPair=function(pairs,viewportSize,currentEnumVerticesType)
{if(this.TestPair(pairs))
{this.ClearGraph();let lines=pairs.split("\n");let regExp=[/^(.+)-(.+)$/g,/^(.+)\>(.+)$/g,/^(.+)<(.+)$/g,/^(.+)-\((\d+|\d+\.?\d+)\)-(.+)$/g,/^(.+)-\((\d+|\d+\.?\d+)\)\>(.+)$/g,/^(.+)<\((\d+|\d+\.?\d+)\)\-(.+)$/g,];let bWeightGraph=false;var newVertices=[];for(var i=0;i<lines.length;i++)
{let line=lines[i];if(line==""){continue;}
for(let j=regExp.length-1;j>=0;--j){if(!line.match(regExp[j])){continue;}
let groupes=Array.from(line.matchAll(regExp[j]));let groupe=groupes[0];let vetext1Title=groupe[1];let vertex1=this.FindVertexByTitle(vetext1Title);if(vertex1==null){let newPosition=this.GetRandomPosition(viewportSize);vertex1=this.vertices[this.AddNewVertex(new BaseVertex(newPosition.x,newPosition.y,currentEnumVerticesType))];vertex1.mainText=vetext1Title;newVertices.push(vertex1);}
let vetext2Title=groupe[j<=2?2:3];let vertex2=this.FindVertexByTitle(vetext2Title);if(vertex2==null){let newPosition=this.GetRandomPosition(viewportSize);vertex2=this.vertices[this.AddNewVertex(new BaseVertex(newPosition.x,newPosition.y,currentEnumVerticesType))];vertex2.mainText=vetext2Title;newVertices.push(vertex2);}
let isDirect=j==1||j==2||j==4||j==5;let weight=1;if(j>2){weight=groupe[2];bWeightGraph=true;}
let isRevertEdge=j==2||j==5;let nEdgeIndex=this.AddNewEdgeSafe(isRevertEdge?vertex2:vertex1,isRevertEdge?vertex1:vertex2,isDirect,weight,false);this.FixEdgeCurve(nEdgeIndex);break;}}
if(!bWeightGraph)
{this.edges.forEach(function(part,index,theArray){theArray[index].useWeight=false;});}
this.VerticesReposition(viewportSize,newVertices);}}
Graph.prototype.TestIncidenceMatrix=function(matrix,rowsObj,colsObj,separator)
{if(separator===undefined)
{separator=",";}
var bGoodFormat=true;rowsObj.rows=[];rowsObj.rows=matrix.split("\n");for(j=0;j<rowsObj.rows.length;++j)
{if(rowsObj.rows[j]==="")
{rowsObj.rows.splice(j--,1);}}
colsObj.cols=[];var columnCount=0;for(var i=0;i<rowsObj.rows.length;i++)
{colsObj.cols[i]=this.SplitMatrixString(rowsObj.rows[i],separator);for(j=0;j<colsObj.cols[i].length;++j)
{if(colsObj.cols[i][j]==="")
{colsObj.cols[i].splice(j--,1);}}
if(i==0)
{columnCount=colsObj.cols[i].length;}
if(colsObj.cols[i].length!=columnCount)
{bGoodFormat=false;break;}}
if(bGoodFormat)
{for(var i=0;i<colsObj.cols[0].length;i++)
{var values=[];for(j=0;j<colsObj.cols.length;++j)
{if(colsObj.cols[j][i]!=0)
{values.push(colsObj.cols[j][i]);}}
if(!(values.length<=1||(values.length==2&&(values[0]==values[1]||values[0]==-values[1]))))
{bGoodFormat=false;break;}}}
return bGoodFormat;}
Graph.prototype.SetIncidenceMatrix=function(matrix,viewportSize,currentEnumVerticesType)
{var rowsObj={};var colsObj={};if(this.TestIncidenceMatrix(matrix,rowsObj,colsObj))
{rows=rowsObj.rows;cols=colsObj.cols;var clonedEdge=this.edges.slice(0);for(var i=0;i<clonedEdge.length;i++)
{this.DeleteEdge(clonedEdge[i]);}
var newVertices=[];var bWeightGraph=false;for(var i=0;i<cols[0].length;i++)
{var edgeValue=[];var edgeIndex=[];for(var j=0;j<cols.length;j++)
{if(j>=this.vertices.length)
{var newPos=new Point(0,0);newVertices.push(new BaseVertex(newPos.x,newPos.y,currentEnumVerticesType));this.AddNewVertex(newVertices[newVertices.length-1]);}
if(cols[j][i]!=0)
{edgeValue.push(cols[j][i]);edgeIndex.push(j);}}
if(edgeIndex.length==1)
{edgeValue.push(edgeValue[0]);edgeIndex.push(edgeIndex[0]);}
if(edgeIndex.length==2)
{if(edgeValue[0]!=edgeValue[1])
{if(edgeValue[1]>0)
{edgeValue=edgeValue.swap(0,1);edgeIndex=edgeIndex.swap(0,1);}}
var nEdgeIndex=this.AddNewEdgeSafe(this.vertices[edgeIndex[0]],this.vertices[edgeIndex[1]],edgeValue[0]!=edgeValue[1],Math.abs(edgeValue[1]),false);this.FixEdgeCurve(nEdgeIndex);if(nEdgeIndex>=0)
{bWeightGraph=bWeightGraph||this.edges[nEdgeIndex].weight!=1;}}}
if(!bWeightGraph)
{this.edges.forEach(function(part,index,theArray){theArray[index].useWeight=false;});}
for(var i=cols.length;i<Math.max(this.vertices.length,cols.length);i++)
{this.DeleteVertex(this.vertices[i]);i--;}
this.VerticesReposition(viewportSize,newVertices);}}
Graph.prototype.GetIncidenceMatrix=function()
{var matrix="";for(var i=0;i<this.vertices.length;i++)
{for(var j=0;j<this.edges.length;j++)
{if(this.edges[j].vertex1==this.vertices[i])
{matrix+=this.edges[j].weight;}
else if(this.edges[j].vertex2==this.vertices[i]&&!this.edges[j].isDirect)
{matrix+=this.edges[j].weight;}
else if(this.edges[j].vertex2==this.vertices[i]&&this.edges[j].isDirect)
{matrix+=-this.edges[j].weight;}
else
{matrix+="0";}
if(j!=this.edges.length-1)
{matrix+=", ";}}
matrix=matrix+"\n";}
return matrix;}
Graph.prototype.SplitMatrixString=function(line,separator)
{if(separator===undefined)
{separator=",";}
var res=[];var i=0;var isZeroOneLine=true;for(i=0;i<line.length;i++)
{if(line.charAt(i)!='0'&&line.charAt(i)!='1')
{isZeroOneLine=false;break;}}
if(!isZeroOneLine)
{if(separator!=",")
{line=line.replace(/,/g,".");}
for(i=0;i<line.length;i++)
{if(("0123456789.-e").indexOf(line.charAt(i))<0)
{if(i>0)
{res.push(line.substr(0,i));}
if(i==0)
{i=1;}
line=line.substr(i,line.length-i);i=-1;}}
if(line.length>0)
{res.push(line);}}
else
{for(i=0;i<line.length;i++)
{res.push(line.charAt(i));}}
console.log(res);return res;}
Graph.prototype.SaveToXML=function(additionalData)
{var mainHeader="<?xml version=\"1.0\" encoding=\"UTF-8\"?><graphml>";var header="<graph id=\"Graph\" uidGraph=\""+this.uidGraph+"\""+" uidEdge=\""+this.uidEdge+"\">";var xmlBody="";for(var i=0;i<this.vertices.length;i++)
{xmlBody=xmlBody+this.vertices[i].SaveToXML();}
xmlBody=xmlBody+"";for(var i=0;i<this.edges.length;i++)
{xmlBody=xmlBody+this.edges[i].SaveToXML();}
xmlBody=xmlBody+"";additionalField="";if(additionalData.length>0)
{additionalField="<additional data=\""+additionalData+"\"/>"}
return mainHeader+header+xmlBody+"</graph>"+additionalField+"</graphml>";}
Graph.prototype.LoadFromXML=function(xmlText,additionalData)
{xmlDoc=$.parseXML(xmlText);var $xml=$(xmlDoc);$graphs=$xml.find("graph");var loadedGraphId=0;var loadedEdgeId=0;$graphs.each(function(){loadedGraphId=parseInt($(this).attr('uidGraph'));loadedEdgeId=parseInt($(this).attr('uidEdge'));});if(isNaN(loadedEdgeId))
{loadedEdgeId=this.edgesOffset;}else if(loadedEdgeId<this.edgesOffset)
{loadedEdgeId=this.edgesOffset;}
this.uidGraph=loadedGraphId;this.uidEdge=loadedEdgeId;$nodes=$xml.find("node");var vertices=[];$nodes.each(function(){var vertex=new BaseVertex();vertex.LoadFromXML($(this));vertices.push(vertex);});this.vertices=vertices;$edges=$xml.find("edge");var edges=[];var graph=this;$edges.each(function(){var edge=new BaseEdge();edge.LoadFromXML($(this),graph);if(edge.id<graph.uidEdge){edge.id=graph.uidEdge;graph.uidEdge++;}
edges.push(edge);});this.edges=edges;$additional=$xml.find("additional");if($additional.length!=0&&additionalData!=null)
{additionalData["data"]=$additional.attr('data');}
this.isMultiGraph=this.checkMutiGraph();}
Graph.prototype.hasDirectEdge=function()
{var res=false;for(var i=0;i<this.edges.length;i++)
{if(this.edges[i].isDirect)
{res=true;break;}}
return res;}
Graph.prototype.hasUndirectEdge=function()
{var res=false;for(var i=0;i<this.edges.length;i++)
{if(!this.edges[i].isDirect)
{res=true;break;}}
return res;}
Graph.prototype.hasEdges=function()
{return this.edges.length>0;}
Graph.prototype.clampPositions=function(viewportSize)
{var diameter=(new VertexModel()).diameter;for(i=0;i<this.vertices.length;i++)
{this.vertices[i].position.x=Math.min(Math.max(this.vertices[i].position.x,diameter),viewportSize.x-diameter);this.vertices[i].position.y=Math.min(Math.max(this.vertices[i].position.y,diameter),viewportSize.y-diameter);}}
Graph.prototype.getGraphBBox=function(viewportSize)
{var pointMin=new Point(1e5,1e5);var pointMax=new Point(-1e5,-1e5);var diameter=(new VertexModel()).diameter;for(i=0;i<this.vertices.length;i++)
{var vertex=this.vertices[i];var factor=vertex.diameterFactor();var deltaVector=new Point(factor.x*diameter,factor.y*diameter);pointMin=pointMin.min(vertex.position.subtract(deltaVector));pointMax=pointMax.max(vertex.position.add(deltaVector));}
var max_curve_length=32;for(i=0;i<this.edges.length;i++)
{var edge=this.edges[i];if(edge.model.type==EdgeModels.curve)
{var max_curve=edge.vertex2.position.subtract(edge.vertex1.position).length()/max_curve_length;for(j=0;j<max_curve;j++)
{var point=edge.model.GetCurvePoint(edge.vertex1.position,edge.vertex2.position,j/max_curve);var deltaVector=new Point(max_curve_length,max_curve_length);pointMin=pointMin.min(point.subtract(deltaVector));pointMax=pointMax.max(point.add(deltaVector));}}}
return new Rect(pointMin,pointMax);}
Graph.prototype.hasPair=function(edge)
{return this.FindPairFor(edge)!=null;}
Graph.prototype.FindPairFor=function(edge)
{var res=this.getNeighborEdges(edge);return res.length==1?res[0]:null;}
Graph.prototype.getNeighborEdges=function(edge)
{var res=[];for(var i=0;i<this.edges.length;i++)
{var curEdge=this.edges[i];if(curEdge==edge)
continue;if((curEdge.vertex1.id==edge.vertex1.id&&curEdge.vertex2.id==edge.vertex2.id)||(curEdge.vertex1.id==edge.vertex2.id&&curEdge.vertex2.id==edge.vertex1.id))
{res.push(curEdge);}}
return res;}
Graph.prototype.checkMutiGraph=function()
{var res=false;var start={};for(var i=0;i<this.edges.length;i++)
{var edge=this.edges[i];if(start.hasOwnProperty(edge.vertex1.id)&&start[edge.vertex1.id]==edge.vertex2.id)
{res=true;break;}
start[edge.vertex1.id]=edge.vertex2.id;if(!edge.isDirect)
{if(start.hasOwnProperty(edge.vertex2.id)&&start[edge.vertex2.id]==edge.vertex1.id)
{res=true;break;}
start[edge.vertex2.id]=edge.vertex1.id;}}
return res;}
Graph.prototype.isMulti=function()
{return this.isMultiGraph;}
Graph.prototype.isNeedReposition=function()
{var res=false;for(var i=0;i<this.vertices.length;i++)
{res=res||this.vertices[i].IsUndefinedPosition();}
return res;}
Graph.prototype.FixEdgeCurve=function(edgeIndex)
{var edgeObject=this.edges[edgeIndex];var hasPair=this.hasPair(edgeObject);var neighborEdges=this.getNeighborEdges(edgeObject);if(hasPair)
{if(edgeObject.model.default)
edgeObject.model.type=EdgeModels.curve;var pairEdge=this.FindPairFor(edgeObject);if(pairEdge.model.default)
{pairEdge.model.type=EdgeModels.curve;if(pairEdge.vertex1==edgeObject.vertex1&&pairEdge.vertex2==edgeObject.vertex2)
pairEdge.model.curveValue=-pairEdge.model.curveValue;}}
else if(neighborEdges.length>=2)
{var curve=this.GetAvailableCurveValue(neighborEdges,edgeObject);if(edgeObject.model.default)
{edgeObject.model.type=EdgeModels.curve;edgeObject.model.curveValue=curve;}}}
Graph.prototype.GetAvailableCurveValue=function(neighborEdges,originalEdge)
{var values=[];for(var i=0;i<neighborEdges.length;i++)
{var edge=neighborEdges[i];var sameDirection=(originalEdge.vertex1.id==edge.vertex1.id);if(edge.model.type==EdgeModels.curve)
{values[(sameDirection?edge.model.curveValue:-edge.model.curveValue)]=true;}}
var changeValue=DefaultHandler.prototype.curveValue;var defaultValue=0.0;var maxSearch=10;for(var i=1;i<maxSearch;i++)
{value=i*changeValue;if(!values.hasOwnProperty(value))
return value;value=-i*changeValue;if(!values.hasOwnProperty(value))
return value;}
return defaultValue;}
Graph.prototype.reverseAllEdges=function()
{for(var i=0;i<this.edges.length;i++)
{if(this.edges[i].isDirect)
{let v1=this.edges[i].vertex1;this.edges[i].vertex1=this.edges[i].vertex2;this.edges[i].vertex2=v1;}}
this.isMultiGraph=this.checkMutiGraph();}
Graph.prototype.makeAllEdgesDirected=function()
{for(var i=0;i<this.edges.length;i++)
{if(!this.edges[i].isDirect)
{this.edges[i].isDirect=true;}}
this.isMultiGraph=this.checkMutiGraph();}
Graph.prototype.makeAllEdgesUndirected=function()
{for(var i=0;i<this.edges.length;i++)
{if(this.edges[i].isDirect)
{this.edges[i].isDirect=false;}}
this.isMultiGraph=this.checkMutiGraph();}
moduleLoader.endCacheLoading();

View File

@@ -0,0 +1,13 @@
// Global version needs to force reload scripts from server.
globalVersion = 75;
{
let modulDir = "pages/create_graph_by_matrix/";
doInclude ([
include ("entities/graph/api/index.js"),
include ("model/createByMatrixMain.js", modulDir),
include ("model/main.js", modulDir)
]);
}

View File

@@ -0,0 +1,670 @@
moduleLoader.beginCacheLoading(["/script/entities/graph/api/index.js?v=75","/script/shared/point.js?v=75","/script/entities/edge/api/index.js?v=75","/script/entities/edge/model/BaseEdge.js?v=75","/script/entities/edge/model/EdgeModel.js?v=75","/script/entities/vertex/api/index.js?v=75","/script/entities/vertex/model/BaseVertex.js?v=75","/script/entities/vertex/model/VertexModel.js?v=75","/script/entities/graph/model/Graph.js?v=75","/script/pages/create_graph_by_matrix/model/createByMatrixMain.js?v=75","/script/pages/create_graph_by_matrix/model/main.js?v=75",]);globalVersion=75;{let modulDir="pages/create_graph_by_matrix/";doInclude([include("entities/graph/api/index.js"),include("model/createByMatrixMain.js",modulDir),include("model/main.js",modulDir)]);}
{let modulDir="entities/graph/";doInclude([include("shared/point.js"),include("entities/edge/api/index.js"),include("entities/vertex/api/index.js"),include("model/Graph.js",modulDir)])}function Point(x,y){this.x=x||0;this.y=y||0;};Point.prototype.x=null;Point.prototype.y=null;Point.prototype.add=function(v){return new Point(this.x+v.x,this.y+v.y);};Point.prototype.addValue=function(v){return new Point(this.x+v,this.y+v);};Point.prototype.clone=function(){return new Point(this.x,this.y);};Point.prototype.degreesTo=function(v){var dx=this.x-v.x;var dy=this.y-v.y;var angle=Math.atan2(dy,dx);return angle*(180/Math.PI);};Point.prototype.distance=function(v){return Math.sqrt(this.distanceSqr(v));};Point.prototype.distanceSqr=function(v){var x=this.x-v.x;var y=this.y-v.y;return x*x+y*y;};Point.prototype.equals=function(toCompare){return this.x==toCompare.x&&this.y==toCompare.y;};Point.prototype.interpolate=function(v,f){return new Point((this.x+v.x)*f,(this.y+v.y)*f);};Point.prototype.length=function(){return Math.sqrt(this.x*this.x+this.y*this.y);};Point.prototype.normalize=function(thickness){var l=this.length();this.x=this.x/l*thickness;this.y=this.y/l*thickness;return new Point(this.x,this.y);};Point.prototype.normalizeCopy=function(thickness){var l=this.length();return new Point(this.x/l*thickness,this.y/l*thickness);};Point.prototype.orbit=function(origin,arcWidth,arcHeight,degrees){var radians=degrees*(Math.PI/180);this.x=origin.x+arcWidth*Math.cos(radians);this.y=origin.y+arcHeight*Math.sin(radians);};Point.prototype.rotate=function(center,degrees){var radians=degrees*(Math.PI/180);offset=this.subtract(center);this.x=offset.x*Math.cos(radians)-offset.y*Math.sin(radians);this.y=offset.x*Math.sin(radians)+offset.y*Math.cos(radians);this.x=this.x+center.x;this.y=this.y+center.y;return this;};Point.prototype.offset=function(dx,dy){this.x+=dx;this.y+=dy;};Point.prototype.subtract=function(v){return new Point(this.x-v.x,this.y-v.y);};Point.prototype.subtractValue=function(value){return new Point(this.x-value,this.y-value);};Point.prototype.multiply=function(value){return new Point(this.x*value,this.y*value);};Point.prototype.toString=function(){return"(x="+this.x+", y="+this.y+")";};Point.prototype.normal=function(){return new Point(-this.y,this.x);};Point.prototype.min=function(point)
{return new Point(Math.min(this.x,point.x),Math.min(this.y,point.y));};Point.prototype.max=function(point)
{return new Point(Math.max(this.x,point.x),Math.max(this.y,point.y));};Point.prototype.inverse=function()
{return new Point(-this.x,-this.y);};Point.prototype.cross=function(point)
{return this.x*point.y-this.y*point.x;};Point.interpolate=function(pt1,pt2,f){return new Point(pt1.x*(1.0-f)+pt2.x*f,pt1.y*(1.0-f)+pt2.y*f);};Point.polar=function(len,angle){return new Point(len*Math.cos(angle),len*Math.sin(angle));};Point.distance=function(pt1,pt2){var x=pt1.x-pt2.x;var y=pt1.y-pt2.y;return Math.sqrt(x*x+y*y);};Point.center=function(pt1,pt2){return new Point((pt1.x+pt2.x)/2.0,(pt1.y+pt2.y)/2.0);};Point.toString=function(){return x+" "+y;}
Point.projection=function(point,line1,line2)
{var x=line2.y-line1.y;var y=line1.x-line2.x;var l=(line1.cross(line2)+line1.cross(point)+line2.cross(point))/(x*(line2.y-line1.y)+y*(line1.x-line2.x));var res=new Point(point.x+x*l,point.y+y*l);return res;}
Point.hitTest=function(pt11,pt12,pt21,pt22)
{var res=null;var n=0.0;var x1=pt11.x;var y1=pt11.y;var x2=pt12.x;var y2=pt12.y;var x3=pt21.x;var y3=pt21.y;var x4=pt22.x;var y4=pt22.y;if(y2-y1!=0.0)
{var q=(x2-x1)/(y1-y2);var sn=(x3-x4)+(y3-y4)*q;if(sn==0.0)
{return res;}
var fn=(x3-x1)+(y3-y1)*q;n=fn/sn;}
else
{if((y3-y4)==0.0)
{return res;}
n=(y3-y1)/(y3-y4);}
res=new Point(x3+(x4-x3)*n,y3+(y4-y3)*n);var epsilon=1E-5;if(!(res.x>=Math.min(x1,x2)-epsilon&&res.x>=Math.min(x3,x4)-epsilon&&res.x<=Math.max(x1,x2)+epsilon&&res.x<=Math.max(x3,x4)+epsilon&&res.y>=Math.min(y1,y2)-epsilon&&res.y>=Math.min(y3,y4)-epsilon&&res.y<=Math.max(y1,y2)+epsilon&&res.y<=Math.max(y3,y4)+epsilon))
{res=null;}
return res;}
function Rect(minPoint,maxPoint){this.minPoint=minPoint;this.maxPoint=maxPoint;};Rect.prototype.center=function()
{return Point.center(this.minPoint,this.maxPoint);};Rect.prototype.size=function()
{return this.maxPoint.subtract(this.minPoint);};Rect.prototype.left=function()
{return this.minPoint.x;};Rect.prototype.top=function()
{return this.minPoint.y;};Rect.prototype.isIn=function(v)
{return this.minPoint.x<=v.x&&this.minPoint.y<=v.y&&this.maxPoint.x>v.x&&this.maxPoint.y>v.y;};{let modulDir="entities/edge/";doInclude([include("model/BaseEdge.js",modulDir),include("model/EdgeModel.js",modulDir)])}
function BaseEdge(vertex1,vertex2,isDirect,weight,upText)
{this.vertex1=vertex1;this.vertex2=vertex2;this.arrayStyleStart="";this.arrayStyleFinish="";this.isDirect=isDirect;this.weight=0;this.text="";this.useWeight=false;this.id=0;this.model=new EdgeModel();if(upText===undefined)
this.upText="";else
this.upText=upText;if(weight!==undefined)
this.SetWeight(weight);this.ownStyles={};}
BaseEdge.prototype.copyFrom=function(other)
{this.vertex1=other.vertex1;this.vertex2=other.vertex2;this.arrayStyleStart=other.arrayStyleStart;this.arrayStyleFinish=other.arrayStyleFinish;this.isDirect=other.isDirect;this.weight=other.weight;this.text=other.text;this.useWeight=other.useWeight;this.id=other.id;this.model=new EdgeModel();this.model.copyFrom(other.model);this.upText=other.upText;this.ownStyles=FullObjectCopy(other.ownStyles);}
BaseEdge.prototype.SaveToXML=function()
{return"<edge "+"source=\""+this.vertex1.id+"\" "+"target=\""+this.vertex2.id+"\" "+"isDirect=\""+this.isDirect+"\" "+"weight=\""+this.weight+"\" "+"useWeight=\""+this.useWeight+"\" "+"id=\""+this.id+"\" "+"text=\""+gEncodeToHTML(this.text)+"\" "+"upText=\""+gEncodeToHTML(this.upText)+"\" "+"arrayStyleStart=\""+this.arrayStyleStart+"\" "+"arrayStyleFinish=\""+this.arrayStyleFinish+"\" "+
((Object.keys(this.ownStyles).length>0)?"ownStyles = \""+gEncodeToHTML(JSON.stringify(this.ownStyles))+"\" ":"")+
this.model.SaveToXML()+"></edge>";}
BaseEdge.prototype.LoadFromXML=function(xml,graph)
{var attr=xml.attr('vertex1');if(typeof attr==='undefined')
{attr=xml.attr('source');}
this.vertex1=graph.FindVertex(typeof attr!=='undefined'?attr:xml.attr('graph1'));var attr=xml.attr('vertex2');if(typeof attr==='undefined')
{attr=xml.attr('target');}
this.vertex2=graph.FindVertex(typeof attr!=='undefined'?attr:xml.attr('graph2'));this.isDirect=xml.attr('isDirect')=="true";this.weight=parseFloat(xml.attr('weight'));if(isNaN(this.weight))
{this.weight=1;}
this.hasPair=xml.attr('hasPair')=="true";this.useWeight=xml.attr('useWeight')=="true";this.id=xml.attr('id');this.text=xml.attr("text")==null?"":gDecodeFromHTML(xml.attr("text"));this.arrayStyleStart=xml.attr("arrayStyleStart")==null?"":xml.attr("arrayStyleStart");this.arrayStyleFinish=xml.attr("arrayStyleFinish")==null?"":xml.attr("arrayStyleFinish");this.upText=xml.attr('upText');if(typeof this.upText==='undefined')
{this.upText="";}
else
{this.upText=gDecodeFromHTML(this.upText);}
var ownStyle=xml.attr('ownStyles');if(typeof ownStyle!=='undefined')
{var parsedSave=gDecodeFromHTML(JSON.parse(ownStyle));for(var indexField in parsedSave)
{var index=parseInt(indexField);this.ownStyles[index]=FullObjectCopy(this.getStyleFor(index));for(var field in parsedSave[indexField])
{if(this.ownStyles[index].ShouldLoad(field))
this.ownStyles[index][field]=parsedSave[indexField][field];}}}
this.model.LoadFromXML(xml);}
BaseEdge.prototype.GetPixelLength=function()
{if(this.vertex1==this.vertex2)
{return this.model.GetLoopSize()*2*Math.PI;}
else
{return Point.distance(this.vertex1.position,this.vertex2.position);}}
BaseEdge.prototype.GetWeight=function()
{return this.useWeight?this.weight:1;}
BaseEdge.prototype.GetText=function()
{return this.text.length>0?this.text:(this.useWeight?this.weight.toString():"");}
BaseEdge.prototype.GetUpText=function()
{return this.upText;}
BaseEdge.prototype.GetStartEdgeStyle=function()
{return this.arrayStyleStart;}
BaseEdge.prototype.GetFinishEdgeStyle=function()
{return(this.arrayStyleFinish!=""?this.arrayStyleFinish:(this.isDirect?"arrow":""));}
BaseEdge.prototype.HitTest=function(pos)
{var positions=this.GetEdgePositionsShift();return this.model.HitTest(positions[0],positions[1],pos);}
BaseEdge.prototype.GetEdgePositionsShift=function()
{return this.GetEdgePositions();}
BaseEdge.prototype.GetEdgePositions=function()
{var res=[];if(this.vertex1==this.vertex2)
{res.push(this.vertex1.position);res.push(this.vertex2.position);return res;}
var position1=this.vertex1.position;var position2=this.vertex2.position;var diameter1=this.vertex1.model.diameter+parseInt(this.vertex1.currentStyle.GetStyle({},this.vertex1).lineWidth);var diameter2=this.vertex2.model.diameter+parseInt(this.vertex2.currentStyle.GetStyle({},this.vertex2).lineWidth);var direction=position1.subtract(position2);var direction1=direction;var direction2=direction;var d1=diameter1;var d2=diameter2;if(this.model.type==EdgeModels.curve)
{var dist=position1.distance(position2);var point1=this.model.GetCurvePoint(position1,position2,10.0/dist);direction1=position1.subtract(point1);var point2=this.model.GetCurvePoint(position1,position2,1.0-10.0/dist);direction2=position2.subtract(point2);d2=diameter2;}
else
{direction2=direction2.multiply(-1);}
direction1.normalize(1.0);direction2.normalize(1.0);var vertices=[];vertices.push({vertex:this.vertex1,direction:direction1,position:position1,diameter:d1});vertices.push({vertex:this.vertex2,direction:direction2,position:position2,diameter:d2});vertices.forEach(function(data)
{var shape=data.vertex.currentStyle.GetStyle({},data.vertex).shape;if(shape==VertexCircleShape)
{var direction=data.direction.multiply(0.5);res.push(data.position.subtract(direction.multiply(data.diameter)));}
else
{var lineFinish1=data.direction.multiply(-1).multiply(1000.0);var pointsVertex1=GetPointsForShape(shape,data.diameter,data.vertex.mainText);pointsVertex1.push(pointsVertex1[0]);for(var i=0;i<pointsVertex1.length-1;i++)
{var hitText=Point.hitTest(new Point(0,0),lineFinish1,pointsVertex1[i],pointsVertex1[i+1]);if(hitText!=null)
{res.push(data.position.add(hitText));break;}}}});return res;}
BaseEdge.prototype.SetWeight=function(weight)
{var useWeight=false;if(!isNaN(parseInt(weight,10)))
{useWeight=true;}
weight=(!isNaN(parseInt(weight,10))&&weight>=0)?weight:1;this.weight=Number(weight);this.useWeight=useWeight;}
BaseEdge.prototype.SetUpText=function(text)
{this.upText=text;}
BaseEdge.prototype.resetOwnStyle=function(index)
{if(this.ownStyles.hasOwnProperty(index))
{delete this.ownStyles[index];}}
BaseEdge.prototype.setOwnStyle=function(index,style)
{this.ownStyles[index]=style;}
BaseEdge.prototype.getStyleFor=function(index)
{if(this.ownStyles.hasOwnProperty(index))
{return this.ownStyles[index];}
else
{var style=null;if(index==0)
style=globalApplication.GetStyle("edge","common");else
style=globalApplication.GetStyle("edge","selected",undefined,index-1);return style;}}
BaseEdge.prototype.hasOwnStyleFor=function(index)
{return this.ownStyles.hasOwnProperty(index);}
var EdgeModels={"line":0,"curve":1};const defaultEdgeWidth=4;function EdgeModel()
{this.width=globalApplication.GetDefaultEdgeWidth();this.type=EdgeModels.line;this.curveValue=EdgeModel.prototype.defaultCurve;this.default=true;this.sizeOfLoop=24;this.loopShiftAngel=Math.PI/6;}
EdgeModel.prototype.defaultCurve=0.1;EdgeModel.prototype.copyFrom=function(other)
{this.width=other.width;this.type=other.type;this.curveValue=other.curveValue;this.default=other.default;}
EdgeModel.prototype.SaveToXML=function()
{return"model_width=\""+this.width+"\" "+"model_type=\""+this.type+"\" "+"model_curveValue=\""+this.curveValue+"\" "+"model_default=\""+this.default+"\" ";}
EdgeModel.prototype.LoadFromXML=function(xml,graph)
{this.width=xml.attr('model_width')==null?this.width:parseFloat(xml.attr("model_width"));this.type=xml.attr('model_type')==null?this.type:xml.attr("model_type");this.curveValue=xml.attr('model_curveValue')==null?this.curveValue:parseFloat(xml.attr("model_curveValue"));this.default=xml.attr('model_default')==null?this.default:parseFloat(xml.attr("model_default"));}
EdgeModel.prototype.GetCurvePoint=function(position1,position2,t)
{var points=this.GetBezierPoints(position1,position2);var firstBezierPoint=points[0];var secondBezierPoint=points[1];var B0_t=Math.pow(1-t,3);var B1_t=3*t*Math.pow(1-t,2);var B2_t=3*t*t*(1-t)
var B3_t=t*t*t;var ax=position1.x;var ay=position1.y;var dx=position2.x;var dy=position2.y;var bx=firstBezierPoint.x;var by=firstBezierPoint.y;var cx=secondBezierPoint.x;var cy=secondBezierPoint.y;var px_t=(B0_t*ax)+(B1_t*bx)+(B2_t*cx)+(B3_t*dx);var py_t=(B0_t*ay)+(B1_t*by)+(B2_t*cy)+(B3_t*dy);return new Point(px_t,py_t);}
EdgeModel.prototype.GetBezierPoints=function(position1,position2)
{var direction=position2.subtract(position1);var delta=direction.length();direction.normalize(1.0);var normal=direction.normal();var deltaOffsetPixels=delta*this.curveValue;var yOffset=normal.multiply(deltaOffsetPixels);var firstBezierPointShift=(direction.multiply(delta*0.2)).add(yOffset);var secondBezierPointShift=(direction.multiply(-delta*0.2)).add(yOffset);var firstBezierPoint=position1.add(firstBezierPointShift);var secondBezierPoint=position2.add(secondBezierPointShift);return[firstBezierPoint,secondBezierPoint];}
EdgeModel.prototype.HitTest=function(position1,position2,mousePos)
{if(this.type==EdgeModels.line)
return this.HitTestLine(position1,position2,mousePos);else if(this.type==EdgeModels.curve)
return this.HitTestCurve(position1,position2,mousePos);return false;}
EdgeModel.prototype.HitTestLine=function(position1,position2,mousePos,factor)
{if(factor===undefined)
{factor=1.0;}
var pos1=position1;var pos2=position2;var pos0=mousePos;if(pos1.equals(pos2))
{var xCenter=pos1.x-Math.cos(this.GetLoopShiftAngel())*this.GetLoopSize();var yCenter=pos1.y-Math.sin(this.GetLoopShiftAngel())*this.GetLoopSize();return Math.abs((Point.distance(new Point(xCenter,yCenter),pos0))-this.GetLoopSize())<=this.width*1.5*factor;}
var r1=pos0.distance(pos1);var r2=pos0.distance(pos2);var r12=pos1.distance(pos2);if(r1>=(new Point(r2,r12)).length()||r2>=(new Point(r1,r12)).length())
{}
else
{var distance=((pos1.y-pos2.y)*pos0.x+(pos2.x-pos1.x)*pos0.y+(pos1.x*pos2.y-pos2.x*pos1.y))/r12;if(Math.abs(distance)<=this.width*1.5*factor)
{return true;}}
return false;}
EdgeModel.prototype.HitTestCurve=function(position1,position2,mousePos)
{var pos1=position1;var pos2=position2;var pos0=mousePos;if(pos1.equals(pos2))
{var xCenter=pos1.x-Math.cos(this.GetLoopShiftAngel())*this.GetLoopSize();var yCenter=pos1.y-Math.sin(this.GetLoopShiftAngel())*this.GetLoopSize();return Math.abs((Point.distance(new Point(xCenter,yCenter),pos0))-this.GetLoopSize())<=this.width*1.5;}
var interval_count=position1.distance(position2)/100*30;var start=position1;for(var i=0;i<interval_count;i++)
{var finish=this.GetCurvePoint(position1,position2,i/interval_count);if(this.HitTestLine(start,finish,mousePos,2.0))
return true;start=finish;}
return false;}
EdgeModel.prototype.ChangeCurveValue=function(delta)
{if(this.type==EdgeModels.line)
{this.type=EdgeModels.curve;this.curveValue=0.0;}
this.curveValue=this.curveValue+delta;if(Math.abs(this.curveValue)<=0.01)
this.type=EdgeModels.line;this.default=false;}
EdgeModel.prototype.SetCurveValue=function(value)
{if(this.type==EdgeModels.line)
{this.type=EdgeModels.curve;this.curveValue=0.0;}
this.curveValue=value;if(Math.abs(this.curveValue)<=0.01)
this.type=EdgeModels.line;this.default=false;}
EdgeModel.prototype.GetLoopSize=function()
{if(Math.abs(this.curveValue)<=0.01)
{return this.sizeOfLoop;}
else
{let normalCurve=this.curveValue;if(this.type==EdgeModels.line){normalCurve=this.defaultCurve;}
else if(normalCurve>=0.0){normalCurve+=this.defaultCurve}
return this.sizeOfLoop*Math.abs(normalCurve)*(1/this.defaultCurve);}}
EdgeModel.prototype.GetLoopShiftAngel=function()
{if(this.type==EdgeModels.line||this.curveValue>=0.0)
{return this.loopShiftAngel;}
else
{return this.loopShiftAngel+Math.PI;}}
{let modulDir="entities/vertex/";doInclude([include("model/BaseVertex.js",modulDir),include("model/VertexModel.js",modulDir)])}
function BaseVertex(x,y,vertexEnumType)
{this.position=new Point(x,y);this.id=0;this.mainText="";this.upText="";this.vertexEnumType=vertexEnumType;this.model=new VertexModel();this.hasUndefinedPosition=false;this.ownStyles={};};BaseVertex.prototype.position=new Point(0,0);BaseVertex.prototype.copyFrom=function(other)
{this.position=new Point(other.position.x,other.position.y);this.id=other.id;this.mainText=other.mainText;this.upText=other.upText;this.vertexEnumType=other.vertexEnumType;this.model=new VertexModel();this.hasUndefinedPosition=other.hasUndefinedPosition;this.ownStyles=FullObjectCopy(other.ownStyles);}
BaseVertex.prototype.SaveToXML=function()
{return"<node "+"positionX=\""+this.position.x+"\" "+"positionY=\""+this.position.y+"\" "+"id=\""+this.id+"\" "+"mainText=\""+gEncodeToHTML(this.mainText)+"\" "+"upText=\""+gEncodeToHTML(this.upText)+"\" "+
((Object.keys(this.ownStyles).length>0)?"ownStyles = \""+gEncodeToHTML(JSON.stringify(this.ownStyles))+"\" ":"")+"size=\""+this.model.diameter+"\" "+"></node>";}
BaseVertex.prototype.LoadFromXML=function(xml)
{var xmlX=xml.attr('positionX');var xmlY=xml.attr('positionY');this.hasUndefinedPosition=(typeof xmlX==='undefined')||(typeof xmlY==='undefined');this.position=new Point(parseFloat(xmlX),parseFloat(xmlY));this.id=xml.attr('id');this.mainText=xml.attr('mainText');this.upText=xml.attr('upText');if(typeof this.mainText==='undefined')
this.mainText=this.id;else
this.mainText=gDecodeFromHTML(this.mainText);if(typeof this.upText==='undefined')
this.upText="";else
this.upText=gDecodeFromHTML(this.upText);var ownStyle=xml.attr('ownStyles');if(typeof ownStyle!=='undefined')
{var parsedSave=gDecodeFromHTML(JSON.parse(ownStyle));for(var indexField in parsedSave)
{var index=parseInt(indexField);this.ownStyles[index]=FullObjectCopy(this.getStyleFor(index));for(var field in parsedSave[indexField])
{if(this.ownStyles[index].ShouldLoad(field))
this.ownStyles[index][field]=parsedSave[indexField][field];}}}
var size=xml.attr('size');if(typeof size!=='undefined')
this.model.diameter=parseInt(size);}
BaseVertex.prototype.SetId=function(id)
{this.id=id;if(this.vertexEnumType!=null)
this.mainText=this.vertexEnumType.GetVertexText(id);}
BaseVertex.prototype.diameterFactor=function()
{return new Point(1.0+(this.mainText.length?this.mainText.length/8.0:0),1.5);}
BaseVertex.prototype.IsUndefinedPosition=function()
{return this.hasUndefinedPosition;}
BaseVertex.prototype.HitTest=function(pos)
{var shape=this.hasOwnProperty('currentStyle')?this.currentStyle.GetStyle({},this).shape:VertexCircleShape;var width=this.hasOwnProperty('currentStyle')?this.currentStyle.GetStyle({},this).lineWidth:0;if(shape==VertexCircleShape)
{return this.position.distance(pos)<this.model.diameter/2.0+width;}
else
{var relativePos=(new Point(pos.x,pos.y)).subtract(this.position);var lineFinish1=relativePos.add(new Point(1000,0));var lineFinish2=relativePos.add(new Point(-1000,0));var pointsVertex1=GetPointsForShape(shape,this.model.diameter+width,this.mainText);pointsVertex1.push(pointsVertex1[0]);var hitNumber1=0;var hitNumber2=0;for(var i=0;i<pointsVertex1.length-1;i++)
{var hitTest=Point.hitTest(relativePos,lineFinish1,pointsVertex1[i],pointsVertex1[i+1]);if(hitTest!=null)
{hitNumber1++;}
hitTest=Point.hitTest(relativePos,lineFinish2,pointsVertex1[i],pointsVertex1[i+1]);if(hitTest!=null)
{hitNumber2++;}}
return hitNumber1==1&&hitNumber2==1;}
return false;}
BaseVertex.prototype.resetOwnStyle=function(index)
{if(this.ownStyles.hasOwnProperty(index))
{delete this.ownStyles[index];}}
BaseVertex.prototype.setOwnStyle=function(index,style)
{this.ownStyles[index]=FullObjectCopy(style);}
BaseVertex.prototype.getStyleFor=function(index)
{if(this.ownStyles.hasOwnProperty(index))
{return this.ownStyles[index];}
else
{var style=null;if(index==0)
style=globalApplication.GetStyle("vertex","common");else
style=globalApplication.GetStyle("vertex","selected",undefined,index-1);return style;}}
BaseVertex.prototype.hasOwnStyleFor=function(index)
{return this.ownStyles.hasOwnProperty(index);}
const defaultVertexDiameter=30;function VertexModel()
{this.diameter=globalApplication.GetDefaultVertexSize();}
function Graph()
{this.vertices=[];this.edges=[];this.uidGraph=0;this.uidEdge=10000;this.hasDirect=false;this.isMultiGraph=false;};Graph.prototype.infinity=1E8;Graph.prototype.maxVertices=1000;Graph.prototype.edgesOffset=10000;Graph.prototype.AddNewVertex=function(vertex)
{if(this.vertices.length<=this.maxVertices)
{vertex.SetId(this.uidGraph);this.uidGraph=this.uidGraph+1;this.vertices.push(vertex);}
return this.vertices.length-1;}
Graph.prototype.ClearGraph=function(){this.vertices=[];this.edges=[];this.uidGraph=0;this.uidEdge=10000;this.hasDirect=false;this.isMultiGraph=false;}
Graph.prototype.AddNewEdgeSafe=function(graph1,graph2,isDirect,weight,replaceIfExists=true)
{return this.AddNewEdge(new BaseEdge(graph1,graph2,isDirect,weight),replaceIfExists);}
Graph.prototype.AddNewEdge=function(edge,replaceIfExists)
{edge.id=this.uidEdge;this.uidEdge=this.uidEdge+1;var edge1=this.FindEdgeAny(edge.vertex1.id,edge.vertex2.id);var edgeRevert=this.FindEdgeAny(edge.vertex2.id,edge.vertex1.id);if(!edge.isDirect)
{if(edge1!=null&&replaceIfExists)
this.DeleteEdge(edge1);if(edgeRevert!=null&&replaceIfExists)
this.DeleteEdge(edgeRevert);this.edges.push(edge);}
else
{if(edge1!=null&&replaceIfExists)
this.DeleteEdge(edge1);if(edgeRevert!=null&&!edgeRevert.isDirect&&replaceIfExists)
this.DeleteEdge(edgeRevert);this.edges.push(edge);}
this.isMultiGraph=this.checkMutiGraph();return this.edges.length-1;}
Graph.prototype.DeleteEdge=function(edgeObject)
{var index=this.edges.indexOf(edgeObject);if(index>-1)
{this.edges.splice(index,1);}
this.isMultiGraph=this.checkMutiGraph();}
Graph.prototype.DeleteVertex=function(vertexObject)
{var index=this.vertices.indexOf(vertexObject);if(index>-1)
{for(var i=0;i<this.edges.length;i++)
{if(this.edges[i].vertex1==vertexObject||this.edges[i].vertex2==vertexObject)
{this.DeleteEdge(this.edges[i]);i--;}}
this.vertices.splice(index,1);}}
Graph.prototype.HasConnectedNodes=function(vertexObject)
{var res=false;var index=this.vertices.indexOf(vertexObject);if(index>-1)
{for(var i=0;i<this.edges.length;i++)
{if(this.edges[i].vertex1==vertexObject||this.edges[i].vertex2==vertexObject)
{res=true;break;}}}
return res;}
Graph.prototype.FindVertex=function(id)
{var res=null;for(var i=0;i<this.vertices.length;i++)
{if(this.vertices[i].id==id)
{res=this.vertices[i];break;}}
return res;}
Graph.prototype.FindVertexByTitle=function(title)
{var res=null;for(var i=0;i<this.vertices.length;i++)
{if(this.vertices[i].mainText==title)
{res=this.vertices[i];break;}}
return res;}
Graph.prototype.FindEdge=function(id1,id2)
{return this.FindEdgeAny(id1,id2);}
Graph.prototype.FindEdgeById=function(edgeId)
{var res=null;for(var i=0;i<this.edges.length;i++)
{if(this.edges[i].id==edgeId)
{res=this.edges[i];break;}}
return res;}
Graph.prototype.FindEdgeAny=function(id1,id2)
{var res=null;for(var i=0;i<this.edges.length;i++)
{if((this.edges[i].vertex1.id==id1&&this.edges[i].vertex2.id==id2)||(!this.edges[i].isDirect&&this.edges[i].vertex1.id==id2&&this.edges[i].vertex2.id==id1))
{res=this.edges[i];break;}}
return res;}
Graph.prototype.FindEdgeMin=function(id1,id2)
{var res=null;var minWeight=this.infinity;for(var i=0;i<this.edges.length;i++)
{var edge=this.edges[i];if((edge.vertex1.id==id1&&edge.vertex2.id==id2)||(!edge.isDirect&&edge.vertex1.id==id2&&edge.vertex2.id==id1))
{if(edge.weight<minWeight)
{res=edge;minWeight=edge.weight;}}}
return res;}
Graph.prototype.FindEdgeMax=function(id1,id2)
{var res=null;var maxWeight=0;for(var i=0;i<this.edges.length;i++)
{var edge=this.edges[i];if((edge.vertex1.id==id1&&edge.vertex2.id==id2)||(!edge.isDirect&&edge.vertex1.id==id2&&edge.vertex2.id==id1))
{if(edge.weight>maxWeight)
{res=edge;maxWeight=edge.weight;}}}
return res;}
Graph.prototype.FindEdgeMinIgnoreDirection=function(id1,id2)
{var res=null;var minWeight=this.infinity;for(var i=0;i<this.edges.length;i++)
{var edge=this.edges[i];if((edge.vertex1.id==id1&&edge.vertex2.id==id2)||(edge.vertex1.id==id2&&edge.vertex2.id==id1))
{if(edge.weight<minWeight)
{res=edge;minWeight=edge.weight;}}}
return res;}
Graph.prototype.FindAllEdges=function(id1,id2)
{var res=[];for(var i=0;i<this.edges.length;i++)
{var edge=this.edges[i];if((edge.vertex1.id==id1&&edge.vertex2.id==id2)||(!edge.isDirect&&edge.vertex1.id==id2&&edge.vertex2.id==id1))
{res.push(edge);}}
return res;}
Graph.prototype.GetAdjacencyMatrixStr=function()
{var matrix="";for(var i=0;i<this.vertices.length;i++)
{for(var j=0;j<this.vertices.length;j++)
{var edge=this.FindEdgeMin(this.vertices[i].id,this.vertices[j].id);if(edge!=null)
{matrix+=edge.weight;}
else
{matrix+="0";}
if(j!=this.vertices.length)
{matrix+=", ";}}
matrix=matrix+"\n";}
return matrix;}
Graph.prototype.GetAdjacencyMatrix=function()
{var matrix=[];for(var i=0;i<this.vertices.length;i++)
{matrix.push([]);var v1=this.vertices[i];for(var j=0;j<this.vertices.length;j++)
{var v2=this.vertices[j];var edge=this.FindEdgeMin(v1.id,v2.id);if(edge!=null)
{matrix[i][j]=edge.GetWeight();}
else
{matrix[i][j]=this.infinity;}}}
return matrix;}
Graph.prototype.TestAdjacencyMatrix=function(matrix,rowsObj,colsObj,separator)
{if(separator===undefined)
{separator=",";}
var bGoodFormat=true;rowsObj.rows=[];rowsObj.rows=matrix.split("\n");for(j=0;j<rowsObj.rows.length;++j)
{if(rowsObj.rows[j]==="")
{rowsObj.rows.splice(j--,1);}}
colsObj.cols=[];for(var i=0;i<rowsObj.rows.length;i++)
{colsObj.cols[i]=this.SplitMatrixString(rowsObj.rows[i],separator);for(j=0;j<colsObj.cols[i].length;++j)
{if(colsObj.cols[i][j]==="")
{colsObj.cols[i].splice(j--,1);}}
if(colsObj.cols[i].length!=rowsObj.rows.length)
{bGoodFormat=false;break;}}
return bGoodFormat;}
Graph.prototype.TestPair=function(pair)
{let lines=pair.split("\n");let regExp=[/^.+-.+$/g,/^.+\>.+$/g,/^.+<.+$/g,/^.+-\(\d+\.?\d+\)-.+$/g,/^.+-\(\d+\.?\d+\)\>.+$/g,/^.+<\(\d+\.?\d+\)\-.+$/g];let res=true;for(let i=0;i<lines.length;++i)
{let resLine=false;let line=lines[i];if(line==""){continue;}
for(let j=0;j<regExp.length;++j){if(line.match(regExp[j])){resLine=true;}}
res=resLine&&res;}
return res;}
Graph.prototype.IsVerticesHaveSamePosition=function(position,vertexCount)
{var res=false;for(var j=0;j<Math.min(this.vertices.length,vertexCount);j++)
{if(position.distance(this.vertices[j].position)<this.vertices[j].model.diameter*2)
{res=true;break;}}
return res;}
Graph.prototype.GetRandomPosition=function(viewportSize){return new Point(Math.random()*viewportSize.x,Math.random()*viewportSize.y);}
Graph.prototype.GetRandomPositionOfVertex=function(matrix,vertexIndex,viewportSize)
{var point=new Point(0,0);var relatedVertex=[];for(var j=0;j<matrix.length;j++)
{if(j<this.vertices.length&&(cols[vertexIndex][j]>0||cols[j][vertexIndex]>0)&&j!=vertexIndex)
{relatedVertex.push(this.vertices[j]);}}
var diameter=(new VertexModel()).diameter;if(relatedVertex.length>1)
{for(var j=0;j<relatedVertex.length;j++)
{point=point.add(relatedVertex[j].position);}
point=point.multiply(1/relatedVertex.length);point.offset(Math.random()*diameter+(Math.random()?-1:1)*2*diameter,Math.random()*diameter+(Math.random()?-1:1)*2*diameter);}
else
{point=new Point(Math.random()*viewportSize.x,Math.random()*viewportSize.y);}
if(this.IsVerticesHaveSamePosition(point,matrix.length))
{point.offset(Math.random()*diameter+ +(Math.random()?-1:1)*4*diameter,Math.random()*diameter+ +(Math.random()?-1:1)*4*diameter);}
point.x=Math.min(Math.max(point.x,diameter),viewportSize.x);point.y=Math.min(Math.max(point.y,diameter),viewportSize.y);return point;}
Graph.prototype.VerticesReposition=function(viewportSize,newVertices)
{var maxGravityDistanceSqr=Math.max(viewportSize.x,viewportSize.y)/5.0;maxGravityDistanceSqr=maxGravityDistanceSqr*maxGravityDistanceSqr;var velocityDamping=0.85;var diameter=(new VertexModel()).diameter;var maxDistance=diameter*3;var gravityDistanceSqr=10*(maxDistance*maxDistance);var edgeGravityKof=10/(maxDistance);var kCenterForce=10/(maxDistance*10);var centerPoint=viewportSize.multiply(0.5);var velocityMax=maxDistance*10;var edgesMatrix={};for(var i=0;i<this.edges.length;i++)
{edgesMatrix[this.edges[i].vertex1.id+this.edges[i].vertex2.id*1000]=1;edgesMatrix[this.edges[i].vertex2.id+this.edges[i].vertex1.id*1000]=1;}
var startAngel=Math.random()*180.0;for(i=0;i<newVertices.length;i++)
{newVertices[i].position.orbit(new Point(viewportSize.x/2,viewportSize.y/2),(viewportSize.x-diameter*2)/2,(viewportSize.y-diameter*2)/2,360*i/newVertices.length+startAngel);}
var k=0;var bChanged=true;while(k<1000&&bChanged)
{var vertexData=[];for(i=0;i<newVertices.length;i++)
{var currentVertex={};currentVertex.object=newVertices[i];currentVertex.net_force=new Point(0,0);currentVertex.velocity=new Point(0,0);vertexData.push(currentVertex);for(j=0;j<this.vertices.length;j++)
{otherVertex=this.vertices[j];if(otherVertex==currentVertex.object)continue;var rsq=currentVertex.object.position.distanceSqr(otherVertex.position);{var force=(currentVertex.object.position.subtract(otherVertex.position)).normalize(gravityDistanceSqr/rsq);currentVertex.net_force=currentVertex.net_force.add(force);}}
for(j=0;j<this.vertices.length;j++)
{otherVertex=this.vertices[j];if(edgesMatrix.hasOwnProperty(currentVertex.object.id+1000*otherVertex.id))
{var distance=currentVertex.object.position.distance(otherVertex.position);if(distance>maxDistance)
{var force=(otherVertex.position.subtract(currentVertex.object.position)).normalize(edgeGravityKof*(distance-maxDistance));currentVertex.net_force=currentVertex.net_force.add(force);}}}
var distanceToCenter=centerPoint.distance(currentVertex.object.position);var force=centerPoint.subtract(currentVertex.object.position).normalize(distanceToCenter*kCenterForce);currentVertex.net_force=currentVertex.net_force.add(force);currentVertex.velocity=currentVertex.velocity.add(currentVertex.net_force);}
bChanged=false;for(i=0;i<vertexData.length;i++)
{var v=vertexData[i];var velocity=v.velocity;if(velocity.length()>velocityMax)
{velocity=velocity.normalize(velocityMax);}
v.object.position=v.object.position.add(velocity);if(velocity.length()>=1)
{bChanged=true;}}
k++;}
var bbox=this.getGraphBBox();if(bbox.size().length()>viewportSize.length()*1000)
{for(i=0;i<newVertices.length;i++)
{newVertices[i].position.orbit(new Point(viewportSize.x/2,viewportSize.y/2),(viewportSize.x-diameter*2)/2,(viewportSize.y-diameter*2)/2,360*i/newVertices.length+startAngel);}}
else
{var count=10;var angle=360.0/count;var viewportAspect=viewportSize.x/viewportSize.y;var bestIndex=0;var graphSize=bbox.size();var bestAspect=graphSize.x/graphSize.y;var center=bbox.center();for(var i=1;i<count;i++)
{for(j=0;j<newVertices.length;j++)
{newVertices[j].position.rotate(center,angle);}
var newBBox=this.getGraphBBox();var newAspect=newBBox.size().x/newBBox.size().y;if(Math.abs(newAspect-viewportAspect)<Math.abs(bestAspect-viewportAspect))
{bestAspect=newAspect;bestIndex=i;}}
for(j=0;j<newVertices.length;j++)
{newVertices[j].position.rotate(center,-angle*(count-bestIndex-1));}}}
Graph.prototype.SetAdjacencyMatrix=function(matrix,viewportSize,currentEnumVerticesType,separator)
{if(separator===undefined)
{separator=",";}
var rowsObj={};var colsObj={};if(this.TestAdjacencyMatrix(matrix,rowsObj,colsObj,separator))
{rows=rowsObj.rows;cols=colsObj.cols;var clonedEdge=this.edges.slice(0);for(var i=0;i<clonedEdge.length;i++)
{this.DeleteEdge(clonedEdge[i]);}
var newVertices=[];var bWeightGraph=false;for(var i=0;i<rows.length;i++)
{for(var j=0;j<rows.length;j++)
{if(j>=this.vertices.length)
{var newPos=this.GetRandomPositionOfVertex(matrix,j,viewportSize);newVertices.push(new BaseVertex(newPos.x,newPos.y,currentEnumVerticesType));this.AddNewVertex(newVertices[newVertices.length-1]);}
if(cols[i][j]>0)
{var nEdgeIndex=this.AddNewEdgeSafe(this.vertices[i],this.vertices[j],cols[i][j]!=cols[j][i],cols[i][j],true);this.FixEdgeCurve(nEdgeIndex);if(nEdgeIndex>=0)
{bWeightGraph=bWeightGraph||this.edges[nEdgeIndex].weight!=1;}}}}
if(!bWeightGraph)
{this.edges.forEach(function(part,index,theArray){theArray[index].useWeight=false;});}
for(var i=rows.length;i<Math.max(this.vertices.length,rows.length);i++)
{this.DeleteVertex(this.vertices[i]);i--;}
this.VerticesReposition(viewportSize,newVertices);}}
Graph.prototype.SetPair=function(pairs,viewportSize,currentEnumVerticesType)
{if(this.TestPair(pairs))
{this.ClearGraph();let lines=pairs.split("\n");let regExp=[/^(.+)-(.+)$/g,/^(.+)\>(.+)$/g,/^(.+)<(.+)$/g,/^(.+)-\((\d+|\d+\.?\d+)\)-(.+)$/g,/^(.+)-\((\d+|\d+\.?\d+)\)\>(.+)$/g,/^(.+)<\((\d+|\d+\.?\d+)\)\-(.+)$/g,];let bWeightGraph=false;var newVertices=[];for(var i=0;i<lines.length;i++)
{let line=lines[i];if(line==""){continue;}
for(let j=regExp.length-1;j>=0;--j){if(!line.match(regExp[j])){continue;}
let groupes=Array.from(line.matchAll(regExp[j]));let groupe=groupes[0];let vetext1Title=groupe[1];let vertex1=this.FindVertexByTitle(vetext1Title);if(vertex1==null){let newPosition=this.GetRandomPosition(viewportSize);vertex1=this.vertices[this.AddNewVertex(new BaseVertex(newPosition.x,newPosition.y,currentEnumVerticesType))];vertex1.mainText=vetext1Title;newVertices.push(vertex1);}
let vetext2Title=groupe[j<=2?2:3];let vertex2=this.FindVertexByTitle(vetext2Title);if(vertex2==null){let newPosition=this.GetRandomPosition(viewportSize);vertex2=this.vertices[this.AddNewVertex(new BaseVertex(newPosition.x,newPosition.y,currentEnumVerticesType))];vertex2.mainText=vetext2Title;newVertices.push(vertex2);}
let isDirect=j==1||j==2||j==4||j==5;let weight=1;if(j>2){weight=groupe[2];bWeightGraph=true;}
let isRevertEdge=j==2||j==5;let nEdgeIndex=this.AddNewEdgeSafe(isRevertEdge?vertex2:vertex1,isRevertEdge?vertex1:vertex2,isDirect,weight,false);this.FixEdgeCurve(nEdgeIndex);break;}}
if(!bWeightGraph)
{this.edges.forEach(function(part,index,theArray){theArray[index].useWeight=false;});}
this.VerticesReposition(viewportSize,newVertices);}}
Graph.prototype.TestIncidenceMatrix=function(matrix,rowsObj,colsObj,separator)
{if(separator===undefined)
{separator=",";}
var bGoodFormat=true;rowsObj.rows=[];rowsObj.rows=matrix.split("\n");for(j=0;j<rowsObj.rows.length;++j)
{if(rowsObj.rows[j]==="")
{rowsObj.rows.splice(j--,1);}}
colsObj.cols=[];var columnCount=0;for(var i=0;i<rowsObj.rows.length;i++)
{colsObj.cols[i]=this.SplitMatrixString(rowsObj.rows[i],separator);for(j=0;j<colsObj.cols[i].length;++j)
{if(colsObj.cols[i][j]==="")
{colsObj.cols[i].splice(j--,1);}}
if(i==0)
{columnCount=colsObj.cols[i].length;}
if(colsObj.cols[i].length!=columnCount)
{bGoodFormat=false;break;}}
if(bGoodFormat)
{for(var i=0;i<colsObj.cols[0].length;i++)
{var values=[];for(j=0;j<colsObj.cols.length;++j)
{if(colsObj.cols[j][i]!=0)
{values.push(colsObj.cols[j][i]);}}
if(!(values.length<=1||(values.length==2&&(values[0]==values[1]||values[0]==-values[1]))))
{bGoodFormat=false;break;}}}
return bGoodFormat;}
Graph.prototype.SetIncidenceMatrix=function(matrix,viewportSize,currentEnumVerticesType)
{var rowsObj={};var colsObj={};if(this.TestIncidenceMatrix(matrix,rowsObj,colsObj))
{rows=rowsObj.rows;cols=colsObj.cols;var clonedEdge=this.edges.slice(0);for(var i=0;i<clonedEdge.length;i++)
{this.DeleteEdge(clonedEdge[i]);}
var newVertices=[];var bWeightGraph=false;for(var i=0;i<cols[0].length;i++)
{var edgeValue=[];var edgeIndex=[];for(var j=0;j<cols.length;j++)
{if(j>=this.vertices.length)
{var newPos=new Point(0,0);newVertices.push(new BaseVertex(newPos.x,newPos.y,currentEnumVerticesType));this.AddNewVertex(newVertices[newVertices.length-1]);}
if(cols[j][i]!=0)
{edgeValue.push(cols[j][i]);edgeIndex.push(j);}}
if(edgeIndex.length==1)
{edgeValue.push(edgeValue[0]);edgeIndex.push(edgeIndex[0]);}
if(edgeIndex.length==2)
{if(edgeValue[0]!=edgeValue[1])
{if(edgeValue[1]>0)
{edgeValue=edgeValue.swap(0,1);edgeIndex=edgeIndex.swap(0,1);}}
var nEdgeIndex=this.AddNewEdgeSafe(this.vertices[edgeIndex[0]],this.vertices[edgeIndex[1]],edgeValue[0]!=edgeValue[1],Math.abs(edgeValue[1]),false);this.FixEdgeCurve(nEdgeIndex);if(nEdgeIndex>=0)
{bWeightGraph=bWeightGraph||this.edges[nEdgeIndex].weight!=1;}}}
if(!bWeightGraph)
{this.edges.forEach(function(part,index,theArray){theArray[index].useWeight=false;});}
for(var i=cols.length;i<Math.max(this.vertices.length,cols.length);i++)
{this.DeleteVertex(this.vertices[i]);i--;}
this.VerticesReposition(viewportSize,newVertices);}}
Graph.prototype.GetIncidenceMatrix=function()
{var matrix="";for(var i=0;i<this.vertices.length;i++)
{for(var j=0;j<this.edges.length;j++)
{if(this.edges[j].vertex1==this.vertices[i])
{matrix+=this.edges[j].weight;}
else if(this.edges[j].vertex2==this.vertices[i]&&!this.edges[j].isDirect)
{matrix+=this.edges[j].weight;}
else if(this.edges[j].vertex2==this.vertices[i]&&this.edges[j].isDirect)
{matrix+=-this.edges[j].weight;}
else
{matrix+="0";}
if(j!=this.edges.length-1)
{matrix+=", ";}}
matrix=matrix+"\n";}
return matrix;}
Graph.prototype.SplitMatrixString=function(line,separator)
{if(separator===undefined)
{separator=",";}
var res=[];var i=0;var isZeroOneLine=true;for(i=0;i<line.length;i++)
{if(line.charAt(i)!='0'&&line.charAt(i)!='1')
{isZeroOneLine=false;break;}}
if(!isZeroOneLine)
{if(separator!=",")
{line=line.replace(/,/g,".");}
for(i=0;i<line.length;i++)
{if(("0123456789.-e").indexOf(line.charAt(i))<0)
{if(i>0)
{res.push(line.substr(0,i));}
if(i==0)
{i=1;}
line=line.substr(i,line.length-i);i=-1;}}
if(line.length>0)
{res.push(line);}}
else
{for(i=0;i<line.length;i++)
{res.push(line.charAt(i));}}
console.log(res);return res;}
Graph.prototype.SaveToXML=function(additionalData)
{var mainHeader="<?xml version=\"1.0\" encoding=\"UTF-8\"?><graphml>";var header="<graph id=\"Graph\" uidGraph=\""+this.uidGraph+"\""+" uidEdge=\""+this.uidEdge+"\">";var xmlBody="";for(var i=0;i<this.vertices.length;i++)
{xmlBody=xmlBody+this.vertices[i].SaveToXML();}
xmlBody=xmlBody+"";for(var i=0;i<this.edges.length;i++)
{xmlBody=xmlBody+this.edges[i].SaveToXML();}
xmlBody=xmlBody+"";additionalField="";if(additionalData.length>0)
{additionalField="<additional data=\""+additionalData+"\"/>"}
return mainHeader+header+xmlBody+"</graph>"+additionalField+"</graphml>";}
Graph.prototype.LoadFromXML=function(xmlText,additionalData)
{xmlDoc=$.parseXML(xmlText);var $xml=$(xmlDoc);$graphs=$xml.find("graph");var loadedGraphId=0;var loadedEdgeId=0;$graphs.each(function(){loadedGraphId=parseInt($(this).attr('uidGraph'));loadedEdgeId=parseInt($(this).attr('uidEdge'));});if(isNaN(loadedEdgeId))
{loadedEdgeId=this.edgesOffset;}else if(loadedEdgeId<this.edgesOffset)
{loadedEdgeId=this.edgesOffset;}
this.uidGraph=loadedGraphId;this.uidEdge=loadedEdgeId;$nodes=$xml.find("node");var vertices=[];$nodes.each(function(){var vertex=new BaseVertex();vertex.LoadFromXML($(this));vertices.push(vertex);});this.vertices=vertices;$edges=$xml.find("edge");var edges=[];var graph=this;$edges.each(function(){var edge=new BaseEdge();edge.LoadFromXML($(this),graph);if(edge.id<graph.uidEdge){edge.id=graph.uidEdge;graph.uidEdge++;}
edges.push(edge);});this.edges=edges;$additional=$xml.find("additional");if($additional.length!=0&&additionalData!=null)
{additionalData["data"]=$additional.attr('data');}
this.isMultiGraph=this.checkMutiGraph();}
Graph.prototype.hasDirectEdge=function()
{var res=false;for(var i=0;i<this.edges.length;i++)
{if(this.edges[i].isDirect)
{res=true;break;}}
return res;}
Graph.prototype.hasUndirectEdge=function()
{var res=false;for(var i=0;i<this.edges.length;i++)
{if(!this.edges[i].isDirect)
{res=true;break;}}
return res;}
Graph.prototype.hasEdges=function()
{return this.edges.length>0;}
Graph.prototype.clampPositions=function(viewportSize)
{var diameter=(new VertexModel()).diameter;for(i=0;i<this.vertices.length;i++)
{this.vertices[i].position.x=Math.min(Math.max(this.vertices[i].position.x,diameter),viewportSize.x-diameter);this.vertices[i].position.y=Math.min(Math.max(this.vertices[i].position.y,diameter),viewportSize.y-diameter);}}
Graph.prototype.getGraphBBox=function(viewportSize)
{var pointMin=new Point(1e5,1e5);var pointMax=new Point(-1e5,-1e5);var diameter=(new VertexModel()).diameter;for(i=0;i<this.vertices.length;i++)
{var vertex=this.vertices[i];var factor=vertex.diameterFactor();var deltaVector=new Point(factor.x*diameter,factor.y*diameter);pointMin=pointMin.min(vertex.position.subtract(deltaVector));pointMax=pointMax.max(vertex.position.add(deltaVector));}
var max_curve_length=32;for(i=0;i<this.edges.length;i++)
{var edge=this.edges[i];if(edge.model.type==EdgeModels.curve)
{var max_curve=edge.vertex2.position.subtract(edge.vertex1.position).length()/max_curve_length;for(j=0;j<max_curve;j++)
{var point=edge.model.GetCurvePoint(edge.vertex1.position,edge.vertex2.position,j/max_curve);var deltaVector=new Point(max_curve_length,max_curve_length);pointMin=pointMin.min(point.subtract(deltaVector));pointMax=pointMax.max(point.add(deltaVector));}}}
return new Rect(pointMin,pointMax);}
Graph.prototype.hasPair=function(edge)
{return this.FindPairFor(edge)!=null;}
Graph.prototype.FindPairFor=function(edge)
{var res=this.getNeighborEdges(edge);return res.length==1?res[0]:null;}
Graph.prototype.getNeighborEdges=function(edge)
{var res=[];for(var i=0;i<this.edges.length;i++)
{var curEdge=this.edges[i];if(curEdge==edge)
continue;if((curEdge.vertex1.id==edge.vertex1.id&&curEdge.vertex2.id==edge.vertex2.id)||(curEdge.vertex1.id==edge.vertex2.id&&curEdge.vertex2.id==edge.vertex1.id))
{res.push(curEdge);}}
return res;}
Graph.prototype.checkMutiGraph=function()
{var res=false;var start={};for(var i=0;i<this.edges.length;i++)
{var edge=this.edges[i];if(start.hasOwnProperty(edge.vertex1.id)&&start[edge.vertex1.id]==edge.vertex2.id)
{res=true;break;}
start[edge.vertex1.id]=edge.vertex2.id;if(!edge.isDirect)
{if(start.hasOwnProperty(edge.vertex2.id)&&start[edge.vertex2.id]==edge.vertex1.id)
{res=true;break;}
start[edge.vertex2.id]=edge.vertex1.id;}}
return res;}
Graph.prototype.isMulti=function()
{return this.isMultiGraph;}
Graph.prototype.isNeedReposition=function()
{var res=false;for(var i=0;i<this.vertices.length;i++)
{res=res||this.vertices[i].IsUndefinedPosition();}
return res;}
Graph.prototype.FixEdgeCurve=function(edgeIndex)
{var edgeObject=this.edges[edgeIndex];var hasPair=this.hasPair(edgeObject);var neighborEdges=this.getNeighborEdges(edgeObject);if(hasPair)
{if(edgeObject.model.default)
edgeObject.model.type=EdgeModels.curve;var pairEdge=this.FindPairFor(edgeObject);if(pairEdge.model.default)
{pairEdge.model.type=EdgeModels.curve;if(pairEdge.vertex1==edgeObject.vertex1&&pairEdge.vertex2==edgeObject.vertex2)
pairEdge.model.curveValue=-pairEdge.model.curveValue;}}
else if(neighborEdges.length>=2)
{var curve=this.GetAvailableCurveValue(neighborEdges,edgeObject);if(edgeObject.model.default)
{edgeObject.model.type=EdgeModels.curve;edgeObject.model.curveValue=curve;}}}
Graph.prototype.GetAvailableCurveValue=function(neighborEdges,originalEdge)
{var values=[];for(var i=0;i<neighborEdges.length;i++)
{var edge=neighborEdges[i];var sameDirection=(originalEdge.vertex1.id==edge.vertex1.id);if(edge.model.type==EdgeModels.curve)
{values[(sameDirection?edge.model.curveValue:-edge.model.curveValue)]=true;}}
var changeValue=DefaultHandler.prototype.curveValue;var defaultValue=0.0;var maxSearch=10;for(var i=1;i<maxSearch;i++)
{value=i*changeValue;if(!values.hasOwnProperty(value))
return value;value=-i*changeValue;if(!values.hasOwnProperty(value))
return value;}
return defaultValue;}
Graph.prototype.reverseAllEdges=function()
{for(var i=0;i<this.edges.length;i++)
{if(this.edges[i].isDirect)
{let v1=this.edges[i].vertex1;this.edges[i].vertex1=this.edges[i].vertex2;this.edges[i].vertex2=v1;}}
this.isMultiGraph=this.checkMutiGraph();}
Graph.prototype.makeAllEdgesDirected=function()
{for(var i=0;i<this.edges.length;i++)
{if(!this.edges[i].isDirect)
{this.edges[i].isDirect=true;}}
this.isMultiGraph=this.checkMutiGraph();}
Graph.prototype.makeAllEdgesUndirected=function()
{for(var i=0;i<this.edges.length;i++)
{if(this.edges[i].isDirect)
{this.edges[i].isDirect=false;}}
this.isMultiGraph=this.checkMutiGraph();}
window.onload=function()
{if(document.getElementById('CreateByAdjacencyMatrix'))
{document.getElementById('CreateByAdjacencyMatrix').onclick=function()
{window.location="./?matrix="+$("#AdjacencyMatrixFieldPage").val();}}}
var g_MatrixSize=3;var g_ctrlPressed=false;function PackMatrix()
{var matrix="";for(i=0;i<g_MatrixSize;i++)
{for(j=0;j<g_MatrixSize;j++)
{var element=document.getElementsByName("field"+i+"_"+j)[0];matrix=matrix+(element.value.length>0?element.value:"0")+", ";}
matrix=matrix+"\n";}
return matrix;}
function getCharCode(event)
{if(event.which==null)
{return event.keyCode;}
if(event.which!=0)
{return event.which;}
return null;}
function getChar(event)
{var k=getCharCode(event)
return String.fromCharCode(k);}
function CopyMatrixToTextInput(event)
{document.getElementById("AdjacencyMatrixFieldPage").value=PackMatrix();if(event)
{var key=getChar(event);var code=getCharCode(event);console.log(key+" code="+code);if(g_ctrlPressed)
{var moveFocus=function(offsetX,offsetY)
{var focused_element=document.activeElement;if(focused_element&&focused_element.name.includes("field"))
{var name=focused_element.name;var coords=name.replace('field','').split("_");if(coords.length==2)
{var focusName="field"+(parseInt(coords[0])+offsetY)+"_"+(parseInt(coords[1])+offsetX)
var element=document.getElementsByName(focusName)[0];if(element)
{element.focus();}}}}
switch(code)
{case 38:{moveFocus(0,-1);break;}
case 40:{moveFocus(0,1);break;}
case 37:{moveFocus(-1,0);break;}
case 39:{moveFocus(1,0);break;}}}}}
function _ShowTextInput()
{$("#AdjacencyMatrixFieldPage").show();$("#MatrixForm").hide();$("#TextDescription").show();$("#MatrixDescription").hide();$("#idSeparatorList").show();}
function _ShowMatrixInput()
{$("#MatrixForm").show();$("#AdjacencyMatrixFieldPage").hide();$("#TextDescription").hide();$("#MatrixDescription").show();$("#idSeparatorList").hide();}
function ShowTextInput()
{_ShowTextInput();document.getElementById("showMatrix").className="btn btn-default";document.getElementById("showText").className="btn btn-default active";}
function ShowMatrixInput()
{_ShowMatrixInput();document.getElementById("showMatrix").className="btn btn-default active";document.getElementById("showText").className="btn btn-default";}
function CopyMatrixToMatrixInput()
{var graph=new Graph();var colsObj={};var rowsObj={};if(graph.TestAdjacencyMatrix($("#AdjacencyMatrixFieldPage").val(),rowsObj,colsObj))
{var rows=rowsObj.rows;var cols=colsObj.cols;for(var i=g_MatrixSize;i<rows.length;i++)
{IncSize();}
for(var i=0;i<rows.length;i++)
{for(var j=0;j<rows.length;j++)
{var element=document.getElementsByName("field"+i+"_"+j)[0];element.value=cols[i][j];}}}
else
{ShowTextInput();}}
function CreateInputElement(col,row)
{var input=document.createElement("input");input.type="text";input.size=3;input.name="field"+col+"_"+row;input.value=0;input.onkeyup=function(event){CopyMatrixToTextInput(event);};return input;}
function InsertBeforeElement(element,beforeName,space)
{var parent=document.getElementsByName(beforeName)[0].parentNode;var beforeElement=document.getElementsByName(beforeName)[0];parent.insertBefore(element,beforeElement);if(space)
{parent.insertBefore(document.createTextNode('\u00A0'),beforeElement);}}
function IncSize()
{for(var i=0;i<g_MatrixSize;i++)
{var input=CreateInputElement(g_MatrixSize,i);InsertBeforeElement(input,"matrixEnd",true);}
var br=document.createElement("br");br.setAttribute("name","row"+g_MatrixSize);InsertBeforeElement(br,"matrixEnd",false);for(var i=0;i<g_MatrixSize+1;i++)
{var input=CreateInputElement(i,g_MatrixSize);InsertBeforeElement(input,"row"+i,g_MatrixSize);}
g_MatrixSize++;CopyMatrixToTextInput();}
function checkFormat()
{var graph=new Graph();var separator=$("#spaceSep").is(':checked')?" ":",";if(!graph.TestAdjacencyMatrix($("#AdjacencyMatrixFieldPage").val(),[],[],separator))
{$("#BadFormatMessage").show();}
else
{$("#BadFormatMessage").hide();}}
window.onload=function()
{if(document.getElementById('CreateByAdjacencyMatrix'))
{document.getElementById('CreateByAdjacencyMatrix').onclick=function()
{$("#matrixForm").submit();}}
$("#AdjacencyMatrixFieldPage").on('keyup change',function(eventObject)
{checkFormat();});$("#BadFormatMessage").hide();$("#AdjacencyMatrixFieldPage").hide();$("#showMatrix").on('click',function(eventObject)
{_ShowMatrixInput();});$("#showText").on('click',function(eventObject)
{_ShowTextInput();});$('input:radio[name="separator"]').change(function(){checkFormat()});CopyMatrixToMatrixInput();$(document).keydown(function(event){if(event.which=="17"||event.which=="91")
g_ctrlPressed=true;});$(document).keyup(function(event){if(event.which=="17"||event.which=="91")
g_ctrlPressed=false;});}
moduleLoader.endCacheLoading();

View File

@@ -0,0 +1,15 @@
/*
Main class for create by matrix page
*/
window.onload = function ()
{
if (document.getElementById('CreateByAdjacencyMatrix'))
{
document.getElementById('CreateByAdjacencyMatrix').onclick = function ()
{
window.location = "./?matrix=" + $( "#AdjacencyMatrixFieldPage" ).val();
}
}
}

View File

@@ -0,0 +1,272 @@
// Current matrix size
var g_MatrixSize = 3;
var g_ctrlPressed = false;
function PackMatrix()
{
var matrix = "";
for (i = 0; i < g_MatrixSize; i++)
{
for (j = 0; j < g_MatrixSize; j++)
{
var element = document.getElementsByName("field" + i + "_" + j)[0];
matrix = matrix + (element.value.length > 0 ? element.value : "0") + ", ";
}
matrix = matrix + "\n";
}
return matrix;
}
function getCharCode(event)
{
if (event.which == null)
{ // IE
return event.keyCode;
}
if (event.which != 0)
{ // <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> IE
return event.which; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
return null; // <20><><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
function getChar(event)
{
var k = getCharCode(event)
return String.fromCharCode(k); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
function CopyMatrixToTextInput(event)
{
document.getElementById("AdjacencyMatrixFieldPage").value = PackMatrix();
// Move between cells.
if (event)
{
var key = getChar(event);
var code = getCharCode(event);
console.log(key + " code=" + code);
if (g_ctrlPressed)
{
var moveFocus = function(offsetX, offsetY)
{
var focused_element = document.activeElement;
if (focused_element && focused_element.name.includes("field"))
{
var name = focused_element.name;
var coords = name.replace('field','').split("_");
if (coords.length == 2)
{
var focusName = "field" + (parseInt(coords[0]) + offsetY) + "_" + (parseInt(coords[1]) + offsetX)
var element = document.getElementsByName(focusName)[0];
if (element)
{
element.focus();
}
}
}
}
switch (code)
{
case 38: // Up
{
moveFocus(0, -1);
break;
}
case 40: // Down
{
moveFocus(0, 1);
break;
}
case 37: // Left
{
moveFocus(-1, 0);
break;
}
case 39: // Right
{
moveFocus(1, 0);
break;
}
}
}
}
}
function _ShowTextInput()
{
$( "#AdjacencyMatrixFieldPage" ).show();
$( "#MatrixForm" ).hide();
$( "#TextDescription").show();
$( "#MatrixDescription").hide();
$( "#idSeparatorList").show();
}
function _ShowMatrixInput()
{
$( "#MatrixForm" ).show();
$( "#AdjacencyMatrixFieldPage" ).hide();
$( "#TextDescription").hide();
$( "#MatrixDescription").show();
$( "#idSeparatorList").hide();
}
function ShowTextInput()
{
_ShowTextInput();
document.getElementById("showMatrix").className = "btn btn-default";
document.getElementById("showText").className = "btn btn-default active";
}
function ShowMatrixInput()
{
_ShowMatrixInput();
document.getElementById("showMatrix").className = "btn btn-default active";
document.getElementById("showText").className = "btn btn-default";
}
function CopyMatrixToMatrixInput()
{
var graph = new Graph();
var colsObj = {};
var rowsObj = {};
if (graph.TestAdjacencyMatrix($( "#AdjacencyMatrixFieldPage" ).val(), rowsObj, colsObj))
{
var rows = rowsObj.rows;
var cols = colsObj.cols;
for (var i = g_MatrixSize; i < rows.length; i++)
{
IncSize();
}
for (var i = 0; i < rows.length; i++)
{
for (var j = 0; j < rows.length; j++)
{
var element = document.getElementsByName("field" + i + "_"+ j)[0];
element.value = cols[i][j];
}
}
}
else
{
ShowTextInput();
}
}
function CreateInputElement(col, row)
{
var input = document.createElement("input");
input.type = "text";
input.size = 3;
input.name = "field" + col + "_" + row;
input.value = 0;
input.onkeyup = function(event) {CopyMatrixToTextInput(event);};
return input;
}
function InsertBeforeElement(element, beforeName, space)
{
var parent = document.getElementsByName(beforeName)[0].parentNode;
var beforeElement = document.getElementsByName(beforeName)[0];
parent.insertBefore(element, beforeElement);
if (space)
{
// Insert space
parent.insertBefore(document.createTextNode( '\u00A0' ), beforeElement);
}
}
function IncSize()
{
// End one more line:
for (var i = 0; i < g_MatrixSize; i ++)
{
var input = CreateInputElement(g_MatrixSize, i);
InsertBeforeElement(input, "matrixEnd", true);
}
var br = document.createElement("br");
br.setAttribute("name", "row" + g_MatrixSize);
InsertBeforeElement(br, "matrixEnd", false);
for (var i = 0; i < g_MatrixSize + 1; i ++)
{
var input = CreateInputElement(i, g_MatrixSize);
InsertBeforeElement(input, "row" + i, g_MatrixSize);
}
g_MatrixSize++;
CopyMatrixToTextInput();
}
function checkFormat()
{
var graph = new Graph();
var separator = $("#spaceSep").is(':checked') ? " " : ",";
if (!graph.TestAdjacencyMatrix($( "#AdjacencyMatrixFieldPage" ).val(), [], [], separator))
{
$( "#BadFormatMessage" ).show();
}
else
{
$( "#BadFormatMessage" ).hide();
}
}
window.onload = function ()
{
if (document.getElementById('CreateByAdjacencyMatrix'))
{
document.getElementById('CreateByAdjacencyMatrix').onclick = function ()
{
$("#matrixForm").submit();
//window.location = "./?matrix=" + $( "#AdjacencyMatrixFieldPage" ).val().replace(/\n/g,'%0A');
}
}
$( "#AdjacencyMatrixFieldPage" ).on('keyup change', function (eventObject)
{
checkFormat();
});
$( "#BadFormatMessage" ).hide();
$( "#AdjacencyMatrixFieldPage" ).hide();
$( "#showMatrix" ).on('click', function (eventObject)
{
_ShowMatrixInput();
});
$( "#showText" ).on('click', function (eventObject)
{
_ShowTextInput();
});
$('input:radio[name="separator"]').change( function(){
checkFormat()
});
CopyMatrixToMatrixInput();
$(document).keydown(function(event) {
if (event.which == "17" || event.which == "91")
g_ctrlPressed = true;
});
$(document).keyup(function(event) {
if (event.which == "17" || event.which == "91")
g_ctrlPressed = false;
});
}

View File

@@ -0,0 +1,55 @@
// Global version needs to force reload scripts from server.
globalVersion = 75;
{
let asyncFilesLoad = null;
function onloadEditor() {
console.log("onload() call");
asyncFilesLoad();
preLoadPage();
postLoadPage();
}
let modulDir = "pages/editor/";
doInclude ([
include ("shared/utils.js"),
include ("entities/graph/api/index.js"),
include ("features/draw_graph/api/index.js"),
include ("features/algorithms/api/index.js"),
include ("features/base_handler/index.js"),
include ("features/default_handler/index.js"),
include ("features/add_vertices_handler/index.js"),
include ("features/connect_vertices_handler/index.js"),
include ("features/delete_objects_handler/index.js"),
include ("features/algorithm_handler/index.js"),
include ("features/serialization/api/index.js"),
include ("features/enum_vertices/EnumVertices.js"),
include ("model/texts.js", modulDir),
include ("model/Application.js", modulDir),
include ("ui/main.js", modulDir)],
onloadEditor);
asyncFilesLoad = function () {
doIncludeAsync ([
include ("shared/canvas2svg.js"),
include ("features/group_rename_handler/index.js"),
include ("features/saved_graph_handler/index.js"),
include ("features/saved_graph_image_handler/index.js"),
include ("features/show_adjacency_matrix/index.js"),
include ("features/show_distance_matrix/index.js"),
include ("features/show_incidence_matrix/index.js"),
include ("features/setup_background_style/index.js"),
include ("features/setup_edge_style/index.js"),
include ("features/setup_vertex_style/index.js"),
]);
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,423 @@
/**
* Place here all tests constants.
*
*/
var g_textsSelectAndMove = "Drag objects";
var g_moveCursorForMoving = "Move cursor";
var g_clickToAddVertex = "Click to add vertex";
var g_selectFirstVertexToConnect = "Select first vertex to connect";
var g_selectSecondVertexToConnect = "Select second vertex to connect";
var g_selectStartVertexForShortPath = "Select start vertex for shortest path";
var g_selectFinishVertexForShortPath = "Select finish vertex for shortest path";
var g_shortestPathResult = "Shortest path is %d";
var g_pathNotExists = "Path does not exists";
var g_selectObjectToDelete = "Select object to delete";
var g_addEdge = "Add edge";
var g_orintEdge = "Directed";
var g_notOrintEdge = "Undirected";
var g_adjacencyMatrixText = "Adjacency Matrix";
var g_save = "Save";
var g_cancel = "Cancel";
var g_save_graph = "Save Graph";
var g_shortestDistance = "lowest-distance is ";
var g_incidenceMatrixText = "Incidence Matrix";
var g_save_dialog = "Save dialog";
var g_close = "close";
var g_sickConnectedComponent = "Sick connected component is ";
var g_connectedComponent = "Connected component is ";
var g_what_do_you_think = "What do you think about site?";
var g_name = "Name";
var g_feedback = "Feedback";
var g_send = "Send";
var g_write_to_us = "Write to us";
var g_fixMatrix = "Fix matrix";
var g_readMatrixHelp = "Matrix format help";
var g_matrixWrongFormat = "Matrix is wrong";
var g_pairWrongFormat = "Edge List is wrong";
var g_fix = "Fix"
var g_save_image_dialog = "Save graph image";
var g_fullReport = "Full report";
var g_shortReport = "Short report";
var g_hasEulerianLoop = "Graph has Eulerian Loop";
var g_hasNotEulerianLoop = "Graph has not Eulerian Loop";
var g_hasEulerianPath = "Graph has Eulerian Path";
var g_hasNotEulerianPath = "Graph has not Eulerian Path";
var g_processing = "Processing...";
var g_customEnumVertex = "Custom";
var g_addVertex = "Add vertex";
var g_renameVertex = "Rename vertex";
var g_rename = "Rename";
var g_language = "en";
var g_editWeight = "Edit weight";
var g_noWeight = "No weight";
var g_groupRename = "Group rename";
var g_vote = "Vote";
var g_recommendAlgorithm = "Recommend algorithm";
var g_graphOfMinDist = "Graph of minimal distances.";
var g_checkToSave = "Check to save";
var g_showDistMatrix = "Show Distance matrix";
var g_minDistMatrixText = "Minimal distances matrix";
var g_selectStartVertexForMaxFlow = "Select source vertex for max flow";
var g_selectFinishVertexForMaxFlow = "Select sink vertex for max flow";
var g_maxFlowResult = "Maximum flow from %2 to %3 is %1";
var g_flowNotExists = "Flow from %1 to %2 does not exists";
var g_sourceVertex = "Source";
var g_sinkVertex = "Sink";
var g_hasHamiltonianLoop = "Graph has Hamiltonian Loop";
var g_hasNotHamiltonianLoop = "Graph has not Hamiltonian Loop";
var g_hasHamiltonianPath = "Graph has Hamiltonian Path";
var g_hasNotHamiltonianPath = "Graph has not Hamiltonian Path";
var g_startTraversal = "Select start traversal vector";
var g_traversalOrder = "Traversal order: ";
var g_curveEdge = "Curved edge";
var g_Undo = "Undo";
var g_default = "default";
var g_vertexDraw = "Vertex draw style";
var g_edgeDraw = "Edge draw style";
var g_backgroundStyle = "Background style";
var g_GraphIsMultiMessage = "Graph is multigraph";
var g_GraphIsGeneralMessage = "";
var g_DefaultWeightPreset = "no weight";
var g_dragGroupText = "Drag group.";
var g_selectGroupText = "Select using ctrl";
var g_copyGroupeButton = "Duplicate";
var g_removeGroupeButton = "Remove objects";
var g_BFSName = "Breadth-first search";
var g_ColoringName = "Graph coloring";
var g_findConnectedComponent = "Find connected components";
var g_DFSName = "Depth-first search";
var g_EulerinLoopName = "Find Eulerian cycle";
var g_EulerinPath = "Find Eulerian path";
var g_FloidName = "FloydWarshall algorithm";
var g_GraphReorder = "Arrange the graph";
var g_HamiltoianCycleName = "Find Hamiltonian cycle";
var g_HamiltonianPath = "Find Hamiltonian path";
var g_MaxFlowName = "Find Maximum flow";
var g_minimumSpanningTree = "Search of minimum spanning tree";
var g_modernGraphStyleName = "Visualization based on weight";
var g_RadiusAndDiameter = "Search graph radius and diameter";
var g_findShortPathName = "Find shortest path using Dijkstra's algorithm";
var g_VerticesDegreeName = "Calculate vertices degree";
var g_SpanningTreeResult = "Min Spanning Tree is";
var g_SpanningTreeIgnoreDir = "We ignored edges direction for calculation";
var g_SpanningTreeNotConnected = "Graph is not connected";
var g_selectFirstGraphIsomorphismCheck = "Select first graph for isomorphic check. Click to any node of graph";
var g_selectSecondGraphIsomorphismCheck = "Select second graph for isomorphic check. Click to any node of graph";
var g_selectFirstGraphPatternCheck = "Select a template graph by clicking to any node of graph";
var g_selectSecondGraphForSearchSubgraph = "Choose a graph in which we will look for isomorphic subgraphs. Click to any node of this graph";
// IsomorphismCheck.js
var g_graphsIsomorph = "Graphs are isomorphic";
var g_graphsNotIsomorph = "Graphs are not isomorphic";
var g_numberOfIsomorphSubgraphIs = "Number of isomorphic subgraphs are ";
var g_graphHasNoIsomorphSubgraph = "Graph don't contain isomorphic subgraphs";
var g_searchIsomorphSubgraph = "Search isomorphic subgraphs";
var g_subgraphNo = "Isomorphic subgraph # ";
var g_graphHasNoAtleast2Graphs = "To use the algorithm, you need to create 2 separate graphs";
var g_IsomorphismCheck = "Check Graphs Isomorphism";
// RadiusAndDiameter.js
var g_graphIsDisconnected = "Graph is disconnected";
var g_graphIsTrivial = "Graph contains only one vertex";
var g_graphRadius = "Graph radius";
var g_graphDiameter = "Graph diameter";
var g_vertexCentral = "Central";
var g_vertexPeripheral = "Peripheral";
// VerticesDegree.js
var g_maximumDegreeOfGraph = "The maximum degree of a graph is";
// Coloring.js
var g_colorNumber = "Color number is";
var g_done = "Done";
var g_action = "Action";
var g_commonEdgeStyle = "Common Edge Style";
var g_selectedEdgeStyle = "Selected Edge Style";
var g_commonVertexStyle = "Common Vertex Style";
var g_selectedVertexStyle = "Selected Vertex Style";
// FindAllPatches.js
var g_findAllPathes = "Find all paths";
var g_numberOfPathesFrom = "Number of paths from "
var g_to = " to ";
var g_are = " are ";
var g_pathN = "Path #";
var g_selectFinishVertex = "Select finish vertex";
var g_selectStartVertex = "Select start vertex";
// FindShortPatchsFromOne.js
var g_findAllPathesFromVertex = "Find all shortest paths from vertex";
var g_distanceFrom = "Distance from ";
var g_pathTo = "Path to ";
var g_useContextMenuText = "Use context menu for addition actions."
var g_findLongestPath = "Find the longest path";
var g_LengthOfLongestPathFrom = "Length of the longest path from ";
var g_additionalActions = "Additional actions";
var g_reverseAllEdges = "Reverse all edges";
var g_makeAllUndirected = "Make all edges undirected";
var g_makeAllDirected = "Make all edges directed";
var g_reuseSavedEdge = "Reuse saved edge";
var g_MaxClique = "Max Clique";
var g_MaxCliqueNotFound = "Max Clique is not found";
var g_MaxCliqueSizeIs = "Max Clique size is ";
var g_MaxCliqueContains = ". Clique contains these vertecies: ";
var g_wrongImageFormatPNGAndJPEG = "Wrong image format. We support only JPEG and PNG.";
var g_wrongImageSizeP1 = "Image size is too big. Image size must be less than {0} pixels.";
function loadTexts()
{
g_textsSelectAndMove = document.getElementById("SelectAndMoveObject").innerHTML;
g_moveCursorForMoving = document.getElementById("MoveCursorForMoving").innerHTML;
g_clickToAddVertex = document.getElementById("clickToAddVertex").innerHTML;
g_selectFirstVertexToConnect = document.getElementById("selectFisrtVertextToConnect").innerHTML;
g_selectSecondVertexToConnect = document.getElementById("selectSecondVertextToConnect").innerHTML;
g_selectStartVertexForShortPath = document.getElementById("selectStartShortPathVertex").innerHTML;
g_selectFinishVertexForShortPath = document.getElementById("selectFinishShortPathVertex").innerHTML;
g_shortestPathResult = document.getElementById("shortPathResult").innerHTML;
g_pathNotExists = document.getElementById("pathNotExists").innerHTML;
g_selectObjectToDelete = document.getElementById("selectObjectToDelete").innerHTML;
g_addEdge = document.getElementById("AddEdge").innerHTML;
g_orintEdge = document.getElementById("OrintEdge").innerHTML;
g_notOrintEdge = document.getElementById("NotOrintdge").innerHTML;
g_adjacencyMatrixText = document.getElementById("AdjacencyMatrixText").innerHTML;
g_save = document.getElementById("Save").innerHTML;
g_cancel = document.getElementById("Cancel").innerHTML;
g_shortestDistance = document.getElementById("shortestDist").innerHTML;
g_incidenceMatrixText = document.getElementById("IncidenceMatrixText").innerHTML;
g_save_dialog = document.getElementById("saveDialogTitle").innerHTML;
g_close = document.getElementById("closeButton").innerHTML;
g_sickConnectedComponent = document.getElementById("sickConnectedComponentResult").innerHTML;
g_connectedComponent = document.getElementById("connectedComponentResult").innerHTML;
g_what_do_you_think = document.getElementById("whatDoYouThink").innerHTML;
g_name = document.getElementById("name").innerHTML;
g_feedback = document.getElementById("feedback").innerHTML;
g_send = document.getElementById("send").innerHTML;
g_write_to_us = document.getElementById("writeToUs").innerHTML;
g_fixMatrix = document.getElementById("fixMatrixButton").innerHTML;
g_readMatrixHelp = document.getElementById("matrixHelp").innerHTML;
g_matrixWrongFormat = document.getElementById("wronMatrixTitle").innerHTML;
g_save_image_dialog = document.getElementById("saveImageDialogTitle").innerHTML;
g_fullReport = document.getElementById("fullReport").innerHTML;
g_shortReport = document.getElementById("shortReport").innerHTML;
g_hasEulerianLoop = document.getElementById("hasEulerianLoop").innerHTML;
g_hasNotEulerianLoop = document.getElementById("hasNotEulerianLoop").innerHTML;
g_processing = document.getElementById("processing").innerHTML;
g_customEnumVertex = document.getElementById("customEnumVertex").innerHTML;
g_addVertex = document.getElementById("addVertexText").innerHTML;
g_renameVertex = document.getElementById("renameVertex").innerHTML;
g_rename = document.getElementById("renameText").innerHTML;
g_language = document.getElementById("currentLanguage").innerHTML;
g_editWeight = document.getElementById("editWeight").innerHTML;
g_noWeight = document.getElementById("noWeight").innerHTML;
g_groupRename = document.getElementById("groupeRenameText").innerHTML;
g_vote = document.getElementById("voteText").innerHTML;
g_recommendAlgorithm = document.getElementById("recommend_algorithm").innerHTML;
g_hasEulerianPath = document.getElementById("hasEulerianPath").innerHTML;
g_hasNotEulerianPath = document.getElementById("hasNotEulerianPath").innerHTML;
g_graphOfMinDist = document.getElementById("graphOfMinDist").innerHTML;
g_checkToSave = document.getElementById("checkToSave").innerHTML;
g_showDistMatrix = document.getElementById("showDistMatrix").innerHTML;
g_minDistMatrixText = document.getElementById("distMatrixText").innerHTML;
g_selectStartVertexForMaxFlow = document.getElementById("selectStartVertexForMaxFlow").innerHTML;
g_selectFinishVertexForMaxFlow = document.getElementById("selectFinishVertexForMaxFlow").innerHTML;
g_maxFlowResult = document.getElementById("maxFlowResult").innerHTML;
g_flowNotExists = document.getElementById("flowNotExists").innerHTML;
g_sourceVertex = document.getElementById("sourceVertex").innerHTML;
g_sinkVertex = document.getElementById("sinkVertex").innerHTML;
g_hasHamiltonianLoop = document.getElementById("hasHamiltonianLoop").innerHTML;
g_hasNotHamiltonianLoop = document.getElementById("hasNotHamiltonianLoop").innerHTML;
g_hasHamiltonianPath = document.getElementById("hasHamiltonianPath").innerHTML;
g_hasNotHamiltonianPath = document.getElementById("hasNotHamiltonianPath").innerHTML;
g_startTraversal = document.getElementById("startTraversal").innerHTML;
g_traversalOrder = document.getElementById("traversalOrder").innerHTML;
g_curveEdge = document.getElementById("curveEdge").innerHTML;
g_Undo = document.getElementById("undoTranslate").innerHTML;
g_save_graph = document.getElementById("saveGraph").innerHTML;
g_default = document.getElementById("default").innerHTML;
g_vertexDraw = document.getElementById("vertexDrawStyle").innerHTML;
g_edgeDraw = document.getElementById("edgeDrawStyle").innerHTML;
g_backgroundStyle = document.getElementById("backgroundStyle").innerHTML;
g_GraphIsMultiMessage = document.getElementById("graphIsMultiMessage").innerHTML;
g_GraphIsGeneralMessage = document.getElementById("graphIsGeneralMessage").innerHTML;
g_DefaultWeightPreset = document.getElementById("defaultWeightPreset").innerHTML;
var isMac = navigator.platform.toUpperCase().indexOf('MAC')>=0;
if (isMac)
g_selectGroupText = document.getElementById("selectGroupMac").innerHTML;
else
g_selectGroupText = document.getElementById("selectGroupWin").innerHTML;
g_dragGroupText = document.getElementById("dragSelectedGroup").innerHTML;
g_copyGroupeButton = document.getElementById("copySelectedGroup").innerHTML;
g_removeGroupeButton = document.getElementById("removeSelectedGroup").innerHTML;
g_BFSName = document.getElementById("BFSName").innerHTML;
g_ColoringName = document.getElementById("ColoringName").innerHTML;
g_findConnectedComponent = document.getElementById("findConnectedComponent").innerHTML;
g_DFSName = document.getElementById("DFSName").innerHTML;
g_EulerinLoopName = document.getElementById("EulerinLoopName").innerHTML;
g_EulerinPath = document.getElementById("EulerinPath").innerHTML;
g_FloidName = document.getElementById("FloidName").innerHTML;
g_GraphReorder = document.getElementById("GraphReorder").innerHTML;
g_HamiltoianCycleName = document.getElementById("HamiltoianCycleName").innerHTML;
g_HamiltonianPath = document.getElementById("HamiltonianPath").innerHTML;
g_MaxFlowName = document.getElementById("MaxFlowName").innerHTML;
g_minimumSpanningTree = document.getElementById("minimumSpanningTree").innerHTML;
g_modernGraphStyleName = document.getElementById("modernGraphStyleName").innerHTML;
g_RadiusAndDiameter = document.getElementById("RadiusAndDiameter").innerHTML;
g_findShortPathName = document.getElementById("findShortPathName").innerHTML;
g_VerticesDegreeName = document.getElementById("VerticesDegreeName").innerHTML;
g_SpanningTreeResult = document.getElementById("MinSpanningTreeResult").innerHTML;
g_SpanningTreeIgnoreDir = document.getElementById("MinSpanningIgnoreDir").innerHTML;
g_SpanningTreeNotConnected = document.getElementById("MinSpanningNotConnected").innerHTML;
g_selectFirstGraphIsomorphismCheck = document.getElementById("SelectFirstGraphIsomorphismCheck").innerHTML;
g_selectSecondGraphIsomorphismCheck = document.getElementById("SelectSecondGraphIsomorphismCheck").innerHTML;
g_selectFirstGraphPatternCheck = document.getElementById("SelectFirstGraphPatternCheck").innerHTML;
g_selectSecondGraphForSearchSubgraph = document.getElementById("SelectSecondGraphForSearchSubgraph").innerHTML;
// IsomorphismCheck.js
g_graphsIsomorph = document.getElementById("GraphsIsomorph").innerHTML;
g_graphsNotIsomorph = document.getElementById("GraphsNotIsomorph").innerHTML;
g_numberOfIsomorphSubgraphIs = document.getElementById("NumberOfIsomorphSubgraphIs").innerHTML;
g_graphHasNoIsomorphSubgraph = document.getElementById("GraphHasNoIsomorphSubgraph").innerHTML;
g_searchIsomorphSubgraph = document.getElementById("SearchIsomorphSubgraph").innerHTML;
g_subgraphNo = document.getElementById("SubgraphNo").innerHTML;
g_graphHasNoAtleast2Graphs = document.getElementById("GraphHasNoAtleast2Graphs").innerHTML;
g_IsomorphismCheck = document.getElementById("IsomorphismCheck").innerHTML;
// RadiusAndDiameter.js
g_graphIsDisconnected = document.getElementById("GraphIsDisconnected").innerHTML;
g_graphIsTrivial = document.getElementById("GraphIsTrivial").innerHTML;
g_graphRadius = document.getElementById("GraphRadius").innerHTML;
g_graphDiameter = document.getElementById("GraphDiameter").innerHTML;
g_vertexCentral = document.getElementById("VertexCentral").innerHTML;
g_vertexPeripheral = document.getElementById("VertexPeripheral").innerHTML;
// VerticesDegree.js
g_maximumDegreeOfGraph = document.getElementById("MaximumDegreeOfGraph").innerHTML;
// Coloring.js
g_colorNumber = document.getElementById("ColorNumber").innerHTML;
g_done = document.getElementById("Done").innerHTML;
g_action = document.getElementById("ActionText").innerHTML;
g_commonEdgeStyle = document.getElementById("CommonEdgeStyleText").innerHTML;
g_selectedEdgeStyle = document.getElementById("SelectedEdgeStyleText").innerHTML;
g_commonVertexStyle = document.getElementById("CommonVertexStyleText").innerHTML;
g_selectedVertexStyle = document.getElementById("SelectedVertexStyleText").innerHTML;
// FindAllPatches.js
g_findAllPathes = document.getElementById("FindAllPathes").innerHTML;
g_numberOfPathesFrom = document.getElementById("NumberOfPathesFrom").innerHTML;
g_to = document.getElementById("To").innerHTML;
g_are = document.getElementById("Are").innerHTML;
g_pathN = document.getElementById("PathN").innerHTML;
g_selectFinishVertex = document.getElementById("SelectFinishVertex").innerHTML;
g_selectStartVertex = document.getElementById("SelectStartVertex").innerHTML;
// FindShortPatchsFromOne.js
g_findAllPathesFromVertex = document.getElementById("findAllPathsFromVertex").innerHTML;
g_distanceFrom = document.getElementById("distanceFrom").innerHTML;
g_pathTo = document.getElementById("pathTo").innerHTML;
g_useContextMenuText = document.getElementById("UseContextMenuText").innerHTML;
g_findLongestPath = document.getElementById("findLongestPath").innerHTML;
g_LengthOfLongestPathFrom = document.getElementById("LengthOfLongestPathFrom").innerHTML;
g_additionalActions = document.getElementById("additionlActions").innerHTML;
g_reverseAllEdges = document.getElementById("reverseAllEdges").innerHTML;
g_makeAllUndirected = document.getElementById("makeAllUndirected").innerHTML;
g_makeAllDirected = document.getElementById("makeAllDirected").innerHTML;
g_pairWrongFormat = document.getElementById("pairWrongFormat").innerHTML;
g_fix = document.getElementById("fixButton").innerHTML;
g_reuseSavedEdge = document.getElementById("reuseSavedEdge").innerHTML;
g_MaxClique = document.getElementById("maxClique").innerHTML;
g_MaxCliqueNotFound = document.getElementById("maxCliqueNotFound").innerHTML;
g_MaxCliqueSizeIs = document.getElementById("maxCliqueSizeIs").innerHTML;
g_MaxCliqueContains = document.getElementById("maxCliqueContains").innerHTML;
g_wrongImageFormatPNGAndJPEG = document.getElementById("wrongImageFormatPNGAndJPEG").innerHTML;
g_wrongImageSizeP1 = document.getElementById("wrongImageSizeP1").innerHTML;
}

View File

@@ -0,0 +1,757 @@
var DisableEmscripten = false;
var algorithmsVersion = 2;
var application = new Application(document, window);
var waitCounter = false;
var fullscreen = false;
var userAction = function(str)
{
if (typeof window.yaCounter25827098 !== "undefined")
{
console.log(g_language + "/" + str);
window.yaCounter25827098.hit(window.location.protocol + "//" + window.location.hostname + (g_language != "ru" ? "/" + g_language : "") + "/UserAction#" + str);
}
else if (!waitCounter)
{
waitCounter = true;
setTimeout(function()
{
userAction(str);
}, 2000);
}
}
var isIe = (navigator.userAgent.toLowerCase().indexOf("msie") != -1
|| navigator.userAgent.toLowerCase().indexOf("trident") != -1);
var buttonsList = ['AddGraph', 'ConnectGraphs', 'DeleteObject', 'Default'];
var g_ctrlPressed = false;
function restButtons (me)
{
var needSetDefault = false;
for (let i = 0; i < buttonsList.length; i ++)
{
if (buttonsList[i] != me)
{
document.getElementById(buttonsList[i]).className = "btn btn-default btn-sm";
}
else
{
if (document.getElementById(buttonsList[i]).className != "btn btn-default btn-sm")
{
needSetDefault = true;
}
}
}
if (needSetDefault)
{
document.getElementById(me).className = "btn btn-primary btn-sm";
}
else
{
document.getElementById(me).className = "btn btn-primary btn-sm";
}
}
var single = 0;
function resizeCanvas()
{
var adv = document.getElementById('bottom_info');
var canvas = document.getElementById('canvas');
canvas.width = document.getElementById('canvasSection').offsetWidth;
var mainContainer = document.getElementById('mainContainer');
var offset = (mainContainer.offsetTop + mainContainer.offsetHeight) - (canvas.offsetTop + canvas.offsetHeight) + ($("#footerContent").css("display") === 'block' ? 0 : 24);
canvas.height = $(window).height() - document.getElementById('canvas').offsetTop - (adv && $("#bottom_info").css("display") === 'block' ? document.getElementById('bottom_info').offsetHeight : 0) - ($("#footer").css("display") === 'block' ? document.getElementById('footer').offsetHeight : 0) - offset;
application.redrawGraph();
}
function touchHandler(event)
{
var touches = event.changedTouches,
first = touches[0],
type = "";
switch(event.type)
{
case "touchstart": type = "mousedown"; break;
case "touchmove": type="mousemove"; break;
case "touchend": type="mouseup"; break;
default: return;
}
var simulatedEvent = document.createEvent("MouseEvent");
simulatedEvent.initMouseEvent(type, true, true, window, 1,
first.screenX, first.screenY,
first.clientX, first.clientY, false,
false, false, false, 0/*left*/, null);
first.target.dispatchEvent(simulatedEvent);
event.preventDefault();
}
function preLoadPage()
{
loadTexts();
application.onLoad();
}
function createAlgorithmMenu()
{
var algorithmBaseId = "Algo";
var algorithms = application.getAlgorithmNames();
var index = 0;
for (var i = 0; i < algorithms.length; i++)
{
algorithm = algorithms[i];
var list = document.getElementById("algorithmCategoryElements" + algorithm.category);
var item = document.getElementById("algTopic" + algorithm.category);
var clone = item.cloneNode(true);
var button = clone.getElementsByTagName("button")[0];
var textSpan = button.getElementsByTagName("span")[1];
button.id = algorithm.id;
textSpan.innerHTML = algorithm.name;
clone.style.display = "block";
buttonsList.push(algorithm.id);
button.onclick = function (e)
{
e["closeThisMenu"] = true;
userAction(this.id);
restButtons (this.id);
application.SetHandlerMode(this.id);
}
var eventData = {};
eventData.index = i;
eventData.object = clone;
eventData.algorithm = algorithm;
$("#openAlgorithmList").bind('click', eventData, function (_eventData) {
var data = _eventData.data;
var algorithm = g_Algorithms[g_AlgorithmIds.indexOf(data.algorithm.id)](application.graph, application);
if (application.graph.isMulti() && !algorithm.IsSupportMultiGraph())
$(data.object).hide();
else
$(data.object).show();
});
list.insertBefore(clone, document.getElementById("insert" + algorithm.category));
index++;
}
}
function handelImportGraph(files) {
var graphFileToLoad = files[0];
var fileReader = new FileReader();
fileReader.onload = function(fileLoadedEvent){
var textFromFileLoaded = fileLoadedEvent.target.result;
console.log(textFromFileLoaded);
application.LoadGraphFromString(textFromFileLoaded);
ImportGraphFiles.value = "";
};
fileReader.readAsText(graphFileToLoad, "UTF-8");
}
function postLoadPage()
{
application.userAction = userAction;
application.canvas.onmousemove = function (e)
{
return application.CanvasOnMouseMove(e);
};
application.canvas.onmousedown = function (e)
{
return application.CanvasOnMouseDown(e);
};
application.canvas.onmouseup = function (e)
{
return application.CanvasOnMouseUp(e);
}
application.canvas.onwheel = function (e)
{
var e = window.event || e; // old IE support
var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
if (delta > 0)
{
application.multCanvasScale(1.3, e);
}
else
{
application.multCanvasScale(1.0 / 1.3, e);
}
}
function getCharCode(event) {
if (event.which == null) { // IE
return event.keyCode;
}
if (event.which != 0 && event.charCode != 0) { // все кроме IE
return event.which; // остальные
}
return null; // спец. символ
}
function getChar(event) {
return String.fromCharCode(getCharCode(event)); // остальные
}
function selectHandler(buttonName, handlerName)
{
userAction(buttonName + "_shortcut");
restButtons (buttonName);
application.SetHandlerMode(handlerName);
}
document.onkeypress = function (e)
{
if (event.defaultPrevented
|| ($('#addVertex').hasClass('ui-dialog-content') && $('#addVertex').dialog('isOpen'))
|| ($('#adjacencyMatrix').hasClass('ui-dialog-content') && $('#adjacencyMatrix').dialog('isOpen'))
|| ($('#addEdge').hasClass('ui-dialog-content') && $('#addEdge').dialog('isOpen'))
|| ($('#incidenceMatrix').hasClass('ui-dialog-content') && $('#incidenceMatrix').dialog('isOpen'))
|| ($('#saveDialog').hasClass('ui-dialog-content') && $('#saveDialog').dialog('isOpen'))
|| ($('#saveImageDialog').hasClass('ui-dialog-content') && $('#saveImageDialog').dialog('isOpen'))
|| ($('#GroupRenameDialog').hasClass('ui-dialog-content') && $('#GroupRenameDialog').dialog('isOpen'))
|| $('#developerTools').css("display") != "none"
|| ($('#NeedAlgorithm').hasClass('ui-dialog-content') && $('#NeedAlgorithm').dialog('isOpen')))
{
console.log("prevent");
return; // Should do nothing if the default action has been cancelled
}
var key = getChar(event);
var code = getCharCode(event);
console.log(key + " code=" + code);
var evtobj = window.event ? event : e;
var isCtrl = evtobj ? evtobj.ctrlKey : false;
var moveValue = 10;
if (code == 61 || code == 43) // +
{
application.multCanvasScale(1.5);
}
else if (code == 45) // -
{
application.multCanvasScale(1 / 1.5);
}
else if (key == 'w' || key == 'ц') // up
{
application.onCanvasMove(new Point(0, moveValue));
}
else if (key == 's' || key == 'ы') // down
{
application.onCanvasMove(new Point(0, -moveValue));
}
else if (key == 'a' || key == 'ф') // left
{
application.onCanvasMove(new Point(moveValue, 0));
}
else if (key == 'd' || key == 'в') // right
{
application.onCanvasMove(new Point(-moveValue, 0));
}
else if (key == 'v' || key == 'м') // vertex
{
selectHandler('AddGraph', 'addGraph');
}
else if (key == 'e' || key == 'у') // edge
{
selectHandler('ConnectGraphs', 'addArc');
}
else if (key == 'r' || key == 'к') // delete
{
selectHandler('DeleteObject', 'delete');
}
// Disabled because it is easy to lose graph, when you press miss letter.
//else if (key == 'n' || key == 'т') // new
//{
// userAction('NewGraph_shortcut');
// application.SetHandlerMode("deleteAll");
// application.SetDefaultTransformations();
//}
else if (key == 'm' || key == 'ь') // move
{
selectHandler('Default', 'default');
}
else if (code == 26 && isCtrl)
{
userAction("Key_GraphUndo");
application.SetHandlerMode("graphUndo");
}
}
$(document).keydown(function(event) {
if (event.which == "17" || event.which == "91")
g_ctrlPressed = true;
});
$(document).keyup(function() {
g_ctrlPressed = false;
});
document.getElementById('ShowAdjacencyMatrix').onclick = function ()
{
userAction(this.id);
application.SetHandlerMode("showAdjacencyMatrix");
}
document.getElementById('ShowIncidenceMatrix').onclick = function ()
{
userAction(this.id);
application.SetHandlerMode("showIncidenceMatrix");
}
document.getElementById('ShowDistanceMatrix').onclick = function ()
{
userAction(this.id);
application.SetHandlerMode("showDistanceMatrix");
}
document.getElementById('GroupRename').onclick = function ()
{
userAction(this.id);
application.SetHandlerMode("GroupRename");
}
document.getElementById('groupRenameButton').onclick = function ()
{
userAction(this.id);
application.SetHandlerMode("GroupRename");
}
document.getElementById('Default').onclick = function ()
{
userAction(this.id);
restButtons ('Default');
application.SetHandlerMode("default");
document.getElementById('Default').className = "btn btn-primary btn-sm";
}
document.getElementById('AddGraph').onclick = function ()
{
userAction(this.id);
restButtons ('AddGraph');
application.SetHandlerMode(document.getElementById('AddGraph').className != "" ? "addGraph" : "default");
}
document.getElementById('ConnectGraphs').onclick = function ()
{
userAction(this.id);
restButtons ('ConnectGraphs');
application.SetHandlerMode(document.getElementById('ConnectGraphs').className != "" ? "addArc" : "default");
}
document.getElementById('DeleteObject').onclick = function ()
{
userAction(this.id);
restButtons ('DeleteObject');
application.SetHandlerMode(document.getElementById('DeleteObject').className != "" ? "delete" : "default");
}
document.getElementById('DeleteAll').onclick = function ()
{
userAction(this.id);
application.SetHandlerMode("deleteAll");
}
document.getElementById('SaveGraph').onclick = function ()
{
userAction(this.id);
application.SetHandlerMode("saveDialog");
}
document.getElementById('NewGraph').onclick = function ()
{
userAction(this.id);
application.SetHandlerMode("deleteAll");
application.SetDefaultTransformations();
}
document.getElementById('SaveGraphImage').onclick = function ()
{
userAction(this.id);
application.SetHandlerMode("saveDialogImage");
}
document.getElementById('SaveFullGraphImage').onclick = function ()
{
userAction(this.id);
application.SetHandlerMode("saveDialogFullImage");
}
document.getElementById('SavePrintGraphImage').onclick = function ()
{
userAction(this.id);
application.SetHandlerMode("savePrintGraphImage");
}
document.getElementById('SaveSvgGraphImage').onclick = function ()
{
userAction(this.id);
application.SetHandlerMode("saveSvgGraphImage");
}
document.getElementById('Zoom100').onclick = function ()
{
userAction(this.id);
application.setCanvasScale(1.0);
}
document.getElementById('Zoom50').onclick = function ()
{
userAction(this.id);
application.setCanvasScale(50 / 100);
}
document.getElementById('Zoom25').onclick = function ()
{
userAction(this.id);
application.setCanvasScale(25 / 100);
}
document.getElementById('ZoomFit').onclick = function ()
{
userAction(this.id);
application.OnAutoAdjustViewport();
}
document.getElementById('ZoomIn').onclick = function ()
{
userAction(this.id);
application.multCanvasScale(1.5);
}
document.getElementById('ZoomOut').onclick = function ()
{
userAction(this.id);
application.multCanvasScale(1.0 / 1.5);
}
document.getElementById('MoveWorspace').onclick = function ()
{
userAction(this.id);
restButtons ('Default');
application.SetHandlerMode("default");
document.getElementById('Default').className = "btn btn-primary btn-sm";
}
document.getElementById('SetupVertexStyle').onclick = function ()
{
userAction(this.id);
application.SetHandlerMode("setupVertexStyle");
}
document.getElementById('SetupVertexStyleSelected').onclick = function ()
{
userAction(this.id);
application.SetHandlerMode("setupVertexStyleSelected");
}
document.getElementById('SetupEdgeStyle').onclick = function ()
{
userAction(this.id);
application.SetHandlerMode("setupEdgeStyle");
}
document.getElementById('SetupEdgeStyleSelected').onclick = function ()
{
userAction(this.id);
application.SetHandlerMode("setupEdgeStyleSelected");
}
document.getElementById('SetupBackgroundStyle').onclick = function ()
{
userAction(this.id);
application.SetHandlerMode("setupBackgroundStyle");
}
document.getElementById('GraphUndo').onclick = function ()
{
userAction(this.id);
application.SetHandlerMode("graphUndo");
}
document.getElementById('runUserScript').onclick = function ()
{
var el = document.getElementById('userScript');
var oldScript = document.getElementById("userScriptSource");
if (oldScript)
{
document.head.removeChild(oldScript);
}
var script = document.createElement('script');
script.type = "text/javascript";
script.innerHTML = el.value;
script.id = "userScriptSource";
document.head.appendChild(script);
application.SetHandlerMode("user.algorithm");
}
document.getElementById('submitUserScript').onclick = function ()
{
var script = document.getElementById('userScript');
var data = "message=" + script.value + "&";
$.ajax({
type: "POST",
url: "/feedback",
data: data
});
$( "#sentAlgorithm" ).dialog({
resizable: false,
height: "auto",
width: 400,
modal: true,
dialogClass: 'EdgeDialog'
});
}
document.getElementById('devToolsZoom').onclick = function ()
{
var devTools = document.getElementById('developerTools');
if (devTools.hasOwnProperty("isMin") && !devTools["isMin"])
{
devTools["isMin"] = true;
devTools.style.width = "30%";
}
else
{
devTools["isMin"] = false;
devTools.style.width = "100%";
}
}
document.getElementById('ExportGraph').onclick = function ()
{
userAction(this.id);
var graphAsString = application.graph.SaveToXML("");
var savedGraphName = application.GetNewGraphName();
var element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(graphAsString));
element.setAttribute('download', "graph_" + savedGraphName + ".graphml");
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
document.getElementById('ImportGraph').onclick = function ()
{
userAction(this.id);
if (ImportGraphFiles) {
ImportGraphFiles.click();
}
}
document.getElementById('openAlgorithmList').onclick = function()
{
// Show menu first
setTimeout(function()
{
var button = document.getElementById('openAlgorithmList');
var buttonRect = button.getBoundingClientRect();
var algorithmList = document.getElementById('algorithmList');
var delta = buttonRect.right - algorithmList.offsetWidth;
if (delta < 0)
{
var value = (delta - 4) + "px";
algorithmList.style.right = value;
}
else
{
algorithmList.style.right = "0";
}
}, 1);
}
document.getElementById('Fullscreen').onclick = function()
{
var idList = ["h1Header", "h1Text", "navigation", "footerContent", "bottom_adv"];
fullscreen = !fullscreen
userAction(fullscreen ? "fullscreen_on" : "fullscreen_off");
for (var i = 0; i < idList.length; i++) {
let element = document.getElementById(idList[i]);
if (!element) continue;
if (fullscreen)
element.style.display = "none";
else
element.style.display = "block";
}
document.getElementById("mainContainer").className = fullscreen ? "container-fluid page-wrap" : "container page-wrap";
document.getElementById("FullscreenIcon").className = fullscreen ? "glyphicon glyphicon-resize-small fa-fw" : "glyphicon glyphicon-resize-full fa-fw";
resizeCanvas();
}
if (document.getElementById('VoteButton') !== null)
document.getElementById('VoteButton').onclick = function ()
{
var dialogButtons = {};
for (var i = 0; i < 6 && document.getElementById('vote' + i) !== null; i++)
{
document.getElementById('vote' + i)["voteIndex"] = i;
document.getElementById('vote' + i).onclick = function ()
{
console.log("Vote" + this["voteIndex"]);
$.ajax({
type: "GET",
url: "/" + SiteDir + "cgi-bin/vote.php?index=" + this["voteIndex"],
dataType: "text"
});
$("#voteDialog").dialog('close');
$("#VoteButton").hide();
}
}
dialogButtons[g_close] = function() {
$( this ).dialog( "close" );
};
$( "#voteDialog" ).dialog({
resizable: false,
title: g_vote,
width: 400,
modal: true,
dialogClass: 'EdgeDialog',
buttons: dialogButtons,
});
}
// Get algorithms list and load it.
loadAsyncAlgorithms(createAlgorithmMenu);
var devTools = document.getElementById('developerTools');
devTools.style.left = 0;
resizeCanvas();
application.onPostLoadEvent();
$(function() {
$('#algorithmList').on('click', function(event) {
if (!event.originalEvent.closeThisMenu) {
event.stopPropagation();
}
});
$(window).on('click', function() {
$('#algorithmList').slideUp();
});
});
let showHideCategory = function(button, elementsListName){
let width = $( button ).width();
let elementsList = $(elementsListName);
var hideMark = button.querySelector('span[name="hideMark"]')
var showMark = button.querySelector('span[name="showMark"]')
if (elementsList.is(":visible")) {
elementsList.hide();
$(hideMark).show();
$(showMark).hide();
} else {
elementsList.show();
$(hideMark).hide();
$(showMark).show();
}
$( button ).width(width);
userAction("algCategory_" + elementsListName);
}
$(document.getElementById("algorithmCategoryBtn1").querySelector('span[name="hideMark"]')).hide();
$(document.getElementById("algorithmCategoryBtn0").querySelector('span[name="hideMark"]')).hide();
$('#algorithmCategoryBtn1').click(function(){
showHideCategory(this, "#algorithmCategoryElements1");
});
$('#algorithmCategoryBtn0').click(function(){
showHideCategory(this, "#algorithmCategoryElements0");
});
}
//window.onload = function ()
$(document).ready(function ()
{
window.onresize = function(event)
{
resizeCanvas();
}
document.getElementById('canvas').addEventListener("touchstart", touchHandler, true);
document.getElementById('canvas').addEventListener("touchmove", touchHandler, true);
document.getElementById('canvas').addEventListener("touchend", touchHandler, true);
document.getElementById('canvas').addEventListener("touchcancel", touchHandler, true);
// Try load emscripten implementation
var isMobile = navigator.userAgent.match(/(iPad)|(iPhone)|(iPod)|(android)|(webOS)/i);
if (!isMobile && !DisableEmscripten) {
let fullPathToGraphffoline = "features/graphoffline/Graphoffline.Emscripten.js";
doIncludeAsync ([
include (fullPathToGraphffoline),
], () => {
Module['onRuntimeInitialized'] = onRuntimeInitialized;
var process = Module.cwrap('ProcessAlgorithm', 'string', ['string']);
function onRuntimeInitialized() {
application.setEmscripten(process);
}
})
}
/*
$(document).ready(function(){
//set up some basic options for the feedback_me plugin
fm_options = {
position: "left-bottom",
message_placeholder: g_what_do_you_think,
message_required: true,
name_label: g_name,
message_label: g_feedback,
trigger_label: g_feedback,
submit_label: g_send,
title_label: g_write_to_us,
feedback_url: "/feedback",
};
//init feedback_me plugin
fm.init(fm_options);
});
*/
});
Array.prototype.swap = function (x,y) {
var b = this[x];
this[x] = this[y];
this[y] = b;
return this;
}