/*
ASCII2MathML-SVGShapes.js v3.41, May 13th 2009
Copyright Dr.ir. S.A. Miedema for polygon, arc, sector, setEndPoints, createLink, oval, mrect, image, dot
Copyright Peter Jipsen for all other functions, see the original ASCIIMathML v2.1
=====================================================================
Copyright Dr.ir. S.A. Miedema, www.Fullxml.org

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or (at
your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 
(at http://www.gnu.org/licences/lgpl.html) for more details.
*/

function setEndPoints(setEP) {
  endpoints = setEP;
}

function createLink(nodeid,url,target) {
  var link = myCreateElementSVG("a");
  if (url!=null) link.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",url);  
  if (url==null) link.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href","");  
  if (target!=null) link.setAttributeNS(null,"target",target);  
  if (target==null) link.setAttributeNS(null,"target","_self");  
  svgpicture.appendChild(link);
  var node = doc.getElementById(nodeid);
  link.appendChild(node);
}

function polygon(center,typ,id) {
  var node;
  var cx = center[0]*xunitlength+origin[0];
  var cy = height-center[1]*yunitlength-origin[1];
  if (id!=null) node = doc.getElementById(id);
  if (node==null) {
    node = myCreateElementSVG("polygon");
    node.setAttribute("id", id);
    svgpicture.appendChild(node);
  }
  node.setAttribute("onclick","try {dot_click(evt,"+center[0]+","+center[1]+")} catch(e) {}");
  setSVGDotStroke(node);
  setSVGDotFill(node);  
  if (typ=="trianglebottom") {
    node.setAttribute("points",(cx-dotradius)+","+(cy-dotradius)+" "+(cx+dotradius)+","+(cy-dotradius)+" "+(cx)+","+(cy+dotradius));
  }
  if (typ=="triangletop") {
    node.setAttribute("points",(cx-dotradius)+","+(cy+dotradius)+" "+(cx+dotradius)+","+(cy+dotradius)+" "+(cx)+","+(cy-dotradius));
  }
  if (typ=="triangleleft") {
    node.setAttribute("points",(cx-dotradius)+","+(cy)+" "+(cx+dotradius)+","+(cy-dotradius)+" "+(cx+dotradius)+","+(cy+dotradius));
  }
  if (typ=="triangleright") {
    node.setAttribute("points",(cx+dotradius)+","+(cy)+" "+(cx-dotradius)+","+(cy-dotradius)+" "+(cx-dotradius)+","+(cy+dotradius));
  }
  if (typ=="square") {
    node.setAttribute("points",(cx+dotradius)+","+(cy+dotradius)+" "+(cx-dotradius)+","+(cy+dotradius)+" "+(cx-dotradius)+","+(cy-dotradius)+" "+(cx+dotradius)+","+(cy-dotradius));
  }
  if (typ=="diamond") {
    node.setAttribute("points",(cx+dotradius)+","+(cy)+" "+(cx)+","+(cy+dotradius)+" "+(cx-dotradius)+","+(cy)+" "+(cx)+","+(cy-dotradius));
  }
}

function line(p,q,id,endpts) { // segment connecting points p,q (coordinates in units)
  var node;
  if (id!=null) node = doc.getElementById(id);
  if (node==null) {
    node = myCreateElementSVG("path");
    node.setAttribute("id", id);
    svgpicture.appendChild(node);
  }
  node.setAttribute("d","M"+(p[0]*xunitlength+origin[0])+","+(height-p[1]*yunitlength-origin[1])+" "+(q[0]*xunitlength+origin[0])+","+(height-q[1]*yunitlength-origin[1]));
  setSVGStroke(node);
  setSVGFill(node);  
  //set markers or arrow
  if (marker=="dot" || marker=="arrowdot") {
    drawMarker(p);
    if (marker=="arrowdot") arrowhead(p,q);
    drawMarker(q);
  } else if (marker=="arrow") arrowhead(p,q);
  if (endpts==null && endpoints!="") endpts = endpoints;
  if (endpts!=null) {
    if (endpts.indexOf("<-") != -1) arrowhead(q,p,id+"_start");
    if (endpts.indexOf("o-") != -1) dot(p, "open",null,null,id+"_start");
    if (endpts.indexOf("*-") != -1) dot(p, "closed",null,null,id+"_start");
    if (endpts.indexOf("->") != -1) arrowhead(p,q,id+"_end");
    if (endpts.indexOf("-o") != -1) dot(q, "open",null,null,id+"_end");
    if (endpts.indexOf("-*") != -1) dot(q, "closed",null,null,id+"_end");
  }
}

function path(plist,id,c,endpts,pathclosed) {
  if (c==null) c="";
  var node, st, i;
  if (id!=null) node = doc.getElementById(id);
  if (node==null) {
    node = myCreateElementSVG("path");
    node.setAttribute("id", id);
    svgpicture.appendChild(node);
  }
  if (typeof plist == "string") st = plist;
  else {
    st = "M";
    st += (plist[0][0]*xunitlength+origin[0])+","+
          (height-plist[0][1]*yunitlength-origin[1])+" "+c;
    for (i=1; i<plist.length; i++)
      st += (plist[i][0]*xunitlength+origin[0])+","+
            (height-plist[i][1]*yunitlength-origin[1])+" ";
  }
  if (pathclosed) {
    st = st + (plist[0][0]*xunitlength+origin[0]) + "," + (height-plist[0][1]*yunitlength-origin[1]) + " Z";
  }
  node.setAttribute("d", st);
  setSVGStroke(node);
  setSVGFill(node);
  //set markers or arrow
  if (marker=="dot" || marker=="arrowdot")
    for (i=0; i<plist.length; i++)
      if (c!="C" && c!="T" || i!=1 && i!=2)
        drawMarker(plist[i]);
  if (endpts==null && endpoints!="") endpts = endpoints;
  if (endpts!=null) {
    if (endpts.indexOf("<-") != -1) arrowhead(plist[1],plist[0]);
    if (endpts.indexOf("o-") != -1) dot(plist[0], "open");
    if (endpts.indexOf("*-") != -1) dot(plist[0], "closed");
    if (endpts.indexOf("->") != -1) arrowhead(plist[plist.length-2],plist[plist.length-1]);
    if (endpts.indexOf("-o") != -1) dot(plist[plist.length-1], "open");
    if (endpts.indexOf("-*") != -1) dot(plist[plist.length-1], "closed");
  }
}

function curve(plist,id,endpts) {
  path(plist,id,"T",endpts);
}

function vector(p,q,id) {
  line(p,q,id,"->");
}

function circle(center,radius,id) { 
  var node;
  if (id!=null) node = doc.getElementById(id);
  if (node==null) {
    node = myCreateElementSVG("circle");
    node.setAttribute("id", id);
    svgpicture.appendChild(node);
  }
  node.setAttribute("onclick","try {dot_click(evt,"+center[0]+","+center[1]+")} catch(e) {}");
  node.setAttribute("cx",center[0]*xunitlength+origin[0]);
  node.setAttribute("cy",height-center[1]*yunitlength-origin[1]);
  node.setAttribute("r",radius*xunitlength);
  setSVGStroke(node);
  setSVGFill(node);
}

function oval(center, radius, width, id, angle) {
  var node;
  if (id!=null) node = doc.getElementById(id);
  if (node==null) {
    node = myCreateElementSVG("path");
    node.setAttribute("id", id);
    svgpicture.appendChild(node);
  }
  var x1 = center[0]+width/2;
  var y1 = center[1]+radius;
  var x2 = center[0]+width/2;
  var y2 = center[1]-radius;
  var x1c = center[0]+width/2+2*radius;
  var y1c = center[1]+radius;
  var x2c = center[0]+width/2+2*radius;
  var y2c = center[1]-radius;
  var x3 = center[0]-width/2;
  var y3 = center[1]+radius;
  var x4 = center[0]-width/2;
  var y4 = center[1]-radius;
  var x3c = center[0]-width/2-2*radius;
  var y3c = center[1]+radius;
  var x4c = center[0]-width/2-2*radius;
  var y4c = center[1]-radius;

  x1 = x1*xunitlength+origin[0];
  y1 = height-y1*yunitlength-origin[1];
  x2 = x2*xunitlength+origin[0];
  y2 = height-y2*yunitlength-origin[1];
  x1c = x1c*xunitlength+origin[0];
  y1c = height-y1c*yunitlength-origin[1];
  x2c = x2c*xunitlength+origin[0];
  y2c = height-y2c*yunitlength-origin[1];
  x3 = x3*xunitlength+origin[0];
  y3 = height-y3*yunitlength-origin[1];
  x4 = x4*xunitlength+origin[0];
  y4 = height-y4*yunitlength-origin[1];
  x3c = x3c*xunitlength+origin[0];
  y3c = height-y3c*yunitlength-origin[1];
  x4c = x4c*xunitlength+origin[0];
  y4c = height-y4c*yunitlength-origin[1];

  node.setAttribute("d","M"+x1+","+y1+" C"+x1c+","+y1c+" "+x2c+","+y2c+" "+x2+","+y2+" L"+x4+","+y4+" C"+x4c+","+y4c+" "+x3c+","+y3c+" "+x3+","+y3+" "+" L"+x1+","+y1+" z");
  setSVGStroke(node);
  setSVGFill(node);
  if (angle!=null) {
  	var xangle = center[0]*xunitlength+origin[0];
  	var yangle = height-center[1]*yunitlength-origin[1];
  	var rotate = "translate("+xangle+","+yangle+") rotate("+angle+") translate(-"+xangle+",-"+yangle+")";
	node.setAttribute("transform",rotate);
  }
}

function loop(p,d,id) { 
// d is a direction vector e.g. [1,0] means loop starts in that direction
  if (d==null) d=[1,0];
  path([p,[p[0]+d[0],p[1]+d[1]],[p[0]-d[1],p[1]+d[0]],p],id,"C");
  if (marker=="arrow" || marker=="arrowdot") 
    arrowhead([p[0]+Math.cos(1.4)*d[0]-Math.sin(1.4)*d[1],
               p[1]+Math.sin(1.4)*d[0]+Math.cos(1.4)*d[1]],p);
}

function arc(center, radius, startangle, endangle, id, endpts) {
  var node, v, largearcflag, sweepflag, xaxisrotation;
  if (id!=null) node = doc.getElementById(id);
  if (node==null) {
    node = myCreateElementSVG("path");
    node.setAttribute("id", id);
    svgpicture.appendChild(node);
  }
  if (abs(startangle-endangle)==360) endangle = endangle-0.1;
  if ((endangle-startangle)>=360) endangle = startangle+359.9;
  if ((startangle-endangle)>=360) startangle = endangle+359.9;
  var stangle = startangle*pi/180;
  var edangle = endangle*pi/180;
  var startx = center[0]+radius*cos(stangle);
  var starty = center[1]+radius*sin(stangle);
  var start = [startx,starty];
  var endx = center[0]+radius*cos(edangle);
  var endy = center[1]+radius*sin(edangle);
  var end = [endx,endy];
  var ux = center[0]+radius*cos(stangle+0.0001);
  var uy = center[1]+radius*sin(stangle+0.0001);
  var u = [ux,uy];
  var vx = center[0]+radius*cos(edangle-0.0001);
  var vy = center[1]+radius*sin(edangle-0.0001);
  var v = [vx,vy];
  if (endangle>=startangle) {xaxisrotation=0;} else {xaxisrotation=1;}
  if (abs(startangle-endangle)>180) {largearcflag=1;} else {largearcflag=0;}
  sweepflag = 0;
  startx = startx*xunitlength+origin[0];
  starty = height-starty*yunitlength-origin[1];
  endx = endx*xunitlength+origin[0];
  endy = height-endy*yunitlength-origin[1];
  node.setAttribute("d","M"+startx+","+starty+" A"+radius*xunitlength+","+radius*yunitlength+" "+xaxisrotation+" "+largearcflag+","+sweepflag+" "+endx+","+endy);
  setSVGStroke(node);
  setSVGFill(node);
  //set markers or arrow
  if (marker=="dot" || marker=="arrowdot") {
    drawMarker(start);
    if (marker=="arrowdot") arrowhead(v,end,id+"_arrow");
    drawMarker(end);
  } else if (marker=="arrow") arrowhead(v,end,id+"_arrow");

  if (endpts==null && endpoints!="") endpts = endpoints;
  if (endpts!=null) {
    if (endpts.indexOf("<-") != -1) arrowhead(u,start,id+"_start");
    if (endpts.indexOf("o-") != -1) dot(start, "open",null,null,id+"_start");
    if (endpts.indexOf("*-") != -1) dot(start, "closed",null,null,id+"_start");
    if (endpts.indexOf("->") != -1) arrowhead(v,end,id+"_end");
    if (endpts.indexOf("-o") != -1) dot(end, "open",null,null,id+"_end");
    if (endpts.indexOf("-*") != -1) dot(end, "closed",null,null,id+"_end");
  }
}

function sector(center, radius, startangle, endangle, id) { 
  var node, largearcflag, sweepflag, xaxisrotation, cx, cy;
  if (id!=null) node = doc.getElementById(id);
  if (node==null) {
    node = myCreateElementSVG("path");
    node.setAttribute("id", id);
    svgpicture.appendChild(node);
  }
  if (abs(startangle-endangle)==360) endangle = endangle-0.1;
  if ((endangle-startangle)>=360) endangle = startangle+359.9;
  if ((startangle-endangle)>=360) startangle = endangle+359.9;
  var stangle = startangle*pi/180;
  var edangle = endangle*pi/180;
  var startx = center[0]+radius*cos(stangle);
  var starty = center[1]+radius*sin(stangle);
  var start = [startx,starty];
  var endx = center[0]+radius*cos(edangle);
  var endy = center[1]+radius*sin(edangle);
  var end = [endx,endy];
  var ux = center[0]+radius*cos(stangle+0.0001);
  var uy = center[1]+radius*sin(stangle+0.0001);
  var u = [ux,uy];
  var vx = center[0]+radius*cos(edangle-0.0001);
  var vy = center[1]+radius*sin(edangle-0.0001);
  var v = [vx,vy];
  if (endangle>=startangle) {xaxisrotation=0;} else {xaxisrotation=1;}
  if (abs(startangle-endangle)>180) {largearcflag=1;} else {largearcflag=0;}
  sweepflag = 0;
  startx = startx*xunitlength+origin[0];
  starty = height-starty*yunitlength-origin[1];
  endx = endx*xunitlength+origin[0];
  endy = height-endy*yunitlength-origin[1];
  cx = center[0]*xunitlength+origin[0];
  cy = height-center[1]*yunitlength-origin[1];
  node.setAttribute("d","M"+startx+","+starty+" A"+radius*xunitlength+","+radius*yunitlength+" "+xaxisrotation+" "+largearcflag+","+sweepflag+" "+endx+","+endy+" L"+cx+","+cy+" L"+startx+","+starty+" z");
  setSVGStroke(node);
  setSVGFill(node);
}

function ellipse(center,rx,ry,id,angle) { // coordinates in units
  var node;
  if (id!=null) node = doc.getElementById(id);
  if (node==null) {
    node = myCreateElementSVG("ellipse");
    node.setAttribute("id", id);
    svgpicture.appendChild(node);
  }
  node.setAttribute("cx",center[0]*xunitlength+origin[0]);
  node.setAttribute("cy",height-center[1]*yunitlength-origin[1]);
  node.setAttribute("rx",rx*xunitlength);
  node.setAttribute("ry",ry*yunitlength);
  setSVGStroke(node);
  setSVGFill(node);
  //set markers or arrow
  if (angle!=null) {
  	var xangle = center[0]*xunitlength+origin[0];
  	var yangle = height-center[1]*yunitlength-origin[1];
  	var rotate = "translate("+xangle+","+yangle+") rotate("+angle+") translate(-"+xangle+",-"+yangle+")";
	node.setAttribute("transform",rotate);
  }
}

function triangle(p,q,r,id) {
  path([p,q,r,p],id)
}

function rtriangle(x,y,a,b,id) {
  path([[x,y],[x,y+b],[x+a,y],[x,y]],id);
}

function rect(p,q,id,rx,ry,angle) { // opposite corners in units, rounded by radii
  var node;
  if (id!=null) node = doc.getElementById(id);
  if (node==null) {
    node = myCreateElementSVG("rect");
    node.setAttribute("id", id);
    svgpicture.appendChild(node);
  }
  node.setAttribute("x",p[0]*xunitlength+origin[0]);
  node.setAttribute("y",height-q[1]*yunitlength-origin[1]);
  node.setAttribute("width",(q[0]-p[0])*xunitlength);
  node.setAttribute("height",(q[1]-p[1])*yunitlength);
  if (rx!=null) node.setAttribute("rx",rx*xunitlength);
  if (ry!=null) node.setAttribute("ry",ry*yunitlength);
  setSVGStroke(node);
  setSVGFill(node);
  if (angle!=null) {
  	var xangle = p[0]*xunitlength+origin[0];
  	var yangle = height-p[1]*yunitlength-origin[1];
  	var rotate = "translate("+xangle+","+yangle+") rotate("+angle+") translate(-"+xangle+",-"+yangle+")";
	node.setAttribute("transform",rotate);
  }
}

function mrect(p,q,id,rx,ry) { // opposite corners in pixels, rounded by radii
  var node;
  if (id!=null) node = doc.getElementById(id);
  if (node==null) {
    node = myCreateElementSVG("rect");
    node.setAttribute("id", id);
    svgpicture.appendChild(node);
  }
  node.setAttribute("x",p[0]);
  node.setAttribute("y",height-q[1]);
  node.setAttribute("width",(q[0]-p[0]));
  node.setAttribute("height",(q[1]-p[1]));
  if (rx!=null) node.setAttribute("rx",rx);
  if (ry!=null) node.setAttribute("ry",ry);
  setSVGStroke(node);
  setSVGFill(node);
}

function text(p,st,pos,id,fontsty,angle) {
  var dnode, node, dx = 0, dy = fontsize/3;
  if (/(`|\$)/.test(st)) {  // layer for ASCIIMathML and LaTeXMathML
    dnode = document.getElementById(svgpicture.getAttribute("name")+"mml");
    if (dnode!=null) {
      if (id!=null) node = document.getElementById(id);
      if (node==null) {
        node = createElementXHTML("div");
        node.setAttribute("id", id);
        node.style.position = "absolute";
        dnode.appendChild(node);
      }
    node.setAttribute("onclick","try {dot_click(evt,"+p[0]+","+p[1]+")} catch(e) {}");
    while (node.childNodes.length>0) node.removeChild(node.lastChild); 
      node.appendChild(document.createTextNode(st));
      if (/`/.test(st)) AMprocessNode(node); else LMprocessNode(node);
      dx = -node.offsetWidth/2;
      dy = -node.offsetHeight/2;
      if (pos!=null) {
        if (/above/.test(pos)) dy = -node.offsetHeight;
        if (/below/.test(pos)) dy = 0;
        if (/right/.test(pos)) dx = 0;
        if ( /left/.test(pos)) dx = -node.offsetWidth;
      }
      node.style.left = ""+(p[0]*xunitlength+origin[0]+dx)+"px";
      node.style.top = ""+(height-p[1]*yunitlength-origin[1]+dy)+"px";
    }
    return p;
  }
  var textanchor = "middle";  // regular text goes into SVG
  if (pos!=null) {
    if (/above/.test(pos)) dy = -fontsize/2;
    if (/below/.test(pos)) dy = fontsize-0;
    if (/right/.test(pos)) {textanchor = "start"; dx = fontsize/4;}
    if ( /left/.test(pos)) {textanchor = "end";  dx = -fontsize/4;}
  }
  if (id!=null) node = doc.getElementById(id);
  if (node==null) {
    node = myCreateElementSVG("text");
    node.setAttribute("id", id);
    svgpicture.appendChild(node);
    node.appendChild(doc.createTextNode(st));
  }
  node.setAttribute("onclick","try {dot_click(evt,"+p[0]+","+p[1]+")} catch(e) {}");
  while (node.childNodes.length>1) node.removeChild(node.lastChild); 
  node.lastChild.nodeValue = "\xA0"+st+"\xA0";
  node.setAttribute("x",p[0]*xunitlength+origin[0]+dx);
  node.setAttribute("y",height-p[1]*yunitlength-origin[1]+dy);
  node.setAttribute("font-style",(fontsty!=null?fontsty:
    (st.search(/^[a-zA-Z]$/)!=-1?"italic":fontstyle)));
  node.setAttribute("font-family",fontfamily);
  node.setAttribute("font-size",fontsize);
  node.setAttribute("font-weight",fontweight);
  node.setAttribute("text-anchor",textanchor);
  if (fontstroke!="none") node.setAttribute("stroke",fontstroke);
  if (fontfill!="none") node.setAttribute("fill",fontfill);
  if (angle!=null) {
  	var xangle = p[0]*xunitlength+origin[0]+dx;
  	var yangle = height-p[1]*yunitlength-origin[1]+dy;
  	var rotate = "translate("+xangle+","+yangle+") rotate("+angle+") translate(-"+xangle+",-"+yangle+")";
	node.setAttribute("transform",rotate);
  }
  return p;
}

function mtext(p,st,pos,fontsty) { // method for updating text on an svg
// "this" is the text object or the svgpicture object
  var textanchor = "middle";
  var dx = 0; var dy = fontsize/3;
  if (pos!=null) {
    if (pos.slice(0,5)=="above") dy = -fontsize/2;
    if (pos.slice(0,5)=="below") dy = fontsize-0;
    if (pos.slice(0,5)=="right" || pos.slice(5,10)=="right") {
      textanchor = "start";
      dx = fontsize/2;
    }
    if (pos.slice(0,4)=="left" || pos.slice(5,9)=="left") {
      textanchor = "end";
      dx = -fontsize/2;
    }
  }
  var node = this;
  if (this.nodeName=="svg") {
    node = myCreateElementSVG("text");
    this.appendChild(node);
    node.appendChild(doc.createTextNode(st));
  }
  node.lastChild.nodeValue = st;
  node.setAttribute("x",p[0]+dx);
  node.setAttribute("y",p[1]+dy);
  node.setAttribute("font-style",(fontsty!=null?fontsty:fontstyle));
  node.setAttribute("font-family",fontfamily);
  node.setAttribute("font-size",fontsize);
  node.setAttribute("font-weight",fontweight);
  node.setAttribute("text-anchor",textanchor);
  if (fontstroke!="none") node.setAttribute("stroke",fontstroke);
  if (fontfill!="none") node.setAttribute("fill",fontfill);
}

function image(imgurl,p,w,h,id) {
  var node;
  if (id!=null) node = doc.getElementById(id);
  if (node==null) {
    node = myCreateElementSVG("image");
    node.setAttribute("id", id);
    svgpicture.appendChild(node);
  }
  node.setAttribute("x",p[0]*xunitlength+origin[0]);
  node.setAttribute("y",height-p[1]*yunitlength-origin[1]-h);
  node.setAttribute("width",w);
  node.setAttribute("height",h);
  node.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",imgurl);
}

function drawMarker(center) {
  var node = myCreateElementSVG("circle");
  node.setAttribute("cx",center[0]*xunitlength+origin[0]);
  node.setAttribute("cy",height-center[1]*yunitlength-origin[1]);
  node.setAttribute("r",markersize);
  setSVGMarkerStroke(node);
  setSVGMarkerFill(node);
  svgpicture.appendChild(node);
}

function dot(center, typ, label, pos, id) {
  var node;
  var cx = center[0]*xunitlength+origin[0];
  var cy = height-center[1]*yunitlength-origin[1];
  if (typ==null) typ = dottype;
  if (id!=null) node = doc.getElementById(id);
  if (typ=="+" || typ=="-" || typ=="|" || typ=="x") {
    if (node==null) {
      node = myCreateElementSVG("path");
      node.setAttribute("id", id);
      svgpicture.appendChild(node);
    }
    node.setAttribute("onclick","try {dot_click(evt,"+center[0]+","+center[1]+")} catch(e) {}");
    if (typ=="+") {
      node.setAttribute("d"," M "+(cx-dotradius)+" "+cy+" L "+(cx+dotradius)+" "+cy+" M "+cx+" "+(cy-dotradius)+" L "+cx+" "+(cy+dotradius));
    } else if (typ=="-") {
      node.setAttribute("d"," M "+(cx-dotradius)+" "+cy+" L "+(cx+dotradius)+" "+cy);
    } else if (typ=="|") {
      node.setAttribute("d"," M "+cx+" "+(cy-dotradius)+" L "+cx+" "+(cy+dotradius));
    } else if (typ=="x") {
      node.setAttribute("d"," M "+(cx-dotradius)+" "+(cy-dotradius)+" L "+(cx+dotradius)+" "+(cy+dotradius)+" M "+(cx+dotradius)+" "+(cy-dotradius)+" L "+(cx-dotradius)+" "+(cy+dotradius));
    }
    setSVGDotStroke(node);
  } else if (typ=="triangletop") {
    polygon(center,typ,id);
  } else if (typ=="trianglebottom") {
    polygon(center,typ,id);
  } else if (typ=="triangleleft") {
    polygon(center,typ,id);
  } else if (typ=="triangleright") {
    polygon(center,typ,id);
  } else if (typ=="square") {
    polygon(center,typ,id);
  } else if (typ=="diamond") {
    polygon(center,typ,id);
  } else {
    if (node==null) {
      node = myCreateElementSVG("circle");
      node.setAttribute("id", id);
      svgpicture.appendChild(node);
    }
    node.setAttribute("onclick","try {dot_click(evt,"+center[0]+","+center[1]+")} catch(e) {}");
    node.setAttribute("cx",cx);
    node.setAttribute("cy",cy);
    node.setAttribute("r",dotradius);
    setSVGDotStroke(node);
    if (typ=="open") setSVGDotFill(node);
    if (typ=="closed") setSVGStrokeFill(node);
  }
  if (label!=null) 
    text(center,label,(pos==null?"below":pos),(id==null?id:id+"label"))
}

point = dot; //alternative name

function arrowhead(p,q, id) { // draw arrowhead at q (in units) add size param
  var node;
  var up;
  var v = [p[0]*xunitlength+origin[0],height-p[1]*yunitlength-origin[1]];
  var w = [q[0]*xunitlength+origin[0],height-q[1]*yunitlength-origin[1]];
  var u = [w[0]-v[0],w[1]-v[1]];
  var d = sqrt(u[0]*u[0]+u[1]*u[1]);
  if (d > 0.00000001) {
    u = [u[0]/d, u[1]/d];
    up = [-u[1],u[0]];
    if (id!=null) node = doc.getElementById(id);
    if (node==null) {
      node = myCreateElementSVG("path");
      node.setAttribute("id", id);
      svgpicture.appendChild(node);
    }
    node.setAttribute("onclick","try {dot_click(evt,"+p[0]+","+p[1]+")} catch(e) {}");
    node.setAttribute("d","M "+(w[0]-4*markersize*u[0]-markersize*up[0])+" "+(w[1]-4*markersize*u[1]-markersize*up[1])+
                         " L "+(w[0]-0.75*markersize*u[0])+" "+(w[1]-0.75*markersize*u[1])+
                         " L "+(w[0]-4*markersize*u[0]+markersize*up[0])+" "+(w[1]-4*markersize*u[1]+markersize*up[1])+" z");
    setSVGMarkerStroke(node);
    setSVGMarkerFill(node);
  }
}
