1 pv.SvgScene.panel = function(scenes) {
  2   var g = scenes.$g, e = g && g.firstChild;
  3   for (var i = 0; i < scenes.length; i++) {
  4     var s = scenes[i];
  5 
  6     /* visible */
  7     if (!s.visible) continue;
  8 
  9     /* svg */
 10     if (!scenes.parent) {
 11       s.canvas.style.display = "inline-block";
 12       if (g && (g.parentNode != s.canvas)) {
 13         g = s.canvas.firstChild;
 14         e = g && g.firstChild;
 15       }
 16       if (!g) {
 17         g = s.canvas.appendChild(this.create("svg"));
 18         g.setAttribute("font-size", "10px");
 19         g.setAttribute("font-family", "sans-serif");
 20         g.setAttribute("fill", "none");
 21         g.setAttribute("stroke", "none");
 22         g.setAttribute("stroke-width", 1.5);
 23         for (var j = 0; j < this.events.length; j++) {
 24           g.addEventListener(this.events[j], this.dispatch, false);
 25         }
 26         e = g.firstChild;
 27       }
 28       scenes.$g = g;
 29       g.setAttribute("width", s.width + s.left + s.right);
 30       g.setAttribute("height", s.height + s.top + s.bottom);
 31     }
 32 
 33     /* clip (nest children) */
 34     if (s.overflow == "hidden") {
 35       var id = pv.id().toString(36),
 36           c = this.expect(e, "g", {"clip-path": "url(#" + id + ")"});
 37       if (!c.parentNode) g.appendChild(c);
 38       scenes.$g = g = c;
 39       e = c.firstChild;
 40 
 41       e = this.expect(e, "clipPath", {"id": id});
 42       var r = e.firstChild || e.appendChild(this.create("rect"));
 43       r.setAttribute("x", s.left);
 44       r.setAttribute("y", s.top);
 45       r.setAttribute("width", s.width);
 46       r.setAttribute("height", s.height);
 47       if (!e.parentNode) g.appendChild(e);
 48       e = e.nextSibling;
 49     }
 50 
 51     /* fill */
 52     e = this.fill(e, scenes, i);
 53 
 54     /* transform (push) */
 55     var k = this.scale,
 56         t = s.transform,
 57         x = s.left + t.x,
 58         y = s.top + t.y;
 59     this.scale *= t.k;
 60 
 61     /* children */
 62     for (var j = 0; j < s.children.length; j++) {
 63       s.children[j].$g = e = this.expect(e, "g", {
 64           "transform": "translate(" + x + "," + y + ")"
 65               + (t.k != 1 ? " scale(" + t.k + ")" : "")
 66         });
 67       this.updateAll(s.children[j]);
 68       if (!e.parentNode) g.appendChild(e);
 69       e = e.nextSibling;
 70     }
 71 
 72     /* transform (pop) */
 73     this.scale = k;
 74 
 75     /* stroke */
 76     e = this.stroke(e, scenes, i);
 77 
 78     /* clip (restore group) */
 79     if (s.overflow == "hidden") {
 80       scenes.$g = g = c.parentNode;
 81       e = c.nextSibling;
 82     }
 83   }
 84   return e;
 85 };
 86 
 87 pv.SvgScene.fill = function(e, scenes, i) {
 88   var s = scenes[i], fill = s.fillStyle;
 89   if (fill.opacity || s.events == "all") {
 90     e = this.expect(e, "rect", {
 91         "shape-rendering": s.antialias ? null : "crispEdges",
 92         "pointer-events": s.events,
 93         "cursor": s.cursor,
 94         "x": s.left,
 95         "y": s.top,
 96         "width": s.width,
 97         "height": s.height,
 98         "fill": fill.color,
 99         "fill-opacity": fill.opacity,
100         "stroke": null
101       });
102     e = this.append(e, scenes, i);
103   }
104   return e;
105 };
106 
107 pv.SvgScene.stroke = function(e, scenes, i) {
108   var s = scenes[i], stroke = s.strokeStyle;
109   if (stroke.opacity || s.events == "all") {
110     e = this.expect(e, "rect", {
111         "shape-rendering": s.antialias ? null : "crispEdges",
112         "pointer-events": s.events == "all" ? "stroke" : s.events,
113         "cursor": s.cursor,
114         "x": s.left,
115         "y": s.top,
116         "width": Math.max(1E-10, s.width),
117         "height": Math.max(1E-10, s.height),
118         "fill": null,
119         "stroke": stroke.color,
120         "stroke-opacity": stroke.opacity,
121         "stroke-width": s.lineWidth / this.scale
122       });
123     e = this.append(e, scenes, i);
124   }
125   return e;
126 };
127