From fccd3e34e4b232af5d7265b330bff01fde785254 Mon Sep 17 00:00:00 2001 From: Tristan Cavelier <tristan.cavelier@nexedi.com> Date: Wed, 20 Jan 2016 07:19:00 -0500 Subject: [PATCH] erp5_svg_editor: add method-draw canvg missing files --- .../erp5_svg_editor/method-draw/lib/canvg.xml | 6 + .../method-draw/lib/canvg/canvg.js.xml | 2667 +++++++++++++++++ .../method-draw/lib/canvg/rgbcolor.js.xml | 334 +++ 3 files changed, 3007 insertions(+) create mode 100644 bt5/erp5_svg_editor/SkinTemplateItem/portal_skins/erp5_svg_editor/method-draw/lib/canvg/canvg.js.xml create mode 100644 bt5/erp5_svg_editor/SkinTemplateItem/portal_skins/erp5_svg_editor/method-draw/lib/canvg/rgbcolor.js.xml diff --git a/bt5/erp5_svg_editor/SkinTemplateItem/portal_skins/erp5_svg_editor/method-draw/lib/canvg.xml b/bt5/erp5_svg_editor/SkinTemplateItem/portal_skins/erp5_svg_editor/method-draw/lib/canvg.xml index c6aaee5117..e1771e4771 100644 --- a/bt5/erp5_svg_editor/SkinTemplateItem/portal_skins/erp5_svg_editor/method-draw/lib/canvg.xml +++ b/bt5/erp5_svg_editor/SkinTemplateItem/portal_skins/erp5_svg_editor/method-draw/lib/canvg.xml @@ -6,6 +6,12 @@ </pickle> <pickle> <dictionary> + <item> + <key> <string>_objects</string> </key> + <value> + <tuple/> + </value> + </item> <item> <key> <string>id</string> </key> <value> <string>canvg</string> </value> diff --git a/bt5/erp5_svg_editor/SkinTemplateItem/portal_skins/erp5_svg_editor/method-draw/lib/canvg/canvg.js.xml b/bt5/erp5_svg_editor/SkinTemplateItem/portal_skins/erp5_svg_editor/method-draw/lib/canvg/canvg.js.xml new file mode 100644 index 0000000000..073fb0649b --- /dev/null +++ b/bt5/erp5_svg_editor/SkinTemplateItem/portal_skins/erp5_svg_editor/method-draw/lib/canvg/canvg.js.xml @@ -0,0 +1,2667 @@ +<?xml version="1.0"?> +<ZopeData> + <record id="1" aka="AAAAAAAAAAE="> + <pickle> + <global name="File" module="OFS.Image"/> + </pickle> + <pickle> + <dictionary> + <item> + <key> <string>_Cacheable__manager_id</string> </key> + <value> <string>anonymous_http_cache</string> </value> + </item> + <item> + <key> <string>_EtagSupport__etag</string> </key> + <value> <string>ts53288356.18</string> </value> + </item> + <item> + <key> <string>__name__</string> </key> + <value> <string>canvg.js</string> </value> + </item> + <item> + <key> <string>content_type</string> </key> + <value> <string>application/javascript</string> </value> + </item> + <item> + <key> <string>data</string> </key> + <value> <string encoding="cdata"><![CDATA[ + +/*\n + * canvg.js - Javascript SVG parser and renderer on Canvas\n + * MIT Licensed \n + * Gabe Lerner (gabelerner@gmail.com)\n + * http://code.google.com/p/canvg/\n + *\n + * Requires: rgbcolor.js - http://www.phpied.com/rgb-color-parser-in-javascript/\n + */\n +if(!window.console) {\n +\twindow.console = {};\n +\twindow.console.log = function(str) {};\n +\twindow.console.dir = function(str) {};\n +}\n +\n +if(!Array.prototype.indexOf){\n +\tArray.prototype.indexOf = function(obj){\n +\t\tfor(var i=0; i<this.length; i++){\n +\t\t\tif(this[i]==obj){\n +\t\t\t\treturn i;\n +\t\t\t}\n +\t\t}\n +\t\treturn -1;\n +\t}\n +}\n +\n +(function(){\n +\t// canvg(target, s)\n +\t// empty parameters: replace all \'svg\' elements on page with \'canvas\' elements\n +\t// target: canvas element or the id of a canvas element\n +\t// s: svg string, url to svg file, or xml document\n +\t// opts: optional hash of options\n +\t//\t\t ignoreMouse: true => ignore mouse events\n +\t//\t\t ignoreAnimation: true => ignore animations\n +\t//\t\t ignoreDimensions: true => does not try to resize canvas\n +\t//\t\t ignoreClear: true => does not clear canvas\n +\t//\t\t offsetX: int => draws at a x offset\n +\t//\t\t offsetY: int => draws at a y offset\n +\t//\t\t scaleWidth: int => scales horizontally to width\n +\t//\t\t scaleHeight: int => scales vertically to height\n +\t//\t\t renderCallback: function => will call the function after the first render is completed\n +\t//\t\t forceRedraw: function => will call the function on every frame, if it returns true, will redraw\n +\tthis.canvg = function (target, s, opts) {\n +\t\t// no parameters\n +\t\tif (target == null && s == null && opts == null) {\n +\t\t\tvar svgTags = document.getElementsByTagName(\'svg\');\n +\t\t\tfor (var i=0; i<svgTags.length; i++) {\n +\t\t\t\tvar svgTag = svgTags[i];\n +\t\t\t\tvar c = document.createElement(\'canvas\');\n +\t\t\t\tc.width = svgTag.clientWidth;\n +\t\t\t\tc.height = svgTag.clientHeight;\n +\t\t\t\tsvgTag.parentNode.insertBefore(c, svgTag);\n +\t\t\t\tsvgTag.parentNode.removeChild(svgTag);\n +\t\t\t\tvar div = document.createElement(\'div\');\n +\t\t\t\tdiv.appendChild(svgTag);\n +\t\t\t\tcanvg(c, div.innerHTML);\n +\t\t\t}\n +\t\t\treturn;\n +\t\t}\t\n +\t\topts = opts || {};\n +\t\n +\t\tif (typeof target == \'string\') {\n +\t\t\ttarget = document.getElementById(target);\n +\t\t}\n +\t\t\n +\t\t// reuse class per canvas\n +\t\tvar svg;\n +\t\tif (target.svg == null) {\n +\t\t\tsvg = build();\n +\t\t\ttarget.svg = svg;\n +\t\t}\n +\t\telse {\n +\t\t\tsvg = target.svg;\n +\t\t\tsvg.stop();\n +\t\t}\n +\t\tsvg.opts = opts;\n +\t\t\n +\t\tvar ctx = target.getContext(\'2d\');\n +\t\tif (typeof(s.documentElement) != \'undefined\') {\n +\t\t\t// load from xml doc\n +\t\t\tsvg.loadXmlDoc(ctx, s);\n +\t\t}\n +\t\telse if (s.substr(0,1) == \'<\') {\n +\t\t\t// load from xml string\n +\t\t\tsvg.loadXml(ctx, s);\n +\t\t}\n +\t\telse {\n +\t\t\t// load from url\n +\t\t\tsvg.load(ctx, s);\n +\t\t}\n +\t}\n +\n +\tfunction build() {\n +\t\tvar svg = { };\n +\t\t\n +\t\tsvg.FRAMERATE = 30;\n +\t\tsvg.MAX_VIRTUAL_PIXELS = 30000;\n +\t\t\n +\t\t// globals\n +\t\tsvg.init = function(ctx) {\n +\t\t\tsvg.Definitions = {};\n +\t\t\tsvg.Styles = {};\n +\t\t\tsvg.Animations = [];\n +\t\t\tsvg.Images = [];\n +\t\t\tsvg.ctx = ctx;\n +\t\t\tsvg.ViewPort = new (function () {\n +\t\t\t\tthis.viewPorts = [];\n +\t\t\t\tthis.Clear = function() { this.viewPorts = []; }\n +\t\t\t\tthis.SetCurrent = function(width, height) { this.viewPorts.push({ width: width, height: height }); }\n +\t\t\t\tthis.RemoveCurrent = function() { this.viewPorts.pop(); }\n +\t\t\t\tthis.Current = function() { return this.viewPorts[this.viewPorts.length - 1]; }\n +\t\t\t\tthis.width = function() { return this.Current().width; }\n +\t\t\t\tthis.height = function() { return this.Current().height; }\n +\t\t\t\tthis.ComputeSize = function(d) {\n +\t\t\t\t\tif (d != null && typeof(d) == \'number\') return d;\n +\t\t\t\t\tif (d == \'x\') return this.width();\n +\t\t\t\t\tif (d == \'y\') return this.height();\n +\t\t\t\t\treturn Math.sqrt(Math.pow(this.width(), 2) + Math.pow(this.height(), 2)) / Math.sqrt(2);\t\t\t\n +\t\t\t\t}\n +\t\t\t});\n +\t\t}\n +\t\tsvg.init();\n +\t\t\n +\t\t// images loaded\n +\t\tsvg.ImagesLoaded = function() { \n +\t\t\tfor (var i=0; i<svg.Images.length; i++) {\n +\t\t\t\tif (!svg.Images[i].loaded) return false;\n +\t\t\t}\n +\t\t\treturn true;\n +\t\t}\n +\n +\t\t// trim\n +\t\tsvg.trim = function(s) { return s.replace(/^\\s+|\\s+$/g, \'\'); }\n +\t\t\n +\t\t// compress spaces\n +\t\tsvg.compressSpaces = function(s) { return s.replace(/[\\s\\r\\t\\n]+/gm,\' \'); }\n +\t\t\n +\t\t// ajax\n +\t\tsvg.ajax = function(url) {\n +\t\t\tvar AJAX;\n +\t\t\tif(window.XMLHttpRequest){AJAX=new XMLHttpRequest();}\n +\t\t\telse{AJAX=new ActiveXObject(\'Microsoft.XMLHTTP\');}\n +\t\t\tif(AJAX){\n +\t\t\t AJAX.open(\'GET\',url,false);\n +\t\t\t AJAX.send(null);\n +\t\t\t return AJAX.responseText;\n +\t\t\t}\n +\t\t\treturn null;\n +\t\t} \n +\t\t\n +\t\t// parse xml\n +\t\tsvg.parseXml = function(xml) {\n +\t\t\tif (window.DOMParser)\n +\t\t\t{\n +\t\t\t\tvar parser = new DOMParser();\n +\t\t\t\treturn parser.parseFromString(xml, \'text/xml\');\n +\t\t\t}\n +\t\t\telse \n +\t\t\t{\n +\t\t\t\txml = xml.replace(/<!DOCTYPE svg[^>]*>/, \'\');\n +\t\t\t\tvar xmlDoc = new ActiveXObject(\'Microsoft.XMLDOM\');\n +\t\t\t\txmlDoc.async = \'false\';\n +\t\t\t\txmlDoc.loadXML(xml); \n +\t\t\t\treturn xmlDoc;\n +\t\t\t}\t\t\n +\t\t}\n +\t\t\n +\t\tsvg.Property = function(name, value) {\n +\t\t\tthis.name = name;\n +\t\t\tthis.value = value;\n +\t\t\t\n +\t\t\tthis.hasValue = function() {\n +\t\t\t\treturn (this.value != null && this.value !== \'\');\n +\t\t\t}\n +\t\t\t\t\t\t\t\n +\t\t\t// return the numerical value of the property\n +\t\t\tthis.numValue = function() {\n +\t\t\t\tif (!this.hasValue()) return 0;\n +\t\t\t\t\n +\t\t\t\tvar n = parseFloat(this.value);\n +\t\t\t\tif ((this.value + \'\').match(/%$/)) {\n +\t\t\t\t\tn = n / 100.0;\n +\t\t\t\t}\n +\t\t\t\treturn n;\n +\t\t\t}\n +\t\t\t\n +\t\t\tthis.valueOrDefault = function(def) {\n +\t\t\t\tif (this.hasValue()) return this.value;\n +\t\t\t\treturn def;\n +\t\t\t}\n +\t\t\t\n +\t\t\tthis.numValueOrDefault = function(def) {\n +\t\t\t\tif (this.hasValue()) return this.numValue();\n +\t\t\t\treturn def;\n +\t\t\t}\n +\t\t\t\n +\t\t\t/* EXTENSIONS */\n +\t\t\tvar that = this;\n +\t\t\t\n +\t\t\t// color extensions\n +\t\t\tthis.Color = {\n +\t\t\t\t// augment the current color value with the opacity\n +\t\t\t\taddOpacity: function(opacity) {\n +\t\t\t\t\tvar newValue = that.value;\n +\t\t\t\t\tif (opacity != null && opacity != \'\') {\n +\t\t\t\t\t\tvar color = new RGBColor(that.value);\n +\t\t\t\t\t\tif (color.ok) {\n +\t\t\t\t\t\t\tnewValue = \'rgba(\' + color.r + \', \' + color.g + \', \' + color.b + \', \' + opacity + \')\';\n +\t\t\t\t\t\t}\n +\t\t\t\t\t}\n +\t\t\t\t\treturn new svg.Property(that.name, newValue);\n +\t\t\t\t}\n +\t\t\t}\n +\t\t\t\n +\t\t\t// definition extensions\n +\t\t\tthis.Definition = {\n +\t\t\t\t// get the definition from the definitions table\n +\t\t\t\tgetDefinition: function() {\n +\t\t\t\t\tvar name = that.value.replace(/^(url\\()?#([^\\)]+)\\)?$/, \'$2\');\n +\t\t\t\t\treturn svg.Definitions[name];\n +\t\t\t\t},\n +\t\t\t\t\n +\t\t\t\tisUrl: function() {\n +\t\t\t\t\treturn that.value.indexOf(\'url(\') == 0\n +\t\t\t\t},\n +\t\t\t\t\n +\t\t\t\tgetFillStyle: function(e) {\n +\t\t\t\t\tvar def = this.getDefinition();\n +\t\t\t\t\t\n +\t\t\t\t\t// gradient\n +\t\t\t\t\tif (def != null && def.createGradient) {\n +\t\t\t\t\t\treturn def.createGradient(svg.ctx, e);\n +\t\t\t\t\t}\n +\t\t\t\t\t\n +\t\t\t\t\t// pattern\n +\t\t\t\t\tif (def != null && def.createPattern) {\n +\t\t\t\t\t\treturn def.createPattern(svg.ctx, e);\n +\t\t\t\t\t}\n +\t\t\t\t\t\n +\t\t\t\t\treturn null;\n +\t\t\t\t}\n +\t\t\t}\n +\t\t\t\n +\t\t\t// length extensions\n +\t\t\tthis.Length = {\n +\t\t\t\tDPI: function(viewPort) {\n +\t\t\t\t\treturn 96.0; // TODO: compute?\n +\t\t\t\t},\n +\t\t\t\t\n +\t\t\t\tEM: function(viewPort) {\n +\t\t\t\t\tvar em = 12;\n +\t\t\t\t\t\n +\t\t\t\t\tvar fontSize = new svg.Property(\'fontSize\', svg.Font.Parse(svg.ctx.font).fontSize);\n +\t\t\t\t\tif (fontSize.hasValue()) em = fontSize.Length.toPixels(viewPort);\n +\t\t\t\t\t\n +\t\t\t\t\treturn em;\n +\t\t\t\t},\n +\t\t\t\n +\t\t\t\t// get the length as pixels\n +\t\t\t\ttoPixels: function(viewPort) {\n +\t\t\t\t\tif (!that.hasValue()) return 0;\n +\t\t\t\t\tvar s = that.value+\'\';\n +\t\t\t\t\tif (s.match(/em$/)) return that.numValue() * this.EM(viewPort);\n +\t\t\t\t\tif (s.match(/ex$/)) return that.numValue() * this.EM(viewPort) / 2.0;\n +\t\t\t\t\tif (s.match(/px$/)) return that.numValue();\n +\t\t\t\t\tif (s.match(/pt$/)) return that.numValue() * 1.25;\n +\t\t\t\t\tif (s.match(/pc$/)) return that.numValue() * 15;\n +\t\t\t\t\tif (s.match(/cm$/)) return that.numValue() * this.DPI(viewPort) / 2.54;\n +\t\t\t\t\tif (s.match(/mm$/)) return that.numValue() * this.DPI(viewPort) / 25.4;\n +\t\t\t\t\tif (s.match(/in$/)) return that.numValue() * this.DPI(viewPort);\n +\t\t\t\t\tif (s.match(/%$/)) return that.numValue() * svg.ViewPort.ComputeSize(viewPort);\n +\t\t\t\t\treturn that.numValue();\n +\t\t\t\t}\n +\t\t\t}\n +\t\t\t\n +\t\t\t// time extensions\n +\t\t\tthis.Time = {\n +\t\t\t\t// get the time as milliseconds\n +\t\t\t\ttoMilliseconds: function() {\n +\t\t\t\t\tif (!that.hasValue()) return 0;\n +\t\t\t\t\tvar s = that.value+\'\';\n +\t\t\t\t\tif (s.match(/s$/)) return that.numValue() * 1000;\n +\t\t\t\t\tif (s.match(/ms$/)) return that.numValue();\n +\t\t\t\t\treturn that.numValue();\n +\t\t\t\t}\n +\t\t\t}\n +\t\t\t\n +\t\t\t// angle extensions\n +\t\t\tthis.Angle = {\n +\t\t\t\t// get the angle as radians\n +\t\t\t\ttoRadians: function() {\n +\t\t\t\t\tif (!that.hasValue()) return 0;\n +\t\t\t\t\tvar s = that.value+\'\';\n +\t\t\t\t\tif (s.match(/deg$/)) return that.numValue() * (Math.PI / 180.0);\n +\t\t\t\t\tif (s.match(/grad$/)) return that.numValue() * (Math.PI / 200.0);\n +\t\t\t\t\tif (s.match(/rad$/)) return that.numValue();\n +\t\t\t\t\treturn that.numValue() * (Math.PI / 180.0);\n +\t\t\t\t}\n +\t\t\t}\n +\t\t}\n +\t\t\n +\t\t// fonts\n +\t\tsvg.Font = new (function() {\n +\t\t\tthis.Styles = [\'normal\',\'italic\',\'oblique\',\'inherit\'];\n +\t\t\tthis.Variants = [\'normal\',\'small-caps\',\'inherit\'];\n +\t\t\tthis.Weights = [\'normal\',\'bold\',\'bolder\',\'lighter\',\'100\',\'200\',\'300\',\'400\',\'500\',\'600\',\'700\',\'800\',\'900\',\'inherit\'];\n +\t\t\t\n +\t\t\tthis.CreateFont = function(fontStyle, fontVariant, fontWeight, fontSize, fontFamily, inherit) { \n +\t\t\t\tvar f = inherit != null ? this.Parse(inherit) : this.CreateFont(\'\', \'\', \'\', \'\', \'\', svg.ctx.font);\n +\t\t\t\treturn { \n +\t\t\t\t\tfontFamily: fontFamily || f.fontFamily, \n +\t\t\t\t\tfontSize: fontSize || f.fontSize, \n +\t\t\t\t\tfontStyle: fontStyle || f.fontStyle, \n +\t\t\t\t\tfontWeight: fontWeight || f.fontWeight, \n +\t\t\t\t\tfontVariant: fontVariant || f.fontVariant,\n +\t\t\t\t\ttoString: function () { return [this.fontStyle, this.fontVariant, this.fontWeight, this.fontSize, this.fontFamily].join(\' \') } \n +\t\t\t\t} \n +\t\t\t}\n +\t\t\t\n +\t\t\tvar that = this;\n +\t\t\tthis.Parse = function(s) {\n +\t\t\t\tvar f = {};\n +\t\t\t\tvar d = svg.trim(svg.compressSpaces(s || \'\')).split(\' \');\n +\t\t\t\tvar set = { fontSize: false, fontStyle: false, fontWeight: false, fontVariant: false }\n +\t\t\t\tvar ff = \'\';\n +\t\t\t\tfor (var i=0; i<d.length; i++) {\n +\t\t\t\t\tif (!set.fontStyle && that.Styles.indexOf(d[i]) != -1) { if (d[i] != \'inherit\') f.fontStyle = d[i]; set.fontStyle = true; }\n +\t\t\t\t\telse if (!set.fontVariant && that.Variants.indexOf(d[i]) != -1) { if (d[i] != \'inherit\') f.fontVariant = d[i]; set.fontStyle = set.fontVariant = true;\t}\n +\t\t\t\t\telse if (!set.fontWeight && that.Weights.indexOf(d[i]) != -1) {\tif (d[i] != \'inherit\') f.fontWeight = d[i]; set.fontStyle = set.fontVariant = set.fontWeight = true; }\n +\t\t\t\t\telse if (!set.fontSize) { if (d[i] != \'inherit\') f.fontSize = d[i].split(\'/\')[0]; set.fontStyle = set.fontVariant = set.fontWeight = set.fontSize = true; }\n +\t\t\t\t\telse { if (d[i] != \'inherit\') ff += d[i]; }\n +\t\t\t\t} if (ff != \'\') f.fontFamily = ff;\n +\t\t\t\treturn f;\n +\t\t\t}\n +\t\t});\n +\t\t\n +\t\t// points and paths\n +\t\tsvg.ToNumberArray = function(s) {\n +\t\t\tvar a = svg.trim(svg.compressSpaces((s || \'\').replace(/,/g, \' \'))).split(\' \');\n +\t\t\tfor (var i=0; i<a.length; i++) {\n +\t\t\t\ta[i] = parseFloat(a[i]);\n +\t\t\t}\n +\t\t\treturn a;\n +\t\t}\t\t\n +\t\tsvg.Point = function(x, y) {\n +\t\t\tthis.x = x;\n +\t\t\tthis.y = y;\n +\t\t\t\n +\t\t\tthis.angleTo = function(p) {\n +\t\t\t\treturn Math.atan2(p.y - this.y, p.x - this.x);\n +\t\t\t}\n +\t\t\t\n +\t\t\tthis.applyTransform = function(v) {\n +\t\t\t\tvar xp = this.x * v[0] + this.y * v[2] + v[4];\n +\t\t\t\tvar yp = this.x * v[1] + this.y * v[3] + v[5];\n +\t\t\t\tthis.x = xp;\n +\t\t\t\tthis.y = yp;\n +\t\t\t}\n +\t\t}\n +\t\tsvg.CreatePoint = function(s) {\n +\t\t\tvar a = svg.ToNumberArray(s);\n +\t\t\treturn new svg.Point(a[0], a[1]);\n +\t\t}\n +\t\tsvg.CreatePath = function(s) {\n +\t\t\tvar a = svg.ToNumberArray(s);\n +\t\t\tvar path = [];\n +\t\t\tfor (var i=0; i<a.length; i+=2) {\n +\t\t\t\tpath.push(new svg.Point(a[i], a[i+1]));\n +\t\t\t}\n +\t\t\treturn path;\n +\t\t}\n +\t\t\n +\t\t// bounding box\n +\t\tsvg.BoundingBox = function(x1, y1, x2, y2) { // pass in initial points if you want\n +\t\t\tthis.x1 = Number.NaN;\n +\t\t\tthis.y1 = Number.NaN;\n +\t\t\tthis.x2 = Number.NaN;\n +\t\t\tthis.y2 = Number.NaN;\n +\t\t\t\n +\t\t\tthis.x = function() { return this.x1; }\n +\t\t\tthis.y = function() { return this.y1; }\n +\t\t\tthis.width = function() { return this.x2 - this.x1; }\n +\t\t\tthis.height = function() { return this.y2 - this.y1; }\n +\t\t\t\n +\t\t\tthis.addPoint = function(x, y) {\t\n +\t\t\t\tif (x != null) {\n +\t\t\t\t\tif (isNaN(this.x1) || isNaN(this.x2)) {\n +\t\t\t\t\t\tthis.x1 = x;\n +\t\t\t\t\t\tthis.x2 = x;\n +\t\t\t\t\t}\n +\t\t\t\t\tif (x < this.x1) this.x1 = x;\n +\t\t\t\t\tif (x > this.x2) this.x2 = x;\n +\t\t\t\t}\n +\t\t\t\n +\t\t\t\tif (y != null) {\n +\t\t\t\t\tif (isNaN(this.y1) || isNaN(this.y2)) {\n +\t\t\t\t\t\tthis.y1 = y;\n +\t\t\t\t\t\tthis.y2 = y;\n +\t\t\t\t\t}\n +\t\t\t\t\tif (y < this.y1) this.y1 = y;\n +\t\t\t\t\tif (y > this.y2) this.y2 = y;\n +\t\t\t\t}\n +\t\t\t}\t\t\t\n +\t\t\tthis.addX = function(x) { this.addPoint(x, null); }\n +\t\t\tthis.addY = function(y) { this.addPoint(null, y); }\n +\t\t\t\n +\t\t\tthis.addBoundingBox = function(bb) {\n +\t\t\t\tthis.addPoint(bb.x1, bb.y1);\n +\t\t\t\tthis.addPoint(bb.x2, bb.y2);\n +\t\t\t}\n +\t\t\t\n +\t\t\tthis.addQuadraticCurve = function(p0x, p0y, p1x, p1y, p2x, p2y) {\n +\t\t\t\tvar cp1x = p0x + 2/3 * (p1x - p0x); // CP1 = QP0 + 2/3 *(QP1-QP0)\n +\t\t\t\tvar cp1y = p0y + 2/3 * (p1y - p0y); // CP1 = QP0 + 2/3 *(QP1-QP0)\n +\t\t\t\tvar cp2x = cp1x + 1/3 * (p2x - p0x); // CP2 = CP1 + 1/3 *(QP2-QP0)\n +\t\t\t\tvar cp2y = cp1y + 1/3 * (p2y - p0y); // CP2 = CP1 + 1/3 *(QP2-QP0)\n +\t\t\t\tthis.addBezierCurve(p0x, p0y, cp1x, cp2x, cp1y,\tcp2y, p2x, p2y);\n +\t\t\t}\n +\t\t\t\n +\t\t\tthis.addBezierCurve = function(p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y) {\n +\t\t\t\t// from http://blog.hackers-cafe.net/2009/06/how-to-calculate-bezier-curves-bounding.html\n +\t\t\t\tvar p0 = [p0x, p0y], p1 = [p1x, p1y], p2 = [p2x, p2y], p3 = [p3x, p3y];\n +\t\t\t\tthis.addPoint(p0[0], p0[1]);\n +\t\t\t\tthis.addPoint(p3[0], p3[1]);\n +\t\t\t\t\n +\t\t\t\tfor (i=0; i<=1; i++) {\n +\t\t\t\t\tvar f = function(t) { \n +\t\t\t\t\t\treturn Math.pow(1-t, 3) * p0[i]\n +\t\t\t\t\t\t+ 3 * Math.pow(1-t, 2) * t * p1[i]\n +\t\t\t\t\t\t+ 3 * (1-t) * Math.pow(t, 2) * p2[i]\n +\t\t\t\t\t\t+ Math.pow(t, 3) * p3[i];\n +\t\t\t\t\t}\n +\t\t\t\t\t\n +\t\t\t\t\tvar b = 6 * p0[i] - 12 * p1[i] + 6 * p2[i];\n +\t\t\t\t\tvar a = -3 * p0[i] + 9 * p1[i] - 9 * p2[i] + 3 * p3[i];\n +\t\t\t\t\tvar c = 3 * p1[i] - 3 * p0[i];\n +\t\t\t\t\t\n +\t\t\t\t\tif (a == 0) {\n +\t\t\t\t\t\tif (b == 0) continue;\n +\t\t\t\t\t\tvar t = -c / b;\n +\t\t\t\t\t\tif (0 < t && t < 1) {\n +\t\t\t\t\t\t\tif (i == 0) this.addX(f(t));\n +\t\t\t\t\t\t\tif (i == 1) this.addY(f(t));\n +\t\t\t\t\t\t}\n +\t\t\t\t\t\tcontinue;\n +\t\t\t\t\t}\n +\t\t\t\t\t\n +\t\t\t\t\tvar b2ac = Math.pow(b, 2) - 4 * c * a;\n +\t\t\t\t\tif (b2ac < 0) continue;\n +\t\t\t\t\tvar t1 = (-b + Math.sqrt(b2ac)) / (2 * a);\n +\t\t\t\t\tif (0 < t1 && t1 < 1) {\n +\t\t\t\t\t\tif (i == 0) this.addX(f(t1));\n +\t\t\t\t\t\tif (i == 1) this.addY(f(t1));\n +\t\t\t\t\t}\n +\t\t\t\t\tvar t2 = (-b - Math.sqrt(b2ac)) / (2 * a);\n +\t\t\t\t\tif (0 < t2 && t2 < 1) {\n +\t\t\t\t\t\tif (i == 0) this.addX(f(t2));\n +\t\t\t\t\t\tif (i == 1) this.addY(f(t2));\n +\t\t\t\t\t}\n +\t\t\t\t}\n +\t\t\t}\n +\t\t\t\n +\t\t\tthis.isPointInBox = function(x, y) {\n +\t\t\t\treturn (this.x1 <= x && x <= this.x2 && this.y1 <= y && y <= this.y2);\n +\t\t\t}\n +\t\t\t\n +\t\t\tthis.addPoint(x1, y1);\n +\t\t\tthis.addPoint(x2, y2);\n +\t\t}\n +\t\t\n +\t\t// transforms\n +\t\tsvg.Transform = function(v) {\t\n +\t\t\tvar that = this;\n +\t\t\tthis.Type = {}\n +\t\t\n +\t\t\t// translate\n +\t\t\tthis.Type.translate = function(s) {\n +\t\t\t\tthis.p = svg.CreatePoint(s);\t\t\t\n +\t\t\t\tthis.apply = function(ctx) {\n +\t\t\t\t\tctx.translate(this.p.x || 0.0, this.p.y || 0.0);\n +\t\t\t\t}\n +\t\t\t\tthis.applyToPoint = function(p) {\n +\t\t\t\t\tp.applyTransform([1, 0, 0, 1, this.p.x || 0.0, this.p.y || 0.0]);\n +\t\t\t\t}\n +\t\t\t}\n +\t\t\t\n +\t\t\t// rotate\n +\t\t\tthis.Type.rotate = function(s) {\n +\t\t\t\tvar a = svg.ToNumberArray(s);\n +\t\t\t\tthis.angle = new svg.Property(\'angle\', a[0]);\n +\t\t\t\tthis.cx = a[1] || 0;\n +\t\t\t\tthis.cy = a[2] || 0;\n +\t\t\t\tthis.apply = function(ctx) {\n +\t\t\t\t\tctx.translate(this.cx, this.cy);\n +\t\t\t\t\tctx.rotate(this.angle.Angle.toRadians());\n +\t\t\t\t\tctx.translate(-this.cx, -this.cy);\n +\t\t\t\t}\n +\t\t\t\tthis.applyToPoint = function(p) {\n +\t\t\t\t\tvar a = this.angle.Angle.toRadians();\n +\t\t\t\t\tp.applyTransform([1, 0, 0, 1, this.p.x || 0.0, this.p.y || 0.0]);\n +\t\t\t\t\tp.applyTransform([Math.cos(a), Math.sin(a), -Math.sin(a), Math.cos(a), 0, 0]);\n +\t\t\t\t\tp.applyTransform([1, 0, 0, 1, -this.p.x || 0.0, -this.p.y || 0.0]);\n +\t\t\t\t}\t\t\t\n +\t\t\t}\n +\t\t\t\n +\t\t\tthis.Type.scale = function(s) {\n +\t\t\t\tthis.p = svg.CreatePoint(s);\n +\t\t\t\tthis.apply = function(ctx) {\n +\t\t\t\t\tctx.scale(this.p.x || 1.0, this.p.y || this.p.x || 1.0);\n +\t\t\t\t}\n +\t\t\t\tthis.applyToPoint = function(p) {\n +\t\t\t\t\tp.applyTransform([this.p.x || 0.0, 0, 0, this.p.y || 0.0, 0, 0]);\n +\t\t\t\t}\t\t\t\t\n +\t\t\t}\n +\t\t\t\n +\t\t\tthis.Type.matrix = function(s) {\n +\t\t\t\tthis.m = svg.ToNumberArray(s);\n +\t\t\t\tthis.apply = function(ctx) {\n +\t\t\t\t\tctx.transform(this.m[0], this.m[1], this.m[2], this.m[3], this.m[4], this.m[5]);\n +\t\t\t\t}\n +\t\t\t\tthis.applyToPoint = function(p) {\n +\t\t\t\t\tp.applyTransform(this.m);\n +\t\t\t\t}\t\t\t\t\t\n +\t\t\t}\n +\t\t\t\n +\t\t\tthis.Type.SkewBase = function(s) {\n +\t\t\t\tthis.base = that.Type.matrix;\n +\t\t\t\tthis.base(s);\n +\t\t\t\tthis.angle = new svg.Property(\'angle\', s);\n +\t\t\t}\n +\t\t\tthis.Type.SkewBase.prototype = new this.Type.matrix;\n +\t\t\t\n +\t\t\tthis.Type.skewX = function(s) {\n +\t\t\t\tthis.base = that.Type.SkewBase;\n +\t\t\t\tthis.base(s);\n +\t\t\t\tthis.m = [1, 0, Math.tan(this.angle.Angle.toRadians()), 1, 0, 0];\n +\t\t\t}\n +\t\t\tthis.Type.skewX.prototype = new this.Type.SkewBase;\n +\t\t\t\n +\t\t\tthis.Type.skewY = function(s) {\n +\t\t\t\tthis.base = that.Type.SkewBase;\n +\t\t\t\tthis.base(s);\n +\t\t\t\tthis.m = [1, Math.tan(this.angle.Angle.toRadians()), 0, 1, 0, 0];\n +\t\t\t}\n +\t\t\tthis.Type.skewY.prototype = new this.Type.SkewBase;\n +\t\t\n +\t\t\tthis.transforms = [];\n +\t\t\t\n +\t\t\tthis.apply = function(ctx) {\n +\t\t\t\tfor (var i=0; i<this.transforms.length; i++) {\n +\t\t\t\t\tthis.transforms[i].apply(ctx);\n +\t\t\t\t}\n +\t\t\t}\n +\t\t\t\n +\t\t\tthis.applyToPoint = function(p) {\n +\t\t\t\tfor (var i=0; i<this.transforms.length; i++) {\n +\t\t\t\t\tthis.transforms[i].applyToPoint(p);\n +\t\t\t\t}\n +\t\t\t}\n +\t\t\t\n +\t\t\tvar data = svg.trim(svg.compressSpaces(v)).split(/\\s(?=[a-z])/);\n +\t\t\tfor (var i=0; i<data.length; i++) {\n +\t\t\t\tvar type = data[i].split(\'(\')[0];\n +\t\t\t\tvar s = data[i].split(\'(\')[1].replace(\')\',\'\');\n +\t\t\t\tvar transform = new this.Type[type](s);\n +\t\t\t\tthis.transforms.push(transform);\n +\t\t\t}\n +\t\t}\n +\t\t\n +\t\t// aspect ratio\n +\t\tsvg.AspectRatio = function(ctx, aspectRatio, width, desiredWidth, height, desiredHeight, minX, minY, refX, refY) {\n +\t\t\t// aspect ratio - http://www.w3.org/TR/SVG/coords.html#PreserveAspectRatioAttribute\n +\t\t\taspectRatio = svg.compressSpaces(aspectRatio);\n +\t\t\taspectRatio = aspectRatio.replace(/^defer\\s/,\'\'); // ignore defer\n +\t\t\tvar align = aspectRatio.split(\' \')[0] || \'xMidYMid\';\n +\t\t\tvar meetOrSlice = aspectRatio.split(\' \')[1] || \'meet\';\t\t\t\t\t\n +\t\n +\t\t\t// calculate scale\n +\t\t\tvar scaleX = width / desiredWidth;\n +\t\t\tvar scaleY = height / desiredHeight;\n +\t\t\tvar scaleMin = Math.min(scaleX, scaleY);\n +\t\t\tvar scaleMax = Math.max(scaleX, scaleY);\n +\t\t\tif (meetOrSlice == \'meet\') { desiredWidth *= scaleMin; desiredHeight *= scaleMin; }\n +\t\t\tif (meetOrSlice == \'slice\') { desiredWidth *= scaleMax; desiredHeight *= scaleMax; }\t\n +\t\t\t\n +\t\t\trefX = new svg.Property(\'refX\', refX);\n +\t\t\trefY = new svg.Property(\'refY\', refY);\n +\t\t\tif (refX.hasValue() && refY.hasValue()) {\t\t\t\t\n +\t\t\t\tctx.translate(-scaleMin * refX.Length.toPixels(\'x\'), -scaleMin * refY.Length.toPixels(\'y\'));\n +\t\t\t} \n +\t\t\telse {\t\t\t\t\t\n +\t\t\t\t// align\n +\t\t\t\tif (align.match(/^xMid/) && ((meetOrSlice == \'meet\' && scaleMin == scaleY) || (meetOrSlice == \'slice\' && scaleMax == scaleY))) ctx.translate(width / 2.0 - desiredWidth / 2.0, 0); \n +\t\t\t\tif (align.match(/YMid$/) && ((meetOrSlice == \'meet\' && scaleMin == scaleX) || (meetOrSlice == \'slice\' && scaleMax == scaleX))) ctx.translate(0, height / 2.0 - desiredHeight / 2.0); \n +\t\t\t\tif (align.match(/^xMax/) && ((meetOrSlice == \'meet\' && scaleMin == scaleY) || (meetOrSlice == \'slice\' && scaleMax == scaleY))) ctx.translate(width - desiredWidth, 0); \n +\t\t\t\tif (align.match(/YMax$/) && ((meetOrSlice == \'meet\' && scaleMin == scaleX) || (meetOrSlice == \'slice\' && scaleMax == scaleX))) ctx.translate(0, height - desiredHeight); \n +\t\t\t}\n +\t\t\t\n +\t\t\t// scale\n +\t\t\tif (align == \'none\') ctx.scale(scaleX, scaleY);\n +\t\t\telse if (meetOrSlice == \'meet\') ctx.scale(scaleMin, scaleMin); \n +\t\t\telse if (meetOrSlice == \'slice\') ctx.scale(scaleMax, scaleMax); \t\n +\t\t\t\n +\t\t\t// translate\n +\t\t\tctx.translate(minX == null ? 0 : -minX, minY == null ? 0 : -minY);\t\t\t\n +\t\t}\n +\t\t\n +\t\t// elements\n +\t\tsvg.Element = {}\n +\t\t\n +\t\tsvg.Element.ElementBase = function(node) {\t\n +\t\t\tthis.attributes = {};\n +\t\t\tthis.styles = {};\n +\t\t\tthis.children = [];\n +\t\t\t\n +\t\t\t// get or create attribute\n +\t\t\tthis.attribute = function(name, createIfNotExists) {\n +\t\t\t\tvar a = this.attributes[name];\n +\t\t\t\tif (a != null) return a;\n +\t\t\t\t\t\t\t\n +\t\t\t\ta = new svg.Property(name, \'\');\n +\t\t\t\tif (createIfNotExists == true) this.attributes[name] = a;\n +\t\t\t\treturn a;\n +\t\t\t}\n +\t\t\t\n +\t\t\t// get or create style, crawls up node tree\n +\t\t\tthis.style = function(name, createIfNotExists) {\n +\t\t\t\tvar s = this.styles[name];\n +\t\t\t\tif (s != null) return s;\n +\t\t\t\t\n +\t\t\t\tvar a = this.attribute(name);\n +\t\t\t\tif (a != null && a.hasValue()) {\n +\t\t\t\t\treturn a;\n +\t\t\t\t}\n +\t\t\t\t\n +\t\t\t\tvar p = this.parent;\n +\t\t\t\tif (p != null) {\n +\t\t\t\t\tvar ps = p.style(name);\n +\t\t\t\t\tif (ps != null && ps.hasValue()) {\n +\t\t\t\t\t\treturn ps;\n +\t\t\t\t\t}\n +\t\t\t\t}\n +\t\t\t\t\t\n +\t\t\t\ts = new svg.Property(name, \'\');\n +\t\t\t\tif (createIfNotExists == true) this.styles[name] = s;\n +\t\t\t\treturn s;\n +\t\t\t}\n +\t\t\t\n +\t\t\t// base render\n +\t\t\tthis.render = function(ctx) {\n +\t\t\t\t// don\'t render display=none\n +\t\t\t\tif (this.style(\'display\').value == \'none\') return;\n +\t\t\t\t\n +\t\t\t\t// don\'t render visibility=hidden\n +\t\t\t\tif (this.attribute(\'visibility\').value == \'hidden\') return;\n +\t\t\t\n +\t\t\t\tctx.save();\n +\t\t\t\t\tthis.setContext(ctx);\n +\t\t\t\t\t\t// mask\n +\t\t\t\t\t\tif (this.attribute(\'mask\').hasValue()) {\n +\t\t\t\t\t\t\tvar mask = this.attribute(\'mask\').Definition.getDefinition();\n +\t\t\t\t\t\t\tif (mask != null) mask.apply(ctx, this);\n +\t\t\t\t\t\t}\n +\t\t\t\t\t\telse if (this.style(\'filter\').hasValue()) {\n +\t\t\t\t\t\t\tvar filter = this.style(\'filter\').Definition.getDefinition();\n +\t\t\t\t\t\t\tif (filter != null) filter.apply(ctx, this);\n +\t\t\t\t\t\t}\n +\t\t\t\t\t\telse this.renderChildren(ctx);\t\t\t\t\n +\t\t\t\t\tthis.clearContext(ctx);\n +\t\t\t\tctx.restore();\n +\t\t\t}\n +\t\t\t\n +\t\t\t// base set context\n +\t\t\tthis.setContext = function(ctx) {\n +\t\t\t\t// OVERRIDE ME!\n +\t\t\t}\n +\t\t\t\n +\t\t\t// base clear context\n +\t\t\tthis.clearContext = function(ctx) {\n +\t\t\t\t// OVERRIDE ME!\n +\t\t\t}\t\t\t\n +\t\t\t\n +\t\t\t// base render children\n +\t\t\tthis.renderChildren = function(ctx) {\n +\t\t\t\tfor (var i=0; i<this.children.length; i++) {\n +\t\t\t\t\tthis.children[i].render(ctx);\n +\t\t\t\t}\n +\t\t\t}\n +\t\t\t\n +\t\t\tthis.addChild = function(childNode, create) {\n +\t\t\t\tvar child = childNode;\n +\t\t\t\tif (create) child = svg.CreateElement(childNode);\n +\t\t\t\tchild.parent = this;\n +\t\t\t\tthis.children.push(child);\t\t\t\n +\t\t\t}\n +\t\t\t\t\n +\t\t\tif (node != null && node.nodeType == 1) { //ELEMENT_NODE\n +\t\t\t\t// add children\n +\t\t\t\tfor (var i=0; i<node.childNodes.length; i++) {\n +\t\t\t\t\tvar childNode = node.childNodes[i];\n +\t\t\t\t\tif (childNode.nodeType == 1) this.addChild(childNode, true); //ELEMENT_NODE\n +\t\t\t\t}\n +\t\t\t\t\n +\t\t\t\t// add attributes\n +\t\t\t\tfor (var i=0; i<node.attributes.length; i++) {\n +\t\t\t\t\tvar attribute = node.attributes[i];\n +\t\t\t\t\tthis.attributes[attribute.nodeName] = new svg.Property(attribute.nodeName, attribute.nodeValue);\n +\t\t\t\t}\n +\t\t\t\t\t\t\t\t\t\t\n +\t\t\t\t// add tag styles\n +\t\t\t\tvar styles = svg.Styles[node.nodeName];\n +\t\t\t\tif (styles != null) {\n +\t\t\t\t\tfor (var name in styles) {\n +\t\t\t\t\t\tthis.styles[name] = styles[name];\n +\t\t\t\t\t}\n +\t\t\t\t}\t\t\t\t\t\n +\t\t\t\t\n +\t\t\t\t// add class styles\n +\t\t\t\tif (this.attribute(\'class\').hasValue()) {\n +\t\t\t\t\tvar classes = svg.compressSpaces(this.attribute(\'class\').value).split(\' \');\n +\t\t\t\t\tfor (var j=0; j<classes.length; j++) {\n +\t\t\t\t\t\tstyles = svg.Styles[\'.\'+classes[j]];\n +\t\t\t\t\t\tif (styles != null) {\n +\t\t\t\t\t\t\tfor (var name in styles) {\n +\t\t\t\t\t\t\t\tthis.styles[name] = styles[name];\n +\t\t\t\t\t\t\t}\n +\t\t\t\t\t\t}\n +\t\t\t\t\t\tstyles = svg.Styles[node.nodeName+\'.\'+classes[j]];\n +\t\t\t\t\t\tif (styles != null) {\n +\t\t\t\t\t\t\tfor (var name in styles) {\n +\t\t\t\t\t\t\t\tthis.styles[name] = styles[name];\n +\t\t\t\t\t\t\t}\n +\t\t\t\t\t\t}\n +\t\t\t\t\t}\n +\t\t\t\t}\n +\t\t\t\t\n +\t\t\t\t// add inline styles\n +\t\t\t\tif (this.attribute(\'style\').hasValue()) {\n +\t\t\t\t\tvar styles = this.attribute(\'style\').value.split(\';\');\n +\t\t\t\t\tfor (var i=0; i<styles.length; i++) {\n +\t\t\t\t\t\tif (svg.trim(styles[i]) != \'\') {\n +\t\t\t\t\t\t\tvar style = styles[i].split(\':\');\n +\t\t\t\t\t\t\tvar name = svg.trim(style[0]);\n +\t\t\t\t\t\t\tvar value = svg.trim(style[1]);\n +\t\t\t\t\t\t\tthis.styles[name] = new svg.Property(name, value);\n +\t\t\t\t\t\t}\n +\t\t\t\t\t}\n +\t\t\t\t}\t\n +\n +\t\t\t\t// add id\n +\t\t\t\tif (this.attribute(\'id\').hasValue()) {\n +\t\t\t\t\tif (svg.Definitions[this.attribute(\'id\').value] == null) {\n +\t\t\t\t\t\tsvg.Definitions[this.attribute(\'id\').value] = this;\n +\t\t\t\t\t}\n +\t\t\t\t}\n +\t\t\t}\n +\t\t}\n +\t\t\n +\t\tsvg.Element.RenderedElementBase = function(node) {\n +\t\t\tthis.base = svg.Element.ElementBase;\n +\t\t\tthis.base(node);\n +\t\t\t\n +\t\t\tthis.setContext = function(ctx) {\n +\t\t\t\t// fill\n +\t\t\t\tif (this.style(\'fill\').Definition.isUrl()) {\n +\t\t\t\t\tvar fs = this.style(\'fill\').Definition.getFillStyle(this);\n +\t\t\t\t\tif (fs != null) ctx.fillStyle = fs;\n +\t\t\t\t}\n +\t\t\t\telse if (this.style(\'fill\').hasValue()) {\n +\t\t\t\t\tvar fillStyle = this.style(\'fill\');\n +\t\t\t\t\tif (this.style(\'fill-opacity\').hasValue()) fillStyle = fillStyle.Color.addOpacity(this.style(\'fill-opacity\').value);\n +\t\t\t\t\tctx.fillStyle = (fillStyle.value == \'none\' ? \'rgba(0,0,0,0)\' : fillStyle.value);\n +\t\t\t\t}\n +\t\t\t\t\t\t\t\t\t\n +\t\t\t\t// stroke\n +\t\t\t\tif (this.style(\'stroke\').Definition.isUrl()) {\n +\t\t\t\t\tvar fs = this.style(\'stroke\').Definition.getFillStyle(this);\n +\t\t\t\t\tif (fs != null) ctx.strokeStyle = fs;\n +\t\t\t\t}\n +\t\t\t\telse if (this.style(\'stroke\').hasValue()) {\n +\t\t\t\t\tvar strokeStyle = this.style(\'stroke\');\n +\t\t\t\t\tif (this.style(\'stroke-opacity\').hasValue()) strokeStyle = strokeStyle.Color.addOpacity(this.style(\'stroke-opacity\').value);\n +\t\t\t\t\tctx.strokeStyle = (strokeStyle.value == \'none\' ? \'rgba(0,0,0,0)\' : strokeStyle.value);\n +\t\t\t\t}\n +\t\t\t\tif (this.style(\'stroke-width\').hasValue()) ctx.lineWidth = this.style(\'stroke-width\').Length.toPixels();\n +\t\t\t\tif (this.style(\'stroke-linecap\').hasValue()) ctx.lineCap = this.style(\'stroke-linecap\').value;\n +\t\t\t\tif (this.style(\'stroke-linejoin\').hasValue()) ctx.lineJoin = this.style(\'stroke-linejoin\').value;\n +\t\t\t\tif (this.style(\'stroke-miterlimit\').hasValue()) ctx.miterLimit = this.style(\'stroke-miterlimit\').value;\n +\n +\t\t\t\t// font\n +\t\t\t\tif (typeof(ctx.font) != \'undefined\') {\n +\t\t\t\t\tctx.font = svg.Font.CreateFont( \n +\t\t\t\t\t\tthis.style(\'font-style\').value, \n +\t\t\t\t\t\tthis.style(\'font-variant\').value, \n +\t\t\t\t\t\tthis.style(\'font-weight\').value, \n +\t\t\t\t\t\tthis.style(\'font-size\').hasValue() ? this.style(\'font-size\').Length.toPixels() + \'px\' : \'\', \n +\t\t\t\t\t\tthis.style(\'font-family\').value).toString();\n +\t\t\t\t}\n +\t\t\t\t\n +\t\t\t\t// transform\n +\t\t\t\tif (this.attribute(\'transform\').hasValue()) { \n +\t\t\t\t\tvar transform = new svg.Transform(this.attribute(\'transform\').value);\n +\t\t\t\t\ttransform.apply(ctx);\n +\t\t\t\t}\n +\t\t\t\t\n +\t\t\t\t// clip\n +\t\t\t\tif (this.attribute(\'clip-path\').hasValue()) {\n +\t\t\t\t\tvar clip = this.attribute(\'clip-path\').Definition.getDefinition();\n +\t\t\t\t\tif (clip != null) clip.apply(ctx);\n +\t\t\t\t}\n +\t\t\t\t\n +\t\t\t\t// opacity\n +\t\t\t\tif (this.style(\'opacity\').hasValue()) {\n +\t\t\t\t\tctx.globalAlpha = this.style(\'opacity\').numValue();\n +\t\t\t\t}\n +\t\t\t}\t\t\n +\t\t}\n +\t\tsvg.Element.RenderedElementBase.prototype = new svg.Element.ElementBase;\n +\t\t\n +\t\tsvg.Element.PathElementBase = function(node) {\n +\t\t\tthis.base = svg.Element.RenderedElementBase;\n +\t\t\tthis.base(node);\n +\t\t\t\n +\t\t\tthis.path = function(ctx) {\n +\t\t\t\tif (ctx != null) ctx.beginPath();\n +\t\t\t\treturn new svg.BoundingBox();\n +\t\t\t}\n +\t\t\t\n +\t\t\tthis.renderChildren = function(ctx) {\n +\t\t\t\tthis.path(ctx);\n +\t\t\t\tsvg.Mouse.checkPath(this, ctx);\n +\t\t\t\tif (ctx.fillStyle != \'\') ctx.fill();\n +\t\t\t\tif (ctx.strokeStyle != \'\') ctx.stroke();\n +\t\t\t\t\n +\t\t\t\tvar markers = this.getMarkers();\n +\t\t\t\tif (markers != null) {\n +\t\t\t\t\tif (this.style(\'marker-start\').Definition.isUrl()) {\n +\t\t\t\t\t\tvar marker = this.style(\'marker-start\').Definition.getDefinition();\n +\t\t\t\t\t\tmarker.render(ctx, markers[0][0], markers[0][1]);\n +\t\t\t\t\t}\n +\t\t\t\t\tif (this.style(\'marker-mid\').Definition.isUrl()) {\n +\t\t\t\t\t\tvar marker = this.style(\'marker-mid\').Definition.getDefinition();\n +\t\t\t\t\t\tfor (var i=1;i<markers.length-1;i++) {\n +\t\t\t\t\t\t\tmarker.render(ctx, markers[i][0], markers[i][1]);\n +\t\t\t\t\t\t}\n +\t\t\t\t\t}\n +\t\t\t\t\tif (this.style(\'marker-end\').Definition.isUrl()) {\n +\t\t\t\t\t\tvar marker = this.style(\'marker-end\').Definition.getDefinition();\n +\t\t\t\t\t\tmarker.render(ctx, markers[markers.length-1][0], markers[markers.length-1][1]);\n +\t\t\t\t\t}\n +\t\t\t\t}\t\t\t\t\t\n +\t\t\t}\n +\t\t\t\n +\t\t\tthis.getBoundingBox = function() {\n +\t\t\t\treturn this.path();\n +\t\t\t}\n +\t\t\t\n +\t\t\tthis.getMarkers = function() {\n +\t\t\t\treturn null;\n +\t\t\t}\n +\t\t}\n +\t\tsvg.Element.PathElementBase.prototype = new svg.Element.RenderedElementBase;\n +\t\t\n +\t\t// svg element\n +\t\tsvg.Element.svg = function(node) {\n +\t\t\tthis.base = svg.Element.RenderedElementBase;\n +\t\t\tthis.base(node);\n +\t\t\t\n +\t\t\tthis.baseClearContext = this.clearContext;\n +\t\t\tthis.clearContext = function(ctx) {\n +\t\t\t\tthis.baseClearContext(ctx);\n +\t\t\t\tsvg.ViewPort.RemoveCurrent();\n +\t\t\t}\n +\t\t\t\n +\t\t\tthis.baseSetContext = this.setContext;\n +\t\t\tthis.setContext = function(ctx) {\n +\t\t\t\t// initial values\n +\t\t\t\tctx.strokeStyle = \'rgba(0,0,0,0)\';\n +\t\t\t\tctx.lineCap = \'butt\';\n +\t\t\t\tctx.lineJoin = \'miter\';\n +\t\t\t\tctx.miterLimit = 4;\t\t\t\n +\t\t\t\n +\t\t\t\tthis.baseSetContext(ctx);\n +\t\t\t\t\n +\t\t\t\t// create new view port\n +\t\t\t\tif (this.attribute(\'x\').hasValue() && this.attribute(\'y\').hasValue()) {\n +\t\t\t\t\tctx.translate(this.attribute(\'x\').Length.toPixels(\'x\'), this.attribute(\'y\').Length.toPixels(\'y\'));\n +\t\t\t\t}\n +\t\t\t\t\n +\t\t\t\tvar width = svg.ViewPort.width();\n +\t\t\t\tvar height = svg.ViewPort.height();\n +\t\t\t\tif (typeof(this.root) == \'undefined\' && this.attribute(\'width\').hasValue() && this.attribute(\'height\').hasValue()) {\n +\t\t\t\t\twidth = this.attribute(\'width\').Length.toPixels(\'x\');\n +\t\t\t\t\theight = this.attribute(\'height\').Length.toPixels(\'y\');\n +\t\t\t\t\t\n +\t\t\t\t\tvar x = 0;\n +\t\t\t\t\tvar y = 0;\n +\t\t\t\t\tif (this.attribute(\'refX\').hasValue() && this.attribute(\'refY\').hasValue()) {\n +\t\t\t\t\t\tx = -this.attribute(\'refX\').Length.toPixels(\'x\');\n +\t\t\t\t\t\ty = -this.attribute(\'refY\').Length.toPixels(\'y\');\n +\t\t\t\t\t}\n +\t\t\t\t\t\n +\t\t\t\t\tctx.beginPath();\n +\t\t\t\t\tctx.moveTo(x, y);\n +\t\t\t\t\tctx.lineTo(width, y);\n +\t\t\t\t\tctx.lineTo(width, height);\n +\t\t\t\t\tctx.lineTo(x, height);\n +\t\t\t\t\tctx.closePath();\n +\t\t\t\t\tctx.clip();\n +\t\t\t\t}\n +\t\t\t\tsvg.ViewPort.SetCurrent(width, height);\t\n +\t\t\t\t\t\t\n +\t\t\t\t// viewbox\n +\t\t\t\tif (this.attribute(\'viewBox\').hasValue()) {\t\t\t\t\n +\t\t\t\t\tvar viewBox = svg.ToNumberArray(this.attribute(\'viewBox\').value);\n +\t\t\t\t\tvar minX = viewBox[0];\n +\t\t\t\t\tvar minY = viewBox[1];\n +\t\t\t\t\twidth = viewBox[2];\n +\t\t\t\t\theight = viewBox[3];\n +\t\t\t\t\t\n +\t\t\t\t\tsvg.AspectRatio(ctx,\n +\t\t\t\t\t\t\t\t\tthis.attribute(\'preserveAspectRatio\').value, \n +\t\t\t\t\t\t\t\t\tsvg.ViewPort.width(), \n +\t\t\t\t\t\t\t\t\twidth,\n +\t\t\t\t\t\t\t\t\tsvg.ViewPort.height(),\n +\t\t\t\t\t\t\t\t\theight,\n +\t\t\t\t\t\t\t\t\tminX,\n +\t\t\t\t\t\t\t\t\tminY,\n +\t\t\t\t\t\t\t\t\tthis.attribute(\'refX\').value,\n +\t\t\t\t\t\t\t\t\tthis.attribute(\'refY\').value);\n +\t\t\t\t\t\t\t\t\t\t\n +\t\t\t\t\tsvg.ViewPort.RemoveCurrent();\t\n +\t\t\t\t\tsvg.ViewPort.SetCurrent(viewBox[2], viewBox[3]);\t\t\t\t\t\t\n +\t\t\t\t}\t\t\t\t\n +\t\t\t}\n +\t\t}\n +\t\tsvg.Element.svg.prototype = new svg.Element.RenderedElementBase;\n +\n +\t\t// rect element\n +\t\tsvg.Element.rect = function(node) {\n +\t\t\tthis.base = svg.Element.PathElementBase;\n +\t\t\tthis.base(node);\n +\t\t\t\n +\t\t\tthis.path = function(ctx) {\n +\t\t\t\tvar x = this.attribute(\'x\').Length.toPixels(\'x\');\n +\t\t\t\tvar y = this.attribute(\'y\').Length.toPixels(\'y\');\n +\t\t\t\tvar width = this.attribute(\'width\').Length.toPixels(\'x\');\n +\t\t\t\tvar height = this.attribute(\'height\').Length.toPixels(\'y\');\n +\t\t\t\tvar rx = this.attribute(\'rx\').Length.toPixels(\'x\');\n +\t\t\t\tvar ry = this.attribute(\'ry\').Length.toPixels(\'y\');\n +\t\t\t\tif (this.attribute(\'rx\').hasValue() && !this.attribute(\'ry\').hasValue()) ry = rx;\n +\t\t\t\tif (this.attribute(\'ry\').hasValue() && !this.attribute(\'rx\').hasValue()) rx = ry;\n +\t\t\t\t\n +\t\t\t\tif (ctx != null) {\n +\t\t\t\t\tctx.beginPath();\n +\t\t\t\t\tctx.moveTo(x + rx, y);\n +\t\t\t\t\tctx.lineTo(x + width - rx, y);\n +\t\t\t\t\tctx.quadraticCurveTo(x + width, y, x + width, y + ry)\n +\t\t\t\t\tctx.lineTo(x + width, y + height - ry);\n +\t\t\t\t\tctx.quadraticCurveTo(x + width, y + height, x + width - rx, y + height)\n +\t\t\t\t\tctx.lineTo(x + rx, y + height);\n +\t\t\t\t\tctx.quadraticCurveTo(x, y + height, x, y + height - ry)\n +\t\t\t\t\tctx.lineTo(x, y + ry);\n +\t\t\t\t\tctx.quadraticCurveTo(x, y, x + rx, y)\n +\t\t\t\t\tctx.closePath();\n +\t\t\t\t}\n +\t\t\t\t\n +\t\t\t\treturn new svg.BoundingBox(x, y, x + width, y + height);\n +\t\t\t}\n +\t\t}\n +\t\tsvg.Element.rect.prototype = new svg.Element.PathElementBase;\n +\t\t\n +\t\t// circle element\n +\t\tsvg.Element.circle = function(node) {\n +\t\t\tthis.base = svg.Element.PathElementBase;\n +\t\t\tthis.base(node);\n +\t\t\t\n +\t\t\tthis.path = function(ctx) {\n +\t\t\t\tvar cx = this.attribute(\'cx\').Length.toPixels(\'x\');\n +\t\t\t\tvar cy = this.attribute(\'cy\').Length.toPixels(\'y\');\n +\t\t\t\tvar r = this.attribute(\'r\').Length.toPixels();\n +\t\t\t\n +\t\t\t\tif (ctx != null) {\n +\t\t\t\t\tctx.beginPath();\n +\t\t\t\t\tctx.arc(cx, cy, r, 0, Math.PI * 2, true); \n +\t\t\t\t\tctx.closePath();\n +\t\t\t\t}\n +\t\t\t\t\n +\t\t\t\treturn new svg.BoundingBox(cx - r, cy - r, cx + r, cy + r);\n +\t\t\t}\n +\t\t}\n +\t\tsvg.Element.circle.prototype = new svg.Element.PathElementBase;\t\n +\n +\t\t// ellipse element\n +\t\tsvg.Element.ellipse = function(node) {\n +\t\t\tthis.base = svg.Element.PathElementBase;\n +\t\t\tthis.base(node);\n +\t\t\t\n +\t\t\tthis.path = function(ctx) {\n +\t\t\t\tvar KAPPA = 4 * ((Math.sqrt(2) - 1) / 3);\n +\t\t\t\tvar rx = this.attribute(\'rx\').Length.toPixels(\'x\');\n +\t\t\t\tvar ry = this.attribute(\'ry\').Length.toPixels(\'y\');\n +\t\t\t\tvar cx = this.attribute(\'cx\').Length.toPixels(\'x\');\n +\t\t\t\tvar cy = this.attribute(\'cy\').Length.toPixels(\'y\');\n +\t\t\t\t\n +\t\t\t\tif (ctx != null) {\n +\t\t\t\t\tctx.beginPath();\n +\t\t\t\t\tctx.moveTo(cx, cy - ry);\n +\t\t\t\t\tctx.bezierCurveTo(cx + (KAPPA * rx), cy - ry, cx + rx, cy - (KAPPA * ry), cx + rx, cy);\n +\t\t\t\t\tctx.bezierCurveTo(cx + rx, cy + (KAPPA * ry), cx + (KAPPA * rx), cy + ry, cx, cy + ry);\n +\t\t\t\t\tctx.bezierCurveTo(cx - (KAPPA * rx), cy + ry, cx - rx, cy + (KAPPA * ry), cx - rx, cy);\n +\t\t\t\t\tctx.bezierCurveTo(cx - rx, cy - (KAPPA * ry), cx - (KAPPA * rx), cy - ry, cx, cy - ry);\n +\t\t\t\t\tctx.closePath();\n +\t\t\t\t}\n +\t\t\t\t\n +\t\t\t\treturn new svg.BoundingBox(cx - rx, cy - ry, cx + rx, cy + ry);\n +\t\t\t}\n +\t\t}\n +\t\tsvg.Element.ellipse.prototype = new svg.Element.PathElementBase;\t\t\t\n +\t\t\n +\t\t// line element\n +\t\tsvg.Element.line = function(node) {\n +\t\t\tthis.base = svg.Element.PathElementBase;\n +\t\t\tthis.base(node);\n +\t\t\t\n +\t\t\tthis.getPoints = function() {\n +\t\t\t\treturn [\n +\t\t\t\t\tnew svg.Point(this.attribute(\'x1\').Length.toPixels(\'x\'), this.attribute(\'y1\').Length.toPixels(\'y\')),\n +\t\t\t\t\tnew svg.Point(this.attribute(\'x2\').Length.toPixels(\'x\'), this.attribute(\'y2\').Length.toPixels(\'y\'))];\n +\t\t\t}\n +\t\t\t\t\t\t\t\t\n +\t\t\tthis.path = function(ctx) {\n +\t\t\t\tvar points = this.getPoints();\n +\t\t\t\t\n +\t\t\t\tif (ctx != null) {\n +\t\t\t\t\tctx.beginPath();\n +\t\t\t\t\tctx.moveTo(points[0].x, points[0].y);\n +\t\t\t\t\tctx.lineTo(points[1].x, points[1].y);\n +\t\t\t\t}\n +\t\t\t\t\n +\t\t\t\treturn new svg.BoundingBox(points[0].x, points[0].y, points[1].x, points[1].y);\n +\t\t\t}\n +\t\t\t\n +\t\t\tthis.getMarkers = function() {\n +\t\t\t\tvar points = this.getPoints();\t\n +\t\t\t\tvar a = points[0].angleTo(points[1]);\n +\t\t\t\treturn [[points[0], a], [points[1], a]];\n +\t\t\t}\n +\t\t}\n +\t\tsvg.Element.line.prototype = new svg.Element.PathElementBase;\t\t\n +\t\t\t\t\n +\t\t// polyline element\n +\t\tsvg.Element.polyline = function(node) {\n +\t\t\tthis.base = svg.Element.PathElementBase;\n +\t\t\tthis.base(node);\n +\t\t\t\n +\t\t\tthis.points = svg.CreatePath(this.attribute(\'points\').value);\n +\t\t\tthis.path = function(ctx) {\n +\t\t\t\tvar bb = new svg.BoundingBox(this.points[0].x, this.points[0].y);\n +\t\t\t\tif (ctx != null) {\n +\t\t\t\t\tctx.beginPath();\n +\t\t\t\t\tctx.moveTo(this.points[0].x, this.points[0].y);\n +\t\t\t\t}\n +\t\t\t\tfor (var i=1; i<this.points.length; i++) {\n +\t\t\t\t\tbb.addPoint(this.points[i].x, this.points[i].y);\n +\t\t\t\t\tif (ctx != null) ctx.lineTo(this.points[i].x, this.points[i].y);\n +\t\t\t\t}\n +\t\t\t\treturn bb;\n +\t\t\t}\n +\t\t\t\n +\t\t\tthis.getMarkers = function() {\n +\t\t\t\tvar markers = [];\n +\t\t\t\tfor (var i=0; i<this.points.length - 1; i++) {\n +\t\t\t\t\tmarkers.push([this.points[i], this.points[i].angleTo(this.points[i+1])]);\n +\t\t\t\t}\n +\t\t\t\tmarkers.push([this.points[this.points.length-1], markers[markers.length-1][1]]);\n +\t\t\t\treturn markers;\n +\t\t\t}\t\t\t\n +\t\t}\n +\t\tsvg.Element.polyline.prototype = new svg.Element.PathElementBase;\t\t\t\t\n +\t\t\t\t\n +\t\t// polygon element\n +\t\tsvg.Element.polygon = function(node) {\n +\t\t\tthis.base = svg.Element.polyline;\n +\t\t\tthis.base(node);\n +\t\t\t\n +\t\t\tthis.basePath = this.path;\n +\t\t\tthis.path = function(ctx) {\n +\t\t\t\tvar bb = this.basePath(ctx);\n +\t\t\t\tif (ctx != null) {\n +\t\t\t\t\tctx.lineTo(this.points[0].x, this.points[0].y);\n +\t\t\t\t\tctx.closePath();\n +\t\t\t\t}\n +\t\t\t\treturn bb;\n +\t\t\t}\n +\t\t}\n +\t\tsvg.Element.polygon.prototype = new svg.Element.polyline;\n +\n +\t\t// path element\n +\t\tsvg.Element.path = function(node) {\n +\t\t\tthis.base = svg.Element.PathElementBase;\n +\t\t\tthis.base(node);\n +\t\t\t\t\t\n +\t\t\tvar d = this.attribute(\'d\').value;\n +\t\t\t// TODO: convert to real lexer based on http://www.w3.org/TR/SVG11/paths.html#PathDataBNF\n +\t\t\td = d.replace(/,/gm,\' \'); // get rid of all commas\n +\t\t\td = d.replace(/([MmZzLlHhVvCcSsQqTtAa])([MmZzLlHhVvCcSsQqTtAa])/gm,\'$1 $2\'); // separate commands from commands\n +\t\t\td = d.replace(/([MmZzLlHhVvCcSsQqTtAa])([MmZzLlHhVvCcSsQqTtAa])/gm,\'$1 $2\'); // separate commands from commands\n +\t\t\td = d.replace(/([MmZzLlHhVvCcSsQqTtAa])([^\\s])/gm,\'$1 $2\'); // separate commands from points\n +\t\t\td = d.replace(/([^\\s])([MmZzLlHhVvCcSsQqTtAa])/gm,\'$1 $2\'); // separate commands from points\n +\t\t\td = d.replace(/([0-9])([+\\-])/gm,\'$1 $2\'); // separate digits when no comma\n +\t\t\td = d.replace(/(\\.[0-9]*)(\\.)/gm,\'$1 $2\'); // separate digits when no comma\n +\t\t\td = d.replace(/([Aa](\\s+[0-9]+){3})\\s+([01])\\s*([01])/gm,\'$1 $3 $4 \'); // shorthand elliptical arc path syntax\n +\t\t\td = svg.compressSpaces(d); // compress multiple spaces\n +\t\t\td = svg.trim(d);\n +\t\t\tthis.PathParser = new (function(d) {\n +\t\t\t\tthis.tokens = d.split(\' \');\n +\t\t\t\t\n +\t\t\t\tthis.reset = function() {\n +\t\t\t\t\tthis.i = -1;\n +\t\t\t\t\tthis.command = \'\';\n +\t\t\t\t\tthis.previousCommand = \'\';\n +\t\t\t\t\tthis.start = new svg.Point(0, 0);\n +\t\t\t\t\tthis.control = new svg.Point(0, 0);\n +\t\t\t\t\tthis.current = new svg.Point(0, 0);\n +\t\t\t\t\tthis.points = [];\n +\t\t\t\t\tthis.angles = [];\n +\t\t\t\t}\n +\t\t\t\t\t\t\t\t\n +\t\t\t\tthis.isEnd = function() {\n +\t\t\t\t\treturn this.i >= this.tokens.length - 1;\n +\t\t\t\t}\n +\t\t\t\t\n +\t\t\t\tthis.isCommandOrEnd = function() {\n +\t\t\t\t\tif (this.isEnd()) return true;\n +\t\t\t\t\treturn this.tokens[this.i + 1].match(/^[A-Za-z]$/) != null;\n +\t\t\t\t}\n +\t\t\t\t\n +\t\t\t\tthis.isRelativeCommand = function() {\n +\t\t\t\t\treturn this.command == this.command.toLowerCase();\n +\t\t\t\t}\n +\t\t\t\t\t\t\t\n +\t\t\t\tthis.getToken = function() {\n +\t\t\t\t\tthis.i = this.i + 1;\n +\t\t\t\t\treturn this.tokens[this.i];\n +\t\t\t\t}\n +\t\t\t\t\n +\t\t\t\tthis.getScalar = function() {\n +\t\t\t\t\treturn parseFloat(this.getToken());\n +\t\t\t\t}\n +\t\t\t\t\n +\t\t\t\tthis.nextCommand = function() {\n +\t\t\t\t\tthis.previousCommand = this.command;\n +\t\t\t\t\tthis.command = this.getToken();\n +\t\t\t\t}\t\t\t\t\n +\t\t\t\t\n +\t\t\t\tthis.getPoint = function() {\n +\t\t\t\t\tvar p = new svg.Point(this.getScalar(), this.getScalar());\n +\t\t\t\t\treturn this.makeAbsolute(p);\n +\t\t\t\t}\n +\t\t\t\t\n +\t\t\t\tthis.getAsControlPoint = function() {\n +\t\t\t\t\tvar p = this.getPoint();\n +\t\t\t\t\tthis.control = p;\n +\t\t\t\t\treturn p;\n +\t\t\t\t}\n +\t\t\t\t\n +\t\t\t\tthis.getAsCurrentPoint = function() {\n +\t\t\t\t\tvar p = this.getPoint();\n +\t\t\t\t\tthis.current = p;\n +\t\t\t\t\treturn p;\t\n +\t\t\t\t}\n +\t\t\t\t\n +\t\t\t\tthis.getReflectedControlPoint = function() {\n +\t\t\t\t\tif (this.previousCommand.toLowerCase() != \'c\' && this.previousCommand.toLowerCase() != \'s\') {\n +\t\t\t\t\t\treturn this.current;\n +\t\t\t\t\t}\n +\t\t\t\t\t\n +\t\t\t\t\t// reflect point\n +\t\t\t\t\tvar p = new svg.Point(2 * this.current.x - this.control.x, 2 * this.current.y - this.control.y);\t\t\t\t\t\n +\t\t\t\t\treturn p;\n +\t\t\t\t}\n +\t\t\t\t\n +\t\t\t\tthis.makeAbsolute = function(p) {\n +\t\t\t\t\tif (this.isRelativeCommand()) {\n +\t\t\t\t\t\tp.x = this.current.x + p.x;\n +\t\t\t\t\t\tp.y = this.current.y + p.y;\n +\t\t\t\t\t}\n +\t\t\t\t\treturn p;\n +\t\t\t\t}\n +\t\t\t\t\n +\t\t\t\tthis.addMarker = function(p, from, priorTo) {\n +\t\t\t\t\t// if the last angle isn\'t filled in because we didn\'t have this point yet ...\n +\t\t\t\t\tif (priorTo != null && this.angles.length > 0 && this.angles[this.angles.length-1] == null) {\n +\t\t\t\t\t\tthis.angles[this.angles.length-1] = this.points[this.points.length-1].angleTo(priorTo);\n +\t\t\t\t\t}\n +\t\t\t\t\tthis.addMarkerAngle(p, from == null ? null : from.angleTo(p));\n +\t\t\t\t}\n +\t\t\t\t\n +\t\t\t\tthis.addMarkerAngle = function(p, a) {\n +\t\t\t\t\tthis.points.push(p);\n +\t\t\t\t\tthis.angles.push(a);\n +\t\t\t\t}\t\t\t\t\n +\t\t\t\t\n +\t\t\t\tthis.getMarkerPoints = function() { return this.points; }\n +\t\t\t\tthis.getMarkerAngles = function() {\n +\t\t\t\t\tfor (var i=0; i<this.angles.length; i++) {\n +\t\t\t\t\t\tif (this.angles[i] == null) {\n +\t\t\t\t\t\t\tfor (var j=i+1; j<this.angles.length; j++) {\n +\t\t\t\t\t\t\t\tif (this.angles[j] != null) {\n +\t\t\t\t\t\t\t\t\tthis.angles[i] = this.angles[j];\n +\t\t\t\t\t\t\t\t\tbreak;\n +\t\t\t\t\t\t\t\t}\n +\t\t\t\t\t\t\t}\n +\t\t\t\t\t\t}\n +\t\t\t\t\t}\n +\t\t\t\t\treturn this.angles;\n +\t\t\t\t}\n +\t\t\t})(d);\n +\n +\t\t\tthis.path = function(ctx) {\n +\t\t\t\tvar pp = this.PathParser;\n +\t\t\t\tpp.reset();\n +\n +\t\t\t\tvar bb = new svg.BoundingBox();\n +\t\t\t\tif (ctx != null) ctx.beginPath();\n +\t\t\t\twhile (!pp.isEnd()) {\n +\t\t\t\t\tpp.nextCommand();\n +\t\t\t\t\tswitch (pp.command.toUpperCase()) {\n +\t\t\t\t\tcase \'M\':\n +\t\t\t\t\t\tvar p = pp.getAsCurrentPoint();\n +\t\t\t\t\t\tpp.addMarker(p);\n +\t\t\t\t\t\tbb.addPoint(p.x, p.y);\n +\t\t\t\t\t\tif (ctx != null) ctx.moveTo(p.x, p.y);\n +\t\t\t\t\t\tpp.start = pp.current;\n +\t\t\t\t\t\twhile (!pp.isCommandOrEnd()) {\n +\t\t\t\t\t\t\tvar p = pp.getAsCurrentPoint();\n +\t\t\t\t\t\t\tpp.addMarker(p, pp.start);\n +\t\t\t\t\t\t\tbb.addPoint(p.x, p.y);\n +\t\t\t\t\t\t\tif (ctx != null) ctx.lineTo(p.x, p.y);\n +\t\t\t\t\t\t}\n +\t\t\t\t\t\tbreak;\n +\t\t\t\t\tcase \'L\':\n +\t\t\t\t\t\twhile (!pp.isCommandOrEnd()) {\n +\t\t\t\t\t\t\tvar c = pp.current;\n +\t\t\t\t\t\t\tvar p = pp.getAsCurrentPoint();\n +\t\t\t\t\t\t\tpp.addMarker(p, c);\n +\t\t\t\t\t\t\tbb.addPoint(p.x, p.y);\n +\t\t\t\t\t\t\tif (ctx != null) ctx.lineTo(p.x, p.y);\n +\t\t\t\t\t\t}\n +\t\t\t\t\t\tbreak;\n +\t\t\t\t\tcase \'H\':\n +\t\t\t\t\t\twhile (!pp.isCommandOrEnd()) {\n +\t\t\t\t\t\t\tvar newP = new svg.Point((pp.isRelativeCommand() ? pp.current.x : 0) + pp.getScalar(), pp.current.y);\n +\t\t\t\t\t\t\tpp.addMarker(newP, pp.current);\n +\t\t\t\t\t\t\tpp.current = newP;\n +\t\t\t\t\t\t\tbb.addPoint(pp.current.x, pp.current.y);\n +\t\t\t\t\t\t\tif (ctx != null) ctx.lineTo(pp.current.x, pp.current.y);\n +\t\t\t\t\t\t}\n +\t\t\t\t\t\tbreak;\n +\t\t\t\t\tcase \'V\':\n +\t\t\t\t\t\twhile (!pp.isCommandOrEnd()) {\n +\t\t\t\t\t\t\tvar newP = new svg.Point(pp.current.x, (pp.isRelativeCommand() ? pp.current.y : 0) + pp.getScalar());\n +\t\t\t\t\t\t\tpp.addMarker(newP, pp.current);\n +\t\t\t\t\t\t\tpp.current = newP;\n +\t\t\t\t\t\t\tbb.addPoint(pp.current.x, pp.current.y);\n +\t\t\t\t\t\t\tif (ctx != null) ctx.lineTo(pp.current.x, pp.current.y);\n +\t\t\t\t\t\t}\n +\t\t\t\t\t\tbreak;\n +\t\t\t\t\tcase \'C\':\n +\t\t\t\t\t\twhile (!pp.isCommandOrEnd()) {\n +\t\t\t\t\t\t\tvar curr = pp.current;\n +\t\t\t\t\t\t\tvar p1 = pp.getPoint();\n +\t\t\t\t\t\t\tvar cntrl = pp.getAsControlPoint();\n +\t\t\t\t\t\t\tvar cp = pp.getAsCurrentPoint();\n +\t\t\t\t\t\t\tpp.addMarker(cp, cntrl, p1);\n +\t\t\t\t\t\t\tbb.addBezierCurve(curr.x, curr.y, p1.x, p1.y, cntrl.x, cntrl.y, cp.x, cp.y);\n +\t\t\t\t\t\t\tif (ctx != null) ctx.bezierCurveTo(p1.x, p1.y, cntrl.x, cntrl.y, cp.x, cp.y);\n +\t\t\t\t\t\t}\n +\t\t\t\t\t\tbreak;\n +\t\t\t\t\tcase \'S\':\n +\t\t\t\t\t\twhile (!pp.isCommandOrEnd()) {\n +\t\t\t\t\t\t\tvar curr = pp.current;\n +\t\t\t\t\t\t\tvar p1 = pp.getReflectedControlPoint();\n +\t\t\t\t\t\t\tvar cntrl = pp.getAsControlPoint();\n +\t\t\t\t\t\t\tvar cp = pp.getAsCurrentPoint();\n +\t\t\t\t\t\t\tpp.addMarker(cp, cntrl, p1);\n +\t\t\t\t\t\t\tbb.addBezierCurve(curr.x, curr.y, p1.x, p1.y, cntrl.x, cntrl.y, cp.x, cp.y);\n +\t\t\t\t\t\t\tif (ctx != null) ctx.bezierCurveTo(p1.x, p1.y, cntrl.x, cntrl.y, cp.x, cp.y);\n +\t\t\t\t\t\t}\n +\t\t\t\t\t\tbreak;\n +\t\t\t\t\tcase \'Q\':\n +\t\t\t\t\t\twhile (!pp.isCommandOrEnd()) {\n +\t\t\t\t\t\t\tvar curr = pp.current;\n +\t\t\t\t\t\t\tvar cntrl = pp.getAsControlPoint();\n +\t\t\t\t\t\t\tvar cp = pp.getAsCurrentPoint();\n +\t\t\t\t\t\t\tpp.addMarker(cp, cntrl, cntrl);\n +\t\t\t\t\t\t\tbb.addQuadraticCurve(curr.x, curr.y, cntrl.x, cntrl.y, cp.x, cp.y);\n +\t\t\t\t\t\t\tif (ctx != null) ctx.quadraticCurveTo(cntrl.x, cntrl.y, cp.x, cp.y);\n +\t\t\t\t\t\t}\n +\t\t\t\t\t\tbreak;\n +\t\t\t\t\tcase \'T\':\n +\t\t\t\t\t\twhile (!pp.isCommandOrEnd()) {\n +\t\t\t\t\t\t\tvar curr = pp.current;\n +\t\t\t\t\t\t\tvar cntrl = pp.getReflectedControlPoint();\n +\t\t\t\t\t\t\tpp.control = cntrl;\n +\t\t\t\t\t\t\tvar cp = pp.getAsCurrentPoint();\n +\t\t\t\t\t\t\tpp.addMarker(cp, cntrl, cntrl);\n +\t\t\t\t\t\t\tbb.addQuadraticCurve(curr.x, curr.y, cntrl.x, cntrl.y, cp.x, cp.y);\n +\t\t\t\t\t\t\tif (ctx != null) ctx.quadraticCurveTo(cntrl.x, cntrl.y, cp.x, cp.y);\n +\t\t\t\t\t\t}\n +\t\t\t\t\t\tbreak;\n +\t\t\t\t\tcase \'A\':\n +\t\t\t\t\t\twhile (!pp.isCommandOrEnd()) {\n +\t\t\t\t\t\t var curr = pp.current;\n +\t\t\t\t\t\t\tvar rx = pp.getScalar();\n +\t\t\t\t\t\t\tvar ry = pp.getScalar();\n +\t\t\t\t\t\t\tvar xAxisRotation = pp.getScalar() * (Math.PI / 180.0);\n +\t\t\t\t\t\t\tvar largeArcFlag = pp.getScalar();\n +\t\t\t\t\t\t\tvar sweepFlag = pp.getScalar();\n +\t\t\t\t\t\t\tvar cp = pp.getAsCurrentPoint();\n +\n +\t\t\t\t\t\t\t// Conversion from endpoint to center parameterization\n +\t\t\t\t\t\t\t// http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes\n +\t\t\t\t\t\t\t// x1\', y1\'\n +\t\t\t\t\t\t\tvar currp = new svg.Point(\n +\t\t\t\t\t\t\t\tMath.cos(xAxisRotation) * (curr.x - cp.x) / 2.0 + Math.sin(xAxisRotation) * (curr.y - cp.y) / 2.0,\n +\t\t\t\t\t\t\t\t-Math.sin(xAxisRotation) * (curr.x - cp.x) / 2.0 + Math.cos(xAxisRotation) * (curr.y - cp.y) / 2.0\n +\t\t\t\t\t\t\t);\n +\t\t\t\t\t\t\t// adjust radii\n +\t\t\t\t\t\t\tvar l = Math.pow(currp.x,2)/Math.pow(rx,2)+Math.pow(currp.y,2)/Math.pow(ry,2);\n +\t\t\t\t\t\t\tif (l > 1) {\n +\t\t\t\t\t\t\t\trx *= Math.sqrt(l);\n +\t\t\t\t\t\t\t\try *= Math.sqrt(l);\n +\t\t\t\t\t\t\t}\n +\t\t\t\t\t\t\t// cx\', cy\'\n +\t\t\t\t\t\t\tvar s = (largeArcFlag == sweepFlag ? -1 : 1) * Math.sqrt(\n +\t\t\t\t\t\t\t\t((Math.pow(rx,2)*Math.pow(ry,2))-(Math.pow(rx,2)*Math.pow(currp.y,2))-(Math.pow(ry,2)*Math.pow(currp.x,2))) /\n +\t\t\t\t\t\t\t\t(Math.pow(rx,2)*Math.pow(currp.y,2)+Math.pow(ry,2)*Math.pow(currp.x,2))\n +\t\t\t\t\t\t\t);\n +\t\t\t\t\t\t\tif (isNaN(s)) s = 0;\n +\t\t\t\t\t\t\tvar cpp = new svg.Point(s * rx * currp.y / ry, s * -ry * currp.x / rx);\n +\t\t\t\t\t\t\t// cx, cy\n +\t\t\t\t\t\t\tvar centp = new svg.Point(\n +\t\t\t\t\t\t\t\t(curr.x + cp.x) / 2.0 + Math.cos(xAxisRotation) * cpp.x - Math.sin(xAxisRotation) * cpp.y,\n +\t\t\t\t\t\t\t\t(curr.y + cp.y) / 2.0 + Math.sin(xAxisRotation) * cpp.x + Math.cos(xAxisRotation) * cpp.y\n +\t\t\t\t\t\t\t);\n +\t\t\t\t\t\t\t// vector magnitude\n +\t\t\t\t\t\t\tvar m = function(v) { return Math.sqrt(Math.pow(v[0],2) + Math.pow(v[1],2)); }\n +\t\t\t\t\t\t\t// ratio between two vectors\n +\t\t\t\t\t\t\tvar r = function(u, v) { return (u[0]*v[0]+u[1]*v[1]) / (m(u)*m(v)) }\n +\t\t\t\t\t\t\t// angle between two vectors\n +\t\t\t\t\t\t\tvar a = function(u, v) { return (u[0]*v[1] < u[1]*v[0] ? -1 : 1) * Math.acos(r(u,v)); }\n +\t\t\t\t\t\t\t// initial angle\n +\t\t\t\t\t\t\tvar a1 = a([1,0], [(currp.x-cpp.x)/rx,(currp.y-cpp.y)/ry]);\n +\t\t\t\t\t\t\t// angle delta\n +\t\t\t\t\t\t\tvar u = [(currp.x-cpp.x)/rx,(currp.y-cpp.y)/ry];\n +\t\t\t\t\t\t\tvar v = [(-currp.x-cpp.x)/rx,(-currp.y-cpp.y)/ry];\n +\t\t\t\t\t\t\tvar ad = a(u, v);\n +\t\t\t\t\t\t\tif (r(u,v) <= -1) ad = Math.PI;\n +\t\t\t\t\t\t\tif (r(u,v) >= 1) ad = 0;\n +\n +\t\t\t\t\t\t\tif (sweepFlag == 0 && ad > 0) ad = ad - 2 * Math.PI;\n +\t\t\t\t\t\t\tif (sweepFlag == 1 && ad < 0) ad = ad + 2 * Math.PI;\n +\n +\t\t\t\t\t\t\t// for markers\n +\t\t\t\t\t\t\tvar halfWay = new svg.Point(\n +\t\t\t\t\t\t\t\tcentp.x - rx * Math.cos((a1 + ad) / 2),\n +\t\t\t\t\t\t\t\tcentp.y - ry * Math.sin((a1 + ad) / 2)\n +\t\t\t\t\t\t\t);\n +\t\t\t\t\t\t\tpp.addMarkerAngle(halfWay, (a1 + ad) / 2 + (sweepFlag == 0 ? 1 : -1) * Math.PI / 2);\n +\t\t\t\t\t\t\tpp.addMarkerAngle(cp, ad + (sweepFlag == 0 ? 1 : -1) * Math.PI / 2);\n +\n +\t\t\t\t\t\t\tbb.addPoint(cp.x, cp.y); // TODO: this is too naive, make it better\n +\t\t\t\t\t\t\tif (ctx != null) {\n +\t\t\t\t\t\t\t\tvar r = rx > ry ? rx : ry;\n +\t\t\t\t\t\t\t\tvar sx = rx > ry ? 1 : rx / ry;\n +\t\t\t\t\t\t\t\tvar sy = rx > ry ? ry / rx : 1;\n +\n +\t\t\t\t\t\t\t\tctx.translate(centp.x, centp.y);\n +\t\t\t\t\t\t\t\tctx.rotate(xAxisRotation);\n +\t\t\t\t\t\t\t\tctx.scale(sx, sy);\n +\t\t\t\t\t\t\t\tctx.arc(0, 0, r, a1, a1 + ad, 1 - sweepFlag);\n +\t\t\t\t\t\t\t\tctx.scale(1/sx, 1/sy);\n +\t\t\t\t\t\t\t\tctx.rotate(-xAxisRotation);\n +\t\t\t\t\t\t\t\tctx.translate(-centp.x, -centp.y);\n +\t\t\t\t\t\t\t}\n +\t\t\t\t\t\t}\n +\t\t\t\t\t\tbreak;\n +\t\t\t\t\tcase \'Z\':\n +\t\t\t\t\t\tif (ctx != null) ctx.closePath();\n +\t\t\t\t\t\tpp.current = pp.start;\n +\t\t\t\t\t}\n +\t\t\t\t}\n +\n +\t\t\t\treturn bb;\n +\t\t\t}\n +\n +\t\t\tthis.getMarkers = function() {\n +\t\t\t\tvar points = this.PathParser.getMarkerPoints();\n +\t\t\t\tvar angles = this.PathParser.getMarkerAngles();\n +\t\t\t\t\n +\t\t\t\tvar markers = [];\n +\t\t\t\tfor (var i=0; i<points.length; i++) {\n +\t\t\t\t\tmarkers.push([points[i], angles[i]]);\n +\t\t\t\t}\n +\t\t\t\treturn markers;\n +\t\t\t}\n +\t\t}\n +\t\tsvg.Element.path.prototype = new svg.Element.PathElementBase;\n +\t\t\n +\t\t// pattern element\n +\t\tsvg.Element.pattern = function(node) {\n +\t\t\tthis.base = svg.Element.ElementBase;\n +\t\t\tthis.base(node);\n +\t\t\t\n +\t\t\tthis.createPattern = function(ctx, element) {\n +\t\t\t\t// render me using a temporary svg element\n +\t\t\t\tvar tempSvg = new svg.Element.svg();\n +\t\t\t\ttempSvg.attributes[\'viewBox\'] = new svg.Property(\'viewBox\', this.attribute(\'viewBox\').value);\n +\t\t\t\ttempSvg.attributes[\'x\'] = new svg.Property(\'x\', this.attribute(\'x\').value);\n +\t\t\t\ttempSvg.attributes[\'y\'] = new svg.Property(\'y\', this.attribute(\'y\').value);\n +\t\t\t\ttempSvg.attributes[\'width\'] = new svg.Property(\'width\', this.attribute(\'width\').value);\n +\t\t\t\ttempSvg.attributes[\'height\'] = new svg.Property(\'height\', this.attribute(\'height\').value);\n +\t\t\t\ttempSvg.children = this.children;\n +\t\t\t\t\n +\t\t\t\tvar c = document.createElement(\'canvas\');\n +\t\t\t\tc.width = this.attribute(\'width\').Length.toPixels(\'x\');\n +\t\t\t\tc.height = this.attribute(\'height\').Length.toPixels(\'y\');\n +\t\t\t\ttempSvg.render(c.getContext(\'2d\'));\t\t\n +\t\t\t\treturn ctx.createPattern(c, \'repeat\');\n +\t\t\t}\n +\t\t}\n +\t\tsvg.Element.pattern.prototype = new svg.Element.ElementBase;\n +\t\t\n +\t\t// marker element\n +\t\tsvg.Element.marker = function(node) {\n +\t\t\tthis.base = svg.Element.ElementBase;\n +\t\t\tthis.base(node);\n +\t\t\t\n +\t\t\tthis.baseRender = this.render;\n +\t\t\tthis.render = function(ctx, point, angle) {\n +\t\t\t\tctx.translate(point.x, point.y);\n +\t\t\t\tif (this.attribute(\'orient\').valueOrDefault(\'auto\') == \'auto\') ctx.rotate(angle);\n +\t\t\t\tif (this.attribute(\'markerUnits\').valueOrDefault(\'strokeWidth\') == \'strokeWidth\') ctx.scale(ctx.lineWidth, ctx.lineWidth);\n +\t\t\t\tctx.save();\n +\t\t\t\t\t\t\t\n +\t\t\t\t// render me using a temporary svg element\n +\t\t\t\tvar tempSvg = new svg.Element.svg();\n +\t\t\t\ttempSvg.attributes[\'viewBox\'] = new svg.Property(\'viewBox\', this.attribute(\'viewBox\').value);\n +\t\t\t\ttempSvg.attributes[\'refX\'] = new svg.Property(\'refX\', this.attribute(\'refX\').value);\n +\t\t\t\ttempSvg.attributes[\'refY\'] = new svg.Property(\'refY\', this.attribute(\'refY\').value);\n +\t\t\t\ttempSvg.attributes[\'width\'] = new svg.Property(\'width\', this.attribute(\'markerWidth\').value);\n +\t\t\t\ttempSvg.attributes[\'height\'] = new svg.Property(\'height\', this.attribute(\'markerHeight\').value);\n +\t\t\t\ttempSvg.attributes[\'fill\'] = new svg.Property(\'fill\', this.attribute(\'fill\').valueOrDefault(\'black\'));\n +\t\t\t\ttempSvg.attributes[\'stroke\'] = new svg.Property(\'stroke\', this.attribute(\'stroke\').valueOrDefault(\'none\'));\n +\t\t\t\ttempSvg.children = this.children;\n +\t\t\t\ttempSvg.render(ctx);\n +\t\t\t\t\n +\t\t\t\tctx.restore();\n +\t\t\t\tif (this.attribute(\'markerUnits\').valueOrDefault(\'strokeWidth\') == \'strokeWidth\') ctx.scale(1/ctx.lineWidth, 1/ctx.lineWidth);\n +\t\t\t\tif (this.attribute(\'orient\').valueOrDefault(\'auto\') == \'auto\') ctx.rotate(-angle);\n +\t\t\t\tctx.translate(-point.x, -point.y);\n +\t\t\t}\n +\t\t}\n +\t\tsvg.Element.marker.prototype = new svg.Element.ElementBase;\n +\t\t\n +\t\t// definitions element\n +\t\tsvg.Element.defs = function(node) {\n +\t\t\tthis.base = svg.Element.ElementBase;\n +\t\t\tthis.base(node);\t\n +\t\t\t\n +\t\t\tthis.render = function(ctx) {\n +\t\t\t\t// NOOP\n +\t\t\t}\n +\t\t}\n +\t\tsvg.Element.defs.prototype = new svg.Element.ElementBase;\n +\t\t\n +\t\t// base for gradients\n +\t\tsvg.Element.GradientBase = function(node) {\n +\t\t\tthis.base = svg.Element.ElementBase;\n +\t\t\tthis.base(node);\n +\t\t\t\n +\t\t\tthis.gradientUnits = this.attribute(\'gradientUnits\').valueOrDefault(\'objectBoundingBox\');\n +\t\t\t\n +\t\t\tthis.stops = [];\t\t\t\n +\t\t\tfor (var i=0; i<this.children.length; i++) {\n +\t\t\t\tvar child = this.children[i];\n +\t\t\t\tthis.stops.push(child);\n +\t\t\t}\t\n +\t\t\t\n +\t\t\tthis.getGradient = function() {\n +\t\t\t\t// OVERRIDE ME!\n +\t\t\t}\t\t\t\n +\n +\t\t\tthis.createGradient = function(ctx, element) {\n +\t\t\t\tvar stopsContainer = this;\n +\t\t\t\tif (this.attribute(\'xlink:href\').hasValue()) {\n +\t\t\t\t\tstopsContainer = this.attribute(\'xlink:href\').Definition.getDefinition();\n +\t\t\t\t}\n +\t\t\t\n +\t\t\t\tvar g = this.getGradient(ctx, element);\n +\t\t\t\tfor (var i=0; i<stopsContainer.stops.length; i++) {\n +\t\t\t\t\tg.addColorStop(stopsContainer.stops[i].offset, stopsContainer.stops[i].color);\n +\t\t\t\t}\n +\t\t\t\t\n +\t\t\t\tif (this.attribute(\'gradientTransform\').hasValue()) {\n +\t\t\t\t\t// render as transformed pattern on temporary canvas\n +\t\t\t\t\tvar rootView = svg.ViewPort.viewPorts[0];\n +\t\t\t\t\t\n +\t\t\t\t\tvar rect = new svg.Element.rect();\n +\t\t\t\t\trect.attributes[\'x\'] = new svg.Property(\'x\', -svg.MAX_VIRTUAL_PIXELS/3.0);\n +\t\t\t\t\trect.attributes[\'y\'] = new svg.Property(\'y\', -svg.MAX_VIRTUAL_PIXELS/3.0);\n +\t\t\t\t\trect.attributes[\'width\'] = new svg.Property(\'width\', svg.MAX_VIRTUAL_PIXELS);\n +\t\t\t\t\trect.attributes[\'height\'] = new svg.Property(\'height\', svg.MAX_VIRTUAL_PIXELS);\n +\t\t\t\t\t\n +\t\t\t\t\tvar group = new svg.Element.g();\n +\t\t\t\t\tgroup.attributes[\'transform\'] = new svg.Property(\'transform\', this.attribute(\'gradientTransform\').value);\n +\t\t\t\t\tgroup.children = [ rect ];\n +\t\t\t\t\t\n +\t\t\t\t\tvar tempSvg = new svg.Element.svg();\n +\t\t\t\t\ttempSvg.attributes[\'x\'] = new svg.Property(\'x\', 0);\n +\t\t\t\t\ttempSvg.attributes[\'y\'] = new svg.Property(\'y\', 0);\n +\t\t\t\t\ttempSvg.attributes[\'width\'] = new svg.Property(\'width\', rootView.width);\n +\t\t\t\t\ttempSvg.attributes[\'height\'] = new svg.Property(\'height\', rootView.height);\n +\t\t\t\t\ttempSvg.children = [ group ];\n +\t\t\t\t\t\n +\t\t\t\t\tvar c = document.createElement(\'canvas\');\n +\t\t\t\t\tc.width = rootView.width;\n +\t\t\t\t\tc.height = rootView.height;\n +\t\t\t\t\tvar tempCtx = c.getContext(\'2d\');\n +\t\t\t\t\ttempCtx.fillStyle = g;\n +\t\t\t\t\ttempSvg.render(tempCtx);\t\t\n +\t\t\t\t\treturn tempCtx.createPattern(c, \'no-repeat\');\n +\t\t\t\t}\n +\t\t\t\t\n +\t\t\t\treturn g;\t\t\t\t\n +\t\t\t}\n +\t\t}\n +\t\tsvg.Element.GradientBase.prototype = new svg.Element.ElementBase;\n +\t\t\n +\t\t// linear gradient element\n +\t\tsvg.Element.linearGradient = function(node) {\n +\t\t\tthis.base = svg.Element.GradientBase;\n +\t\t\tthis.base(node);\n +\t\t\t\n +\t\t\tthis.getGradient = function(ctx, element) {\n +\t\t\t\tvar bb = element.getBoundingBox();\n +\t\t\t\t\n +\t\t\t\tvar x1 = (this.gradientUnits == \'objectBoundingBox\' \n +\t\t\t\t\t? bb.x() + bb.width() * this.attribute(\'x1\').numValue() \n +\t\t\t\t\t: this.attribute(\'x1\').Length.toPixels(\'x\'));\n +\t\t\t\tvar y1 = (this.gradientUnits == \'objectBoundingBox\' \n +\t\t\t\t\t? bb.y() + bb.height() * this.attribute(\'y1\').numValue()\n +\t\t\t\t\t: this.attribute(\'y1\').Length.toPixels(\'y\'));\n +\t\t\t\tvar x2 = (this.gradientUnits == \'objectBoundingBox\' \n +\t\t\t\t\t? bb.x() + bb.width() * this.attribute(\'x2\').numValue()\n +\t\t\t\t\t: this.attribute(\'x2\').Length.toPixels(\'x\'));\n +\t\t\t\tvar y2 = (this.gradientUnits == \'objectBoundingBox\' \n +\t\t\t\t\t? bb.y() + bb.height() * this.attribute(\'y2\').numValue()\n +\t\t\t\t\t: this.attribute(\'y2\').Length.toPixels(\'y\'));\n +\n +\t\t\t\treturn ctx.createLinearGradient(x1, y1, x2, y2);\n +\t\t\t}\n +\t\t}\n +\t\tsvg.Element.linearGradient.prototype = new svg.Element.GradientBase;\n +\t\t\n +\t\t// radial gradient element\n +\t\tsvg.Element.radialGradient = function(node) {\n +\t\t\tthis.base = svg.Element.GradientBase;\n +\t\t\tthis.base(node);\n +\t\t\t\n +\t\t\tthis.getGradient = function(ctx, element) {\n +\t\t\t\tvar bb = element.getBoundingBox();\n +\t\t\t\t\n +\t\t\t\tvar cx = (this.gradientUnits == \'objectBoundingBox\' \n +\t\t\t\t\t? bb.x() + bb.width() * this.attribute(\'cx\').numValue() \n +\t\t\t\t\t: this.attribute(\'cx\').Length.toPixels(\'x\'));\n +\t\t\t\tvar cy = (this.gradientUnits == \'objectBoundingBox\' \n +\t\t\t\t\t? bb.y() + bb.height() * this.attribute(\'cy\').numValue() \n +\t\t\t\t\t: this.attribute(\'cy\').Length.toPixels(\'y\'));\n +\t\t\t\t\n +\t\t\t\tvar fx = cx;\n +\t\t\t\tvar fy = cy;\n +\t\t\t\tif (this.attribute(\'fx\').hasValue()) {\n +\t\t\t\t\tfx = (this.gradientUnits == \'objectBoundingBox\' \n +\t\t\t\t\t? bb.x() + bb.width() * this.attribute(\'fx\').numValue() \n +\t\t\t\t\t: this.attribute(\'fx\').Length.toPixels(\'x\'));\n +\t\t\t\t}\n +\t\t\t\tif (this.attribute(\'fy\').hasValue()) {\n +\t\t\t\t\tfy = (this.gradientUnits == \'objectBoundingBox\' \n +\t\t\t\t\t? bb.y() + bb.height() * this.attribute(\'fy\').numValue() \n +\t\t\t\t\t: this.attribute(\'fy\').Length.toPixels(\'y\'));\n +\t\t\t\t}\n +\t\t\t\t\n +\t\t\t\tvar r = (this.gradientUnits == \'objectBoundingBox\' \n +\t\t\t\t\t? (bb.width() + bb.height()) / 2.0 * this.attribute(\'r\').numValue()\n +\t\t\t\t\t: this.attribute(\'r\').Length.toPixels());\n +\t\t\t\t\n +\t\t\t\treturn ctx.createRadialGradient(fx, fy, 0, cx, cy, r);\n +\t\t\t}\n +\t\t}\n +\t\tsvg.Element.radialGradient.prototype = new svg.Element.GradientBase;\n +\t\t\n +\t\t// gradient stop element\n +\t\tsvg.Element.stop = function(node) {\n +\t\t\tthis.base = svg.Element.ElementBase;\n +\t\t\tthis.base(node);\n +\t\t\t\n +\t\t\tthis.offset = this.attribute(\'offset\').numValue();\n +\t\t\t\n +\t\t\tvar stopColor = this.style(\'stop-color\');\n +\t\t\tif (this.style(\'stop-opacity\').hasValue()) stopColor = stopColor.Color.addOpacity(this.style(\'stop-opacity\').value);\n +\t\t\tthis.color = stopColor.value;\n +\t\t}\n +\t\tsvg.Element.stop.prototype = new svg.Element.ElementBase;\n +\t\t\n +\t\t// animation base element\n +\t\tsvg.Element.AnimateBase = function(node) {\n +\t\t\tthis.base = svg.Element.ElementBase;\n +\t\t\tthis.base(node);\n +\t\t\t\n +\t\t\tsvg.Animations.push(this);\n +\t\t\t\n +\t\t\tthis.duration = 0.0;\n +\t\t\tthis.begin = this.attribute(\'begin\').Time.toMilliseconds();\n +\t\t\tthis.maxDuration = this.begin + this.attribute(\'dur\').Time.toMilliseconds();\n +\t\t\t\n +\t\t\tthis.getProperty = function() {\n +\t\t\t\tvar attributeType = this.attribute(\'attributeType\').value;\n +\t\t\t\tvar attributeName = this.attribute(\'attributeName\').value;\n +\t\t\t\t\n +\t\t\t\tif (attributeType == \'CSS\') {\n +\t\t\t\t\treturn this.parent.style(attributeName, true);\n +\t\t\t\t}\n +\t\t\t\treturn this.parent.attribute(attributeName, true);\t\t\t\n +\t\t\t};\n +\t\t\t\n +\t\t\tthis.initialValue = null;\n +\t\t\tthis.removed = false;\t\t\t\n +\n +\t\t\tthis.calcValue = function() {\n +\t\t\t\t// OVERRIDE ME!\n +\t\t\t\treturn \'\';\n +\t\t\t}\n +\t\t\t\n +\t\t\tthis.update = function(delta) {\t\n +\t\t\t\t// set initial value\n +\t\t\t\tif (this.initialValue == null) {\n +\t\t\t\t\tthis.initialValue = this.getProperty().value;\n +\t\t\t\t}\n +\t\t\t\n +\t\t\t\t// if we\'re past the end time\n +\t\t\t\tif (this.duration > this.maxDuration) {\n +\t\t\t\t\t// loop for indefinitely repeating animations\n +\t\t\t\t\tif (this.attribute(\'repeatCount\').value == \'indefinite\') {\n +\t\t\t\t\t\tthis.duration = 0.0\n +\t\t\t\t\t}\n +\t\t\t\t\telse if (this.attribute(\'fill\').valueOrDefault(\'remove\') == \'remove\' && !this.removed) {\n +\t\t\t\t\t\tthis.removed = true;\n +\t\t\t\t\t\tthis.getProperty().value = this.initialValue;\n +\t\t\t\t\t\treturn true;\n +\t\t\t\t\t}\n +\t\t\t\t\telse {\n +\t\t\t\t\t\treturn false; // no updates made\n +\t\t\t\t\t}\n +\t\t\t\t}\t\t\t\n +\t\t\t\tthis.duration = this.duration + delta;\n +\t\t\t\n +\t\t\t\t// if we\'re past the begin time\n +\t\t\t\tvar updated = false;\n +\t\t\t\tif (this.begin < this.duration) {\n +\t\t\t\t\tvar newValue = this.calcValue(); // tween\n +\t\t\t\t\t\n +\t\t\t\t\tif (this.attribute(\'type\').hasValue()) {\n +\t\t\t\t\t\t// for transform, etc.\n +\t\t\t\t\t\tvar type = this.attribute(\'type\').value;\n +\t\t\t\t\t\tnewValue = type + \'(\' + newValue + \')\';\n +\t\t\t\t\t}\n +\t\t\t\t\t\n +\t\t\t\t\tthis.getProperty().value = newValue;\n +\t\t\t\t\tupdated = true;\n +\t\t\t\t}\n +\t\t\t\t\n +\t\t\t\treturn updated;\n +\t\t\t}\n +\t\t\t\n +\t\t\t// fraction of duration we\'ve covered\n +\t\t\tthis.progress = function() {\n +\t\t\t\treturn ((this.duration - this.begin) / (this.maxDuration - this.begin));\n +\t\t\t}\t\t\t\n +\t\t}\n +\t\tsvg.Element.AnimateBase.prototype = new svg.Element.ElementBase;\n +\t\t\n +\t\t// animate element\n +\t\tsvg.Element.animate = function(node) {\n +\t\t\tthis.base = svg.Element.AnimateBase;\n +\t\t\tthis.base(node);\n +\t\t\t\n +\t\t\tthis.calcValue = function() {\n +\t\t\t\tvar from = this.attribute(\'from\').numValue();\n +\t\t\t\tvar to = this.attribute(\'to\').numValue();\n +\t\t\t\t\n +\t\t\t\t// tween value linearly\n +\t\t\t\treturn from + (to - from) * this.progress(); \n +\t\t\t};\n +\t\t}\n +\t\tsvg.Element.animate.prototype = new svg.Element.AnimateBase;\n +\t\t\t\n +\t\t// animate color element\n +\t\tsvg.Element.animateColor = function(node) {\n +\t\t\tthis.base = svg.Element.AnimateBase;\n +\t\t\tthis.base(node);\n +\n +\t\t\tthis.calcValue = function() {\n +\t\t\t\tvar from = new RGBColor(this.attribute(\'from\').value);\n +\t\t\t\tvar to = new RGBColor(this.attribute(\'to\').value);\n +\t\t\t\t\n +\t\t\t\tif (from.ok && to.ok) {\n +\t\t\t\t\t// tween color linearly\n +\t\t\t\t\tvar r = from.r + (to.r - from.r) * this.progress();\n +\t\t\t\t\tvar g = from.g + (to.g - from.g) * this.progress();\n +\t\t\t\t\tvar b = from.b + (to.b - from.b) * this.progress();\n +\t\t\t\t\treturn \'rgb(\'+parseInt(r,10)+\',\'+parseInt(g,10)+\',\'+parseInt(b,10)+\')\';\n +\t\t\t\t}\n +\t\t\t\treturn this.attribute(\'from\').value;\n +\t\t\t};\n +\t\t}\n +\t\tsvg.Element.animateColor.prototype = new svg.Element.AnimateBase;\n +\t\t\n +\t\t// animate transform element\n +\t\tsvg.Element.animateTransform = function(node) {\n +\t\t\tthis.base = svg.Element.animate;\n +\t\t\tthis.base(node);\n +\t\t}\n +\t\tsvg.Element.animateTransform.prototype = new svg.Element.animate;\n +\t\t\n +\t\t// font element\n +\t\tsvg.Element.font = function(node) {\n +\t\t\tthis.base = svg.Element.ElementBase;\n +\t\t\tthis.base(node);\n +\n +\t\t\tthis.horizAdvX = this.attribute(\'horiz-adv-x\').numValue();\t\t\t\n +\t\t\t\n +\t\t\tthis.isRTL = false;\n +\t\t\tthis.isArabic = false;\n +\t\t\tthis.fontFace = null;\n +\t\t\tthis.missingGlyph = null;\n +\t\t\tthis.glyphs = [];\t\t\t\n +\t\t\tfor (var i=0; i<this.children.length; i++) {\n +\t\t\t\tvar child = this.children[i];\n +\t\t\t\tif (child.type == \'font-face\') {\n +\t\t\t\t\tthis.fontFace = child;\n +\t\t\t\t\tif (child.style(\'font-family\').hasValue()) {\n +\t\t\t\t\t\tsvg.Definitions[child.style(\'font-family\').value] = this;\n +\t\t\t\t\t}\n +\t\t\t\t}\n +\t\t\t\telse if (child.type == \'missing-glyph\') this.missingGlyph = child;\n +\t\t\t\telse if (child.type == \'glyph\') {\n +\t\t\t\t\tif (child.arabicForm != \'\') {\n +\t\t\t\t\t\tthis.isRTL = true;\n +\t\t\t\t\t\tthis.isArabic = true;\n +\t\t\t\t\t\tif (typeof(this.glyphs[child.unicode]) == \'undefined\') this.glyphs[child.unicode] = [];\n +\t\t\t\t\t\tthis.glyphs[child.unicode][child.arabicForm] = child;\n +\t\t\t\t\t}\n +\t\t\t\t\telse {\n +\t\t\t\t\t\tthis.glyphs[child.unicode] = child;\n +\t\t\t\t\t}\n +\t\t\t\t}\n +\t\t\t}\t\n +\t\t}\n +\t\tsvg.Element.font.prototype = new svg.Element.ElementBase;\n +\t\t\n +\t\t// font-face element\n +\t\tsvg.Element.fontface = function(node) {\n +\t\t\tthis.base = svg.Element.ElementBase;\n +\t\t\tthis.base(node);\t\n +\t\t\t\n +\t\t\tthis.ascent = this.attribute(\'ascent\').value;\n +\t\t\tthis.descent = this.attribute(\'descent\').value;\n +\t\t\tthis.unitsPerEm = this.attribute(\'units-per-em\').numValue();\t\t\t\t\n +\t\t}\n +\t\tsvg.Element.fontface.prototype = new svg.Element.ElementBase;\n +\t\t\n +\t\t// missing-glyph element\n +\t\tsvg.Element.missingglyph = function(node) {\n +\t\t\tthis.base = svg.Element.path;\n +\t\t\tthis.base(node);\t\n +\t\t\t\n +\t\t\tthis.horizAdvX = 0;\n +\t\t}\n +\t\tsvg.Element.missingglyph.prototype = new svg.Element.path;\n +\t\t\n +\t\t// glyph element\n +\t\tsvg.Element.glyph = function(node) {\n +\t\t\tthis.base = svg.Element.path;\n +\t\t\tthis.base(node);\t\n +\t\t\t\n +\t\t\tthis.horizAdvX = this.attribute(\'horiz-adv-x\').numValue();\n +\t\t\tthis.unicode = this.attribute(\'unicode\').value;\n +\t\t\tthis.arabicForm = this.attribute(\'arabic-form\').value;\n +\t\t}\n +\t\tsvg.Element.glyph.prototype = new svg.Element.path;\n +\t\t\n +\t\t// text element\n +\t\tsvg.Element.text = function(node) {\n +\t\t\tthis.base = svg.Element.RenderedElementBase;\n +\t\t\tthis.base(node);\n +\t\t\t\n +\t\t\tif (node != null) {\n +\t\t\t\t// add children\n +\t\t\t\tthis.children = [];\n +\t\t\t\tfor (var i=0; i<node.childNodes.length; i++) {\n +\t\t\t\t\tvar childNode = node.childNodes[i];\n +\t\t\t\t\tif (childNode.nodeType == 1) { // capture tspan and tref nodes\n +\t\t\t\t\t\tthis.addChild(childNode, true);\n +\t\t\t\t\t}\n +\t\t\t\t\telse if (childNode.nodeType == 3) { // capture text\n +\t\t\t\t\t\tthis.addChild(new svg.Element.tspan(childNode), false);\n +\t\t\t\t\t}\n +\t\t\t\t}\n +\t\t\t}\n +\t\t\t\n +\t\t\tthis.baseSetContext = this.setContext;\n +\t\t\tthis.setContext = function(ctx) {\n +\t\t\t\tthis.baseSetContext(ctx);\n +\t\t\t\tif (this.style(\'dominant-baseline\').hasValue()) ctx.textBaseline = this.style(\'dominant-baseline\').value;\n +\t\t\t\tif (this.style(\'alignment-baseline\').hasValue()) ctx.textBaseline = this.style(\'alignment-baseline\').value;\n +\t\t\t}\n +\t\t\t\n +\t\t\tthis.renderChildren = function(ctx) {\n +\t\t\t\tvar textAnchor = this.style(\'text-anchor\').valueOrDefault(\'start\');\n +\t\t\t\tvar x = this.attribute(\'x\').Length.toPixels(\'x\');\n +\t\t\t\tvar y = this.attribute(\'y\').Length.toPixels(\'y\');\n +\t\t\t\tfor (var i=0; i<this.children.length; i++) {\n +\t\t\t\t\tvar child = this.children[i];\n +\t\t\t\t\n +\t\t\t\t\tif (child.attribute(\'x\').hasValue()) {\n +\t\t\t\t\t\tchild.x = child.attribute(\'x\').Length.toPixels(\'x\');\n +\t\t\t\t\t}\n +\t\t\t\t\telse {\n +\t\t\t\t\t\tif (child.attribute(\'dx\').hasValue()) x += child.attribute(\'dx\').Length.toPixels(\'x\');\n +\t\t\t\t\t\tchild.x = x;\n +\t\t\t\t\t}\n +\t\t\t\t\t\n +\t\t\t\t\tvar childLength = child.measureText(ctx);\n +\t\t\t\t\tif (textAnchor != \'start\' && (i==0 || child.attribute(\'x\').hasValue())) { // new group?\n +\t\t\t\t\t\t// loop through rest of children\n +\t\t\t\t\t\tvar groupLength = childLength;\n +\t\t\t\t\t\tfor (var j=i+1; j<this.children.length; j++) {\n +\t\t\t\t\t\t\tvar childInGroup = this.children[j];\n +\t\t\t\t\t\t\tif (childInGroup.attribute(\'x\').hasValue()) break; // new group\n +\t\t\t\t\t\t\tgroupLength += childInGroup.measureText(ctx);\n +\t\t\t\t\t\t}\n +\t\t\t\t\t\tchild.x -= (textAnchor == \'end\' ? groupLength : groupLength / 2.0);\n +\t\t\t\t\t}\n +\t\t\t\t\tx = child.x + childLength;\n +\t\t\t\t\t\n +\t\t\t\t\tif (child.attribute(\'y\').hasValue()) {\n +\t\t\t\t\t\tchild.y = child.attribute(\'y\').Length.toPixels(\'y\');\n +\t\t\t\t\t}\n +\t\t\t\t\telse {\n +\t\t\t\t\t\tif (child.attribute(\'dy\').hasValue()) y += child.attribute(\'dy\').Length.toPixels(\'y\');\n +\t\t\t\t\t\tchild.y = y;\n +\t\t\t\t\t}\t\n +\t\t\t\t\ty = child.y;\n +\t\t\t\t\t\n +\t\t\t\t\tchild.render(ctx);\n +\t\t\t\t}\n +\t\t\t}\n +\t\t}\n +\t\tsvg.Element.text.prototype = new svg.Element.RenderedElementBase;\n +\t\t\n +\t\t// text base\n +\t\tsvg.Element.TextElementBase = function(node) {\n +\t\t\tthis.base = svg.Element.RenderedElementBase;\n +\t\t\tthis.base(node);\n +\t\t\t\n +\t\t\tthis.getGlyph = function(font, text, i) {\n +\t\t\t\tvar c = text[i];\n +\t\t\t\tvar glyph = null;\n +\t\t\t\tif (font.isArabic) {\n +\t\t\t\t\tvar arabicForm = \'isolated\';\n +\t\t\t\t\tif ((i==0 || text[i-1]==\' \') && i<text.length-2 && text[i+1]!=\' \') arabicForm = \'terminal\'; \n +\t\t\t\t\tif (i>0 && text[i-1]!=\' \' && i<text.length-2 && text[i+1]!=\' \') arabicForm = \'medial\';\n +\t\t\t\t\tif (i>0 && text[i-1]!=\' \' && (i == text.length-1 || text[i+1]==\' \')) arabicForm = \'initial\';\n +\t\t\t\t\tif (typeof(font.glyphs[c]) != \'undefined\') {\n +\t\t\t\t\t\tglyph = font.glyphs[c][arabicForm];\n +\t\t\t\t\t\tif (glyph == null && font.glyphs[c].type == \'glyph\') glyph = font.glyphs[c];\n +\t\t\t\t\t}\n +\t\t\t\t}\n +\t\t\t\telse {\n +\t\t\t\t\tglyph = font.glyphs[c];\n +\t\t\t\t}\n +\t\t\t\tif (glyph == null) glyph = font.missingGlyph;\n +\t\t\t\treturn glyph;\n +\t\t\t}\n +\t\t\t\n +\t\t\tthis.renderChildren = function(ctx) {\n +\t\t\t\tvar customFont = this.parent.style(\'font-family\').Definition.getDefinition();\n +\t\t\t\tif (customFont != null) {\n +\t\t\t\t\tvar fontSize = this.parent.style(\'font-size\').numValueOrDefault(svg.Font.Parse(svg.ctx.font).fontSize);\n +\t\t\t\t\tvar fontStyle = this.parent.style(\'font-style\').valueOrDefault(svg.Font.Parse(svg.ctx.font).fontStyle);\n +\t\t\t\t\tvar text = this.getText();\n +\t\t\t\t\tif (customFont.isRTL) text = text.split("").reverse().join("");\n +\t\t\t\t\t\n +\t\t\t\t\tvar dx = svg.ToNumberArray(this.parent.attribute(\'dx\').value);\n +\t\t\t\t\tfor (var i=0; i<text.length; i++) {\n +\t\t\t\t\t\tvar glyph = this.getGlyph(customFont, text, i);\n +\t\t\t\t\t\tvar scale = fontSize / customFont.fontFace.unitsPerEm;\n +\t\t\t\t\t\tctx.translate(this.x, this.y);\n +\t\t\t\t\t\tctx.scale(scale, -scale);\n +\t\t\t\t\t\tvar lw = ctx.lineWidth;\n +\t\t\t\t\t\tctx.lineWidth = ctx.lineWidth * customFont.fontFace.unitsPerEm / fontSize;\n +\t\t\t\t\t\tif (fontStyle == \'italic\') ctx.transform(1, 0, .4, 1, 0, 0);\n +\t\t\t\t\t\tglyph.render(ctx);\n +\t\t\t\t\t\tif (fontStyle == \'italic\') ctx.transform(1, 0, -.4, 1, 0, 0);\n +\t\t\t\t\t\tctx.lineWidth = lw;\n +\t\t\t\t\t\tctx.scale(1/scale, -1/scale);\n +\t\t\t\t\t\tctx.translate(-this.x, -this.y);\t\n +\t\t\t\t\t\t\n +\t\t\t\t\t\tthis.x += fontSize * (glyph.horizAdvX || customFont.horizAdvX) / customFont.fontFace.unitsPerEm;\n +\t\t\t\t\t\tif (typeof(dx[i]) != \'undefined\' && !isNaN(dx[i])) {\n +\t\t\t\t\t\t\tthis.x += dx[i];\n +\t\t\t\t\t\t}\n +\t\t\t\t\t}\n +\t\t\t\t\treturn;\n +\t\t\t\t}\n +\t\t\t\n +\t\t\t\tif (ctx.strokeStyle != \'\') ctx.strokeText(svg.compressSpaces(this.getText()), this.x, this.y);\n +\t\t\t\tif (ctx.fillStyle != \'\') ctx.fillText(svg.compressSpaces(this.getText()), this.x, this.y);\n +\t\t\t}\n +\t\t\t\n +\t\t\tthis.getText = function() {\n +\t\t\t\t// OVERRIDE ME\n +\t\t\t}\n +\t\t\t\n +\t\t\tthis.measureText = function(ctx) {\n +\t\t\t\tvar customFont = this.parent.style(\'font-family\').Definition.getDefinition();\n +\t\t\t\tif (customFont != null) {\n +\t\t\t\t\tvar fontSize = this.parent.style(\'font-size\').numValueOrDefault(svg.Font.Parse(svg.ctx.font).fontSize);\n +\t\t\t\t\tvar measure = 0;\n +\t\t\t\t\tvar text = this.getText();\n +\t\t\t\t\tif (customFont.isRTL) text = text.split("").reverse().join("");\n +\t\t\t\t\tvar dx = svg.ToNumberArray(this.parent.attribute(\'dx\').value);\n +\t\t\t\t\tfor (var i=0; i<text.length; i++) {\n +\t\t\t\t\t\tvar glyph = this.getGlyph(customFont, text, i);\n +\t\t\t\t\t\tmeasure += (glyph.horizAdvX || customFont.horizAdvX) * fontSize / customFont.fontFace.unitsPerEm;\n +\t\t\t\t\t\tif (typeof(dx[i]) != \'undefined\' && !isNaN(dx[i])) {\n +\t\t\t\t\t\t\tmeasure += dx[i];\n +\t\t\t\t\t\t}\n +\t\t\t\t\t}\n +\t\t\t\t\treturn measure;\n +\t\t\t\t}\n +\t\t\t\n +\t\t\t\tvar textToMeasure = svg.compressSpaces(this.getText());\n +\t\t\t\tif (!ctx.measureText) return textToMeasure.length * 10;\n +\t\t\t\t\n +\t\t\t\tctx.save();\n +\t\t\t\tthis.setContext(ctx);\n +\t\t\t\tvar width = ctx.measureText(textToMeasure).width;\n +\t\t\t\tctx.restore();\n +\t\t\t\treturn width;\n +\t\t\t}\n +\t\t}\n +\t\tsvg.Element.TextElementBase.prototype = new svg.Element.RenderedElementBase;\n +\t\t\n +\t\t// tspan \n +\t\tsvg.Element.tspan = function(node) {\n +\t\t\tthis.base = svg.Element.TextElementBase;\n +\t\t\tthis.base(node);\n +\t\t\t\n +\t\t\tthis.text = node.nodeType == 3 ? node.nodeValue : // text\n +\t\t\t\t\t\tnode.childNodes.length > 0 ? node.childNodes[0].nodeValue : // element\n +\t\t\t\t\t\tnode.text;\n +\t\t\tthis.getText = function() {\n +\t\t\t\treturn this.text;\n +\t\t\t}\n +\t\t}\n +\t\tsvg.Element.tspan.prototype = new svg.Element.TextElementBase;\n +\t\t\n +\t\t// tref\n +\t\tsvg.Element.tref = function(node) {\n +\t\t\tthis.base = svg.Element.TextElementBase;\n +\t\t\tthis.base(node);\n +\t\t\t\n +\t\t\tthis.getText = function() {\n +\t\t\t\tvar element = this.attribute(\'xlink:href\').Definition.getDefinition();\n +\t\t\t\tif (element != null) return element.children[0].getText();\n +\t\t\t}\n +\t\t}\n +\t\tsvg.Element.tref.prototype = new svg.Element.TextElementBase;\t\t\n +\t\t\n +\t\t// a element\n +\t\tsvg.Element.a = function(node) {\n +\t\t\tthis.base = svg.Element.TextElementBase;\n +\t\t\tthis.base(node);\n +\t\t\t\n +\t\t\tthis.hasText = true;\n +\t\t\tfor (var i=0; i<node.childNodes.length; i++) {\n +\t\t\t\tif (node.childNodes[i].nodeType != 3) this.hasText = false;\n +\t\t\t}\n +\t\t\t\n +\t\t\t// this might contain text\n +\t\t\tthis.text = this.hasText ? node.childNodes[0].nodeValue : \'\';\n +\t\t\tthis.getText = function() {\n +\t\t\t\treturn this.text;\n +\t\t\t}\t\t\n +\n +\t\t\tthis.baseRenderChildren = this.renderChildren;\n +\t\t\tthis.renderChildren = function(ctx) {\n +\t\t\t\tif (this.hasText) {\n +\t\t\t\t\t// render as text element\n +\t\t\t\t\tthis.baseRenderChildren(ctx);\n +\t\t\t\t\tvar fontSize = new svg.Property(\'fontSize\', svg.Font.Parse(svg.ctx.font).fontSize);\n +\t\t\t\t\tsvg.Mouse.checkBoundingBox(this, new svg.BoundingBox(this.x, this.y - fontSize.Length.toPixels(\'y\'), this.x + this.measureText(ctx), this.y));\t\t\t\t\t\n +\t\t\t\t}\n +\t\t\t\telse {\n +\t\t\t\t\t// render as temporary group\n +\t\t\t\t\tvar g = new svg.Element.g();\n +\t\t\t\t\tg.children = this.children;\n +\t\t\t\t\tg.parent = this;\n +\t\t\t\t\tg.render(ctx);\n +\t\t\t\t}\n +\t\t\t}\n +\t\t\t\n +\t\t\tthis.onclick = function() {\n +\t\t\t\twindow.open(this.attribute(\'xlink:href\').value);\n +\t\t\t}\n +\t\t\t\n +\t\t\tthis.onmousemove = function() {\n +\t\t\t\tsvg.ctx.canvas.style.cursor = \'pointer\';\n +\t\t\t}\n +\t\t}\n +\t\tsvg.Element.a.prototype = new svg.Element.TextElementBase;\t\t\n +\t\t\n +\t\t// image element\n +\t\tsvg.Element.image = function(node) {\n +\t\t\tthis.base = svg.Element.RenderedElementBase;\n +\t\t\tthis.base(node);\n +\t\t\t\n +\t\t\tsvg.Images.push(this);\n +\t\t\tthis.img = document.createElement(\'img\');\n +\t\t\tthis.loaded = false;\n +\t\t\tvar that = this;\n +\t\t\tthis.img.onload = function() { that.loaded = true; }\n +\t\t\tthis.img.src = this.attribute(\'xlink:href\').value;\n +\t\t\t\n +\t\t\tthis.renderChildren = function(ctx) {\n +\t\t\t\tvar x = this.attribute(\'x\').Length.toPixels(\'x\');\n +\t\t\t\tvar y = this.attribute(\'y\').Length.toPixels(\'y\');\n +\t\t\t\t\n +\t\t\t\tvar width = this.attribute(\'width\').Length.toPixels(\'x\');\n +\t\t\t\tvar height = this.attribute(\'height\').Length.toPixels(\'y\');\t\t\t\n +\t\t\t\tif (width == 0 || height == 0) return;\n +\t\t\t\n +\t\t\t\tctx.save();\n +\t\t\t\tctx.translate(x, y);\n +\t\t\t\tsvg.AspectRatio(ctx,\n +\t\t\t\t\t\t\t\tthis.attribute(\'preserveAspectRatio\').value,\n +\t\t\t\t\t\t\t\twidth,\n +\t\t\t\t\t\t\t\tthis.img.width,\n +\t\t\t\t\t\t\t\theight,\n +\t\t\t\t\t\t\t\tthis.img.height,\n +\t\t\t\t\t\t\t\t0,\n +\t\t\t\t\t\t\t\t0);\t\n +\t\t\t\tctx.drawImage(this.img, 0, 0);\t\t\t\n +\t\t\t\tctx.restore();\n +\t\t\t}\n +\t\t}\n +\t\tsvg.Element.image.prototype = new svg.Element.RenderedElementBase;\n +\t\t\n +\t\t// group element\n +\t\tsvg.Element.g = function(node) {\n +\t\t\tthis.base = svg.Element.RenderedElementBase;\n +\t\t\tthis.base(node);\n +\t\t\t\n +\t\t\tthis.getBoundingBox = function() {\n +\t\t\t\tvar bb = new svg.BoundingBox();\n +\t\t\t\tfor (var i=0; i<this.children.length; i++) {\n +\t\t\t\t\tbb.addBoundingBox(this.children[i].getBoundingBox());\n +\t\t\t\t}\n +\t\t\t\treturn bb;\n +\t\t\t};\n +\t\t}\n +\t\tsvg.Element.g.prototype = new svg.Element.RenderedElementBase;\n +\n +\t\t// symbol element\n +\t\tsvg.Element.symbol = function(node) {\n +\t\t\tthis.base = svg.Element.RenderedElementBase;\n +\t\t\tthis.base(node);\n +\t\t\t\n +\t\t\tthis.baseSetContext = this.setContext;\n +\t\t\tthis.setContext = function(ctx) {\t\t\n +\t\t\t\tthis.baseSetContext(ctx);\n +\t\t\t\t\n +\t\t\t\t// viewbox\n +\t\t\t\tif (this.attribute(\'viewBox\').hasValue()) {\t\t\t\t\n +\t\t\t\t\tvar viewBox = svg.ToNumberArray(this.attribute(\'viewBox\').value);\n +\t\t\t\t\tvar minX = viewBox[0];\n +\t\t\t\t\tvar minY = viewBox[1];\n +\t\t\t\t\twidth = viewBox[2];\n +\t\t\t\t\theight = viewBox[3];\n +\t\t\t\t\t\n +\t\t\t\t\tsvg.AspectRatio(ctx,\n +\t\t\t\t\t\t\t\t\tthis.attribute(\'preserveAspectRatio\').value, \n +\t\t\t\t\t\t\t\t\tthis.attribute(\'width\').Length.toPixels(\'x\'),\n +\t\t\t\t\t\t\t\t\twidth,\n +\t\t\t\t\t\t\t\t\tthis.attribute(\'height\').Length.toPixels(\'y\'),\n +\t\t\t\t\t\t\t\t\theight,\n +\t\t\t\t\t\t\t\t\tminX,\n +\t\t\t\t\t\t\t\t\tminY);\n +\n +\t\t\t\t\tsvg.ViewPort.SetCurrent(viewBox[2], viewBox[3]);\t\t\t\t\t\t\n +\t\t\t\t}\n +\t\t\t}\t\t\t\n +\t\t}\n +\t\tsvg.Element.symbol.prototype = new svg.Element.RenderedElementBase;\t\t\n +\t\t\t\n +\t\t// style element\n +\t\tsvg.Element.style = function(node) { \n +\t\t\tthis.base = svg.Element.ElementBase;\n +\t\t\tthis.base(node);\n +\t\t\t\n +\t\t\t// text, or spaces then CDATA\n +\t\t\tvar css = node.childNodes[0].nodeValue + (node.childNodes.length > 1 ? node.childNodes[1].nodeValue : \'\');\n +\t\t\tcss = css.replace(/(\\/\\*([^*]|[\\r\\n]|(\\*+([^*\\/]|[\\r\\n])))*\\*+\\/)|(^[\\s]*\\/\\/.*)/gm, \'\'); // remove comments\n +\t\t\tcss = svg.compressSpaces(css); // replace whitespace\n +\t\t\tvar cssDefs = css.split(\'}\');\n +\t\t\tfor (var i=0; i<cssDefs.length; i++) {\n +\t\t\t\tif (svg.trim(cssDefs[i]) != \'\') {\n +\t\t\t\t\tvar cssDef = cssDefs[i].split(\'{\');\n +\t\t\t\t\tvar cssClasses = cssDef[0].split(\',\');\n +\t\t\t\t\tvar cssProps = cssDef[1].split(\';\');\n +\t\t\t\t\tfor (var j=0; j<cssClasses.length; j++) {\n +\t\t\t\t\t\tvar cssClass = svg.trim(cssClasses[j]);\n +\t\t\t\t\t\tif (cssClass != \'\') {\n +\t\t\t\t\t\t\tvar props = {};\n +\t\t\t\t\t\t\tfor (var k=0; k<cssProps.length; k++) {\n +\t\t\t\t\t\t\t\tvar prop = cssProps[k].indexOf(\':\');\n +\t\t\t\t\t\t\t\tvar name = cssProps[k].substr(0, prop);\n +\t\t\t\t\t\t\t\tvar value = cssProps[k].substr(prop + 1, cssProps[k].length - prop);\n +\t\t\t\t\t\t\t\tif (name != null && value != null) {\n +\t\t\t\t\t\t\t\t\tprops[svg.trim(name)] = new svg.Property(svg.trim(name), svg.trim(value));\n +\t\t\t\t\t\t\t\t}\n +\t\t\t\t\t\t\t}\n +\t\t\t\t\t\t\tsvg.Styles[cssClass] = props;\n +\t\t\t\t\t\t\tif (cssClass == \'@font-face\') {\n +\t\t\t\t\t\t\t\tvar fontFamily = props[\'font-family\'].value.replace(/"/g,\'\');\n +\t\t\t\t\t\t\t\tvar srcs = props[\'src\'].value.split(\',\');\n +\t\t\t\t\t\t\t\tfor (var s=0; s<srcs.length; s++) {\n +\t\t\t\t\t\t\t\t\tif (srcs[s].indexOf(\'format("svg")\') > 0) {\n +\t\t\t\t\t\t\t\t\t\tvar urlStart = srcs[s].indexOf(\'url\');\n +\t\t\t\t\t\t\t\t\t\tvar urlEnd = srcs[s].indexOf(\')\', urlStart);\n +\t\t\t\t\t\t\t\t\t\tvar url = srcs[s].substr(urlStart + 5, urlEnd - urlStart - 6);\n +\t\t\t\t\t\t\t\t\t\tvar doc = svg.parseXml(svg.ajax(url));\n +\t\t\t\t\t\t\t\t\t\tvar fonts = doc.getElementsByTagName(\'font\');\n +\t\t\t\t\t\t\t\t\t\tfor (var f=0; f<fonts.length; f++) {\n +\t\t\t\t\t\t\t\t\t\t\tvar font = svg.CreateElement(fonts[f]);\n +\t\t\t\t\t\t\t\t\t\t\tsvg.Definitions[fontFamily] = font;\n +\t\t\t\t\t\t\t\t\t\t}\n +\t\t\t\t\t\t\t\t\t}\n +\t\t\t\t\t\t\t\t}\n +\t\t\t\t\t\t\t}\n +\t\t\t\t\t\t}\n +\t\t\t\t\t}\n +\t\t\t\t}\n +\t\t\t}\n +\t\t}\n +\t\tsvg.Element.style.prototype = new svg.Element.ElementBase;\n +\t\t\n +\t\t// use element \n +\t\tsvg.Element.use = function(node) {\n +\t\t\tthis.base = svg.Element.RenderedElementBase;\n +\t\t\tthis.base(node);\n +\t\t\t\n +\t\t\tthis.baseSetContext = this.setContext;\n +\t\t\tthis.setContext = function(ctx) {\n +\t\t\t\tthis.baseSetContext(ctx);\n +\t\t\t\tif (this.attribute(\'x\').hasValue()) ctx.translate(this.attribute(\'x\').Length.toPixels(\'x\'), 0);\n +\t\t\t\tif (this.attribute(\'y\').hasValue()) ctx.translate(0, this.attribute(\'y\').Length.toPixels(\'y\'));\n +\t\t\t}\n +\t\t\t\n +\t\t\tthis.getDefinition = function() {\n +\t\t\t\tvar element = this.attribute(\'xlink:href\').Definition.getDefinition();\n +\t\t\t\tif (this.attribute(\'width\').hasValue()) element.attribute(\'width\', true).value = this.attribute(\'width\').value;\n +\t\t\t\tif (this.attribute(\'height\').hasValue()) element.attribute(\'height\', true).value = this.attribute(\'height\').value;\n +\t\t\t\treturn element;\n +\t\t\t}\n +\t\t\t\n +\t\t\tthis.path = function(ctx) {\n +\t\t\t\tvar element = this.getDefinition();\n +\t\t\t\tif (element != null) element.path(ctx);\n +\t\t\t}\n +\t\t\t\n +\t\t\tthis.renderChildren = function(ctx) {\n +\t\t\t\tvar element = this.getDefinition();\n +\t\t\t\tif (element != null) element.render(ctx);\n +\t\t\t}\n +\t\t}\n +\t\tsvg.Element.use.prototype = new svg.Element.RenderedElementBase;\n +\t\t\n +\t\t// mask element\n +\t\tsvg.Element.mask = function(node) {\n +\t\t\tthis.base = svg.Element.ElementBase;\n +\t\t\tthis.base(node);\n +\t\t\t\t\t\t\n +\t\t\tthis.apply = function(ctx, element) {\n +\t\t\t\t// render as temp svg\t\n +\t\t\t\tvar x = this.attribute(\'x\').Length.toPixels(\'x\');\n +\t\t\t\tvar y = this.attribute(\'y\').Length.toPixels(\'y\');\n +\t\t\t\tvar width = this.attribute(\'width\').Length.toPixels(\'x\');\n +\t\t\t\tvar height = this.attribute(\'height\').Length.toPixels(\'y\');\n +\t\t\t\t\n +\t\t\t\t// temporarily remove mask to avoid recursion\n +\t\t\t\tvar mask = element.attribute(\'mask\').value;\n +\t\t\t\telement.attribute(\'mask\').value = \'\';\n +\t\t\t\t\n +\t\t\t\t\tvar cMask = document.createElement(\'canvas\');\n +\t\t\t\t\tcMask.width = x + width;\n +\t\t\t\t\tcMask.height = y + height;\n +\t\t\t\t\tvar maskCtx = cMask.getContext(\'2d\');\n +\t\t\t\t\tthis.renderChildren(maskCtx);\n +\t\t\t\t\n +\t\t\t\t\tvar c = document.createElement(\'canvas\');\n +\t\t\t\t\tc.width = x + width;\n +\t\t\t\t\tc.height = y + height;\n +\t\t\t\t\tvar tempCtx = c.getContext(\'2d\');\n +\t\t\t\t\telement.render(tempCtx);\n +\t\t\t\t\ttempCtx.globalCompositeOperation = \'destination-in\';\n +\t\t\t\t\ttempCtx.fillStyle = maskCtx.createPattern(cMask, \'no-repeat\');\n +\t\t\t\t\ttempCtx.fillRect(0, 0, x + width, y + height);\n +\t\t\t\t\t\n +\t\t\t\t\tctx.fillStyle = tempCtx.createPattern(c, \'no-repeat\');\n +\t\t\t\t\tctx.fillRect(0, 0, x + width, y + height);\n +\t\t\t\t\t\n +\t\t\t\t// reassign mask\n +\t\t\t\telement.attribute(\'mask\').value = mask;\t\n +\t\t\t}\n +\t\t\t\n +\t\t\tthis.render = function(ctx) {\n +\t\t\t\t// NO RENDER\n +\t\t\t}\n +\t\t}\n +\t\tsvg.Element.mask.prototype = new svg.Element.ElementBase;\n +\t\t\n +\t\t// clip element\n +\t\tsvg.Element.clipPath = function(node) {\n +\t\t\tthis.base = svg.Element.ElementBase;\n +\t\t\tthis.base(node);\n +\t\t\t\n +\t\t\tthis.apply = function(ctx) {\n +\t\t\t\tfor (var i=0; i<this.children.length; i++) {\n +\t\t\t\t\tif (this.children[i].path) {\n +\t\t\t\t\t\tthis.children[i].path(ctx);\n +\t\t\t\t\t\tctx.clip();\n +\t\t\t\t\t}\n +\t\t\t\t}\n +\t\t\t}\n +\t\t\t\n +\t\t\tthis.render = function(ctx) {\n +\t\t\t\t// NO RENDER\n +\t\t\t}\n +\t\t}\n +\t\tsvg.Element.clipPath.prototype = new svg.Element.ElementBase;\n +\n +\t\t// filters\n +\t\tsvg.Element.filter = function(node) {\n +\t\t\tthis.base = svg.Element.ElementBase;\n +\t\t\tthis.base(node);\n +\t\t\t\t\t\t\n +\t\t\tthis.apply = function(ctx, element) {\n +\t\t\t\t// render as temp svg\t\n +\t\t\t\tvar bb = element.getBoundingBox();\n +\t\t\t\tvar x = this.attribute(\'x\').Length.toPixels(\'x\');\n +\t\t\t\tvar y = this.attribute(\'y\').Length.toPixels(\'y\');\n +\t\t\t\tif (x == 0 || y == 0) {\n +\t\t\t\t\tx = bb.x1;\n +\t\t\t\t\ty = bb.y1;\n +\t\t\t\t}\n +\t\t\t\tvar width = this.attribute(\'width\').Length.toPixels(\'x\');\n +\t\t\t\tvar height = this.attribute(\'height\').Length.toPixels(\'y\');\n +\t\t\t\tif (width == 0 || height == 0) {\n +\t\t\t\t\twidth = bb.width();\n +\t\t\t\t\theight = bb.height();\n +\t\t\t\t}\n +\t\t\t\t\n +\t\t\t\t// temporarily remove filter to avoid recursion\n +\t\t\t\tvar filter = element.style(\'filter\').value;\n +\t\t\t\telement.style(\'filter\').value = \'\';\n +\t\t\t\t\n +\t\t\t\t// max filter distance\n +\t\t\t\tvar extraPercent = .20;\n +\t\t\t\tvar px = extraPercent * width;\n +\t\t\t\tvar py = extraPercent * height;\n +\t\t\t\t\n +\t\t\t\tvar c = document.createElement(\'canvas\');\n +\t\t\t\tc.width = width + 2*px;\n +\t\t\t\tc.height = height + 2*py;\n +\t\t\t\tvar tempCtx = c.getContext(\'2d\');\n +\t\t\t\ttempCtx.translate(-x + px, -y + py);\n +\t\t\t\telement.render(tempCtx);\n +\t\t\t\n +\t\t\t\t// apply filters\n +\t\t\t\tfor (var i=0; i<this.children.length; i++) {\n +\t\t\t\t\tthis.children[i].apply(tempCtx, 0, 0, width + 2*px, height + 2*py);\n +\t\t\t\t}\n +\t\t\t\t\n +\t\t\t\t// render on me\n +\t\t\t\tctx.drawImage(c, 0, 0, width + 2*px, height + 2*py, x - px, y - py, width + 2*px, height + 2*py);\n +\t\t\t\t\n +\t\t\t\t// reassign filter\n +\t\t\t\telement.style(\'filter\', true).value = filter;\t\n +\t\t\t}\n +\t\t\t\n +\t\t\tthis.render = function(ctx) {\n +\t\t\t\t// NO RENDER\n +\t\t\t}\t\t\n +\t\t}\n +\t\tsvg.Element.filter.prototype = new svg.Element.ElementBase;\n +\t\t\n +\t\tsvg.Element.feGaussianBlur = function(node) {\n +\t\t\tthis.base = svg.Element.ElementBase;\n +\t\t\tthis.base(node);\t\n +\t\t\t\n +\t\t\tfunction make_fgauss(sigma) {\n +\t\t\t\tsigma = Math.max(sigma, 0.01);\t\t\t \n +\t\t\t\tvar len = Math.ceil(sigma * 4.0) + 1; \n +\t\t\t\tmask = []; \n +\t\t\t\tfor (var i = 0; i < len; i++) { \n +\t\t\t\t\tmask[i] = Math.exp(-0.5 * (i / sigma) * (i / sigma)); \n +\t\t\t\t} \n +\t\t\t\treturn mask; \n +\t\t\t}\n +\t\t\t\n +\t\t\tfunction normalize(mask) {\n +\t\t\t\tvar sum = 0;\n +\t\t\t\tfor (var i = 1; i < mask.length; i++) {\n +\t\t\t\t\tsum += Math.abs(mask[i]);\n +\t\t\t\t}\n +\t\t\t\tsum = 2 * sum + Math.abs(mask[0]);\n +\t\t\t\tfor (var i = 0; i < mask.length; i++) {\n +\t\t\t\t\tmask[i] /= sum;\n +\t\t\t\t}\n +\t\t\t\treturn mask;\n +\t\t\t}\n +\t\t\t\n +\t\t\tfunction convolve_even(src, dst, mask, width, height) {\n +\t\t\t for (var y = 0; y < height; y++) {\n +\t\t\t\tfor (var x = 0; x < width; x++) {\n +\t\t\t\t var a = imGet(src, x, y, width, height, 3)/255;\n +\t\t\t\t for (var rgba = 0; rgba < 4; rgba++) {\t\t\t\t\t \n +\t\t\t\t\t var sum = mask[0] * (a==0?255:imGet(src, x, y, width, height, rgba)) * (a==0||rgba==3?1:a);\n +\t\t\t\t\t for (var i = 1; i < mask.length; i++) {\n +\t\t\t\t\t\tvar a1 = imGet(src, Math.max(x-i,0), y, width, height, 3)/255;\n +\t\t\t\t\t var a2 = imGet(src, Math.min(x+i, width-1), y, width, height, 3)/255;\n +\t\t\t\t\t\tsum += mask[i] * \n +\t\t\t\t\t\t ((a1==0?255:imGet(src, Math.max(x-i,0), y, width, height, rgba)) * (a1==0||rgba==3?1:a1) + \n +\t\t\t\t\t\t (a2==0?255:imGet(src, Math.min(x+i, width-1), y, width, height, rgba)) * (a2==0||rgba==3?1:a2));\n +\t\t\t\t\t }\n +\t\t\t\t\t imSet(dst, y, x, height, width, rgba, sum);\n +\t\t\t\t }\t\t\t \n +\t\t\t\t}\n +\t\t\t }\n +\t\t\t}\t\t\n +\n +\t\t\tfunction imGet(img, x, y, width, height, rgba) {\n +\t\t\t\treturn img[y*width*4 + x*4 + rgba];\n +\t\t\t}\n +\t\t\t\n +\t\t\tfunction imSet(img, x, y, width, height, rgba, val) {\n +\t\t\t\timg[y*width*4 + x*4 + rgba] = val;\n +\t\t\t}\n +\t\t\t\t\t\t\n +\t\t\tfunction blur(ctx, width, height, sigma)\n +\t\t\t{\n +\t\t\t\tvar srcData = ctx.getImageData(0, 0, width, height);\n +\t\t\t\tvar mask = make_fgauss(sigma);\n +\t\t\t\tmask = normalize(mask);\n +\t\t\t\ttmp = [];\n +\t\t\t\tconvolve_even(srcData.data, tmp, mask, width, height);\n +\t\t\t\tconvolve_even(tmp, srcData.data, mask, height, width);\n +\t\t\t\tctx.clearRect(0, 0, width, height);\n +\t\t\t\tctx.putImageData(srcData, 0, 0);\n +\t\t\t}\t\t\t\n +\t\t\n +\t\t\tthis.apply = function(ctx, x, y, width, height) {\n +\t\t\t\t// assuming x==0 && y==0 for now\n +\t\t\t\tblur(ctx, width, height, this.attribute(\'stdDeviation\').numValue());\n +\t\t\t}\n +\t\t}\n +\t\tsvg.Element.filter.prototype = new svg.Element.feGaussianBlur;\n +\t\t\n +\t\t// title element, do nothing\n +\t\tsvg.Element.title = function(node) {\n +\t\t}\n +\t\tsvg.Element.title.prototype = new svg.Element.ElementBase;\n +\n +\t\t// desc element, do nothing\n +\t\tsvg.Element.desc = function(node) {\n +\t\t}\n +\t\tsvg.Element.desc.prototype = new svg.Element.ElementBase;\t\t\n +\t\t\n +\t\tsvg.Element.MISSING = function(node) {\n +\t\t\tconsole.log(\'ERROR: Element \\\'\' + node.nodeName + \'\\\' not yet implemented.\');\n +\t\t}\n +\t\tsvg.Element.MISSING.prototype = new svg.Element.ElementBase;\n +\t\t\n +\t\t// element factory\n +\t\tsvg.CreateElement = function(node) {\t\n +\t\t\tvar className = node.nodeName.replace(/^[^:]+:/,\'\'); // remove namespace\n +\t\t\tclassName = className.replace(/\\-/g,\'\'); // remove dashes\n +\t\t\tvar e = null;\n +\t\t\tif (typeof(svg.Element[className]) != \'undefined\') {\n +\t\t\t\te = new svg.Element[className](node);\n +\t\t\t}\n +\t\t\telse {\n +\t\t\t\te = new svg.Element.MISSING(node);\n +\t\t\t}\n +\n +\t\t\te.type = node.nodeName;\n +\t\t\treturn e;\n +\t\t}\n +\t\t\t\t\n +\t\t// load from url\n +\t\tsvg.load = function(ctx, url) {\n +\t\t\tsvg.loadXml(ctx, svg.ajax(url));\n +\t\t}\n +\t\t\n +\t\t// load from xml\n +\t\tsvg.loadXml = function(ctx, xml) {\n +\t\t\tsvg.loadXmlDoc(ctx, svg.parseXml(xml));\n +\t\t}\n +\t\t\n +\t\tsvg.loadXmlDoc = function(ctx, dom) {\n +\t\t\tsvg.init(ctx);\n +\t\t\t\n +\t\t\tvar mapXY = function(p) {\n +\t\t\t\tvar e = ctx.canvas;\n +\t\t\t\twhile (e) {\n +\t\t\t\t\tp.x -= e.offsetLeft;\n +\t\t\t\t\tp.y -= e.offsetTop;\n +\t\t\t\t\te = e.offsetParent;\n +\t\t\t\t}\n +\t\t\t\tif (window.scrollX) p.x += window.scrollX;\n +\t\t\t\tif (window.scrollY) p.y += window.scrollY;\n +\t\t\t\treturn p;\n +\t\t\t}\n +\t\t\t\n +\t\t\t// bind mouse\n +\t\t\tif (svg.opts[\'ignoreMouse\'] != true) {\n +\t\t\t\tctx.canvas.onclick = function(e) {\n +\t\t\t\t\tvar p = mapXY(new svg.Point(e != null ? e.clientX : event.clientX, e != null ? e.clientY : event.clientY));\n +\t\t\t\t\tsvg.Mouse.onclick(p.x, p.y);\n +\t\t\t\t};\n +\t\t\t\tctx.canvas.onmousemove = function(e) {\n +\t\t\t\t\tvar p = mapXY(new svg.Point(e != null ? e.clientX : event.clientX, e != null ? e.clientY : event.clientY));\n +\t\t\t\t\tsvg.Mouse.onmousemove(p.x, p.y);\n +\t\t\t\t};\n +\t\t\t}\n +\t\t\n +\t\t\tvar e = svg.CreateElement(dom.documentElement);\n +\t\t\te.root = true;\n +\t\t\t\t\t\n +\t\t\t// render loop\n +\t\t\tvar isFirstRender = true;\n +\t\t\tvar draw = function() {\n +\t\t\t\tsvg.ViewPort.Clear();\n +\t\t\t\tif (ctx.canvas.parentNode) svg.ViewPort.SetCurrent(ctx.canvas.parentNode.clientWidth, ctx.canvas.parentNode.clientHeight);\n +\t\t\t\n +\t\t\t\tif (svg.opts[\'ignoreDimensions\'] != true) {\n +\t\t\t\t\t// set canvas size\n +\t\t\t\t\tif (e.style(\'width\').hasValue()) {\n +\t\t\t\t\t\tctx.canvas.width = e.style(\'width\').Length.toPixels(\'x\');\n +\t\t\t\t\t\tctx.canvas.style.width = ctx.canvas.width + \'px\';\n +\t\t\t\t\t}\n +\t\t\t\t\tif (e.style(\'height\').hasValue()) {\n +\t\t\t\t\t\tctx.canvas.height = e.style(\'height\').Length.toPixels(\'y\');\n +\t\t\t\t\t\tctx.canvas.style.height = ctx.canvas.height + \'px\';\n +\t\t\t\t\t}\n +\t\t\t\t}\n +\t\t\t\tvar cWidth = ctx.canvas.clientWidth || ctx.canvas.width;\n +\t\t\t\tvar cHeight = ctx.canvas.clientHeight || ctx.canvas.height;\n +\t\t\t\tsvg.ViewPort.SetCurrent(cWidth, cHeight);\t\t\n +\t\t\t\t\n +\t\t\t\tif (svg.opts != null && svg.opts[\'offsetX\'] != null) e.attribute(\'x\', true).value = svg.opts[\'offsetX\'];\n +\t\t\t\tif (svg.opts != null && svg.opts[\'offsetY\'] != null) e.attribute(\'y\', true).value = svg.opts[\'offsetY\'];\n +\t\t\t\tif (svg.opts != null && svg.opts[\'scaleWidth\'] != null && svg.opts[\'scaleHeight\'] != null) {\n +\t\t\t\t\tvar xRatio = 1, yRatio = 1;\n +\t\t\t\t\tif (e.attribute(\'width\').hasValue()) xRatio = e.attribute(\'width\').Length.toPixels(\'x\') / svg.opts[\'scaleWidth\'];\n +\t\t\t\t\tif (e.attribute(\'height\').hasValue()) yRatio = e.attribute(\'height\').Length.toPixels(\'y\') / svg.opts[\'scaleHeight\'];\n +\t\t\t\t\n +\t\t\t\t\te.attribute(\'width\', true).value = svg.opts[\'scaleWidth\'];\n +\t\t\t\t\te.attribute(\'height\', true).value = svg.opts[\'scaleHeight\'];\t\t\t\n +\t\t\t\t\te.attribute(\'viewBox\', true).value = \'0 0 \' + (cWidth * xRatio) + \' \' + (cHeight * yRatio);\n +\t\t\t\t\te.attribute(\'preserveAspectRatio\', true).value = \'none\';\n +\t\t\t\t}\n +\t\t\t\n +\t\t\t\t// clear and render\n +\t\t\t\tif (svg.opts[\'ignoreClear\'] != true) {\n +\t\t\t\t\tctx.clearRect(0, 0, cWidth, cHeight);\n +\t\t\t\t}\n +\t\t\t\te.render(ctx);\n +\t\t\t\tif (isFirstRender) {\n +\t\t\t\t\tisFirstRender = false;\n +\t\t\t\t\tif (svg.opts != null && typeof(svg.opts[\'renderCallback\']) == \'function\') svg.opts[\'renderCallback\']();\n +\t\t\t\t}\t\t\t\n +\t\t\t}\n +\t\t\t\n +\t\t\tvar waitingForImages = true;\n +\t\t\tif (svg.ImagesLoaded()) {\n +\t\t\t\twaitingForImages = false;\n +\t\t\t\tdraw();\n +\t\t\t}\n +\t\t\tsvg.intervalID = setInterval(function() { \n +\t\t\t\tvar needUpdate = false;\n +\t\t\t\t\n +\t\t\t\tif (waitingForImages && svg.ImagesLoaded()) {\n +\t\t\t\t\twaitingForImages = false;\n +\t\t\t\t\tneedUpdate = true;\n +\t\t\t\t}\n +\t\t\t\n +\t\t\t\t// need update from mouse events?\n +\t\t\t\tif (svg.opts[\'ignoreMouse\'] != true) {\n +\t\t\t\t\tneedUpdate = needUpdate | svg.Mouse.hasEvents();\n +\t\t\t\t}\n +\t\t\t\n +\t\t\t\t// need update from animations?\n +\t\t\t\tif (svg.opts[\'ignoreAnimation\'] != true) {\n +\t\t\t\t\tfor (var i=0; i<svg.Animations.length; i++) {\n +\t\t\t\t\t\tneedUpdate = needUpdate | svg.Animations[i].update(1000 / svg.FRAMERATE);\n +\t\t\t\t\t}\n +\t\t\t\t}\n +\t\t\t\t\n +\t\t\t\t// need update from redraw?\n +\t\t\t\tif (svg.opts != null && typeof(svg.opts[\'forceRedraw\']) == \'function\') {\n +\t\t\t\t\tif (svg.opts[\'forceRedraw\']() == true) needUpdate = true;\n +\t\t\t\t}\n +\t\t\t\t\n +\t\t\t\t// render if needed\n +\t\t\t\tif (needUpdate) {\n +\t\t\t\t\tdraw();\t\t\t\t\n +\t\t\t\t\tsvg.Mouse.runEvents(); // run and clear our events\n +\t\t\t\t}\n +\t\t\t}, 1000 / svg.FRAMERATE);\n +\t\t}\n +\t\t\n +\t\tsvg.stop = function() {\n +\t\t\tif (svg.intervalID) {\n +\t\t\t\tclearInterval(svg.intervalID);\n +\t\t\t}\n +\t\t}\n +\t\t\n +\t\tsvg.Mouse = new (function() {\n +\t\t\tthis.events = [];\n +\t\t\tthis.hasEvents = function() { return this.events.length != 0; }\n +\t\t\n +\t\t\tthis.onclick = function(x, y) {\n +\t\t\t\tthis.events.push({ type: \'onclick\', x: x, y: y, \n +\t\t\t\t\trun: function(e) { if (e.onclick) e.onclick(); }\n +\t\t\t\t});\n +\t\t\t}\n +\t\t\t\n +\t\t\tthis.onmousemove = function(x, y) {\n +\t\t\t\tthis.events.push({ type: \'onmousemove\', x: x, y: y,\n +\t\t\t\t\trun: function(e) { if (e.onmousemove) e.onmousemove(); }\n +\t\t\t\t});\n +\t\t\t}\t\t\t\n +\t\t\t\n +\t\t\tthis.eventElements = [];\n +\t\t\t\n +\t\t\tthis.checkPath = function(element, ctx) {\n +\t\t\t\tfor (var i=0; i<this.events.length; i++) {\n +\t\t\t\t\tvar e = this.events[i];\n +\t\t\t\t\tif (ctx.isPointInPath && ctx.isPointInPath(e.x, e.y)) this.eventElements[i] = element;\n +\t\t\t\t}\n +\t\t\t}\n +\t\t\t\n +\t\t\tthis.checkBoundingBox = function(element, bb) {\n +\t\t\t\tfor (var i=0; i<this.events.length; i++) {\n +\t\t\t\t\tvar e = this.events[i];\n +\t\t\t\t\tif (bb.isPointInBox(e.x, e.y)) this.eventElements[i] = element;\n +\t\t\t\t}\t\t\t\n +\t\t\t}\n +\t\t\t\n +\t\t\tthis.runEvents = function() {\n +\t\t\t\tsvg.ctx.canvas.style.cursor = \'\';\n +\t\t\t\t\n +\t\t\t\tfor (var i=0; i<this.events.length; i++) {\n +\t\t\t\t\tvar e = this.events[i];\n +\t\t\t\t\tvar element = this.eventElements[i];\n +\t\t\t\t\twhile (element) {\n +\t\t\t\t\t\te.run(element);\n +\t\t\t\t\t\telement = element.parent;\n +\t\t\t\t\t}\n +\t\t\t\t}\t\t\n +\t\t\t\n +\t\t\t\t// done running, clear\n +\t\t\t\tthis.events = []; \n +\t\t\t\tthis.eventElements = [];\n +\t\t\t}\n +\t\t});\n +\t\t\n +\t\treturn svg;\n +\t}\n +})();\n +\n +if (CanvasRenderingContext2D) {\n +\tCanvasRenderingContext2D.prototype.drawSvg = function(s, dx, dy, dw, dh) {\n +\t\tcanvg(this.canvas, s, { \n +\t\t\tignoreMouse: true, \n +\t\t\tignoreAnimation: true, \n +\t\t\tignoreDimensions: true, \n +\t\t\tignoreClear: true, \n +\t\t\toffsetX: dx, \n +\t\t\toffsetY: dy, \n +\t\t\tscaleWidth: dw, \n +\t\t\tscaleHeight: dh\n +\t\t});\n +\t}\n +} + +]]></string> </value> + </item> + <item> + <key> <string>precondition</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>size</string> </key> + <value> <int>85700</int> </value> + </item> + <item> + <key> <string>title</string> </key> + <value> <string></string> </value> + </item> + </dictionary> + </pickle> + </record> +</ZopeData> diff --git a/bt5/erp5_svg_editor/SkinTemplateItem/portal_skins/erp5_svg_editor/method-draw/lib/canvg/rgbcolor.js.xml b/bt5/erp5_svg_editor/SkinTemplateItem/portal_skins/erp5_svg_editor/method-draw/lib/canvg/rgbcolor.js.xml new file mode 100644 index 0000000000..56c0828c61 --- /dev/null +++ b/bt5/erp5_svg_editor/SkinTemplateItem/portal_skins/erp5_svg_editor/method-draw/lib/canvg/rgbcolor.js.xml @@ -0,0 +1,334 @@ +<?xml version="1.0"?> +<ZopeData> + <record id="1" aka="AAAAAAAAAAE="> + <pickle> + <global name="File" module="OFS.Image"/> + </pickle> + <pickle> + <dictionary> + <item> + <key> <string>_Cacheable__manager_id</string> </key> + <value> <string>anonymous_http_cache</string> </value> + </item> + <item> + <key> <string>_EtagSupport__etag</string> </key> + <value> <string>ts53288375.64</string> </value> + </item> + <item> + <key> <string>__name__</string> </key> + <value> <string>rgbcolor.js</string> </value> + </item> + <item> + <key> <string>content_type</string> </key> + <value> <string>application/javascript</string> </value> + </item> + <item> + <key> <string>data</string> </key> + <value> <string encoding="cdata"><![CDATA[ + +/**\n + * A class to parse color values\n + * @author Stoyan Stefanov <sstoo@gmail.com>\n + * @link http://www.phpied.com/rgb-color-parser-in-javascript/\n + * @license Use it if you like it\n + */\n +function RGBColor(color_string)\n +{\n + this.ok = false;\n +\n + // strip any leading #\n + if (color_string.charAt(0) == \'#\') { // remove # if any\n + color_string = color_string.substr(1,6);\n + }\n +\n + color_string = color_string.replace(/ /g,\'\');\n + color_string = color_string.toLowerCase();\n +\n + // before getting into regexps, try simple matches\n + // and overwrite the input\n + var simple_colors = {\n + aliceblue: \'f0f8ff\',\n + antiquewhite: \'faebd7\',\n + aqua: \'00ffff\',\n + aquamarine: \'7fffd4\',\n + azure: \'f0ffff\',\n + beige: \'f5f5dc\',\n + bisque: \'ffe4c4\',\n + black: \'000000\',\n + blanchedalmond: \'ffebcd\',\n + blue: \'0000ff\',\n + blueviolet: \'8a2be2\',\n + brown: \'a52a2a\',\n + burlywood: \'deb887\',\n + cadetblue: \'5f9ea0\',\n + chartreuse: \'7fff00\',\n + chocolate: \'d2691e\',\n + coral: \'ff7f50\',\n + cornflowerblue: \'6495ed\',\n + cornsilk: \'fff8dc\',\n + crimson: \'dc143c\',\n + cyan: \'00ffff\',\n + darkblue: \'00008b\',\n + darkcyan: \'008b8b\',\n + darkgoldenrod: \'b8860b\',\n + darkgray: \'a9a9a9\',\n + darkgreen: \'006400\',\n + darkkhaki: \'bdb76b\',\n + darkmagenta: \'8b008b\',\n + darkolivegreen: \'556b2f\',\n + darkorange: \'ff8c00\',\n + darkorchid: \'9932cc\',\n + darkred: \'8b0000\',\n + darksalmon: \'e9967a\',\n + darkseagreen: \'8fbc8f\',\n + darkslateblue: \'483d8b\',\n + darkslategray: \'2f4f4f\',\n + darkturquoise: \'00ced1\',\n + darkviolet: \'9400d3\',\n + deeppink: \'ff1493\',\n + deepskyblue: \'00bfff\',\n + dimgray: \'696969\',\n + dodgerblue: \'1e90ff\',\n + feldspar: \'d19275\',\n + firebrick: \'b22222\',\n + floralwhite: \'fffaf0\',\n + forestgreen: \'228b22\',\n + fuchsia: \'ff00ff\',\n + gainsboro: \'dcdcdc\',\n + ghostwhite: \'f8f8ff\',\n + gold: \'ffd700\',\n + goldenrod: \'daa520\',\n + gray: \'808080\',\n + green: \'008000\',\n + greenyellow: \'adff2f\',\n + honeydew: \'f0fff0\',\n + hotpink: \'ff69b4\',\n + indianred : \'cd5c5c\',\n + indigo : \'4b0082\',\n + ivory: \'fffff0\',\n + khaki: \'f0e68c\',\n + lavender: \'e6e6fa\',\n + lavenderblush: \'fff0f5\',\n + lawngreen: \'7cfc00\',\n + lemonchiffon: \'fffacd\',\n + lightblue: \'add8e6\',\n + lightcoral: \'f08080\',\n + lightcyan: \'e0ffff\',\n + lightgoldenrodyellow: \'fafad2\',\n + lightgrey: \'d3d3d3\',\n + lightgreen: \'90ee90\',\n + lightpink: \'ffb6c1\',\n + lightsalmon: \'ffa07a\',\n + lightseagreen: \'20b2aa\',\n + lightskyblue: \'87cefa\',\n + lightslateblue: \'8470ff\',\n + lightslategray: \'778899\',\n + lightsteelblue: \'b0c4de\',\n + lightyellow: \'ffffe0\',\n + lime: \'00ff00\',\n + limegreen: \'32cd32\',\n + linen: \'faf0e6\',\n + magenta: \'ff00ff\',\n + maroon: \'800000\',\n + mediumaquamarine: \'66cdaa\',\n + mediumblue: \'0000cd\',\n + mediumorchid: \'ba55d3\',\n + mediumpurple: \'9370d8\',\n + mediumseagreen: \'3cb371\',\n + mediumslateblue: \'7b68ee\',\n + mediumspringgreen: \'00fa9a\',\n + mediumturquoise: \'48d1cc\',\n + mediumvioletred: \'c71585\',\n + midnightblue: \'191970\',\n + mintcream: \'f5fffa\',\n + mistyrose: \'ffe4e1\',\n + moccasin: \'ffe4b5\',\n + navajowhite: \'ffdead\',\n + navy: \'000080\',\n + oldlace: \'fdf5e6\',\n + olive: \'808000\',\n + olivedrab: \'6b8e23\',\n + orange: \'ffa500\',\n + orangered: \'ff4500\',\n + orchid: \'da70d6\',\n + palegoldenrod: \'eee8aa\',\n + palegreen: \'98fb98\',\n + paleturquoise: \'afeeee\',\n + palevioletred: \'d87093\',\n + papayawhip: \'ffefd5\',\n + peachpuff: \'ffdab9\',\n + peru: \'cd853f\',\n + pink: \'ffc0cb\',\n + plum: \'dda0dd\',\n + powderblue: \'b0e0e6\',\n + purple: \'800080\',\n + red: \'ff0000\',\n + rosybrown: \'bc8f8f\',\n + royalblue: \'4169e1\',\n + saddlebrown: \'8b4513\',\n + salmon: \'fa8072\',\n + sandybrown: \'f4a460\',\n + seagreen: \'2e8b57\',\n + seashell: \'fff5ee\',\n + sienna: \'a0522d\',\n + silver: \'c0c0c0\',\n + skyblue: \'87ceeb\',\n + slateblue: \'6a5acd\',\n + slategray: \'708090\',\n + snow: \'fffafa\',\n + springgreen: \'00ff7f\',\n + steelblue: \'4682b4\',\n + tan: \'d2b48c\',\n + teal: \'008080\',\n + thistle: \'d8bfd8\',\n + tomato: \'ff6347\',\n + turquoise: \'40e0d0\',\n + violet: \'ee82ee\',\n + violetred: \'d02090\',\n + wheat: \'f5deb3\',\n + white: \'ffffff\',\n + whitesmoke: \'f5f5f5\',\n + yellow: \'ffff00\',\n + yellowgreen: \'9acd32\'\n + };\n + for (var key in simple_colors) {\n + if (color_string == key) {\n + color_string = simple_colors[key];\n + }\n + }\n + // emd of simple type-in colors\n +\n + // array of color definition objects\n + var color_defs = [\n + {\n + re: /^rgb\\((\\d{1,3}),\\s*(\\d{1,3}),\\s*(\\d{1,3})\\)$/,\n + example: [\'rgb(123, 234, 45)\', \'rgb(255,234,245)\'],\n + process: function (bits){\n + return [\n + parseInt(bits[1]),\n + parseInt(bits[2]),\n + parseInt(bits[3])\n + ];\n + }\n + },\n + {\n + re: /^(\\w{2})(\\w{2})(\\w{2})$/,\n + example: [\'#00ff00\', \'336699\'],\n + process: function (bits){\n + return [\n + parseInt(bits[1], 16),\n + parseInt(bits[2], 16),\n + parseInt(bits[3], 16)\n + ];\n + }\n + },\n + {\n + re: /^(\\w{1})(\\w{1})(\\w{1})$/,\n + example: [\'#fb0\', \'f0f\'],\n + process: function (bits){\n + return [\n + parseInt(bits[1] + bits[1], 16),\n + parseInt(bits[2] + bits[2], 16),\n + parseInt(bits[3] + bits[3], 16)\n + ];\n + }\n + }\n + ];\n +\n + // search through the definitions to find a match\n + for (var i = 0; i < color_defs.length; i++) {\n + var re = color_defs[i].re;\n + var processor = color_defs[i].process;\n + var bits = re.exec(color_string);\n + if (bits) {\n + channels = processor(bits);\n + this.r = channels[0];\n + this.g = channels[1];\n + this.b = channels[2];\n + this.ok = true;\n + }\n +\n + }\n +\n + // validate/cleanup values\n + this.r = (this.r < 0 || isNaN(this.r)) ? 0 : ((this.r > 255) ? 255 : this.r);\n + this.g = (this.g < 0 || isNaN(this.g)) ? 0 : ((this.g > 255) ? 255 : this.g);\n + this.b = (this.b < 0 || isNaN(this.b)) ? 0 : ((this.b > 255) ? 255 : this.b);\n +\n + // some getters\n + this.toRGB = function () {\n + return \'rgb(\' + this.r + \', \' + this.g + \', \' + this.b + \')\';\n + }\n + this.toHex = function () {\n + var r = this.r.toString(16);\n + var g = this.g.toString(16);\n + var b = this.b.toString(16);\n + if (r.length == 1) r = \'0\' + r;\n + if (g.length == 1) g = \'0\' + g;\n + if (b.length == 1) b = \'0\' + b;\n + return \'#\' + r + g + b;\n + }\n +\n + // help\n + this.getHelpXML = function () {\n +\n + var examples = new Array();\n + // add regexps\n + for (var i = 0; i < color_defs.length; i++) {\n + var example = color_defs[i].example;\n + for (var j = 0; j < example.length; j++) {\n + examples[examples.length] = example[j];\n + }\n + }\n + // add type-in colors\n + for (var sc in simple_colors) {\n + examples[examples.length] = sc;\n + }\n +\n + var xml = document.createElement(\'ul\');\n + xml.setAttribute(\'id\', \'rgbcolor-examples\');\n + for (var i = 0; i < examples.length; i++) {\n + try {\n + var list_item = document.createElement(\'li\');\n + var list_color = new RGBColor(examples[i]);\n + var example_div = document.createElement(\'div\');\n + example_div.style.cssText =\n + \'margin: 3px; \'\n + + \'border: 1px solid black; \'\n + + \'background:\' + list_color.toHex() + \'; \'\n + + \'color:\' + list_color.toHex()\n + ;\n + example_div.appendChild(document.createTextNode(\'test\'));\n + var list_item_value = document.createTextNode(\n + \' \' + examples[i] + \' -> \' + list_color.toRGB() + \' -> \' + list_color.toHex()\n + );\n + list_item.appendChild(example_div);\n + list_item.appendChild(list_item_value);\n + xml.appendChild(list_item);\n +\n + } catch(e){}\n + }\n + return xml;\n +\n + }\n +\n +} + +]]></string> </value> + </item> + <item> + <key> <string>precondition</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>size</string> </key> + <value> <int>8752</int> </value> + </item> + <item> + <key> <string>title</string> </key> + <value> <string></string> </value> + </item> + </dictionary> + </pickle> + </record> +</ZopeData> -- 2.30.9