<?xml version="1.0"?>
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:svg="http://www.w3.org/2000/svg" 
  xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
  >
  <head>
  <style>
<![CDATA[
img {
  border:0;
}
ul {
  list-style-type: none;
  list-style-position: outside;
  border-left: 1px dashed #aaaaaa;
}

a.item {
 color: black;
 border-bottom: 1px dashed #aaaaaa;
 text-decoration: none;
}

a.item:HOVER {
  background-color: #EEEEEE
	   }

.C3Object {
fill:#BBBBBB; 
stroke:black;
 }

.Line {
 fill:black; 
 stroke:black; 
 stroke-width:2;
 }

.Arrow {
fill:black;
stroke:black;
 }

]]>
</style>

	<script>
	  <![CDATA[

function none() {};

var SVG_NS = "http://www.w3.org/2000/svg";
var XHTML_NS = "http://www.w3.org/1999/xhtml"
var dx,dy;
var dragging = null;
var dropTarget = null;

baseUrl = "http://www.cheshire3.org/ajax/";
baseDb = "db_marc";


// AJAX

http_request = false;

function sendRequest(url, receiveFn) {
  http_request = false;
  if (window.XMLHttpRequest) {
    http_request = new XMLHttpRequest();
    if (http_request.overrideMimeType) {
      http_request.overrideMimeType('text/xml');
    }
  } else if (window.ActiveXObject) {
    try {
      http_request = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
      try {
        http_request = new ActiveXObject("Microsoft.XMLHTTP");
      } catch (e) {}
    }
  }
  if (http_request != false) {
    http_request.onreadystatechange = receiveFn;
    http_request.open('GET', url, true);
    http_request.send(null);
    return 0;
  } else {
    return 1;
  }
}



processList = function() {
  if (http_request.readyState == 4) {
    if (http_request.status == 200) {
      xmldoc = http_request.responseXML;
      targetNode = document.getElementById('objectListCell');
      kid = xmldoc.childNodes[0];
      targetNode.appendChild(kid);
      collapseList('ObjectList', '', 1);
    } else {
      alert('There was a problem with the request.');
    }
  }
}

processHelp = function() {
  if (http_request.readyState == 4) {
    if (http_request.status == 200) {
      xmldoc = http_request.responseXML;
      // <docs> <doc> node </doc> ... </docs>
      targetNode = document.getElementById('helpNode');
      while (targetNode.firstChild) {
	targetNode.removeChild(targetNode.firstChild);
      }
      docs = xmldoc.getElementsByTagName('doc')
      for (d=0;d<docs.length;d+=1) {
	node = docs.item(d);
	from = node.getAttribute('from');
	sub = document.createElementNS(XHTML_NS, 'p');
	b = document.createElementNS(XHTML_NS, 'b');
	b.appendChild(document.createTextNode("(From " + from + ")"))
	sub.appendChild(b)		     
	sub.appendChild(document.createTextNode(node.childNodes[0].data))
	targetNode.appendChild(sub);
      }
      // Now to find the location of the node
      helpNode = document.getElementById('helpLayer');      
      helpNode.style.left='50px';
      helpNode.style.top= currEvtY + 30 + 'px';
      helpNode.style.visibility='visible';
    } else {
      alert('There was a problem with the request.');
    }
  }
}



function getList() {
  url = baseUrl + "listObjects?contextId=" + baseDb;
  error = sendRequest(url, processList);
  if (error) {
    // die
    alert("Browser not AJAX compliant :(");
  }
}

currEvtY = 0;
function help(event, oid) {
  url = baseUrl + "docs?contextId=" + baseDb + "&targetId=" + oid;
  currEvtY  = event.clientY;
  error = sendRequest(url, processHelp);
  if (error) {
    alert("Browser not AJAX compliant?! :(");
  }
}

function unhelp() {
  helpNode = document.getElementById('helpLayer');      
  helpNode.style.visibility='hidden';
}


// Tree Collapse Stuff

var expandedLists = [];
var listCount = 0;
var collapsedUrl = 'closed.jpg';
var expandedUrl = 'open.jpg';
var itemUrl = 'tBar.gif'


function collapseList(listId, tocState, collapseChildren) {
  /* args: 
     listId -> str - id attr of list to collapse
     tocState -> str - string representation of state of list
     collapseChildren -> bool - collapse sub-lists?
  */
  if( !document.getElementsByTagName || !document.childNodes || !document.createElement ) { return; }
  listCount = 0;
  var rootListObj = document.getElementById( listId ); 
  if( !rootListObj ) { 
    return; 
  }
  collapseSubLists( rootListObj, 0, listId, tocState, collapseChildren, rootListObj.tagName.toLowerCase());
}


function collapseSubLists( listObj, level, rootListId, tocState, collapseChildren, listTag) {
  /* args: 
     listObj -> obj - root node of tree to collapse
     level -> int - level of the sub-list we're collapsing
     rootListId -> str - id attr of root list
     tocState -> str - string representation of state of list
     collapseChildren -> bool - collapse sub-lists?
     listTag - str - tag used for root list 'ul' or 'ol' 
  */
  var listItems = listObj.childNodes;
  tocLevels = tocState.split(':');
  if( !level ) { 
    rootListId = escape(rootListId); 
    if( collapseChildren ) { 
      expandedLists[rootListId] = []; 
    }
  }
  for( var i = 0 ; i < listItems.length; i++ ) { 
    // for each <li>
    if( listItems[i].tagName ) {
      var nextSubList = listItems[i].getElementsByTagName( listTag )[0];
      if( nextSubList ) {
	//collapse 1st sub-list
	nextSubList.style.display = 'none';
	//create a link for expanding/collapsing
	var newLink = document.createElementNS(XHTML_NS, 'a');
	newLink.setAttribute( 'href', '#' );
	newLink.onclick = new Function( 'switchState(this,' + level + ',\'' + rootListId + '\',' + collapseChildren + ',\'' + escape(listTag) + '\');return false;' );
	var imgElem = document.createElementNS(XHTML_NS, 'img');
	if (tocLevels[level] && listCount == tocLevels[level]) {
	  imgElem.setAttribute( 'src', expandedUrl );
	  imgElem.setAttribute( 'alt', '????');
	  newLink.appendChild(imgElem);
	  listItems[i].insertBefore(newLink, listItems[i].childNodes[0]);
	}
	else {
	  imgElem.setAttribute( 'src', collapsedUrl );
	  imgElem.setAttribute( 'alt', '????');
	  newLink.appendChild(imgElem);
	  listItems[i].insertBefore(newLink, listItems[i].childNodes[0]);
	  nextSubList.colListId = listCount++;
	  collapseSubLists( nextSubList, level + 1, rootListId, tocState, collapseChildren, listTag);
	}
      } else {
	var imgElem = document.createElementNS(XHTML_NS, 'img');
	imgElem.setAttribute( 'src', itemUrl );
	imgElem.setAttribute( 'alt', '????');
	listItems[i].insertBefore(imgElem, listItems[i].childNodes[0])
      }
    } 
  } 
}

function switchState( thisObj, level, rootListId, collapseChildren, listTag ) {
  /* args:
     thisObj = obj - node of tree to switch state expanded/collapsed
     level = int - level of element being switched
     rootListId -> str - id attr of root list
     collapseChildren -> bool - keep sub-lists collapsed?
     listTag - str - tag used for root list 'ul' or 'ol' 
   */
  if( thisObj.blur ) { 
    thisObj.blur(); 
  }
  var linkElem = thisObj.parentNode.getElementsByTagName( 'a' )[0];
  if (linkElem) {
    var imgElem = linkElem.getElementsByTagName( 'img' )[0];
    if (imgElem) {
      if (imgElem.getAttribute('src') == expandedUrl) {
	imgElem.setAttribute( 'src', collapsedUrl);
      } else {
	imgElem.setAttribute( 'src', expandedUrl);
      }
    }
  }
  thisObj = thisObj.parentNode.getElementsByTagName( unescape(listTag) )[0];
  if( collapseChildren ) {
    for( var x = expandedLists[rootListId].length - 1; x >= level; x-=1 ) { 
      if( expandedLists[rootListId][x] ) {
	expandedLists[rootListId][x].style.display = 'none';
	var linkElem = expandedLists[rootListId][x].parentNode.getElementsByTagName('a')[0];
	if (linkElem) {
	  var imgElem = linkElem.getElementsByTagName( 'img' )[0];
	  if (imgElem) {
	    imgElem.setAttribute( 'src', collapsedUrl);
	  }
	}
	if( level != x ) { 
	  expandedLists[rootListId][x] = null; 
	}
      } 
    }
    if( thisObj == expandedLists[rootListId][level] ) {
      expandedLists[rootListId][level] = null; 
    } 
    else { 
      thisObj.style.display = 'block'; 
      expandedLists[rootListId][level] = thisObj; 
    }
  } 
  else { 
    thisObj.style.display = ( thisObj.style.display == 'block' );// ? 'none' : 'block'; 
  }
  return true;
}

function stateToString(listId) {
  /* args:
     listId = str - id attr of list to create string representation of state for
  */
  if( !document.getElementsByTagName || !document.childNodes || !document.createElement ) { 
    return ''; 
  }
  var rootListObj = document.getElementById(listId);
  if (!rootListObj) {
    return '';
  }
  var stateStr = listId;
  for (var level = 0; level < expandedLists[listId].length; level++) {
    var listObj = expandedLists[listId][level]
    if (listObj) {
      stateStr += ':' + listObj.colListId;
    }
  }
  return stateStr;
}

function setCookie (name, val) {
  if (!name) {return false;}
  document.cookie = escape(name) + "=" + escape(val) + ";path=/ead/html";
}

function getCookie (name) {
  var cookieList = document.cookie.split(';');
  for (var x = 0; x < cookieList.length; x++) {
    var cookie = cookieList[x].split('=');
    if( cookie[0] == escape(name)) { 
      return unescape(cookie[1]); 
    }
  }
  return '';
}

function isInArray(obj, array) {
  /* args:
     obj = obj - the object to look for existence of
     array = obj - array object to search in
  */
  for(var i = 0; i < array.length; i++) { 
    if(obj == array[i]) { 
      return true;
    }
  } 
  return false;
}

function stringToState(listId, stateString) {

}


// ------------------ SVG Stuff ----------------------------


currZoom = 1.0;
currPanX = 0;
currPanY = 0;

function zoom(dir) {
  svgnode = document.getElementById('canvas');
  currZoom += (0.1 * dir);

  viewbox = svgnode.getAttribute('viewBox');
  currcoords = viewbox.split(/ /);

  coords = new Array(4);
  coords[0] = currPanX * currZoom;
  coords[1] = currPanY * currZoom;
  coords[2] = 700 * currZoom;
  coords[3] = 640 * currZoom;
  svgnode.setAttribute('viewBox', coords.join(' '));
  
  zoomNode = document.getElementById('zoomLevel');
  zoomNode.removeChild(zoomNode.firstChild);
  zoomNode.appendChild(document.createTextNode(String(currZoom).slice(0,3)));
}

function panX(dir) {
  svgnode = document.getElementById('canvas');
  currPanX += (50 * dir);
  viewbox = svgnode.getAttribute('viewBox');
  coords = viewbox.split(/ /);
  coords[0] = currPanX * currZoom;
  svgnode.setAttribute('viewBox', coords.join(' '));
  panNode = document.getElementById('panLevel');
  panNode.removeChild(panNode.firstChild);
  panNode.appendChild(document.createTextNode(currPanX + " " + currPanY));
}

function panY(dir) {
  svgnode = document.getElementById('canvas');
  currPanY += (50 * dir);
  viewbox = svgnode.getAttribute('viewBox');
  coords = viewbox.split(/ /);
  coords[1] = currPanY * currZoom;
  svgnode.setAttribute('viewBox', coords.join(' '));
  panNode = document.getElementById('panLevel');
  panNode.removeChild(panNode.firstChild);
  panNode.appendChild(document.createTextNode(currPanX + " " + currPanY));
}

start_attach = function() {
  t = this.group.transform.baseVal.getItem(0);
  cx = this.cx.baseVal.value + t.matrix.e;
  cy = this.cy.baseVal.value + t.matrix.f;
  dragging.cx.baseVal.value = cx;
  dragging.cy.baseVal.value = cy;
  dragging.dx = 0;
  dragging.dy = 0;    
}



function trash_mouseover_listener(evt) {
  if (dragging) {
    trash = document.getElementById('trashCan');
    trash.style.opacity = 0.6;
    dropTarget = "TRASH";
  } else {
    return 0;
  }
}

function trash_mouseout_listener(evt) {
  if (dropTarget == "TRASH") {
    trash = document.getElementById('trashCan');
    trash.style.opacity = 1.0;
    dropTarget = null;
  }
}



function init() {
  // attach event handlers to startPoint
  sp = document.getElementById('startPoint');
  sp.addEventListener("mousedown", mousedown_listener, true);
  sp.addEventListener("mouseover", mouseover_listener, true);
  sp.addEventListener("mouseout", mouseout_listener, true);
  sp.shine = foreach_shine;
  sp.fade = foreach_fade;
  sp.attachPoint = start_attach;
  sp.lines = new Array();
  sp.group = sp.parentNode;

  // Create initial line  and attach to start point
  line = create_line();
  dragging = line.pt1;
  sp.attachPoint()
  dragging.line.setAttribute('x1', dragging.cx.baseVal.value);
  dragging.line.setAttribute('y1', dragging.cy.baseVal.value);
  dragging.line.setAttribute('x2', dragging.cx.baseVal.value);
  dragging.line.setAttribute('y2', dragging.cy.baseVal.value + 50);
  dragging.line.pt2.setAttribute('cx', dragging.cx.baseVal.value);
  dragging.line.pt2.setAttribute('cy', dragging.cy.baseVal.value + 50);


  sp.lines.push(dragging);
  if (dragging.attachedTo != null) {
    // Moving from one to another
    for (i in dragging.attachedTo.lines) {
      item = dragging.attachedTo.lines[i];
      if (item == dragging) {
	dragging.attachedTo.lines.pop(i);
	break;
      }
    }
  }
  dragging.attachedTo = sp;
  dragging = null;

  // object destroying trashcan courtesy of crystal SVG
  trash = document.getElementById('trashCan');
  trash.addEventListener("mouseover", trash_mouseover_listener, true);
  trash.addEventListener("mouseout", trash_mouseout_listener, true);
  
  // and fetch our dynamic list of objects  
  getList()
}


function traverse_line(line) {
  
  var flow = new Array()
  while (line != null) {
    var nextObj = line.pt2.attachedTo;
    var oid = nextObj.oid;
    if (nextObj.type != "") {
      flow.push(oid + "|" + nextObj.type);
    } else {
      flow.push(oid); 
    }
    if (oid == "__FORK__") {
      // need to split multiple ways. 
      // Top is in. Right is out to forks. Left is out to flow
      var out = null;
      for (var l=0; l <= nextObj.lines.length-1; l++) {
	var pt = nextObj.lines[l];
	if (pt.dx == 50 && pt.dy == 45) {
	  flow.push("__SPLIT__");
	  nflow = traverse_line(pt.line);
	  flow = flow.concat(nflow);
	  flow.push("__/SPLIT__");
	} else if (pt.dy == 45) {
	  out = pt.line;
	} 
      }
      flow.push("__/FORK__");
      line = out;
    } else if (oid == "__FOR__") {
      // process loop
      // Top is in, right is out to loop, down is out to flow
      var out = null;
      for (var l=0; l <= nextObj.lines.length-1; l++) {
	var pt = nextObj.lines[l];
	if (pt.dy == 0) {
	  nflow = traverse_line(pt.line);
	  flow = flow.concat(nflow);
	} else if (pt.dx > 0) {
	  out = pt.line;
	} 
      }
      flow.push("__/FOR__");
      line = out;
    } else {
      // continue to next
      if (nextObj.lines.length < 2) {
	line = null;
      } else {
	line = (nextObj.lines[0].line == line ? nextObj.lines[1].line : nextObj.lines[0].line);
      }    
    }
  }
  return flow
}


function traverse_flow() {
  // start at start point
  sp = document.getElementById('startPoint');
  line = sp.lines[0].line;
  flow = traverse_line(line);

  txt = "<workflow>\n";
  indent = 2;
  for (thing in flow) {
    bit = flow[thing];
    for (s=0; s<indent;s++) {
      txt += " ";
    }
    if (bit.slice(0, 2) == "__") {
      name = bit.slice(2,-2);
      if (name == "FOR") {
	name = "for-each";
      } else if (name == "/FOR") {
	name = "/for-each";
      } else {
	name = name.toLowerCase(); 
      }
      txt += "<" + name + ">";
      if (name[0] == "/") {
	indent -= 2;
      } else {
	indent += 2;
      }
    } else {
      bits = bit.split('|');
      txt += '<object type="' + bits[1] + '" ref="' + bits[0] + '"/>';
    }
    txt += "\n";
  }
  txt += "</workflow>\n";
  alert(txt);
}


// -------------- Default Event Handlers -----------------

function mouseover_listener(evt)
{
  if (dragging != null && evt.target != dragging) {
    evt.target.shine();
    dropTarget = evt.target;
  } else {
    return 0;
  }
}
function mouseout_listener(evt)
{
  if (dropTarget != null) {
    dropTarget.fade();
    dropTarget = null;
  }
}

function mousedown_listener(evt) {
  dragging = evt.target;
  dragging.removeEventListener("mouseover", mouseover_listener, true);
  document.addEventListener("mousemove", mousemove_listener, true);
  document.addEventListener("mouseup", mouseup_listener, true);
  var id = dragging.ownerSVGElement.suspendRedraw(1000);
  svgnode = document.getElementById('canvas');
  svgnode.insertBefore(dragging.group, svgnode.childNodes[0]);
  dragging.ownerSVGElement.unsuspendRedraw(id);
  t = dragging.group.transform.baseVal.getItem(0);
  dx = t.matrix.e - (evt.clientX * currZoom);
  dy = t.matrix.f - (evt.clientY * currZoom);
}

function mouseup_listener(evt) {
  document.removeEventListener("mousemove", mousemove_listener, true);
  document.removeEventListener("mouseup", mouseup_listener, true);
  svgnode = document.getElementById('canvas');

  if (dropTarget == "TRASH") {
    // 'destroy' object
    // XXX Unattach lines
    svgnode.removeChild(dragging.group);
  } else {
    var id = dragging.ownerSVGElement.suspendRedraw(1000);
    svgnode.appendChild(dragging.group);
    dragging.ownerSVGElement.unsuspendRedraw(id);
    dragging.addEventListener("mouseover", mouseover_listener, false);
  }
  dragging = null;
}

function mousemove_listener(evt) {
  var id = dragging.ownerSVGElement.suspendRedraw(1000);
  
  t = dragging.group.transform.baseVal.getItem(0);
  t.matrix.e = ((evt.clientX * currZoom) + dx); 
  t.matrix.f = ((evt.clientY * currZoom) + dy) ; 
  
  for (i in dragging.lines) {
    item = dragging.lines[i];
    item.cx.baseVal.value = (evt.clientX * currZoom) + dx + item.dx;
    item.cy.baseVal.value = (evt.clientY * currZoom) + dy + item.dy;
    item.line.setAttribute('x' + item.end, item.cx.baseVal.value);
    item.line.setAttribute('y' + item.end, item.cy.baseVal.value);
  }
  dragging.ownerSVGElement.unsuspendRedraw(id);
}


// ---------------- Objects -------------------

ellipse_shine = function(){
  this.style.opacity = 0.4;
}
ellipse_fade = function() {
  this.style.opacity = 1.0;
}

ellipse_attach = function() {
  t = this.group.transform.baseVal.getItem(0);
  cx = this.cx.baseVal.value + t.matrix.e;
  cy = this.cy.baseVal.value + t.matrix.f;
  
  if (dragging.cx.baseVal.value > (cx + 20)) {
    dx = 60;
  } else if (dragging.cx.baseVal.value < (cx - 20)) { 
    dx =  -60;
  } else {
    dx = 0;
  }
  
  if (dragging.cy.baseVal.value > (cy + 8)) {
    if (dx != 0) {
      // calculate position on circle
      dy = 19;
      if (dx > 0) {
	dx = 38; 
      } else {
	dx = -38;
      }
    } else {
      dy = 25;
    }
  } else if (dragging.cy.baseVal.value < (cy - 8)) { 
    if (dx != 0) {
      // calculate position on ellipse
      dy = -19;
      if (dx > 0) {
	dx = 38; 
      } else {
	dx =  -38;
      }
    } else {
      dy = -25;
    }
  } else {
    dy = 0;
  }
  if (dx == 0 && dy == 0) {
    // default to north
    dx = 0;
    dy = -40;
  }
  dragging.cx.baseVal.value = cx + dx;
  dragging.cy.baseVal.value = cy + dy;
  dragging.dx = dx;
  dragging.dy = dy;    
}


function create_ellipse(oid, type) {
  // create a new SVG object
  svgnode = document.getElementById('canvas');
  g = document.createElementNS(SVG_NS, 'g');
  g.setAttribute('transform', 'translate(100,100)');

  circ = document.createElementNS(SVG_NS, "ellipse");
  circ.setAttribute('rx', '60');
  circ.setAttribute('ry', '25');
  circ.setAttribute('cx', '0');
  circ.setAttribute('cy', '0');
  circ.addEventListener("mousedown", mousedown_listener, true);
  circ.addEventListener("mouseover", mouseover_listener, true);
  circ.addEventListener("mouseout", mouseout_listener, true);
  circ.shine = ellipse_shine;
  circ.fade = ellipse_fade;
  circ.attachPoint = ellipse_attach;
  circ.setAttribute('class', 'C3Object');
  circ.lines = new Array();
  g.appendChild(circ);
  circ.group = g;


  // Wrapping!
  circ.oid = oid;
  circ.type = type;
  if (oid.length > 18) {
    bits = oid.match(/(^[a-z0-9_]+|([A-Z][a-z0-9_]+))/g);
    bits.reverse()
    line = "";
    txts = new Array();
    while (bits.length) {
      bit = bits.pop();
      nline = line + bit;
      if (nline.length > 18) {
	// create with line, set line to bits
	text = document.createElementNS(SVG_NS, 'text');
	text.setAttribute('font-size', '12');
	text.setAttribute('transform', 'translate(-'+ (3 * line.length)  + ', -2)');
	text.appendChild(document.createTextNode(line));
	txts.push(text);
	line = bit;
      } else {
	line = nline;
      }
    }
    if (line != "") { 
      text = document.createElementNS(SVG_NS, 'text');
      text.setAttribute('font-size', '12');
      text.setAttribute('transform', 'translate(-'+ (3 * line.length)  + ', 9)');
      text.appendChild(document.createTextNode(line));
      txts.push(text);
    }
    for (t in txts) {
      g.appendChild(txts[t]);
    }
  } else {
    text = document.createElementNS(SVG_NS, 'text');
    text.setAttribute('font-size', '12');
    text.setAttribute('transform', 'translate(-'+ (3 * oid.length)  + ', 3)');
    text.appendChild(document.createTextNode(oid));
    g.appendChild(text);
  }

  svgnode.appendChild(g);
  return true;
}

// --------------------- Fork ----------------------


fork_shine = function() {
  // for now, change color. But should add scale transform
  this.style.opacity = 0.3;
};

fork_fade = function() {
  this.style.opacity = 1.0;
};

fork_attach = function() {
  t = this.group.transform.baseVal.getItem(0);
  myx = t.matrix.e;
  myy = t.matrix.f;

  dx = 0;
  dy = 0;
  if (dragging.cy.baseVal.value < (myy + 20)) {
    // attach to top point
    dx = 25;
  } else {
    dy = 45;
    if (dragging.cx.baseVal.value > (myx+25)) {
      dx = 50;
    }
  }
  dragging.dx = dx;
  dragging.dy = dy;
  dragging.cx.baseVal.value = myx + dx;
  dragging.cy.baseVal.value = myy + dy;
}

function create_fork() {
  // create a new SVG object
  svgnode = document.getElementById('canvas');
  g = document.createElementNS(SVG_NS, 'g');
  g.setAttribute('transform', 'translate(100,100)');

  fork = document.createElementNS(SVG_NS, "polygon");
  fork.setAttribute('points', '25,0 50,45 0,45');
  fork.addEventListener("mousedown", mousedown_listener, true);
  fork.addEventListener("mouseover", mouseover_listener, true);
  fork.addEventListener("mouseout", mouseout_listener, true);
  fork.shine = fork_shine;
  fork.fade = fork_fade;
  fork.attachPoint = fork_attach;
  fork.setAttribute('class', 'C3Object');
  fork.lines = new Array();
  g.appendChild(fork);
  fork.group = g;
  fork.oid = "__FORK__";
  fork.type = "";
  svgnode.appendChild(g);
}

// ------------------ foreach ---------------

foreach_shine = function() {
  this.style.opacity = 0.4;
};
foreach_fade = function() {
  this.style.opacity = 1.0;
};

foreach_attach = function() {
  // target is circle.  Only attach to N E and S
  t = this.group.transform.baseVal.getItem(0);
  cx = this.cx.baseVal.value + t.matrix.e;
  cy = this.cy.baseVal.value + t.matrix.f;

  dx = 0;
  dy = 0;
  if (dragging.cx.baseVal.value > cx) {
    dx = 25;
  } else if (dragging.cy.baseVal.value < cy) { 
    dy =  -25;
  } else {
    dy = 25;
  }

  dragging.cx.baseVal.value = cx + dx;
  dragging.cy.baseVal.value = cy + dy;
  dragging.dx = dx;
  dragging.dy = dy;    
}


function create_foreach() {
  // create a new SVG object
  svgnode = document.getElementById('canvas');
  g = document.createElementNS(SVG_NS, 'g');
  g.setAttribute('transform', 'translate(100,100)');

  forh = document.createElementNS(SVG_NS, "circle");
  forh.setAttribute('r', '25');
  forh.setAttribute('class', 'C3Object');
  forh.addEventListener("mousedown", mousedown_listener, true);
  forh.addEventListener("mouseover", mouseover_listener, true);
  forh.addEventListener("mouseout", mouseout_listener, true);
  forh.shine = foreach_shine;
  forh.fade = foreach_fade;
  forh.attachPoint = foreach_attach;
  forh.lines = new Array();
  g.appendChild(forh);
  forh.group = g;
  forh.oid = "__FOR__";
  forh.type = "";
  // and an arrowhead to represent looping

  arrow = document.createElementNS(SVG_NS, "polygon");
  arrow.setAttribute('points', '0,0 10,3 0,6');
  arrow.setAttribute('class', 'Arrow');
  arrow.setAttribute('transform', 'translate(0,-28) rotate(7)');
  g.appendChild(arrow);

  arrow = document.createElementNS(SVG_NS, "polygon");
  arrow.setAttribute('points', '0,0 10,3 0,6');
  arrow.setAttribute('class', 'Arrow');
  arrow.setAttribute('transform', 'translate(0,28) rotate(187)');
  g.appendChild(arrow);

  svgnode.appendChild(g);
}


// ---------- Stores ---------


store_shine = function(){
  this.style.opacity = 0.4;
}
store_fade = function() {
  this.style.opacity = 1.0;
}

store_attach = function() {
  // target is ellipse
  t = this.group.transform.baseVal.getItem(0);
  cx = this.cx.baseVal.value + t.matrix.e;
  cy = this.cy.baseVal.value + t.matrix.f;
  
  if (dragging.cx.baseVal.value > (cx + 20)) {
    dx = 60;
  } else if (dragging.cx.baseVal.value < (cx - 20)) { 
    dx =  -60;
  } else {
    dx = 0;
  }
  
  if (dragging.cy.baseVal.value > (cy + 8)) {
    if (dx != 0) {
      // calculate position on circle
      dy = 19;
      if (dx > 0) {
	dx = 38; 
      } else {
	dx = -38;
      }
    } else {
      dy = 15;
    }
  } else if (dragging.cy.baseVal.value < (cy - 8)) { 
    if (dx != 0) {
      // calculate position on ellipse
      dy = -19;
      if (dx > 0) {
	dx = 38; 
      } else {
	dx =  -38;
      }
    } else {
      dy = -15;
    }
  } else {
    dy = 0;
  }
  if (dx == 0 && dy == 0) {
    // default to north
    dx = 0;
    dy = -15;
  }
  dragging.cx.baseVal.value = cx + dx;
  dragging.cy.baseVal.value = cy + dy;
  dragging.dx = dx;
  dragging.dy = dy;    
}



function create_store(oid, type) {
  // create a new SVG object
  svgnode = document.getElementById('canvas');
  g = document.createElementNS(SVG_NS, 'g');
  g.setAttribute('transform', 'translate(100,100)');

  store = document.createElementNS(SVG_NS, "ellipse");
  store.setAttribute('rx', '60');
  store.setAttribute('ry', '15');
  store.setAttribute('cx', '0');
  store.setAttribute('cy', '0');
  store.setAttribute('class', 'C3Object');  
  store.addEventListener("mousedown", mousedown_listener, true);
  store.addEventListener("mouseover", mouseover_listener, true);
  store.addEventListener("mouseout", mouseout_listener, true);
  store.shine = store_shine;
  store.fade = store_fade;
  store.attachPoint = store_attach;
  store.lines = new Array();
  g.appendChild(store);
  store.group = g;

  store2 = document.createElementNS(SVG_NS, "path");
  store2.setAttribute('d', 'M -60,0 L -60,25 A 60,15 0 1,0 60,25 L 60,0 A 60,15 0 0,1 -60,0 Z');
  store2.setAttribute('class', 'C3Object');  
  g.appendChild(store2);


  // Wrapping!
  store.oid = oid;
  store.type = type;
  if (oid.length > 19) {
    bits = oid.match(/(^[a-z0-9_]+|([A-Z][a-z0-9_]+))/g);
    bits.reverse()
    line = "";
    txts = new Array();
    while (bits.length) {
      bit = bits.pop();
      nline = line + bit;
      if (nline.length > 19) {
	// create with line, set line to bits
	text = document.createElementNS(SVG_NS, 'text');
	text.setAttribute('font-size', '12');
	text.setAttribute('transform', 'translate(-'+ (3 * line.length)  + ', 24)');
	text.appendChild(document.createTextNode(line));
	txts.push(text);
	line = bit;
      } else {
	line = nline;
      }
    }
    if (line != "") { 
      text = document.createElementNS(SVG_NS, 'text');
      text.setAttribute('font-size', '12');
      text.setAttribute('transform', 'translate(-'+ (3 * line.length)  + ', 35)');
      text.appendChild(document.createTextNode(line));
      txts.push(text);
    }
    for (t in txts) {
      g.appendChild(txts[t]);
    }
  } else {
    text = document.createElementNS(SVG_NS, 'text');
    text.setAttribute('font-size', '12');
    text.setAttribute('transform', 'translate(-'+ (3 * oid.length)  + ', 28)');
    text.appendChild(document.createTextNode(oid));
    g.appendChild(text);
  }


  svgnode.appendChild(g);
}

// --------- Rectangle -------

rect_shine = function() {};
rect_fade = function() {};
rect_attach = function() {
  t = this.group.transform.baseVal.getItem(0);
  cx = t.matrix.e + 60;
  cy = t.matrix.f + 25;
  dx = 0;
  dy = 0;
  if (dragging.cx.baseVal.value > (cx + 20)) {
    dx = 120;
  } else if (dragging.cx.baseVal.value > (cx - 20)) { 
    dx =  60;
  }
  
  if (dragging.cy.baseVal.value > (cy + 7)) {
    dy = 50;
  } else if (dragging.cy.baseVal.value > (cy - 7)) { 
    dy = 25;
  }

  if (dx == 60 && dy == 25) {
    // default to north
    dx = 60;
    dy = 0;
  }
  dragging.cx.baseVal.value = cx + dx - 60;
  dragging.cy.baseVal.value = cy + dy - 25;
  dragging.dx = dx;
  dragging.dy = dy;    

};

function create_rect(oid, type) {
  // Database, Server, Index, Workflow
  svgnode = document.getElementById('canvas');
  g = document.createElementNS(SVG_NS, 'g');
  g.setAttribute('transform', 'translate(100,100)');

  store = document.createElementNS(SVG_NS, "rect");
  store.setAttribute('width', '120');
  store.setAttribute('height', '50');
  store.setAttribute('class', 'C3Object');  
  store.addEventListener("mousedown", mousedown_listener, true);
  store.addEventListener("mouseover", mouseover_listener, true);
  store.addEventListener("mouseout", mouseout_listener, true);
  store.shine = store_shine;
  store.fade = store_fade;
  store.attachPoint = rect_attach;
  store.lines = new Array();
  g.appendChild(store);
  store.group = g;

  // Wrapping!
  store.oid = oid;
  store.type = type;
  if (oid.length > 20) {
    bits = oid.match(/(^[a-z0-9_]+|([A-Z][a-z0-9_]+))/g);
    bits.reverse()
    line = "";
    txts = new Array();
    while (bits.length) {
      bit = bits.pop();
      nline = line + bit;
      if (nline.length > 20) {
	// create with line, set line to bits
	text = document.createElementNS(SVG_NS, 'text');
	text.setAttribute('font-size', '12');
	text.setAttribute('transform', 'translate('+ (3 * (20 - line.length))  + ', 24)');
	text.appendChild(document.createTextNode(line));
	txts.push(text);
	line = bit;
      } else {
	line = nline;
      }
    }
    if (line != "") { 
      text = document.createElementNS(SVG_NS, 'text');
      text.setAttribute('font-size', '12');
      text.setAttribute('transform', 'translate('+ (3 * (20 - line.length))  + ', 35)');
      text.appendChild(document.createTextNode(line));
      txts.push(text);
    }
    for (t in txts) {
      g.appendChild(txts[t]);
    }
  } else {
    text = document.createElementNS(SVG_NS, 'text');
    text.setAttribute('font-size', '12');
    text.setAttribute('transform', 'translate('+ (3 * (20 - oid.length))  + ', 28)');
    text.appendChild(document.createTextNode(oid));
    g.appendChild(text);
  }

  svgnode.appendChild(g);
}



// ---------- Lines ----------


function pt_mouseover_listener(evt) {
  evt.target.style.opacity = 1.0;  
}

function pt_mouseout_listener(evt){
  evt.target.style.opacity = 0.1;
}

function pt_mousedown_listener(evt) {
  dragging = evt.target;
  dx = dragging.cx.baseVal.value - evt.clientX;
  dy = dragging.cy.baseVal.value - evt.clientY;
  document.addEventListener("mousemove", pt_mousemove_listener, true);
  document.addEventListener("mouseup", pt_mouseup_listener, true);
  dragging.removeEventListener("mouseover", pt_mouseover_listener, true);
  svgnode = document.getElementById('canvas');
  var id = dragging.ownerSVGElement.suspendRedraw(1000);
  // move to back so we can drop on things
  svgnode.insertBefore(dragging, svgnode.childNodes[0]);
  dragging.ownerSVGElement.unsuspendRedraw(id);
}

function pt_mouseup_listener(evt) {
  svgnode = document.getElementById('canvas')
  document.removeEventListener("mousemove", pt_mousemove_listener, true);
  document.removeEventListener("mouseup", pt_mouseup_listener, true);
  if (dropTarget) {
    if (dropTarget == 'TRASH') {
      // XXX unattach!
      svgnode.removeChild(dragging.line.pt1);
      svgnode.removeChild(dragging.line.pt2);
      svgnode.removeChild(dragging.line);
      dragging = null;
      return;
    } else {
      // do drop on target
      dropTarget.fade();
      dropTarget.attachPoint();
      
      dragging.style.opacity = 0.1;
      dragging.line.setAttribute('x' + dragging.end, dragging.cx.baseVal.value);
      dragging.line.setAttribute('y' + dragging.end, dragging.cy.baseVal.value);
      dropTarget.lines.push(dragging);
      if (dragging.attachedTo != null) {
	// Moving from one to another
	for (i in dragging.attachedTo.lines) {
	  item = dragging.attachedTo.lines[i];
	  if (item == dragging) {
	    dragging.attachedTo.lines.pop(i);
	    break;
	  }
	}
      }
      dragging.attachedTo = dropTarget;
    }

  } else if (dragging.attachedTo != null) {
    newlines = new Array();
    for (i in dragging.attachedTo.lines) {
      item = dragging.attachedTo.lines[i];
      if (item != dragging) {
	newlines.push(item);
      }
    }
    dragging.attachedTo.lines = newlines;
    dragging.attachedTo = null;
  }        
  var id = dragging.ownerSVGElement.suspendRedraw(1000);
  // move to top
  svgnode.appendChild(dragging);
  dragging.ownerSVGElement.unsuspendRedraw(id);
  dragging.addEventListener("mouseover", mouseover_listener, false);
  dragging = null;
}

function pt_mousemove_listener(evt) {
  var id = dragging.ownerSVGElement.suspendRedraw(1000);
  dragging.cx.baseVal.value = evt.clientX + dx;
  dragging.cy.baseVal.value = evt.clientY + dy;
  dragging.line.setAttribute('x' + dragging.end, dragging.cx.baseVal.value)
  dragging.line.setAttribute('y' + dragging.end, dragging.cy.baseVal.value)
  dragging.ownerSVGElement.unsuspendRedraw(id);
}



function create_line() {
  svgnode = document.getElementById('canvas');
  
  line = document.createElementNS(SVG_NS, 'line');
  line.setAttribute('x1', '10');
  line.setAttribute('y1', '10');
  line.setAttribute('x2', '50');
  line.setAttribute('y2', '50');
  line.setAttribute('class', 'Line');
  line.setAttribute('marker-end', 'url(#ArrowHead)'); 
  
  pt1 = document.createElementNS(SVG_NS, 'circle');
  pt1.setAttribute('r', '6');
  pt1.setAttribute('cx', '10');
  pt1.setAttribute('cy', '10');
  pt1.setAttribute('style', 'fill:white; stroke:black; stroke-width:1; opacity:0.1');
  pt1.line = line;
  line.pt1 = pt1;
  pt1.end = 1;
  pt1.attachedTo = null;
  pt2 = document.createElementNS(SVG_NS, 'circle');
  pt2.setAttribute('r', '6');
  pt2.setAttribute('cx', '50');
  pt2.setAttribute('cy', '50');
  pt2.setAttribute('style', 'fill:white; stroke:black; stroke-width:1; opacity:0.1');
  pt2.line = line;
  pt2.end = 2;
  line.pt2 = pt2;
  pt2.attachedTo = null;
  
  pt1.addEventListener("mouseover", pt_mouseover_listener, false);
  pt1.addEventListener("mouseout", pt_mouseout_listener, false);
  pt2.addEventListener("mouseover", pt_mouseover_listener, false);
  pt2.addEventListener("mouseout", pt_mouseout_listener, false);
  pt1.addEventListener("mousedown", pt_mousedown_listener, false);
  pt2.addEventListener("mousedown", pt_mousedown_listener, false);
  
  svgnode.appendChild(line);
  svgnode.appendChild(pt1);
  svgnode.appendChild(pt2);
  
  return line;

}

	  ]]>

	</script>

  </head>
  <body onload="init()">

<table border="1" cellpadding="0" cellspacing="0">
<tr>
<td valign="top" width="300px" id="objectListCell">


</td>
<td valign="top" width="700px">

    <svg:svg id = "canvas" width="700px" height="640px" viewBox = "0 0 700 640">
    <svg:defs>
    <svg:marker id="ArrowHead"
      viewBox="0 0 15 15" refX="0" refY="7" 
      markerUnits="strokeWidth"
      markerWidth="4" markerHeight="3"
      orient="auto">
    <svg:path d="M 0 0 L 15 5 L 0 15 z" />
    </svg:marker>
    </svg:defs>
    <svg:g transform="translate(300, 22)"> 
      <svg:circle id="startPoint" r="15" style="fill:white; stroke:black; stroke-width:3;"/>
    </svg:g>

    <svg:g id="trashCan" transform="translate(630 580) scale(0.4 0.4)">
	<svg:g id="Layer_1">
		<svg:g> 
			<svg:path fill="#FFFFFF" d="M64,1.646c-14.747,0-27.848,3.476-36.012,8.826c-4.476,2.723-7.412,5.977-8.224,9.511
				c-0.355,1.101-0.544,2.229-0.544,3.376c0,2.932,0.797,23.982,1.566,44.342c0.703,18.578,1.5,36.129,1.5,38.337
				c0,11.203,18.64,20.317,41.713,20.317s41.713-9.114,41.713-20.317c0-2.208,0.796-19.759,1.5-38.337
				c0.769-20.359,1.566-41.41,1.566-44.342C108.779,11.387,88.691,1.646,64,1.646z"/>
			<svg:linearGradient id="XMLID_1_" gradientUnits="userSpaceOnUse" x1="24.1519" y1="97.4473" x2="86.4698" y2="97.4473">
				<svg:stop  offset="0" style="stop-color:#FFFFFF"/>
				<svg:stop  offset="1" style="stop-color:#797E81"/>
				
				
				
			</svg:linearGradient>
			<svg:path fill="url(#XMLID_1_)" enable-background="new    " d="M63.977,122.538c22.69,0,40.951-7.926,40.951-17.706
				c0-1.203,0.37-9.484,0.713-17.835c-5.128-7.846-21.665-14.642-41.293-14.642c-20.616,0-37.832,7.388-41.986,15.841
				c0.313,7.738,0.661,15.491,0.661,16.636C23.022,114.612,41.285,122.538,63.977,122.538z"/>
			<svg:linearGradient id="XMLID_2_" gradientUnits="userSpaceOnUse" x1="64.5503" y1="115.959" x2="64.5503" y2="85.5083">
				<svg:stop  offset="0" style="stop-color:#FFFFFF"/>
				<svg:stop  offset="1" style="stop-color:#B1B1C5"/>
				
				
				
			</svg:linearGradient>
			<svg:path fill="url(#XMLID_2_)" d="M103.808,102.696c0,9.841-18.357,19.91-39.808,19.91s-38.708-7.975-38.708-17.815
				c0-9.84,17.258-19.913,38.708-19.913S103.808,92.856,103.808,102.696z"/>
			<svg:linearGradient id="XMLID_3_" gradientUnits="userSpaceOnUse" x1="7.5874" y1="63.9995" x2="61.6346" y2="63.9995">
				<svg:stop  offset="0.2022" style="stop-color:#CDF8FF"/>
				<svg:stop  offset="1" style="stop-color:#0074FF"/>
				
				
				
			</svg:linearGradient>
			<svg:path opacity="0.6" fill="url(#XMLID_3_)" d="M107.573,23.358c0-11.558-19.708-20.928-44.02-20.928s-44.02,9.37-44.02,20.928
				c0,5.581,3.066,78.02,3.066,82.679c0,10.787,18.263,19.531,40.953,19.531s40.953-8.744,40.953-19.531
				C104.507,101.378,107.573,28.939,107.573,23.358z"/>
			<svg:linearGradient id="XMLID_4_" gradientUnits="userSpaceOnUse" x1="39.9062" y1="107.0527" x2="117.9357" y2="108.0662">
				<svg:stop  offset="0" style="stop-color:#FFFFFF"/>
				<svg:stop  offset="1" style="stop-color:#B1B1C5"/>
				
				
				
			</svg:linearGradient>
			<svg:path fill="url(#XMLID_4_)" d="M64,108.643c-20.59,0-38.288-7.302-41.397-16.846c0.192,5.385,0.444,11.203,0.444,12.146
				c0,10.786,18.263,19.53,40.953,19.53c22.689,0,40.952-8.744,40.952-19.53c0-0.943,0.253-6.762,0.445-12.146
				C102.289,101.341,84.588,108.643,64,108.643z"/>
			<svg:linearGradient id="XMLID_5_" gradientUnits="userSpaceOnUse" x1="87.7939" y1="109.7314" x2="-14.5277" y2="109.7314">
				<svg:stop  offset="0" style="stop-color:#FFFFFF"/>
				<svg:stop  offset="1" style="stop-color:#B1B1C5"/>
				
				
				
			</svg:linearGradient>
			<svg:path id ="myTrash" fill="url(#XMLID_5_)" d="M64,110.738c-20.939,0-38.157-7.305-41.265-16.845c0.192,5.384,0.312,11.2,0.312,12.145
				c0,10.786,18.263,19.53,40.953,19.53c22.689,0,40.952-8.744,40.952-19.53c0-0.944,0.12-6.761,0.313-12.145
				C102.156,103.434,84.94,110.738,64,110.738z"/>
			<svg:linearGradient id="XMLID_6_" gradientUnits="userSpaceOnUse" x1="45.4297" y1="23.3594" x2="112.3054" y2="23.3594">
				<svg:stop  offset="0" style="stop-color:#B1E1FF"/>
				<svg:stop  offset="0.0737" style="stop-color:#A9DBFF"/>
				<svg:stop  offset="0.1861" style="stop-color:#94CAFF"/>
				<svg:stop  offset="0.323" style="stop-color:#72AFFF"/>
				<svg:stop  offset="0.4793" style="stop-color:#428AFF"/>
				<svg:stop  offset="0.6499" style="stop-color:#055AFF"/>
				<svg:stop  offset="0.6629" style="stop-color:#0056FF"/>
				<svg:stop  offset="1" style="stop-color:#000090"/>
				
				
				
				
				
			</svg:linearGradient>
			<svg:path opacity="0.6" fill="url(#XMLID_6_)" d="M104.6,23.358c0,10.66-18.178,19.303-40.6,19.303c-22.423,0-40.6-8.643-40.6-19.303
				C23.4,12.699,41.577,4.058,64,4.058C86.422,4.058,104.6,12.699,104.6,23.358z"/>
			<svg:linearGradient id="XMLID_7_" gradientUnits="userSpaceOnUse" x1="28.8057" y1="14.2324" x2="28.033" y2="94.5769">
				<svg:stop  offset="0" style="stop-color:#FFFFFF"/>
				<svg:stop offset="1" style="stop-color:#FFFFFF;stop-opacity:0"/>
				
				
				
			</svg:linearGradient>
			<svg:path id ="myTrash" fill="url(#XMLID_7_)"  d="M33.628,38.128c-7.777-3.38-13.104-8.136-13.977-13.851
				c-0.033-0.968-0.06-1.405-0.078-1.646c-0.018,0.242-0.039,0.483-0.039,0.727c0,5.581,3.066,78.02,3.066,82.679
				c0,5.964,5.499,11.302,14.363,14.884c-0.277-1.008-0.436-2.035-0.436-3.08C36.528,113.746,34.647,66.21,33.628,38.128z"/>
			<svg:linearGradient id="XMLID_8_" gradientUnits="userSpaceOnUse" x1="102.0596" y1="14.5005" x2="101.3065" y2="92.8034">
				<svg:stop  offset="0" style="stop-color:#FFFFFF"/>
				<svg:stop offset="1" style="stop-color:#FFFFFF;stop-opacity:0"/>
				
				
				
			</svg:linearGradient>
			<svg:path fill="url(#XMLID_8_)"  d="M107.545,22.825c-0.03,0.522-0.084,1.341-0.154,3.349
				c-1.024,4.151-4.253,7.576-8.912,10.268c-0.98,26.997-2.696,70.589-3.017,81.896c5.735-3.359,9.045-7.639,9.045-12.301
				c0-4.659,3.066-77.098,3.066-82.679C107.573,23.18,107.554,23.003,107.545,22.825z"/>
			<svg:path fill="#FFFFFF" d="M64,43.713c20.6,0,40.534-5.883,43.391-17.306c0.115-3.195,0.183-3.343,0.183-4.124
				c0-10.661-19.708-19.303-44.02-19.303s-44.02,8.642-44.02,19.303c0,0.618,0.042,0.067,0.117,2.253
				C21.44,36.108,41.966,43.713,64,43.713z M64,4.48c22.422,0,40.6,7.971,40.6,17.803S86.422,40.086,64,40.086
				c-22.423,0-40.6-7.971-40.6-17.803S41.577,4.48,64,4.48z"/>
			<svg:linearGradient id="XMLID_9_" gradientUnits="userSpaceOnUse" x1="7.5928" y1="27.5571" x2="61.6329" y2="27.5571">
				<svg:stop  offset="0.2022" style="stop-color:#CDF8FF"/>
				<svg:stop  offset="1" style="stop-color:#0074FF"/>
				
				
				
			</svg:linearGradient>
			<svg:path opacity="0.6" fill="url(#XMLID_9_)" d="M23.659,24.012c0.643,2.564,2.496,4.965,5.299,7.091
				C26.872,28.991,25.085,26.608,23.659,24.012z"/>
			<svg:path opacity="0.1" fill="#FFFFFF" d="M84.7,9.857c0-0.723-0.035-1.437-0.088-2.146C78.556,5.94,71.309,4.907,63.517,4.907
				c-21.234,0-38.448,7.649-38.448,17.086c0,0.646,0.088,1.283,0.246,1.911c1.35,2.459,3.042,4.715,5.018,6.715
				c6.324,4.794,17.75,8.097,30.971,8.431C74.772,35.62,84.7,23.852,84.7,9.857z"/>
			
				<svg:radialGradient id="XMLID_10_" cx="62.355" cy="116.2754" r="30.4899" fx="62.355" fy="116.2754" gradientTransform="matrix(0.9676 0 0 1 3.665 0)" gradientUnits="userSpaceOnUse">
				<svg:stop  offset="0" style="stop-color:#FFFFFF"/>
				<svg:stop  offset="1" style="stop-color:#B1B1C5"/>
				
				
				
			</svg:radialGradient>
			<svg:path  fill="url(#XMLID_10_)" d="M64,123.167c-19.809,0-36.277-6.898-40.742-16.186C25.355,117.42,42.723,125.568,64,125.568
				s38.644-8.148,40.741-18.587C100.276,116.269,83.808,123.167,64,123.167z"/>
			<svg:linearGradient id="XMLID_11_" gradientUnits="userSpaceOnUse" x1="64.0005" y1="135.7324" x2="64.0005" y2="-49.0357">
				<svg:stop  offset="0.0112" style="stop-color:#0051C5"/>
				<svg:stop  offset="1" style="stop-color:#3995E5"/>
				
				
				
			</svg:linearGradient>
			<svg:path fill="url(#XMLID_11_)" d="M19.221,23.358c0,2.932,0.797,23.982,1.566,44.342c0.703,18.578,1.5,36.129,1.5,38.337
				c0,11.203,18.64,20.317,41.713,20.317s41.713-9.114,41.713-20.317c0-2.208,0.796-19.759,1.5-38.337
				c0.769-20.359,1.566-41.41,1.566-44.342c0-11.972-20.088-21.713-44.779-21.713S19.221,11.387,19.221,23.358z M23.808,106.037
				c0-2.238-0.798-19.803-1.501-38.399C21.536,47.295,20.74,26.26,20.74,23.358C20.74,12.253,40.146,3.217,64,3.217
				c23.853,0,43.26,9.036,43.26,20.142c0,2.901-0.796,23.937-1.566,44.279c-0.705,18.597-1.501,36.161-1.501,38.399
				c0,10.338-17.958,18.747-40.192,18.747C41.765,124.784,23.808,116.375,23.808,106.037z"/>
		</svg:g>
		<svg:path fill="none" d="M128,128H0V0h128V128z"/>
	</svg:g>
</svg:g>


    </svg:svg>
</td>
</tr>
</table>

<div id="helpLayer" style="position:absolute; z-index: 1010; left: 0px; top: 0px; width:400px; visibility: hidden; background-color: #aaffff; opacity:0.9; border: 1px solid black; padding-left: 2px;">
<p id="helpNode">
</p>
(<a href="javascript:none()" onclick="unhelp()">close</a>)
</div>
  </body>
</html>

