function magnifier(e) {
  var de = svgNode(e), g, m = {$number:magnification}, s = {$number:sensitivity},
    w, h, x, y, x1, y1, m1, xform, n, pos;

  while(de) {
    pos = svgCursorCoords(e,de);
    w = de.width.baseVal.value;
    h = de.height.baseVal.value;
    for(x = 0; x < de.childNodes.length; ++x) {
      n = de.childNodes[x];
      if(n.classList && n.classList.contains('svggraph-magnifier')) {
        g = n;
        break;
      }
    }
    if(g) {
      de = null;
    } else {
      de = de.parentNode;
      while(de && de.nodeName != '{$string:namespace}svg')
        de = de.parentNode;
    }
  }
  if(!g)
    return;

  if(pos[0] < 0 || pos[1] < 0 || pos[0] > w || pos[1] > h) {
    setattr(g, 'transform', '');
    return;
  }

  x1 = magPan(pos[0], w, s);
  y1 = magPan(pos[1], h, s);
  m1 = m - 1.0;
  x = -x1 * m1;
  y = -y1 * m1;

  xform = '';
  xform += 'translate(' + x + ' ' + y + ')';
  xform += 'scale(' + m + ' ' + m + ')';
  setattr(g, 'transform', xform);
}
function closeMagnifier(e) {
  var de = svgNode(e), g;
  if(!de)
    return;
  g = de.querySelector('.svggraph-magnifier');
  if(!g)
    return;
  setattr(g, 'transform', '');
}
function magPan(x, w, s) {
  var x1 = 0.5 * w / s;
  if(x <= x1)
    return 0;
  if(x >= w - x1)
    return w;
  return ((x - x1) * s / (s - 1));
}
