visage-app 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/.gitignore +9 -0
  2. data/README.md +138 -0
  3. data/Rakefile +33 -0
  4. data/VERSION +1 -0
  5. data/bin/visage +17 -0
  6. data/config.ru +7 -0
  7. data/features/json.feature +66 -0
  8. data/features/site.feature +9 -0
  9. data/features/step_definitions/form_steps.rb +6 -0
  10. data/features/step_definitions/json_steps.rb +79 -0
  11. data/features/step_definitions/result_steps.rb +19 -0
  12. data/features/step_definitions/site_steps.rb +4 -0
  13. data/features/step_definitions/visage_steps.rb +20 -0
  14. data/features/step_definitions/webrat_steps.rb +42 -0
  15. data/features/support/env.rb +36 -0
  16. data/features/visage.feature +11 -0
  17. data/lib/visage/collectd/json.rb +142 -0
  18. data/lib/visage/collectd/profile.rb +36 -0
  19. data/lib/visage/config/fallback-colors.yaml +82 -0
  20. data/lib/visage/config/init.rb +33 -0
  21. data/lib/visage/config/plugin-colors.yaml +63 -0
  22. data/lib/visage/config/profiles.yaml +35 -0
  23. data/lib/visage/config/profiles.yaml.sample +33 -0
  24. data/lib/visage/config.rb +51 -0
  25. data/lib/visage/patches.rb +18 -0
  26. data/lib/visage/public/favicon.gif +0 -0
  27. data/lib/visage/public/javascripts/application.js +4 -0
  28. data/lib/visage/public/javascripts/g.line.js +217 -0
  29. data/lib/visage/public/javascripts/g.raphael.js +7 -0
  30. data/lib/visage/public/javascripts/graph.js +510 -0
  31. data/lib/visage/public/javascripts/mootools-1.2.3-core.js +4036 -0
  32. data/lib/visage/public/javascripts/mootools-1.2.3.1-more.js +104 -0
  33. data/lib/visage/public/javascripts/raphael-min.js +7 -0
  34. data/lib/visage/public/javascripts/raphael.js +3215 -0
  35. data/lib/visage/public/stylesheets/screen.css +96 -0
  36. data/lib/visage/views/index.haml +48 -0
  37. data/lib/visage/views/layout.haml +22 -0
  38. data/lib/visage/views/single.haml +43 -0
  39. data/lib/visage-app.rb +81 -0
  40. metadata +142 -0
@@ -0,0 +1,3215 @@
1
+ /*!
2
+ * Raphael 1.3.0 - JavaScript Vector Library
3
+ *
4
+ * Copyright (c) 2008 - 2009 Dmitry Baranovskiy (http://raphaeljs.com)
5
+ * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
6
+ */
7
+
8
+
9
+ window.Raphael = (function () {
10
+ var separator = /[, ]+/,
11
+ elements = /^(circle|rect|path|ellipse|text|image)$/,
12
+ doc = document,
13
+ win = window,
14
+ oldRaphael = {
15
+ was: "Raphael" in win,
16
+ is: win.Raphael
17
+ },
18
+ R = function () {
19
+ if (R.is(arguments[0], "array")) {
20
+ var a = arguments[0],
21
+ cnv = create[apply](R, a.splice(0, 3 + R.is(a[0], nu))),
22
+ res = cnv.set();
23
+ for (var i = 0, ii = a[length]; i < ii; i++) {
24
+ var j = a[i] || {};
25
+ elements.test(j.type) && res[push](cnv[j.type]().attr(j));
26
+ }
27
+ return res;
28
+ }
29
+ return create[apply](R, arguments);
30
+ },
31
+ Paper = function () {},
32
+ appendChild = "appendChild",
33
+ apply = "apply",
34
+ concat = "concat",
35
+ E = "",
36
+ S = " ",
37
+ split = "split",
38
+ events = "click dblclick mousedown mousemove mouseout mouseover mouseup"[split](S),
39
+ has = "hasOwnProperty",
40
+ join = "join",
41
+ length = "length",
42
+ proto = "prototype",
43
+ lowerCase = String[proto].toLowerCase,
44
+ math = Math,
45
+ mmax = math.max,
46
+ mmin = math.min,
47
+ nu = "number",
48
+ toString = "toString",
49
+ objectToString = Object[proto][toString],
50
+ paper = {},
51
+ pow = math.pow,
52
+ push = "push",
53
+ rg = /^(?=[\da-f]$)/,
54
+ ISURL = /^url\(['"]?([^\)]+)['"]?\)$/i,
55
+ colourRegExp = /^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgb\(\s*([\d\.]+\s*,\s*[\d\.]+\s*,\s*[\d\.]+)\s*\)|rgb\(\s*([\d\.]+%\s*,\s*[\d\.]+%\s*,\s*[\d\.]+%)\s*\)|hs[bl]\(\s*([\d\.]+\s*,\s*[\d\.]+\s*,\s*[\d\.]+)\s*\)|hs[bl]\(\s*([\d\.]+%\s*,\s*[\d\.]+%\s*,\s*[\d\.]+%)\s*\))\s*$/i,
56
+ round = math.round,
57
+ setAttribute = "setAttribute",
58
+ toFloat = parseFloat,
59
+ toInt = parseInt,
60
+ upperCase = String[proto].toUpperCase,
61
+ availableAttrs = {"clip-rect": "0 0 1e9 1e9", cursor: "default", cx: 0, cy: 0, fill: "#fff", "fill-opacity": 1, font: '10px "Arial"', "font-family": '"Arial"', "font-size": "10", "font-style": "normal", "font-weight": 400, gradient: 0, height: 0, href: "http://raphaeljs.com/", opacity: 1, path: "M0,0", r: 0, rotation: 0, rx: 0, ry: 0, scale: "1 1", src: "", stroke: "#000", "stroke-dasharray": "", "stroke-linecap": "butt", "stroke-linejoin": "butt", "stroke-miterlimit": 0, "stroke-opacity": 1, "stroke-width": 1, target: "_blank", "text-anchor": "middle", title: "Raphael", translation: "0 0", width: 0, x: 0, y: 0},
62
+ availableAnimAttrs = {along: "along", "clip-rect": "csv", cx: nu, cy: nu, fill: "colour", "fill-opacity": nu, "font-size": nu, height: nu, opacity: nu, path: "path", r: nu, rotation: "csv", rx: nu, ry: nu, scale: "csv", stroke: "colour", "stroke-opacity": nu, "stroke-width": nu, translation: "csv", width: nu, x: nu, y: nu},
63
+ rp = "replace";
64
+ R.version = "1.3.0";
65
+ R.type = (win.SVGAngle || doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") ? "SVG" : "VML");
66
+ if (R.type == "VML") {
67
+ var d = document.createElement("div");
68
+ d.innerHTML = '<!--[if vml]><br><br><![endif]-->';
69
+ if (d.childNodes[length] != 2) {
70
+ return null;
71
+ }
72
+ }
73
+ R.svg = !(R.vml = R.type == "VML");
74
+ Paper[proto] = R[proto];
75
+ R._id = 0;
76
+ R._oid = 0;
77
+ R.fn = {};
78
+ R.is = function (o, type) {
79
+ type = lowerCase.call(type);
80
+ return ((type == "object" || type == "undefined") && typeof o == type) || (o == null && type == "null") || lowerCase.call(objectToString.call(o).slice(8, -1)) == type;
81
+ };
82
+ R.setWindow = function (newwin) {
83
+ win = newwin;
84
+ doc = win.document;
85
+ };
86
+ // colour utilities
87
+ var toHex = function (color) {
88
+ if (R.vml) {
89
+ // http://dean.edwards.name/weblog/2009/10/convert-any-colour-value-to-hex-in-msie/
90
+ var trim = /^\s+|\s+$/g;
91
+ toHex = cacher(function (color) {
92
+ var bod;
93
+ color = (color + E)[rp](trim, E);
94
+ try {
95
+ var docum = new ActiveXObject("htmlfile");
96
+ docum.write("<body>");
97
+ docum.close();
98
+ bod = docum.body;
99
+ } catch(e) {
100
+ bod = createPopup().document.body;
101
+ }
102
+ var range = bod.createTextRange();
103
+ try {
104
+ bod.style.color = color;
105
+ var value = range.queryCommandValue("ForeColor");
106
+ value = ((value & 255) << 16) | (value & 65280) | ((value & 16711680) >>> 16);
107
+ return "#" + ("000000" + value[toString](16)).slice(-6);
108
+ } catch(e) {
109
+ return "none";
110
+ }
111
+ });
112
+ } else {
113
+ var i = doc.createElement("i");
114
+ i.title = "Rapha\xebl Colour Picker";
115
+ i.style.display = "none";
116
+ doc.body[appendChild](i);
117
+ toHex = cacher(function (color) {
118
+ i.style.color = color;
119
+ return doc.defaultView.getComputedStyle(i, E).getPropertyValue("color");
120
+ });
121
+ }
122
+ return toHex(color);
123
+ };
124
+ R.hsb2rgb = cacher(function (hue, saturation, brightness) {
125
+ if (R.is(hue, "object") && "h" in hue && "s" in hue && "b" in hue) {
126
+ brightness = hue.b;
127
+ saturation = hue.s;
128
+ hue = hue.h;
129
+ }
130
+ var red,
131
+ green,
132
+ blue;
133
+ if (brightness == 0) {
134
+ return {r: 0, g: 0, b: 0, hex: "#000"};
135
+ }
136
+ if (hue > 1 || saturation > 1 || brightness > 1) {
137
+ hue /= 255;
138
+ saturation /= 255;
139
+ brightness /= 255;
140
+ }
141
+ var i = ~~(hue * 6),
142
+ f = (hue * 6) - i,
143
+ p = brightness * (1 - saturation),
144
+ q = brightness * (1 - (saturation * f)),
145
+ t = brightness * (1 - (saturation * (1 - f)));
146
+ red = [brightness, q, p, p, t, brightness, brightness][i];
147
+ green = [t, brightness, brightness, q, p, p, t][i];
148
+ blue = [p, p, t, brightness, brightness, q, p][i];
149
+ red *= 255;
150
+ green *= 255;
151
+ blue *= 255;
152
+ var rgb = {r: red, g: green, b: blue},
153
+ r = (~~red)[toString](16),
154
+ g = (~~green)[toString](16),
155
+ b = (~~blue)[toString](16);
156
+ r = r[rp](rg, "0");
157
+ g = g[rp](rg, "0");
158
+ b = b[rp](rg, "0");
159
+ rgb.hex = "#" + r + g + b;
160
+ return rgb;
161
+ }, R);
162
+ R.rgb2hsb = cacher(function (red, green, blue) {
163
+ if (R.is(red, "object") && "r" in red && "g" in red && "b" in red) {
164
+ blue = red.b;
165
+ green = red.g;
166
+ red = red.r;
167
+ }
168
+ if (R.is(red, "string")) {
169
+ var clr = R.getRGB(red);
170
+ red = clr.r;
171
+ green = clr.g;
172
+ blue = clr.b;
173
+ }
174
+ if (red > 1 || green > 1 || blue > 1) {
175
+ red /= 255;
176
+ green /= 255;
177
+ blue /= 255;
178
+ }
179
+ var max = mmax(red, green, blue),
180
+ min = mmin(red, green, blue),
181
+ hue,
182
+ saturation,
183
+ brightness = max;
184
+ if (min == max) {
185
+ return {h: 0, s: 0, b: max};
186
+ } else {
187
+ var delta = (max - min);
188
+ saturation = delta / max;
189
+ if (red == max) {
190
+ hue = (green - blue) / delta;
191
+ } else if (green == max) {
192
+ hue = 2 + ((blue - red) / delta);
193
+ } else {
194
+ hue = 4 + ((red - green) / delta);
195
+ }
196
+ hue /= 6;
197
+ hue < 0 && hue++;
198
+ hue > 1 && hue--;
199
+ }
200
+ return {h: hue, s: saturation, b: brightness};
201
+ }, R);
202
+ var p2s = /,?([achlmqrstvxz]),?/gi;
203
+ R._path2string = function () {
204
+ return this.join(",")[rp](p2s, "$1");
205
+ };
206
+ function cacher(f, scope, postprocessor) {
207
+ function newf() {
208
+ var arg = Array[proto].slice.call(arguments, 0),
209
+ args = arg[join]("\u25ba"),
210
+ cache = newf.cache = newf.cache || {},
211
+ count = newf.count = newf.count || [];
212
+ if (cache[has](args)) {
213
+ return postprocessor ? postprocessor(cache[args]) : cache[args];
214
+ }
215
+ count[length] >= 1e3 && delete cache[count.shift()];
216
+ count[push](args);
217
+ cache[args] = f[apply](scope, arg);
218
+ return postprocessor ? postprocessor(cache[args]) : cache[args];
219
+ }
220
+ return newf;
221
+ }
222
+
223
+ R.getRGB = cacher(function (colour) {
224
+ if (!colour || !!((colour = colour + E).indexOf("-") + 1)) {
225
+ return {r: -1, g: -1, b: -1, hex: "none", error: 1};
226
+ }
227
+ if (colour == "none") {
228
+ return {r: -1, g: -1, b: -1, hex: "none"};
229
+ }
230
+ !(({hs: 1, rg: 1})[has](colour.substring(0, 2)) || colour.charAt() == "#") && (colour = toHex(colour));
231
+ var res,
232
+ red,
233
+ green,
234
+ blue,
235
+ t,
236
+ rgb = colour.match(colourRegExp);
237
+ if (rgb) {
238
+ if (rgb[2]) {
239
+ blue = toInt(rgb[2].substring(5), 16);
240
+ green = toInt(rgb[2].substring(3, 5), 16);
241
+ red = toInt(rgb[2].substring(1, 3), 16);
242
+ }
243
+ if (rgb[3]) {
244
+ blue = toInt((t = rgb[3].charAt(3)) + t, 16);
245
+ green = toInt((t = rgb[3].charAt(2)) + t, 16);
246
+ red = toInt((t = rgb[3].charAt(1)) + t, 16);
247
+ }
248
+ if (rgb[4]) {
249
+ rgb = rgb[4][split](/\s*,\s*/);
250
+ red = toFloat(rgb[0]);
251
+ green = toFloat(rgb[1]);
252
+ blue = toFloat(rgb[2]);
253
+ }
254
+ if (rgb[5]) {
255
+ rgb = rgb[5][split](/\s*,\s*/);
256
+ red = toFloat(rgb[0]) * 2.55;
257
+ green = toFloat(rgb[1]) * 2.55;
258
+ blue = toFloat(rgb[2]) * 2.55;
259
+ }
260
+ if (rgb[6]) {
261
+ rgb = rgb[6][split](/\s*,\s*/);
262
+ red = toFloat(rgb[0]);
263
+ green = toFloat(rgb[1]);
264
+ blue = toFloat(rgb[2]);
265
+ return R.hsb2rgb(red, green, blue);
266
+ }
267
+ if (rgb[7]) {
268
+ rgb = rgb[7][split](/\s*,\s*/);
269
+ red = toFloat(rgb[0]) * 2.55;
270
+ green = toFloat(rgb[1]) * 2.55;
271
+ blue = toFloat(rgb[2]) * 2.55;
272
+ return R.hsb2rgb(red, green, blue);
273
+ }
274
+ rgb = {r: red, g: green, b: blue};
275
+ var r = (~~red)[toString](16),
276
+ g = (~~green)[toString](16),
277
+ b = (~~blue)[toString](16);
278
+ r = r[rp](rg, "0");
279
+ g = g[rp](rg, "0");
280
+ b = b[rp](rg, "0");
281
+ rgb.hex = "#" + r + g + b;
282
+ return rgb;
283
+ }
284
+ return {r: -1, g: -1, b: -1, hex: "none", error: 1};
285
+ }, R);
286
+ R.getColor = function (value) {
287
+ var start = this.getColor.start = this.getColor.start || {h: 0, s: 1, b: value || .75},
288
+ rgb = this.hsb2rgb(start.h, start.s, start.b);
289
+ start.h += .075;
290
+ if (start.h > 1) {
291
+ start.h = 0;
292
+ start.s -= .2;
293
+ start.s <= 0 && (this.getColor.start = {h: 0, s: 1, b: start.b});
294
+ }
295
+ return rgb.hex;
296
+ };
297
+ R.getColor.reset = function () {
298
+ delete this.start;
299
+ };
300
+ // path utilities
301
+ R.parsePathString = cacher(function (pathString) {
302
+ if (!pathString) {
303
+ return null;
304
+ }
305
+ var paramCounts = {a: 7, c: 6, h: 1, l: 2, m: 2, q: 4, s: 4, t: 2, v: 1, z: 0},
306
+ data = [];
307
+ if (R.is(pathString, "array") && R.is(pathString[0], "array")) { // rough assumption
308
+ data = pathClone(pathString);
309
+ }
310
+ if (!data[length]) {
311
+ (pathString + E)[rp](/([achlmqstvz])[\s,]*((-?\d*\.?\d*(?:e[-+]?\d+)?\s*,?\s*)+)/ig, function (a, b, c) {
312
+ var params = [],
313
+ name = lowerCase.call(b);
314
+ c[rp](/(-?\d*\.?\d*(?:e[-+]?\d+)?)\s*,?\s*/ig, function (a, b) {
315
+ b && params[push](+b);
316
+ });
317
+ while (params[length] >= paramCounts[name]) {
318
+ data[push]([b][concat](params.splice(0, paramCounts[name])));
319
+ if (!paramCounts[name]) {
320
+ break;
321
+ };
322
+ }
323
+ });
324
+ }
325
+ data[toString] = R._path2string;
326
+ return data;
327
+ });
328
+ R.findDotsAtSegment = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) {
329
+ var t1 = 1 - t,
330
+ x = pow(t1, 3) * p1x + pow(t1, 2) * 3 * t * c1x + t1 * 3 * t * t * c2x + pow(t, 3) * p2x,
331
+ y = pow(t1, 3) * p1y + pow(t1, 2) * 3 * t * c1y + t1 * 3 * t * t * c2y + pow(t, 3) * p2y,
332
+ mx = p1x + 2 * t * (c1x - p1x) + t * t * (c2x - 2 * c1x + p1x),
333
+ my = p1y + 2 * t * (c1y - p1y) + t * t * (c2y - 2 * c1y + p1y),
334
+ nx = c1x + 2 * t * (c2x - c1x) + t * t * (p2x - 2 * c2x + c1x),
335
+ ny = c1y + 2 * t * (c2y - c1y) + t * t * (p2y - 2 * c2y + c1y),
336
+ ax = (1 - t) * p1x + t * c1x,
337
+ ay = (1 - t) * p1y + t * c1y,
338
+ cx = (1 - t) * c2x + t * p2x,
339
+ cy = (1 - t) * c2y + t * p2y,
340
+ alpha = (90 - math.atan((mx - nx) / (my - ny)) * 180 / math.PI);
341
+ (mx > nx || my < ny) && (alpha += 180);
342
+ return {x: x, y: y, m: {x: mx, y: my}, n: {x: nx, y: ny}, start: {x: ax, y: ay}, end: {x: cx, y: cy}, alpha: alpha};
343
+ };
344
+ var pathDimensions = cacher(function (path) {
345
+ if (!path) {
346
+ return {x: 0, y: 0, width: 0, height: 0};
347
+ }
348
+ path = path2curve(path);
349
+ var x = 0,
350
+ y = 0,
351
+ X = [],
352
+ Y = [],
353
+ p;
354
+ for (var i = 0, ii = path[length]; i < ii; i++) {
355
+ p = path[i];
356
+ if (p[0] == "M") {
357
+ x = p[1];
358
+ y = p[2];
359
+ X[push](x);
360
+ Y[push](y);
361
+ } else {
362
+ var dim = curveDim(x, y, p[1], p[2], p[3], p[4], p[5], p[6]);
363
+ X = X[concat](dim.min.x, dim.max.x);
364
+ Y = Y[concat](dim.min.y, dim.max.y);
365
+ x = p[5];
366
+ y = p[6];
367
+ }
368
+ }
369
+ var xmin = mmin[apply](0, X),
370
+ ymin = mmin[apply](0, Y);
371
+ return {
372
+ x: xmin,
373
+ y: ymin,
374
+ width: mmax[apply](0, X) - xmin,
375
+ height: mmax[apply](0, Y) - ymin
376
+ };
377
+ }),
378
+ pathClone = function (pathArray) {
379
+ var res = [];
380
+ if (!R.is(pathArray, "array") || !R.is(pathArray && pathArray[0], "array")) { // rough assumption
381
+ pathArray = R.parsePathString(pathArray);
382
+ }
383
+ for (var i = 0, ii = pathArray[length]; i < ii; i++) {
384
+ res[i] = [];
385
+ for (var j = 0, jj = pathArray[i][length]; j < jj; j++) {
386
+ res[i][j] = pathArray[i][j];
387
+ }
388
+ }
389
+ res[toString] = R._path2string;
390
+ return res;
391
+ },
392
+ pathToRelative = cacher(function (pathArray) {
393
+ if (!R.is(pathArray, "array") || !R.is(pathArray && pathArray[0], "array")) { // rough assumption
394
+ pathArray = R.parsePathString(pathArray);
395
+ }
396
+ var res = [],
397
+ x = 0,
398
+ y = 0,
399
+ mx = 0,
400
+ my = 0,
401
+ start = 0;
402
+ if (pathArray[0][0] == "M") {
403
+ x = pathArray[0][1];
404
+ y = pathArray[0][2];
405
+ mx = x;
406
+ my = y;
407
+ start++;
408
+ res[push](["M", x, y]);
409
+ }
410
+ for (var i = start, ii = pathArray[length]; i < ii; i++) {
411
+ var r = res[i] = [],
412
+ pa = pathArray[i];
413
+ if (pa[0] != lowerCase.call(pa[0])) {
414
+ r[0] = lowerCase.call(pa[0]);
415
+ switch (r[0]) {
416
+ case "a":
417
+ r[1] = pa[1];
418
+ r[2] = pa[2];
419
+ r[3] = pa[3];
420
+ r[4] = pa[4];
421
+ r[5] = pa[5];
422
+ r[6] = +(pa[6] - x).toFixed(3);
423
+ r[7] = +(pa[7] - y).toFixed(3);
424
+ break;
425
+ case "v":
426
+ r[1] = +(pa[1] - y).toFixed(3);
427
+ break;
428
+ case "m":
429
+ mx = pa[1];
430
+ my = pa[2];
431
+ default:
432
+ for (var j = 1, jj = pa[length]; j < jj; j++) {
433
+ r[j] = +(pa[j] - ((j % 2) ? x : y)).toFixed(3);
434
+ }
435
+ }
436
+ } else {
437
+ r = res[i] = [];
438
+ if (pa[0] == "m") {
439
+ mx = pa[1] + x;
440
+ my = pa[2] + y;
441
+ }
442
+ for (var k = 0, kk = pa[length]; k < kk; k++) {
443
+ res[i][k] = pa[k];
444
+ }
445
+ }
446
+ var len = res[i][length];
447
+ switch (res[i][0]) {
448
+ case "z":
449
+ x = mx;
450
+ y = my;
451
+ break;
452
+ case "h":
453
+ x += +res[i][len - 1];
454
+ break;
455
+ case "v":
456
+ y += +res[i][len - 1];
457
+ break;
458
+ default:
459
+ x += +res[i][len - 2];
460
+ y += +res[i][len - 1];
461
+ }
462
+ }
463
+ res[toString] = R._path2string;
464
+ return res;
465
+ }, 0, pathClone),
466
+ pathToAbsolute = cacher(function (pathArray) {
467
+ if (!R.is(pathArray, "array") || !R.is(pathArray && pathArray[0], "array")) { // rough assumption
468
+ pathArray = R.parsePathString(pathArray);
469
+ }
470
+ var res = [],
471
+ x = 0,
472
+ y = 0,
473
+ mx = 0,
474
+ my = 0,
475
+ start = 0;
476
+ if (pathArray[0][0] == "M") {
477
+ x = +pathArray[0][1];
478
+ y = +pathArray[0][2];
479
+ mx = x;
480
+ my = y;
481
+ start++;
482
+ res[0] = ["M", x, y];
483
+ }
484
+ for (var i = start, ii = pathArray[length]; i < ii; i++) {
485
+ var r = res[i] = [],
486
+ pa = pathArray[i];
487
+ if (pa[0] != upperCase.call(pa[0])) {
488
+ r[0] = upperCase.call(pa[0]);
489
+ switch (r[0]) {
490
+ case "A":
491
+ r[1] = pa[1];
492
+ r[2] = pa[2];
493
+ r[3] = pa[3];
494
+ r[4] = pa[4];
495
+ r[5] = pa[5];
496
+ r[6] = +(pa[6] + x);
497
+ r[7] = +(pa[7] + y);
498
+ break;
499
+ case "V":
500
+ r[1] = +pa[1] + y;
501
+ break;
502
+ case "H":
503
+ r[1] = +pa[1] + x;
504
+ break;
505
+ case "M":
506
+ mx = +pa[1] + x;
507
+ my = +pa[2] + y;
508
+ default:
509
+ for (var j = 1, jj = pa[length]; j < jj; j++) {
510
+ r[j] = +pa[j] + ((j % 2) ? x : y);
511
+ }
512
+ }
513
+ } else {
514
+ for (var k = 0, kk = pa[length]; k < kk; k++) {
515
+ res[i][k] = pa[k];
516
+ }
517
+ }
518
+ switch (r[0]) {
519
+ case "Z":
520
+ x = mx;
521
+ y = my;
522
+ break;
523
+ case "H":
524
+ x = r[1];
525
+ break;
526
+ case "V":
527
+ y = r[1];
528
+ break;
529
+ default:
530
+ x = res[i][res[i][length] - 2];
531
+ y = res[i][res[i][length] - 1];
532
+ }
533
+ }
534
+ res[toString] = R._path2string;
535
+ return res;
536
+ }, null, pathClone),
537
+ l2c = function (x1, y1, x2, y2) {
538
+ return [x1, y1, x2, y2, x2, y2];
539
+ },
540
+ q2c = function (x1, y1, ax, ay, x2, y2) {
541
+ var _13 = 1 / 3,
542
+ _23 = 2 / 3;
543
+ return [
544
+ _13 * x1 + _23 * ax,
545
+ _13 * y1 + _23 * ay,
546
+ _13 * x2 + _23 * ax,
547
+ _13 * y2 + _23 * ay,
548
+ x2,
549
+ y2
550
+ ];
551
+ },
552
+ a2c = function (x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2, recursive) {
553
+ // for more information of where this math came from visit:
554
+ // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes
555
+ var PI = math.PI,
556
+ _120 = PI * 120 / 180,
557
+ rad = PI / 180 * (+angle || 0),
558
+ res = [],
559
+ xy,
560
+ rotate = cacher(function (x, y, rad) {
561
+ var X = x * math.cos(rad) - y * math.sin(rad),
562
+ Y = x * math.sin(rad) + y * math.cos(rad);
563
+ return {x: X, y: Y};
564
+ });
565
+ if (!recursive) {
566
+ xy = rotate(x1, y1, -rad);
567
+ x1 = xy.x;
568
+ y1 = xy.y;
569
+ xy = rotate(x2, y2, -rad);
570
+ x2 = xy.x;
571
+ y2 = xy.y;
572
+ var cos = math.cos(PI / 180 * angle),
573
+ sin = math.sin(PI / 180 * angle),
574
+ x = (x1 - x2) / 2,
575
+ y = (y1 - y2) / 2;
576
+ rx = mmax(rx, math.abs(x));
577
+ ry = mmax(ry, math.abs(y));
578
+ var rx2 = rx * rx,
579
+ ry2 = ry * ry,
580
+ k = (large_arc_flag == sweep_flag ? -1 : 1) *
581
+ math.sqrt(math.abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x))),
582
+ cx = k * rx * y / ry + (x1 + x2) / 2,
583
+ cy = k * -ry * x / rx + (y1 + y2) / 2,
584
+ f1 = math.asin(((y1 - cy) / ry).toFixed(7)),
585
+ f2 = math.asin(((y2 - cy) / ry).toFixed(7));
586
+
587
+ f1 = x1 < cx ? PI - f1 : f1;
588
+ f2 = x2 < cx ? PI - f2 : f2;
589
+ f1 < 0 && (f1 = PI * 2 + f1);
590
+ f2 < 0 && (f2 = PI * 2 + f2);
591
+ if (sweep_flag && f1 > f2) {
592
+ f1 = f1 - PI * 2;
593
+ }
594
+ if (!sweep_flag && f2 > f1) {
595
+ f2 = f2 - PI * 2;
596
+ }
597
+ } else {
598
+ f1 = recursive[0];
599
+ f2 = recursive[1];
600
+ cx = recursive[2];
601
+ cy = recursive[3];
602
+ }
603
+ var df = f2 - f1;
604
+ if (math.abs(df) > _120) {
605
+ var f2old = f2,
606
+ x2old = x2,
607
+ y2old = y2;
608
+ f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1);
609
+ x2 = cx + rx * math.cos(f2);
610
+ y2 = cy + ry * math.sin(f2);
611
+ res = a2c(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [f2, f2old, cx, cy]);
612
+ }
613
+ df = f2 - f1;
614
+ var c1 = math.cos(f1),
615
+ s1 = math.sin(f1),
616
+ c2 = math.cos(f2),
617
+ s2 = math.sin(f2),
618
+ t = math.tan(df / 4),
619
+ hx = 4 / 3 * rx * t,
620
+ hy = 4 / 3 * ry * t,
621
+ m1 = [x1, y1],
622
+ m2 = [x1 + hx * s1, y1 - hy * c1],
623
+ m3 = [x2 + hx * s2, y2 - hy * c2],
624
+ m4 = [x2, y2];
625
+ m2[0] = 2 * m1[0] - m2[0];
626
+ m2[1] = 2 * m1[1] - m2[1];
627
+ if (recursive) {
628
+ return [m2, m3, m4][concat](res);
629
+ } else {
630
+ res = [m2, m3, m4][concat](res)[join]()[split](",");
631
+ var newres = [];
632
+ for (var i = 0, ii = res[length]; i < ii; i++) {
633
+ newres[i] = i % 2 ? rotate(res[i - 1], res[i], rad).y : rotate(res[i], res[i + 1], rad).x;
634
+ }
635
+ return newres;
636
+ }
637
+ },
638
+ findDotAtSegment = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) {
639
+ var t1 = 1 - t;
640
+ return {
641
+ x: pow(t1, 3) * p1x + pow(t1, 2) * 3 * t * c1x + t1 * 3 * t * t * c2x + pow(t, 3) * p2x,
642
+ y: pow(t1, 3) * p1y + pow(t1, 2) * 3 * t * c1y + t1 * 3 * t * t * c2y + pow(t, 3) * p2y
643
+ };
644
+ },
645
+ curveDim = cacher(function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) {
646
+ var a = (c2x - 2 * c1x + p1x) - (p2x - 2 * c2x + c1x),
647
+ b = 2 * (c1x - p1x) - 2 * (c2x - c1x),
648
+ c = p1x - c1x,
649
+ t1 = (-b + math.sqrt(b * b - 4 * a * c)) / 2 / a,
650
+ t2 = (-b - math.sqrt(b * b - 4 * a * c)) / 2 / a,
651
+ y = [p1y, p2y],
652
+ x = [p1x, p2x],
653
+ dot;
654
+ math.abs(t1) > 1e12 && (t1 = .5);
655
+ math.abs(t2) > 1e12 && (t2 = .5);
656
+ if (t1 > 0 && t1 < 1) {
657
+ dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t1);
658
+ x[push](dot.x);
659
+ y[push](dot.y);
660
+ }
661
+ if (t2 > 0 && t2 < 1) {
662
+ dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t2);
663
+ x[push](dot.x);
664
+ y[push](dot.y);
665
+ }
666
+ a = (c2y - 2 * c1y + p1y) - (p2y - 2 * c2y + c1y);
667
+ b = 2 * (c1y - p1y) - 2 * (c2y - c1y);
668
+ c = p1y - c1y;
669
+ t1 = (-b + math.sqrt(b * b - 4 * a * c)) / 2 / a;
670
+ t2 = (-b - math.sqrt(b * b - 4 * a * c)) / 2 / a;
671
+ math.abs(t1) > 1e12 && (t1 = .5);
672
+ math.abs(t2) > 1e12 && (t2 = .5);
673
+ if (t1 > 0 && t1 < 1) {
674
+ dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t1);
675
+ x[push](dot.x);
676
+ y[push](dot.y);
677
+ }
678
+ if (t2 > 0 && t2 < 1) {
679
+ dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t2);
680
+ x[push](dot.x);
681
+ y[push](dot.y);
682
+ }
683
+ return {
684
+ min: {x: mmin[apply](0, x), y: mmin[apply](0, y)},
685
+ max: {x: mmax[apply](0, x), y: mmax[apply](0, y)}
686
+ };
687
+ }),
688
+ path2curve = cacher(function (path, path2) {
689
+ var p = pathToAbsolute(path),
690
+ p2 = path2 && pathToAbsolute(path2),
691
+ attrs = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null},
692
+ attrs2 = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null},
693
+ processPath = function (path, d) {
694
+ var nx, ny;
695
+ if (!path) {
696
+ return ["C", d.x, d.y, d.x, d.y, d.x, d.y];
697
+ }
698
+ !(path[0] in {T:1, Q:1}) && (d.qx = d.qy = null);
699
+ switch (path[0]) {
700
+ case "M":
701
+ d.X = path[1];
702
+ d.Y = path[2];
703
+ break;
704
+ case "A":
705
+ path = ["C"][concat](a2c[apply](0, [d.x, d.y][concat](path.slice(1))));
706
+ break;
707
+ case "S":
708
+ nx = d.x + (d.x - (d.bx || d.x));
709
+ ny = d.y + (d.y - (d.by || d.y));
710
+ path = ["C", nx, ny][concat](path.slice(1));
711
+ break;
712
+ case "T":
713
+ d.qx = d.x + (d.x - (d.qx || d.x));
714
+ d.qy = d.y + (d.y - (d.qy || d.y));
715
+ path = ["C"][concat](q2c(d.x, d.y, d.qx, d.qy, path[1], path[2]));
716
+ break;
717
+ case "Q":
718
+ d.qx = path[1];
719
+ d.qy = path[2];
720
+ path = ["C"][concat](q2c(d.x, d.y, path[1], path[2], path[3], path[4]));
721
+ break;
722
+ case "L":
723
+ path = ["C"][concat](l2c(d.x, d.y, path[1], path[2]));
724
+ break;
725
+ case "H":
726
+ path = ["C"][concat](l2c(d.x, d.y, path[1], d.y));
727
+ break;
728
+ case "V":
729
+ path = ["C"][concat](l2c(d.x, d.y, d.x, path[1]));
730
+ break;
731
+ case "Z":
732
+ path = ["C"][concat](l2c(d.x, d.y, d.X, d.Y));
733
+ break;
734
+ }
735
+ return path;
736
+ },
737
+ fixArc = function (pp, i) {
738
+ if (pp[i][length] > 7) {
739
+ pp[i].shift();
740
+ var pi = pp[i];
741
+ while (pi[length]) {
742
+ pp.splice(i++, 0, ["C"][concat](pi.splice(0, 6)));
743
+ }
744
+ pp.splice(i, 1);
745
+ ii = mmax(p[length], p2 && p2[length] || 0);
746
+ }
747
+ },
748
+ fixM = function (path1, path2, a1, a2, i) {
749
+ if (path1 && path2 && path1[i][0] == "M" && path2[i][0] != "M") {
750
+ path2.splice(i, 0, ["M", a2.x, a2.y]);
751
+ a1.bx = 0;
752
+ a1.by = 0;
753
+ a1.x = path1[i][1];
754
+ a1.y = path1[i][2];
755
+ ii = mmax(p[length], p2 && p2[length] || 0);
756
+ }
757
+ };
758
+ for (var i = 0, ii = mmax(p[length], p2 && p2[length] || 0); i < ii; i++) {
759
+ p[i] = processPath(p[i], attrs);
760
+ fixArc(p, i);
761
+ p2 && (p2[i] = processPath(p2[i], attrs2));
762
+ p2 && fixArc(p2, i);
763
+ fixM(p, p2, attrs, attrs2, i);
764
+ fixM(p2, p, attrs2, attrs, i);
765
+ var seg = p[i],
766
+ seg2 = p2 && p2[i],
767
+ seglen = seg[length],
768
+ seg2len = p2 && seg2[length];
769
+ attrs.x = seg[seglen - 2];
770
+ attrs.y = seg[seglen - 1];
771
+ attrs.bx = toFloat(seg[seglen - 4]) || attrs.x;
772
+ attrs.by = toFloat(seg[seglen - 3]) || attrs.y;
773
+ attrs2.bx = p2 && (toFloat(seg2[seg2len - 4]) || attrs2.x);
774
+ attrs2.by = p2 && (toFloat(seg2[seg2len - 3]) || attrs2.y);
775
+ attrs2.x = p2 && seg2[seg2len - 2];
776
+ attrs2.y = p2 && seg2[seg2len - 1];
777
+ }
778
+ return p2 ? [p, p2] : p;
779
+ }, null, pathClone),
780
+ parseDots = cacher(function (gradient) {
781
+ var dots = [];
782
+ for (var i = 0, ii = gradient[length]; i < ii; i++) {
783
+ var dot = {},
784
+ par = gradient[i].match(/^([^:]*):?([\d\.]*)/);
785
+ dot.color = R.getRGB(par[1]);
786
+ if (dot.color.error) {
787
+ return null;
788
+ }
789
+ dot.color = dot.color.hex;
790
+ par[2] && (dot.offset = par[2] + "%");
791
+ dots[push](dot);
792
+ }
793
+ for (var i = 1, ii = dots[length] - 1; i < ii; i++) {
794
+ if (!dots[i].offset) {
795
+ var start = toFloat(dots[i - 1].offset || 0),
796
+ end = 0;
797
+ for (var j = i + 1; j < ii; j++) {
798
+ if (dots[j].offset) {
799
+ end = dots[j].offset;
800
+ break;
801
+ }
802
+ }
803
+ if (!end) {
804
+ end = 100;
805
+ j = ii;
806
+ }
807
+ end = toFloat(end);
808
+ var d = (end - start) / (j - i + 1);
809
+ for (; i < j; i++) {
810
+ start += d;
811
+ dots[i].offset = start + "%";
812
+ }
813
+ }
814
+ }
815
+ return dots;
816
+ }),
817
+ getContainer = function () {
818
+ var container,
819
+ x,
820
+ y,
821
+ width,
822
+ height;
823
+ if (R.is(arguments[0], "string") || R.is(arguments[0], "object")) {
824
+ if (R.is(arguments[0], "string")) {
825
+ container = doc.getElementById(arguments[0]);
826
+ } else {
827
+ container = arguments[0];
828
+ }
829
+ if (container.tagName) {
830
+ if (arguments[1] == null) {
831
+ return {
832
+ container: container,
833
+ width: container.style.pixelWidth || container.offsetWidth,
834
+ height: container.style.pixelHeight || container.offsetHeight
835
+ };
836
+ } else {
837
+ return {container: container, width: arguments[1], height: arguments[2]};
838
+ }
839
+ }
840
+ } else if (R.is(arguments[0], nu) && arguments[length] > 3) {
841
+ return {container: 1, x: arguments[0], y: arguments[1], width: arguments[2], height: arguments[3]};
842
+ }
843
+ },
844
+ plugins = function (con, add) {
845
+ var that = this;
846
+ for (var prop in add) if (add[has](prop) && !(prop in con)) {
847
+ switch (typeof add[prop]) {
848
+ case "function":
849
+ (function (f) {
850
+ con[prop] = con === that ? f : function () { return f[apply](that, arguments); };
851
+ })(add[prop]);
852
+ break;
853
+ case "object":
854
+ con[prop] = con[prop] || {};
855
+ plugins.call(this, con[prop], add[prop]);
856
+ break;
857
+ default:
858
+ con[prop] = add[prop];
859
+ break;
860
+ }
861
+ }
862
+ },
863
+ tear = function (el, paper) {
864
+ el == paper.top && (paper.top = el.prev);
865
+ el == paper.bottom && (paper.bottom = el.next);
866
+ el.next && (el.next.prev = el.prev);
867
+ el.prev && (el.prev.next = el.next);
868
+ },
869
+ tofront = function (el, paper) {
870
+ if (paper.top === el) {
871
+ return;
872
+ }
873
+ tear(el, paper);
874
+ el.next = null;
875
+ el.prev = paper.top;
876
+ paper.top.next = el;
877
+ paper.top = el;
878
+ },
879
+ toback = function (el, paper) {
880
+ if (paper.bottom === el) {
881
+ return;
882
+ }
883
+ tear(el, paper);
884
+ el.next = paper.bottom;
885
+ el.prev = null;
886
+ paper.bottom.prev = el;
887
+ paper.bottom = el;
888
+ },
889
+ insertafter = function (el, el2, paper) {
890
+ tear(el, paper);
891
+ el2 == paper.top && (paper.top = el);
892
+ el2.next && (el2.next.prev = el);
893
+ el.next = el2.next;
894
+ el.prev = el2;
895
+ el2.next = el;
896
+ },
897
+ insertbefore = function (el, el2, paper) {
898
+ tear(el, paper);
899
+ el2 == paper.bottom && (paper.bottom = el);
900
+ el2.prev && (el2.prev.next = el);
901
+ el.prev = el2.prev;
902
+ el2.prev = el;
903
+ el.next = el2;
904
+ },
905
+ removed = function (methodname) {
906
+ return function () {
907
+ throw new Error("Rapha\xebl: you are calling to method \u201c" + methodname + "\u201d of removed object");
908
+ };
909
+ },
910
+ radial_gradient = /^r(?:\(([^,]+?)\s*,\s*([^\)]+?)\))?/;
911
+
912
+ // SVG
913
+ if (R.svg) {
914
+ Paper[proto].svgns = "http://www.w3.org/2000/svg";
915
+ Paper[proto].xlink = "http://www.w3.org/1999/xlink";
916
+ var round = function (num) {
917
+ return +num + (~~num === num) * .5;
918
+ },
919
+ roundPath = function (path) {
920
+ for (var i = 0, ii = path[length]; i < ii; i++) {
921
+ if (lowerCase.call(path[i][0]) != "a") {
922
+ for (var j = 1, jj = path[i][length]; j < jj; j++) {
923
+ path[i][j] = round(path[i][j]);
924
+ }
925
+ } else {
926
+ path[i][6] = round(path[i][6]);
927
+ path[i][7] = round(path[i][7]);
928
+ }
929
+ }
930
+ return path;
931
+ },
932
+ $ = function (el, attr) {
933
+ if (attr) {
934
+ for (var key in attr) if (attr[has](key)) {
935
+ el[setAttribute](key, attr[key]);
936
+ }
937
+ } else {
938
+ return doc.createElementNS(Paper[proto].svgns, el);
939
+ }
940
+ };
941
+ R[toString] = function () {
942
+ return "Your browser supports SVG.\nYou are running Rapha\xebl " + this.version;
943
+ };
944
+ var thePath = function (pathString, SVG) {
945
+ var el = $("path");
946
+ SVG.canvas && SVG.canvas[appendChild](el);
947
+ var p = new Element(el, SVG);
948
+ p.type = "path";
949
+ setFillAndStroke(p, {fill: "none", stroke: "#000", path: pathString});
950
+ return p;
951
+ };
952
+ var addGradientFill = function (o, gradient, SVG) {
953
+ var type = "linear",
954
+ fx = .5, fy = .5,
955
+ s = o.style;
956
+ gradient = (gradient + E)[rp](radial_gradient, function (all, _fx, _fy) {
957
+ type = "radial";
958
+ if (_fx && _fy) {
959
+ fx = toFloat(_fx);
960
+ fy = toFloat(_fy);
961
+ var dir = ((fy > .5) * 2 - 1);
962
+ pow(fx - .5, 2) + pow(fy - .5, 2) > .25 &&
963
+ (fy = math.sqrt(.25 - pow(fx - .5, 2)) * dir + .5) &&
964
+ fy != .5 &&
965
+ (fy = fy.toFixed(5) - 1e-5 * dir);
966
+ }
967
+ return E;
968
+ });
969
+ gradient = gradient[split](/\s*\-\s*/);
970
+ if (type == "linear") {
971
+ var angle = gradient.shift();
972
+ angle = -toFloat(angle);
973
+ if (isNaN(angle)) {
974
+ return null;
975
+ }
976
+ var vector = [0, 0, math.cos(angle * math.PI / 180), math.sin(angle * math.PI / 180)],
977
+ max = 1 / (mmax(math.abs(vector[2]), math.abs(vector[3])) || 1);
978
+ vector[2] *= max;
979
+ vector[3] *= max;
980
+ if (vector[2] < 0) {
981
+ vector[0] = -vector[2];
982
+ vector[2] = 0;
983
+ }
984
+ if (vector[3] < 0) {
985
+ vector[1] = -vector[3];
986
+ vector[3] = 0;
987
+ }
988
+ }
989
+ var dots = parseDots(gradient);
990
+ if (!dots) {
991
+ return null;
992
+ }
993
+ var el = $(type + "Gradient");
994
+ el.id = "r" + (R._id++)[toString](36);
995
+ $(el, type == "radial" ? {fx: fx, fy: fy} : {x1: vector[0], y1: vector[1], x2: vector[2], y2: vector[3]});
996
+ SVG.defs[appendChild](el);
997
+ for (var i = 0, ii = dots[length]; i < ii; i++) {
998
+ var stop = $("stop");
999
+ $(stop, {
1000
+ offset: dots[i].offset ? dots[i].offset : !i ? "0%" : "100%",
1001
+ "stop-color": dots[i].color || "#fff"
1002
+ });
1003
+ el[appendChild](stop);
1004
+ };
1005
+ $(o, {
1006
+ fill: "url(#" + el.id + ")",
1007
+ opacity: 1,
1008
+ "fill-opacity": 1
1009
+ });
1010
+ s.fill = E;
1011
+ s.opacity = 1;
1012
+ s.fillOpacity = 1;
1013
+ return 1;
1014
+ };
1015
+ var updatePosition = function (o) {
1016
+ var bbox = o.getBBox();
1017
+ $(o.pattern, {patternTransform: R.format("translate({0},{1})", bbox.x, bbox.y)});
1018
+ };
1019
+ var setFillAndStroke = function (o, params) {
1020
+ var dasharray = {
1021
+ "": [0],
1022
+ "none": [0],
1023
+ "-": [3, 1],
1024
+ ".": [1, 1],
1025
+ "-.": [3, 1, 1, 1],
1026
+ "-..": [3, 1, 1, 1, 1, 1],
1027
+ ". ": [1, 3],
1028
+ "- ": [4, 3],
1029
+ "--": [8, 3],
1030
+ "- .": [4, 3, 1, 3],
1031
+ "--.": [8, 3, 1, 3],
1032
+ "--..": [8, 3, 1, 3, 1, 3]
1033
+ },
1034
+ node = o.node,
1035
+ attrs = o.attrs,
1036
+ rot = o.rotate(),
1037
+ addDashes = function (o, value) {
1038
+ value = dasharray[lowerCase.call(value)];
1039
+ if (value) {
1040
+ var width = o.attrs["stroke-width"] || "1",
1041
+ butt = {round: width, square: width, butt: 0}[o.attrs["stroke-linecap"] || params["stroke-linecap"]] || 0,
1042
+ dashes = [];
1043
+ var i = value[length];
1044
+ while (i--) {
1045
+ dashes[i] = value[i] * width + ((i % 2) ? 1 : -1) * butt;
1046
+ }
1047
+ $(node, {"stroke-dasharray": dashes[join](",")});
1048
+ }
1049
+ };
1050
+ params[has]("rotation") && (rot = params.rotation);
1051
+ var rotxy = (rot + E)[split](separator);
1052
+ if (!(rotxy.length - 1)) {
1053
+ rotxy = null;
1054
+ } else {
1055
+ rotxy[1] = +rotxy[1];
1056
+ rotxy[2] = +rotxy[2];
1057
+ }
1058
+ toFloat(rot) && o.rotate(0, true);
1059
+ for (var att in params) if (params[has](att)) {
1060
+ if (!availableAttrs[has](att)) {
1061
+ continue;
1062
+ }
1063
+ var value = params[att];
1064
+ attrs[att] = value;
1065
+ switch (att) {
1066
+ case "rotation":
1067
+ o.rotate(value, true);
1068
+ break;
1069
+ // Hyperlink
1070
+ case "href":
1071
+ case "title":
1072
+ case "target":
1073
+ var pn = node.parentNode;
1074
+ if (lowerCase.call(pn.tagName) != "a") {
1075
+ var hl = $("a");
1076
+ pn.insertBefore(hl, node);
1077
+ hl[appendChild](node);
1078
+ pn = hl;
1079
+ }
1080
+ pn.setAttributeNS(o.Paper[proto].xlink, att, value);
1081
+ break;
1082
+ case "cursor":
1083
+ node.style.cursor = value;
1084
+ break;
1085
+ case "clip-rect":
1086
+ var rect = (value + E)[split](separator);
1087
+ if (rect[length] == 4) {
1088
+ o.clip && o.clip.parentNode.parentNode.removeChild(o.clip.parentNode);
1089
+ var el = $("clipPath"),
1090
+ rc = $("rect");
1091
+ el.id = "r" + (R._id++)[toString](36);
1092
+ $(rc, {
1093
+ x: rect[0],
1094
+ y: rect[1],
1095
+ width: rect[2],
1096
+ height: rect[3]
1097
+ });
1098
+ el[appendChild](rc);
1099
+ o.paper.defs[appendChild](el);
1100
+ $(node, {"clip-path": "url(#" + el.id + ")"});
1101
+ o.clip = rc;
1102
+ }
1103
+ if (!value) {
1104
+ var clip = doc.getElementById(node.getAttribute("clip-path")[rp](/(^url\(#|\)$)/g, E));
1105
+ clip && clip.parentNode.removeChild(clip);
1106
+ $(node, {"clip-path": E});
1107
+ delete o.clip;
1108
+ }
1109
+ break;
1110
+ case "path":
1111
+ if (value && o.type == "path") {
1112
+ attrs.path = roundPath(pathToAbsolute(value));
1113
+ $(node, {d: attrs.path});
1114
+ }
1115
+ break;
1116
+ case "width":
1117
+ node[setAttribute](att, value);
1118
+ if (attrs.fx) {
1119
+ att = "x";
1120
+ value = attrs.x;
1121
+ } else {
1122
+ break;
1123
+ }
1124
+ case "x":
1125
+ if (attrs.fx) {
1126
+ value = -attrs.x - (attrs.width || 0);
1127
+ }
1128
+ case "rx":
1129
+ if (att == "rx" && o.type == "rect") {
1130
+ break;
1131
+ }
1132
+ case "cx":
1133
+ rotxy && (att == "x" || att == "cx") && (rotxy[1] += value - attrs[att]);
1134
+ node[setAttribute](att, round(value));
1135
+ o.pattern && updatePosition(o);
1136
+ break;
1137
+ case "height":
1138
+ node[setAttribute](att, value);
1139
+ if (attrs.fy) {
1140
+ att = "y";
1141
+ value = attrs.y;
1142
+ } else {
1143
+ break;
1144
+ }
1145
+ case "y":
1146
+ if (attrs.fy) {
1147
+ value = -attrs.y - (attrs.height || 0);
1148
+ }
1149
+ case "ry":
1150
+ if (att == "ry" && o.type == "rect") {
1151
+ break;
1152
+ }
1153
+ case "cy":
1154
+ rotxy && (att == "y" || att == "cy") && (rotxy[2] += value - attrs[att]);
1155
+ node[setAttribute](att, round(value));
1156
+ o.pattern && updatePosition(o);
1157
+ break;
1158
+ case "r":
1159
+ if (o.type == "rect") {
1160
+ $(node, {rx: value, ry: value});
1161
+ } else {
1162
+ node[setAttribute](att, value);
1163
+ }
1164
+ break;
1165
+ case "src":
1166
+ if (o.type == "image") {
1167
+ node.setAttributeNS(o.paper.xlink, "href", value);
1168
+ }
1169
+ break;
1170
+ case "stroke-width":
1171
+ node.style.strokeWidth = value;
1172
+ // Need following line for Firefox
1173
+ node[setAttribute](att, value);
1174
+ if (attrs["stroke-dasharray"]) {
1175
+ addDashes(o, attrs["stroke-dasharray"]);
1176
+ }
1177
+ break;
1178
+ case "stroke-dasharray":
1179
+ addDashes(o, value);
1180
+ break;
1181
+ case "translation":
1182
+ var xy = (value + E)[split](separator);
1183
+ xy[0] = +xy[0] || 0;
1184
+ xy[1] = +xy[1] || 0;
1185
+ if (rotxy) {
1186
+ rotxy[1] += xy[0];
1187
+ rotxy[2] += xy[1];
1188
+ }
1189
+ translate.call(o, xy[0], xy[1]);
1190
+ break;
1191
+ case "scale":
1192
+ var xy = (value + E)[split](separator);
1193
+ o.scale(+xy[0] || 1, +xy[1] || +xy[0] || 1, +xy[2] || null, +xy[3] || null);
1194
+ break;
1195
+ case "fill":
1196
+ var isURL = (value + E).match(ISURL);
1197
+ if (isURL) {
1198
+ var el = $("pattern"),
1199
+ ig = $("image");
1200
+ el.id = "r" + (R._id++)[toString](36);
1201
+ $(el, {x: 0, y: 0, patternUnits: "userSpaceOnUse", height: 1, width: 1});
1202
+ $(ig, {x: 0, y: 0});
1203
+ ig.setAttributeNS(o.paper.xlink, "href", isURL[1]);
1204
+ el[appendChild](ig);
1205
+
1206
+ var img = doc.createElement("img");
1207
+ img.style.cssText = "position:absolute;left:-9999em;top-9999em";
1208
+ img.onload = function () {
1209
+ $(el, {width: this.offsetWidth, height: this.offsetHeight});
1210
+ $(ig, {width: this.offsetWidth, height: this.offsetHeight});
1211
+ doc.body.removeChild(this);
1212
+ o.paper.safari();
1213
+ };
1214
+ doc.body[appendChild](img);
1215
+ img.src = isURL[1];
1216
+ o.paper.defs[appendChild](el);
1217
+ node.style.fill = "url(#" + el.id + ")";
1218
+ $(node, {fill: "url(#" + el.id + ")"});
1219
+ o.pattern = el;
1220
+ o.pattern && updatePosition(o);
1221
+ break;
1222
+ }
1223
+ if (!R.getRGB(value).error) {
1224
+ delete params.gradient;
1225
+ delete attrs.gradient;
1226
+ !R.is(attrs.opacity, "undefined") &&
1227
+ R.is(params.opacity, "undefined") &&
1228
+ $(node, {opacity: attrs.opacity});
1229
+ !R.is(attrs["fill-opacity"], "undefined") &&
1230
+ R.is(params["fill-opacity"], "undefined") &&
1231
+ $(node, {"fill-opacity": attrs["fill-opacity"]});
1232
+ } else if ((({circle: 1, ellipse: 1})[has](o.type) || (value + E).charAt() != "r") && addGradientFill(node, value, o.paper)) {
1233
+ attrs.gradient = value;
1234
+ attrs.fill = "none";
1235
+ break;
1236
+ }
1237
+ case "stroke":
1238
+ node[setAttribute](att, R.getRGB(value).hex);
1239
+ break;
1240
+ case "gradient":
1241
+ (({circle: 1, ellipse: 1})[has](o.type) || (value + E).charAt() != "r") && addGradientFill(node, value, o.paper);
1242
+ break;
1243
+ case "opacity":
1244
+ case "fill-opacity":
1245
+ if (attrs.gradient) {
1246
+ var gradient = doc.getElementById(node.getAttribute("fill")[rp](/^url\(#|\)$/g, E));
1247
+ if (gradient) {
1248
+ var stops = gradient.getElementsByTagName("stop");
1249
+ stops[stops[length] - 1][setAttribute]("stop-opacity", value);
1250
+ }
1251
+ break;
1252
+ }
1253
+ default:
1254
+ att == "font-size" && (value = toInt(value, 10) + "px");
1255
+ var cssrule = att[rp](/(\-.)/g, function (w) {
1256
+ return upperCase.call(w.substring(1));
1257
+ });
1258
+ node.style[cssrule] = value;
1259
+ // Need following line for Firefox
1260
+ node[setAttribute](att, value);
1261
+ break;
1262
+ }
1263
+ }
1264
+
1265
+ tuneText(o, params);
1266
+ if (rotxy) {
1267
+ o.rotate(rotxy.join(S));
1268
+ } else {
1269
+ toFloat(rot) && o.rotate(rot, true);
1270
+ }
1271
+ };
1272
+ var leading = 1.2;
1273
+ var tuneText = function (el, params) {
1274
+ if (el.type != "text" || !(params[has]("text") || params[has]("font") || params[has]("font-size") || params[has]("x") || params[has]("y"))) {
1275
+ return;
1276
+ }
1277
+ var a = el.attrs,
1278
+ node = el.node,
1279
+ fontSize = node.firstChild ? toInt(doc.defaultView.getComputedStyle(node.firstChild, E).getPropertyValue("font-size"), 10) : 10;
1280
+
1281
+ if (params[has]("text")) {
1282
+ a.text = params.text;
1283
+ while (node.firstChild) {
1284
+ node.removeChild(node.firstChild);
1285
+ }
1286
+ var texts = (params.text + E)[split]("\n");
1287
+ for (var i = 0, ii = texts[length]; i < ii; i++) if (texts[i]) {
1288
+ var tspan = $("tspan");
1289
+ i && $(tspan, {dy: fontSize * leading, x: a.x});
1290
+ tspan[appendChild](doc.createTextNode(texts[i]));
1291
+ node[appendChild](tspan);
1292
+ }
1293
+ } else {
1294
+ var texts = node.getElementsByTagName("tspan");
1295
+ for (var i = 0, ii = texts[length]; i < ii; i++) {
1296
+ i && $(texts[i], {dy: fontSize * leading, x: a.x});
1297
+ }
1298
+ }
1299
+ $(node, {y: a.y});
1300
+ var bb = el.getBBox(),
1301
+ dif = a.y - (bb.y + bb.height / 2);
1302
+ dif && isFinite(dif) && $(node, {y: a.y + dif});
1303
+ };
1304
+ var Element = function (node, svg) {
1305
+ var X = 0,
1306
+ Y = 0;
1307
+ this[0] = node;
1308
+ this.id = R._oid++;
1309
+ this.node = node;
1310
+ node.raphael = this;
1311
+ this.paper = svg;
1312
+ this.attrs = this.attrs || {};
1313
+ this.transformations = []; // rotate, translate, scale
1314
+ this._ = {
1315
+ tx: 0,
1316
+ ty: 0,
1317
+ rt: {deg: 0, cx: 0, cy: 0},
1318
+ sx: 1,
1319
+ sy: 1
1320
+ };
1321
+ !svg.bottom && (svg.bottom = this);
1322
+ this.prev = svg.top;
1323
+ svg.top && (svg.top.next = this);
1324
+ svg.top = this;
1325
+ this.next = null;
1326
+ };
1327
+ Element[proto].rotate = function (deg, cx, cy) {
1328
+ if (this.removed) {
1329
+ return this;
1330
+ }
1331
+ if (deg == null) {
1332
+ if (this._.rt.cx) {
1333
+ return [this._.rt.deg, this._.rt.cx, this._.rt.cy][join](S);
1334
+ }
1335
+ return this._.rt.deg;
1336
+ }
1337
+ var bbox = this.getBBox();
1338
+ deg = (deg + E)[split](separator);
1339
+ if (deg[length] - 1) {
1340
+ cx = toFloat(deg[1]);
1341
+ cy = toFloat(deg[2]);
1342
+ }
1343
+ deg = toFloat(deg[0]);
1344
+ if (cx != null) {
1345
+ this._.rt.deg = deg;
1346
+ } else {
1347
+ this._.rt.deg += deg;
1348
+ }
1349
+ (cy == null) && (cx = null);
1350
+ this._.rt.cx = cx;
1351
+ this._.rt.cy = cy;
1352
+ cx = cx == null ? bbox.x + bbox.width / 2 : cx;
1353
+ cy = cy == null ? bbox.y + bbox.height / 2 : cy;
1354
+ if (this._.rt.deg) {
1355
+ this.transformations[0] = R.format("rotate({0} {1} {2})", this._.rt.deg, cx, cy);
1356
+ this.clip && $(this.clip, {transform: R.format("rotate({0} {1} {2})", -this._.rt.deg, cx, cy)});
1357
+ } else {
1358
+ this.transformations[0] = E;
1359
+ this.clip && $(this.clip, {transform: E});
1360
+ }
1361
+ $(this.node, {transform: this.transformations[join](S)});
1362
+ return this;
1363
+ };
1364
+ Element[proto].hide = function () {
1365
+ !this.removed && (this.node.style.display = "none");
1366
+ return this;
1367
+ };
1368
+ Element[proto].show = function () {
1369
+ !this.removed && (this.node.style.display = "");
1370
+ return this;
1371
+ };
1372
+ Element[proto].remove = function () {
1373
+ if (this.removed) {
1374
+ return;
1375
+ }
1376
+ tear(this, this.paper);
1377
+ this.node.parentNode.removeChild(this.node);
1378
+ for (var i in this) {
1379
+ delete this[i];
1380
+ }
1381
+ this.removed = true;
1382
+ };
1383
+ Element[proto].getBBox = function () {
1384
+ if (this.removed) {
1385
+ return this;
1386
+ }
1387
+ if (this.type == "path") {
1388
+ return pathDimensions(this.attrs.path);
1389
+ }
1390
+ if (this.node.style.display == "none") {
1391
+ this.show();
1392
+ var hide = true;
1393
+ }
1394
+ var bbox = {};
1395
+ try {
1396
+ bbox = this.node.getBBox();
1397
+ } catch(e) {
1398
+ // Firefox 3.0.x plays badly here
1399
+ } finally {
1400
+ bbox = bbox || {};
1401
+ }
1402
+ if (this.type == "text") {
1403
+ bbox = {x: bbox.x, y: Infinity, width: 0, height: 0};
1404
+ for (var i = 0, ii = this.node.getNumberOfChars(); i < ii; i++) {
1405
+ var bb = this.node.getExtentOfChar(i);
1406
+ (bb.y < bbox.y) && (bbox.y = bb.y);
1407
+ (bb.y + bb.height - bbox.y > bbox.height) && (bbox.height = bb.y + bb.height - bbox.y);
1408
+ (bb.x + bb.width - bbox.x > bbox.width) && (bbox.width = bb.x + bb.width - bbox.x);
1409
+ }
1410
+ }
1411
+ hide && this.hide();
1412
+ return bbox;
1413
+ };
1414
+ Element[proto].attr = function () {
1415
+ if (this.removed) {
1416
+ return this;
1417
+ }
1418
+ if (arguments[length] == 0) {
1419
+ var res = {};
1420
+ for (var i in this.attrs) if (this.attrs[has](i)) {
1421
+ res[i] = this.attrs[i];
1422
+ }
1423
+ this._.rt.deg && (res.rotation = this.rotate());
1424
+ (this._.sx != 1 || this._.sy != 1) && (res.scale = this.scale());
1425
+ res.gradient && res.fill == "none" && (res.fill = res.gradient) && delete res.gradient;
1426
+ return res;
1427
+ }
1428
+ if (arguments[length] == 1 && R.is(arguments[0], "string")) {
1429
+ if (arguments[0] == "translation") {
1430
+ return translate.call(this);
1431
+ }
1432
+ if (arguments[0] == "rotation") {
1433
+ return this.rotate();
1434
+ }
1435
+ if (arguments[0] == "scale") {
1436
+ return this.scale();
1437
+ }
1438
+ if (arguments[0] == "fill" && this.attrs.fill == "none" && this.attrs.gradient) {
1439
+ return this.attrs.gradient;
1440
+ }
1441
+ return this.attrs[arguments[0]];
1442
+ }
1443
+ if (arguments[length] == 1 && R.is(arguments[0], "array")) {
1444
+ var values = {};
1445
+ for (var j in arguments[0]) if (arguments[0][has](j)) {
1446
+ values[arguments[0][j]] = this.attrs[arguments[0][j]];
1447
+ }
1448
+ return values;
1449
+ }
1450
+ if (arguments[length] == 2) {
1451
+ var params = {};
1452
+ params[arguments[0]] = arguments[1];
1453
+ setFillAndStroke(this, params);
1454
+ } else if (arguments[length] == 1 && R.is(arguments[0], "object")) {
1455
+ setFillAndStroke(this, arguments[0]);
1456
+ }
1457
+ return this;
1458
+ };
1459
+ Element[proto].toFront = function () {
1460
+ if (this.removed) {
1461
+ return this;
1462
+ }
1463
+ this.node.parentNode[appendChild](this.node);
1464
+ var svg = this.paper;
1465
+ svg.top != this && tofront(this, svg);
1466
+ return this;
1467
+ };
1468
+ Element[proto].toBack = function () {
1469
+ if (this.removed) {
1470
+ return this;
1471
+ }
1472
+ if (this.node.parentNode.firstChild != this.node) {
1473
+ this.node.parentNode.insertBefore(this.node, this.node.parentNode.firstChild);
1474
+ toback(this, this.paper);
1475
+ var svg = this.paper;
1476
+ }
1477
+ return this;
1478
+ };
1479
+ Element[proto].insertAfter = function (element) {
1480
+ if (this.removed) {
1481
+ return this;
1482
+ }
1483
+ var node = element.node;
1484
+ if (node.nextSibling) {
1485
+ node.parentNode.insertBefore(this.node, node.nextSibling);
1486
+ } else {
1487
+ node.parentNode[appendChild](this.node);
1488
+ }
1489
+ insertafter(this, element, this.paper);
1490
+ return this;
1491
+ };
1492
+ Element[proto].insertBefore = function (element) {
1493
+ if (this.removed) {
1494
+ return this;
1495
+ }
1496
+ var node = element.node;
1497
+ node.parentNode.insertBefore(this.node, node);
1498
+ insertbefore(this, element, this.paper);
1499
+ return this;
1500
+ };
1501
+ var theCircle = function (svg, x, y, r) {
1502
+ x = round(x);
1503
+ y = round(y);
1504
+ var el = $("circle");
1505
+ svg.canvas && svg.canvas[appendChild](el);
1506
+ var res = new Element(el, svg);
1507
+ res.attrs = {cx: x, cy: y, r: r, fill: "none", stroke: "#000"};
1508
+ res.type = "circle";
1509
+ $(el, res.attrs);
1510
+ return res;
1511
+ };
1512
+ var theRect = function (svg, x, y, w, h, r) {
1513
+ x = round(x);
1514
+ y = round(y);
1515
+ var el = $("rect");
1516
+ svg.canvas && svg.canvas[appendChild](el);
1517
+ var res = new Element(el, svg);
1518
+ res.attrs = {x: x, y: y, width: w, height: h, r: r || 0, rx: r || 0, ry: r || 0, fill: "none", stroke: "#000"};
1519
+ res.type = "rect";
1520
+ $(el, res.attrs);
1521
+ return res;
1522
+ };
1523
+ var theEllipse = function (svg, x, y, rx, ry) {
1524
+ x = round(x);
1525
+ y = round(y);
1526
+ var el = $("ellipse");
1527
+ svg.canvas && svg.canvas[appendChild](el);
1528
+ var res = new Element(el, svg);
1529
+ res.attrs = {cx: x, cy: y, rx: rx, ry: ry, fill: "none", stroke: "#000"};
1530
+ res.type = "ellipse";
1531
+ $(el, res.attrs);
1532
+ return res;
1533
+ };
1534
+ var theImage = function (svg, src, x, y, w, h) {
1535
+ var el = $("image");
1536
+ $(el, {x: x, y: y, width: w, height: h, preserveAspectRatio: "none"});
1537
+ el.setAttributeNS(svg.xlink, "href", src);
1538
+ svg.canvas && svg.canvas[appendChild](el);
1539
+ var res = new Element(el, svg);
1540
+ res.attrs = {x: x, y: y, width: w, height: h, src: src};
1541
+ res.type = "image";
1542
+ return res;
1543
+ };
1544
+ var theText = function (svg, x, y, text) {
1545
+ var el = $("text");
1546
+ $(el, {x: x, y: y, "text-anchor": "middle"});
1547
+ svg.canvas && svg.canvas[appendChild](el);
1548
+ var res = new Element(el, svg);
1549
+ res.attrs = {x: x, y: y, "text-anchor": "middle", text: text, font: availableAttrs.font, stroke: "none", fill: "#000"};
1550
+ res.type = "text";
1551
+ setFillAndStroke(res, res.attrs);
1552
+ return res;
1553
+ };
1554
+ var setSize = function (width, height) {
1555
+ this.width = width || this.width;
1556
+ this.height = height || this.height;
1557
+ this.canvas[setAttribute]("width", this.width);
1558
+ this.canvas[setAttribute]("height", this.height);
1559
+ return this;
1560
+ };
1561
+ var create = function () {
1562
+ var con = getContainer[apply](null, arguments),
1563
+ container = con && con.container,
1564
+ x = con.x,
1565
+ y = con.y,
1566
+ width = con.width,
1567
+ height = con.height;
1568
+ if (!container) {
1569
+ throw new Error("SVG container not found.");
1570
+ }
1571
+ var cnvs = $("svg");
1572
+ width = width || 512;
1573
+ height = height || 342;
1574
+ $(cnvs, {
1575
+ xmlns: "http://www.w3.org/2000/svg",
1576
+ version: 1.1,
1577
+ width: width,
1578
+ height: height
1579
+ });
1580
+ if (container == 1) {
1581
+ cnvs.style.cssText = "position:absolute;left:" + x + "px;top:" + y + "px";
1582
+ doc.body[appendChild](cnvs);
1583
+ } else {
1584
+ if (container.firstChild) {
1585
+ container.insertBefore(cnvs, container.firstChild);
1586
+ } else {
1587
+ container[appendChild](cnvs);
1588
+ }
1589
+ }
1590
+ container = new Paper;
1591
+ container.width = width;
1592
+ container.height = height;
1593
+ container.canvas = cnvs;
1594
+ plugins.call(container, container, R.fn);
1595
+ container.clear();
1596
+ return container;
1597
+ };
1598
+ Paper[proto].clear = function () {
1599
+ var c = this.canvas;
1600
+ while (c.firstChild) {
1601
+ c.removeChild(c.firstChild);
1602
+ }
1603
+ this.bottom = this.top = null;
1604
+ (this.desc = $("desc"))[appendChild](doc.createTextNode("Created with Rapha\xebl"));
1605
+ c[appendChild](this.desc);
1606
+ c[appendChild](this.defs = $("defs"));
1607
+ };
1608
+ Paper[proto].remove = function () {
1609
+ this.canvas.parentNode && this.canvas.parentNode.removeChild(this.canvas);
1610
+ for (var i in this) {
1611
+ this[i] = removed(i);
1612
+ }
1613
+ };
1614
+ }
1615
+
1616
+ // VML
1617
+ if (R.vml) {
1618
+ var path2vml = function (path) {
1619
+ var total = /[ahqstv]/ig,
1620
+ command = pathToAbsolute;
1621
+ (path + E).match(total) && (command = path2curve);
1622
+ total = /[clmz]/g;
1623
+ if (command == pathToAbsolute && !(path + E).match(total)) {
1624
+ var map = {M: "m", L: "l", C: "c", Z: "x", m: "t", l: "r", c: "v", z: "x"},
1625
+ bites = /([clmz]),?([^clmz]*)/gi,
1626
+ val = /-?[^,\s-]+/g;
1627
+ var res = (path + E)[rp](bites, function (all, command, args) {
1628
+ var vals = [];
1629
+ args[rp](val, function (value) {
1630
+ vals[push](round(value));
1631
+ });
1632
+ return map[command] + vals;
1633
+ });
1634
+ return res;
1635
+ }
1636
+ var pa = command(path), p, res = [], r;
1637
+ for (var i = 0, ii = pa[length]; i < ii; i++) {
1638
+ p = pa[i];
1639
+ r = lowerCase.call(pa[i][0]);
1640
+ r == "z" && (r = "x");
1641
+ for (var j = 1, jj = p[length]; j < jj; j++) {
1642
+ r += round(p[j]) + (j != jj - 1 ? "," : E);
1643
+ }
1644
+ res[push](r);
1645
+ }
1646
+ return res[join](S);
1647
+ };
1648
+
1649
+ R[toString] = function () {
1650
+ return "Your browser doesn\u2019t support SVG. Falling down to VML.\nYou are running Rapha\xebl " + this.version;
1651
+ };
1652
+ var thePath = function (pathString, VML) {
1653
+ var g = createNode("group");
1654
+ g.style.cssText = "position:absolute;left:0;top:0;width:" + VML.width + "px;height:" + VML.height + "px";
1655
+ g.coordsize = VML.coordsize;
1656
+ g.coordorigin = VML.coordorigin;
1657
+ var el = createNode("shape"), ol = el.style;
1658
+ ol.width = VML.width + "px";
1659
+ ol.height = VML.height + "px";
1660
+ el.coordsize = this.coordsize;
1661
+ el.coordorigin = this.coordorigin;
1662
+ g[appendChild](el);
1663
+ var p = new Element(el, g, VML);
1664
+ p.isAbsolute = true;
1665
+ p.type = "path";
1666
+ p.path = [];
1667
+ p.Path = E;
1668
+ pathString && setFillAndStroke(p, {fill: "none", stroke: "#000", path: pathString});
1669
+ VML.canvas[appendChild](g);
1670
+ return p;
1671
+ };
1672
+ var setFillAndStroke = function (o, params) {
1673
+ o.attrs = o.attrs || {};
1674
+ var node = o.node,
1675
+ a = o.attrs,
1676
+ s = node.style,
1677
+ xy,
1678
+ res = o;
1679
+ for (var par in params) if (params[has](par)) {
1680
+ a[par] = params[par];
1681
+ }
1682
+ params.href && (node.href = params.href);
1683
+ params.title && (node.title = params.title);
1684
+ params.target && (node.target = params.target);
1685
+ params.cursor && (s.cursor = params.cursor);
1686
+ if (params.path && o.type == "path") {
1687
+ a.path = params.path;
1688
+ node.path = path2vml(a.path);
1689
+ }
1690
+ if (params.rotation != null) {
1691
+ o.rotate(params.rotation, true);
1692
+ }
1693
+ if (params.translation) {
1694
+ xy = (params.translation + E)[split](separator);
1695
+ translate.call(o, xy[0], xy[1]);
1696
+ if (o._.rt.cx != null) {
1697
+ o._.rt.cx +=+ xy[0];
1698
+ o._.rt.cy +=+ xy[1];
1699
+ o.setBox(o.attrs, xy[0], xy[1]);
1700
+ }
1701
+ }
1702
+ if (params.scale) {
1703
+ xy = (params.scale + E)[split](separator);
1704
+ o.scale(+xy[0] || 1, +xy[1] || +xy[0] || 1, +xy[2] || null, +xy[3] || null);
1705
+ }
1706
+ if ("clip-rect" in params) {
1707
+ var rect = (params["clip-rect"] + E)[split](separator);
1708
+ if (rect[length] == 4) {
1709
+ rect[2] = +rect[2] + (+rect[0]);
1710
+ rect[3] = +rect[3] + (+rect[1]);
1711
+ var div = node.clipRect || doc.createElement("div"),
1712
+ dstyle = div.style,
1713
+ group = node.parentNode;
1714
+ dstyle.clip = R.format("rect({1}px {2}px {3}px {0}px)", rect);
1715
+ if (!node.clipRect) {
1716
+ dstyle.position = "absolute";
1717
+ dstyle.top = 0;
1718
+ dstyle.left = 0;
1719
+ dstyle.width = o.paper.width + "px";
1720
+ dstyle.height = o.paper.height + "px";
1721
+ group.parentNode.insertBefore(div, group);
1722
+ div[appendChild](group);
1723
+ node.clipRect = div;
1724
+ }
1725
+ }
1726
+ if (!params["clip-rect"]) {
1727
+ node.clipRect && (node.clipRect.style.clip = E);
1728
+ }
1729
+ }
1730
+ if (o.type == "image" && params.src) {
1731
+ node.src = params.src;
1732
+ }
1733
+ if (o.type == "image" && params.opacity) {
1734
+ node.filterOpacity = " progid:DXImageTransform.Microsoft.Alpha(opacity=" + (params.opacity * 100) + ")";
1735
+ s.filter = (node.filterMatrix || E) + (node.filterOpacity || E);
1736
+ }
1737
+ params.font && (s.font = params.font);
1738
+ params["font-family"] && (s.fontFamily = '"' + params["font-family"][split](",")[0][rp](/^['"]+|['"]+$/g, E) + '"');
1739
+ params["font-size"] && (s.fontSize = params["font-size"]);
1740
+ params["font-weight"] && (s.fontWeight = params["font-weight"]);
1741
+ params["font-style"] && (s.fontStyle = params["font-style"]);
1742
+ if (params.opacity != null ||
1743
+ params["stroke-width"] != null ||
1744
+ params.fill != null ||
1745
+ params.stroke != null ||
1746
+ params["stroke-width"] != null ||
1747
+ params["stroke-opacity"] != null ||
1748
+ params["fill-opacity"] != null ||
1749
+ params["stroke-dasharray"] != null ||
1750
+ params["stroke-miterlimit"] != null ||
1751
+ params["stroke-linejoin"] != null ||
1752
+ params["stroke-linecap"] != null) {
1753
+ node = o.shape || node;
1754
+ var fill = (node.getElementsByTagName("fill") && node.getElementsByTagName("fill")[0]),
1755
+ newfill = false;
1756
+ !fill && (newfill = fill = createNode("fill"));
1757
+ if ("fill-opacity" in params || "opacity" in params) {
1758
+ var opacity = ((+a["fill-opacity"] + 1 || 2) - 1) * ((+a.opacity + 1 || 2) - 1);
1759
+ opacity < 0 && (opacity = 0);
1760
+ opacity > 1 && (opacity = 1);
1761
+ fill.opacity = opacity;
1762
+ }
1763
+ params.fill && (fill.on = true);
1764
+ if (fill.on == null || params.fill == "none") {
1765
+ fill.on = false;
1766
+ }
1767
+ if (fill.on && params.fill) {
1768
+ var isURL = params.fill.match(ISURL);
1769
+ if (isURL) {
1770
+ fill.src = isURL[1];
1771
+ fill.type = "tile";
1772
+ } else {
1773
+ fill.color = R.getRGB(params.fill).hex;
1774
+ fill.src = E;
1775
+ fill.type = "solid";
1776
+ if (R.getRGB(params.fill).error && (res.type in {circle: 1, ellipse: 1} || (params.fill + E).charAt() != "r") && addGradientFill(res, params.fill)) {
1777
+ a.fill = "none";
1778
+ a.gradient = params.fill;
1779
+ }
1780
+ }
1781
+ }
1782
+ newfill && node[appendChild](fill);
1783
+ var stroke = (node.getElementsByTagName("stroke") && node.getElementsByTagName("stroke")[0]),
1784
+ newstroke = false;
1785
+ !stroke && (newstroke = stroke = createNode("stroke"));
1786
+ if ((params.stroke && params.stroke != "none") ||
1787
+ params["stroke-width"] ||
1788
+ params["stroke-opacity"] != null ||
1789
+ params["stroke-dasharray"] ||
1790
+ params["stroke-miterlimit"] ||
1791
+ params["stroke-linejoin"] ||
1792
+ params["stroke-linecap"]) {
1793
+ stroke.on = true;
1794
+ }
1795
+ (params.stroke == "none" || stroke.on == null || params.stroke == 0 || params["stroke-width"] == 0) && (stroke.on = false);
1796
+ stroke.on && params.stroke && (stroke.color = R.getRGB(params.stroke).hex);
1797
+ var opacity = ((+a["stroke-opacity"] + 1 || 2) - 1) * ((+a.opacity + 1 || 2) - 1),
1798
+ width = (toFloat(params["stroke-width"]) || 1) * .75;
1799
+ opacity < 0 && (opacity = 0);
1800
+ opacity > 1 && (opacity = 1);
1801
+ params["stroke-width"] == null && (width = a["stroke-width"]);
1802
+ params["stroke-width"] && (stroke.weight = width);
1803
+ width && width < 1 && (opacity *= width) && (stroke.weight = 1);
1804
+ stroke.opacity = opacity;
1805
+
1806
+ params["stroke-linejoin"] && (stroke.joinstyle = params["stroke-linejoin"] || "miter");
1807
+ stroke.miterlimit = params["stroke-miterlimit"] || 8;
1808
+ params["stroke-linecap"] && (stroke.endcap = params["stroke-linecap"] == "butt" ? "flat" : params["stroke-linecap"] == "square" ? "square" : "round");
1809
+ if (params["stroke-dasharray"]) {
1810
+ var dasharray = {
1811
+ "-": "shortdash",
1812
+ ".": "shortdot",
1813
+ "-.": "shortdashdot",
1814
+ "-..": "shortdashdotdot",
1815
+ ". ": "dot",
1816
+ "- ": "dash",
1817
+ "--": "longdash",
1818
+ "- .": "dashdot",
1819
+ "--.": "longdashdot",
1820
+ "--..": "longdashdotdot"
1821
+ };
1822
+ stroke.dashstyle = dasharray[has](params["stroke-dasharray"]) ? dasharray[params["stroke-dasharray"]] : E;
1823
+ }
1824
+ newstroke && node[appendChild](stroke);
1825
+ }
1826
+ if (res.type == "text") {
1827
+ var s = res.paper.span.style;
1828
+ a.font && (s.font = a.font);
1829
+ a["font-family"] && (s.fontFamily = a["font-family"]);
1830
+ a["font-size"] && (s.fontSize = a["font-size"]);
1831
+ a["font-weight"] && (s.fontWeight = a["font-weight"]);
1832
+ a["font-style"] && (s.fontStyle = a["font-style"]);
1833
+ res.node.string && (res.paper.span.innerHTML = (res.node.string + E)[rp](/</g, "&#60;")[rp](/&/g, "&#38;")[rp](/\n/g, "<br>"));
1834
+ res.W = a.w = res.paper.span.offsetWidth;
1835
+ res.H = a.h = res.paper.span.offsetHeight;
1836
+ res.X = a.x;
1837
+ res.Y = a.y + round(res.H / 2);
1838
+
1839
+ // text-anchor emulationm
1840
+ switch (a["text-anchor"]) {
1841
+ case "start":
1842
+ res.node.style["v-text-align"] = "left";
1843
+ res.bbx = round(res.W / 2);
1844
+ break;
1845
+ case "end":
1846
+ res.node.style["v-text-align"] = "right";
1847
+ res.bbx = -round(res.W / 2);
1848
+ break;
1849
+ default:
1850
+ res.node.style["v-text-align"] = "center";
1851
+ break;
1852
+ }
1853
+ }
1854
+ };
1855
+ var addGradientFill = function (o, gradient) {
1856
+ o.attrs = o.attrs || {};
1857
+ var attrs = o.attrs,
1858
+ fill = o.node.getElementsByTagName("fill"),
1859
+ type = "linear",
1860
+ fxfy = ".5 .5";
1861
+ o.attrs.gradient = gradient;
1862
+ gradient = (gradient + E)[rp](radial_gradient, function (all, fx, fy) {
1863
+ type = "radial";
1864
+ if (fx && fy) {
1865
+ fx = toFloat(fx);
1866
+ fy = toFloat(fy);
1867
+ pow(fx - .5, 2) + pow(fy - .5, 2) > .25 && (fy = math.sqrt(.25 - pow(fx - .5, 2)) * ((fy > .5) * 2 - 1) + .5);
1868
+ fxfy = fx + S + fy;
1869
+ }
1870
+ return E;
1871
+ });
1872
+ gradient = gradient[split](/\s*\-\s*/);
1873
+ if (type == "linear") {
1874
+ var angle = gradient.shift();
1875
+ angle = -toFloat(angle);
1876
+ if (isNaN(angle)) {
1877
+ return null;
1878
+ }
1879
+ }
1880
+ var dots = parseDots(gradient);
1881
+ if (!dots) {
1882
+ return null;
1883
+ }
1884
+ o = o.shape || o.node;
1885
+ fill = fill[0] || createNode("fill");
1886
+ if (dots[length]) {
1887
+ fill.on = true;
1888
+ fill.method = "none";
1889
+ fill.type = (type == "radial") ? "gradientradial" : "gradient";
1890
+ fill.color = dots[0].color;
1891
+ fill.color2 = dots[dots[length] - 1].color;
1892
+ var clrs = [];
1893
+ for (var i = 0, ii = dots[length]; i < ii; i++) {
1894
+ dots[i].offset && clrs[push](dots[i].offset + S + dots[i].color);
1895
+ }
1896
+ fill.colors && (fill.colors.value = clrs[length] ? clrs[join](",") : "0% " + fill.color);
1897
+ if (type == "radial") {
1898
+ fill.focus = "100%";
1899
+ fill.focussize = fxfy;
1900
+ fill.focusposition = fxfy;
1901
+ } else {
1902
+ fill.angle = (270 - angle) % 360;
1903
+ }
1904
+ }
1905
+ return 1;
1906
+ };
1907
+ var Element = function (node, group, vml) {
1908
+ var Rotation = 0,
1909
+ RotX = 0,
1910
+ RotY = 0,
1911
+ Scale = 1;
1912
+ this[0] = node;
1913
+ this.id = R._oid++;
1914
+ this.node = node;
1915
+ node.raphael = this;
1916
+ this.X = 0;
1917
+ this.Y = 0;
1918
+ this.attrs = {};
1919
+ this.Group = group;
1920
+ this.paper = vml;
1921
+ this._ = {
1922
+ tx: 0,
1923
+ ty: 0,
1924
+ rt: {deg:0},
1925
+ sx: 1,
1926
+ sy: 1
1927
+ };
1928
+ !vml.bottom && (vml.bottom = this);
1929
+ this.prev = vml.top;
1930
+ vml.top && (vml.top.next = this);
1931
+ vml.top = this;
1932
+ this.next = null;
1933
+ };
1934
+ Element[proto].rotate = function (deg, cx, cy) {
1935
+ if (this.removed) {
1936
+ return this;
1937
+ }
1938
+ if (deg == null) {
1939
+ if (this._.rt.cx) {
1940
+ return [this._.rt.deg, this._.rt.cx, this._.rt.cy][join](S);
1941
+ }
1942
+ return this._.rt.deg;
1943
+ }
1944
+ deg = (deg + E)[split](separator);
1945
+ if (deg[length] - 1) {
1946
+ cx = toFloat(deg[1]);
1947
+ cy = toFloat(deg[2]);
1948
+ }
1949
+ deg = toFloat(deg[0]);
1950
+ if (cx != null) {
1951
+ this._.rt.deg = deg;
1952
+ } else {
1953
+ this._.rt.deg += deg;
1954
+ }
1955
+ cy == null && (cx = null);
1956
+ this._.rt.cx = cx;
1957
+ this._.rt.cy = cy;
1958
+ this.setBox(this.attrs, cx, cy);
1959
+ this.Group.style.rotation = this._.rt.deg;
1960
+ // gradient fix for rotation. TODO
1961
+ // var fill = (this.shape || this.node).getElementsByTagName("fill");
1962
+ // fill = fill[0] || {};
1963
+ // var b = ((360 - this._.rt.deg) - 270) % 360;
1964
+ // !R.is(fill.angle, "undefined") && (fill.angle = b);
1965
+ return this;
1966
+ };
1967
+ Element[proto].setBox = function (params, cx, cy) {
1968
+ if (this.removed) {
1969
+ return this;
1970
+ }
1971
+ var gs = this.Group.style,
1972
+ os = (this.shape && this.shape.style) || this.node.style;
1973
+ params = params || {};
1974
+ for (var i in params) if (params[has](i)) {
1975
+ this.attrs[i] = params[i];
1976
+ }
1977
+ cx = cx || this._.rt.cx;
1978
+ cy = cy || this._.rt.cy;
1979
+ var attr = this.attrs,
1980
+ x,
1981
+ y,
1982
+ w,
1983
+ h;
1984
+ switch (this.type) {
1985
+ case "circle":
1986
+ x = attr.cx - attr.r;
1987
+ y = attr.cy - attr.r;
1988
+ w = h = attr.r * 2;
1989
+ break;
1990
+ case "ellipse":
1991
+ x = attr.cx - attr.rx;
1992
+ y = attr.cy - attr.ry;
1993
+ w = attr.rx * 2;
1994
+ h = attr.ry * 2;
1995
+ break;
1996
+ case "rect":
1997
+ case "image":
1998
+ x = +attr.x;
1999
+ y = +attr.y;
2000
+ w = attr.width || 0;
2001
+ h = attr.height || 0;
2002
+ break;
2003
+ case "text":
2004
+ this.textpath.v = ["m", round(attr.x), ", ", round(attr.y - 2), "l", round(attr.x) + 1, ", ", round(attr.y - 2)][join](E);
2005
+ x = attr.x - round(this.W / 2);
2006
+ y = attr.y - this.H / 2;
2007
+ w = this.W;
2008
+ h = this.H;
2009
+ break;
2010
+ case "path":
2011
+ if (!this.attrs.path) {
2012
+ x = 0;
2013
+ y = 0;
2014
+ w = this.paper.width;
2015
+ h = this.paper.height;
2016
+ } else {
2017
+ var dim = pathDimensions(this.attrs.path);
2018
+ x = dim.x;
2019
+ y = dim.y;
2020
+ w = dim.width;
2021
+ h = dim.height;
2022
+ }
2023
+ break;
2024
+ default:
2025
+ x = 0;
2026
+ y = 0;
2027
+ w = this.paper.width;
2028
+ h = this.paper.height;
2029
+ break;
2030
+ }
2031
+ cx = (cx == null) ? x + w / 2 : cx;
2032
+ cy = (cy == null) ? y + h / 2 : cy;
2033
+ var left = cx - this.paper.width / 2,
2034
+ top = cy - this.paper.height / 2;
2035
+ if (this.type == "path" || this.type == "text") {
2036
+ (gs.left != left + "px") && (gs.left = left + "px");
2037
+ (gs.top != top + "px") && (gs.top = top + "px");
2038
+ this.X = this.type == "text" ? x : -left;
2039
+ this.Y = this.type == "text" ? y : -top;
2040
+ this.W = w;
2041
+ this.H = h;
2042
+ (os.left != -left + "px") && (os.left = -left + "px");
2043
+ (os.top != -top + "px") && (os.top = -top + "px");
2044
+ } else {
2045
+ (gs.left != left + "px") && (gs.left = left + "px");
2046
+ (gs.top != top + "px") && (gs.top = top + "px");
2047
+ this.X = x;
2048
+ this.Y = y;
2049
+ this.W = w;
2050
+ this.H = h;
2051
+ (gs.width != this.paper.width + "px") && (gs.width = this.paper.width + "px");
2052
+ (gs.height != this.paper.height + "px") && (gs.height = this.paper.height + "px");
2053
+ (os.left != x - left + "px") && (os.left = x - left + "px");
2054
+ (os.top != y - top + "px") && (os.top = y - top + "px");
2055
+ (os.width != w + "px") && (os.width = w + "px");
2056
+ (os.height != h + "px") && (os.height = h + "px");
2057
+ var arcsize = (+params.r || 0) / mmin(w, h);
2058
+ if (this.type == "rect" && this.arcsize.toFixed(4) != arcsize.toFixed(4) && (arcsize || this.arcsize)) {
2059
+ // We should replace element with the new one
2060
+ var o = createNode("roundrect"),
2061
+ a = {},
2062
+ i = 0,
2063
+ ii = this.events && this.events[length];
2064
+ o.arcsize = arcsize;
2065
+ o.raphael = this;
2066
+ this.Group[appendChild](o);
2067
+ this.Group.removeChild(this.node);
2068
+ this[0] = this.node = o;
2069
+ this.arcsize = arcsize;
2070
+ for (var i in attr) {
2071
+ a[i] = attr[i];
2072
+ }
2073
+ delete a.scale;
2074
+ this.attr(a);
2075
+ if (this.events) for (; i < ii; i++) {
2076
+ this.events[i].unbind = addEvent(this.node, this.events[i].name, this.events[i].f, this);
2077
+ }
2078
+ }
2079
+ }
2080
+ };
2081
+ Element[proto].hide = function () {
2082
+ !this.removed && (this.Group.style.display = "none");
2083
+ return this;
2084
+ };
2085
+ Element[proto].show = function () {
2086
+ !this.removed && (this.Group.style.display = "block");
2087
+ return this;
2088
+ };
2089
+ Element[proto].getBBox = function () {
2090
+ if (this.removed) {
2091
+ return this;
2092
+ }
2093
+ if (this.type == "path") {
2094
+ return pathDimensions(this.attrs.path);
2095
+ }
2096
+ return {
2097
+ x: this.X + (this.bbx || 0),
2098
+ y: this.Y,
2099
+ width: this.W,
2100
+ height: this.H
2101
+ };
2102
+ };
2103
+ Element[proto].remove = function () {
2104
+ if (this.removed) {
2105
+ return;
2106
+ }
2107
+ tear(this, this.paper);
2108
+ this.node.parentNode.removeChild(this.node);
2109
+ this.Group.parentNode.removeChild(this.Group);
2110
+ this.shape && this.shape.parentNode.removeChild(this.shape);
2111
+ for (var i in this) {
2112
+ delete this[i];
2113
+ }
2114
+ this.removed = true;
2115
+ };
2116
+ Element[proto].attr = function () {
2117
+ if (this.removed) {
2118
+ return this;
2119
+ }
2120
+ if (arguments[length] == 0) {
2121
+ var res = {};
2122
+ for (var i in this.attrs) if (this.attrs[has](i)) {
2123
+ res[i] = this.attrs[i];
2124
+ }
2125
+ this._.rt.deg && (res.rotation = this.rotate());
2126
+ (this._.sx != 1 || this._.sy != 1) && (res.scale = this.scale());
2127
+ res.gradient && res.fill == "none" && (res.fill = res.gradient) && delete res.gradient;
2128
+ return res;
2129
+ }
2130
+ if (arguments[length] == 1 && R.is(arguments[0], "string")) {
2131
+ if (arguments[0] == "translation") {
2132
+ return translate.call(this);
2133
+ }
2134
+ if (arguments[0] == "rotation") {
2135
+ return this.rotate();
2136
+ }
2137
+ if (arguments[0] == "scale") {
2138
+ return this.scale();
2139
+ }
2140
+ if (arguments[0] == "fill" && this.attrs.fill == "none" && this.attrs.gradient) {
2141
+ return this.attrs.gradient;
2142
+ }
2143
+ return this.attrs[arguments[0]];
2144
+ }
2145
+ if (this.attrs && arguments[length] == 1 && R.is(arguments[0], "array")) {
2146
+ var values = {};
2147
+ for (var i = 0, ii = arguments[0][length]; i < ii; i++) {
2148
+ values[arguments[0][i]] = this.attrs[arguments[0][i]];
2149
+ };
2150
+ return values;
2151
+ }
2152
+ var params;
2153
+ if (arguments[length] == 2) {
2154
+ params = {};
2155
+ params[arguments[0]] = arguments[1];
2156
+ }
2157
+ arguments[length] == 1 && R.is(arguments[0], "object") && (params = arguments[0]);
2158
+ if (params) {
2159
+ if (params.text && this.type == "text") {
2160
+ this.node.string = params.text;
2161
+ }
2162
+ setFillAndStroke(this, params);
2163
+ if (params.gradient && (({circle: 1, ellipse: 1})[has](this.type) || (params.gradient + E).charAt() != "r")) {
2164
+ addGradientFill(this, params.gradient);
2165
+ }
2166
+ (this.type != "path" || this._.rt.deg) && this.setBox(this.attrs);
2167
+ }
2168
+ return this;
2169
+ };
2170
+ Element[proto].toFront = function () {
2171
+ !this.removed && this.Group.parentNode[appendChild](this.Group);
2172
+ this.paper.top != this && tofront(this, this.paper);
2173
+ return this;
2174
+ };
2175
+ Element[proto].toBack = function () {
2176
+ if (this.removed) {
2177
+ return this;
2178
+ }
2179
+ if (this.Group.parentNode.firstChild != this.Group) {
2180
+ this.Group.parentNode.insertBefore(this.Group, this.Group.parentNode.firstChild);
2181
+ toback(this, this.paper);
2182
+ }
2183
+ return this;
2184
+ };
2185
+ Element[proto].insertAfter = function (element) {
2186
+ if (this.removed) {
2187
+ return this;
2188
+ }
2189
+ if (element.Group.nextSibling) {
2190
+ element.Group.parentNode.insertBefore(this.Group, element.Group.nextSibling);
2191
+ } else {
2192
+ element.Group.parentNode[appendChild](this.Group);
2193
+ }
2194
+ insertafter(this, element, this.paper);
2195
+ return this;
2196
+ };
2197
+ Element[proto].insertBefore = function (element) {
2198
+ if (this.removed) {
2199
+ return this;
2200
+ }
2201
+ element.Group.parentNode.insertBefore(this.Group, element.Group);
2202
+ insertbefore(this, element, this.paper);
2203
+ return this;
2204
+ };
2205
+
2206
+ var theCircle = function (vml, x, y, r) {
2207
+ var g = createNode("group"),
2208
+ o = createNode("oval"),
2209
+ ol = o.style;
2210
+ g.style.cssText = "position:absolute;left:0;top:0;width:" + vml.width + "px;height:" + vml.height + "px";
2211
+ g.coordsize = vml.coordsize;
2212
+ g.coordorigin = vml.coordorigin;
2213
+ g[appendChild](o);
2214
+ var res = new Element(o, g, vml);
2215
+ res.type = "circle";
2216
+ setFillAndStroke(res, {stroke: "#000", fill: "none"});
2217
+ res.attrs.cx = x;
2218
+ res.attrs.cy = y;
2219
+ res.attrs.r = r;
2220
+ res.setBox({x: x - r, y: y - r, width: r * 2, height: r * 2});
2221
+ vml.canvas[appendChild](g);
2222
+ return res;
2223
+ },
2224
+ theRect = function (vml, x, y, w, h, r) {
2225
+ var g = createNode("group"),
2226
+ o = createNode("roundrect"),
2227
+ arcsize = (+r || 0) / (mmin(w, h));
2228
+ g.style.cssText = "position:absolute;left:0;top:0;width:" + vml.width + "px;height:" + vml.height + "px";
2229
+ g.coordsize = vml.coordsize;
2230
+ g.coordorigin = vml.coordorigin;
2231
+ g[appendChild](o);
2232
+ o.arcsize = arcsize;
2233
+ var res = new Element(o, g, vml);
2234
+ res.type = "rect";
2235
+ setFillAndStroke(res, {stroke: "#000"});
2236
+ res.arcsize = arcsize;
2237
+ res.setBox({x: x, y: y, width: w, height: h, r: r});
2238
+ vml.canvas[appendChild](g);
2239
+ return res;
2240
+ },
2241
+ theEllipse = function (vml, x, y, rx, ry) {
2242
+ var g = createNode("group"),
2243
+ o = createNode("oval"),
2244
+ ol = o.style;
2245
+ g.style.cssText = "position:absolute;left:0;top:0;width:" + vml.width + "px;height:" + vml.height + "px";
2246
+ g.coordsize = vml.coordsize;
2247
+ g.coordorigin = vml.coordorigin;
2248
+ g[appendChild](o);
2249
+ var res = new Element(o, g, vml);
2250
+ res.type = "ellipse";
2251
+ setFillAndStroke(res, {stroke: "#000"});
2252
+ res.attrs.cx = x;
2253
+ res.attrs.cy = y;
2254
+ res.attrs.rx = rx;
2255
+ res.attrs.ry = ry;
2256
+ res.setBox({x: x - rx, y: y - ry, width: rx * 2, height: ry * 2});
2257
+ vml.canvas[appendChild](g);
2258
+ return res;
2259
+ },
2260
+ theImage = function (vml, src, x, y, w, h) {
2261
+ var g = createNode("group"),
2262
+ o = createNode("image"),
2263
+ ol = o.style;
2264
+ g.style.cssText = "position:absolute;left:0;top:0;width:" + vml.width + "px;height:" + vml.height + "px";
2265
+ g.coordsize = vml.coordsize;
2266
+ g.coordorigin = vml.coordorigin;
2267
+ o.src = src;
2268
+ g[appendChild](o);
2269
+ var res = new Element(o, g, vml);
2270
+ res.type = "image";
2271
+ res.attrs.src = src;
2272
+ res.attrs.x = x;
2273
+ res.attrs.y = y;
2274
+ res.attrs.w = w;
2275
+ res.attrs.h = h;
2276
+ res.setBox({x: x, y: y, width: w, height: h});
2277
+ vml.canvas[appendChild](g);
2278
+ return res;
2279
+ },
2280
+ theText = function (vml, x, y, text) {
2281
+ var g = createNode("group"),
2282
+ el = createNode("shape"),
2283
+ ol = el.style,
2284
+ path = createNode("path"),
2285
+ ps = path.style,
2286
+ o = createNode("textpath");
2287
+ g.style.cssText = "position:absolute;left:0;top:0;width:" + vml.width + "px;height:" + vml.height + "px";
2288
+ g.coordsize = vml.coordsize;
2289
+ g.coordorigin = vml.coordorigin;
2290
+ path.v = R.format("m{0},{1}l{2},{1}", round(x), round(y), round(x) + 1);
2291
+ path.textpathok = true;
2292
+ ol.width = vml.width;
2293
+ ol.height = vml.height;
2294
+ o.string = text + E;
2295
+ o.on = true;
2296
+ el[appendChild](o);
2297
+ el[appendChild](path);
2298
+ g[appendChild](el);
2299
+ var res = new Element(o, g, vml);
2300
+ res.shape = el;
2301
+ res.textpath = path;
2302
+ res.type = "text";
2303
+ res.attrs.text = text;
2304
+ res.attrs.x = x;
2305
+ res.attrs.y = y;
2306
+ res.attrs.w = 1;
2307
+ res.attrs.h = 1;
2308
+ setFillAndStroke(res, {font: availableAttrs.font, stroke: "none", fill: "#000"});
2309
+ res.setBox();
2310
+ vml.canvas[appendChild](g);
2311
+ return res;
2312
+ },
2313
+ setSize = function (width, height) {
2314
+ var cs = this.canvas.style;
2315
+ width == +width && (width += "px");
2316
+ height == +height && (height += "px");
2317
+ cs.width = width;
2318
+ cs.height = height;
2319
+ cs.clip = "rect(0 " + width + " " + height + " 0)";
2320
+ return this;
2321
+ },
2322
+ createNode;
2323
+ doc.createStyleSheet().addRule(".rvml", "behavior:url(#default#VML)");
2324
+ try {
2325
+ !doc.namespaces.rvml && doc.namespaces.add("rvml", "urn:schemas-microsoft-com:vml");
2326
+ createNode = function (tagName) {
2327
+ return doc.createElement('<rvml:' + tagName + ' class="rvml">');
2328
+ };
2329
+ } catch (e) {
2330
+ createNode = function (tagName) {
2331
+ return doc.createElement('<' + tagName + ' xmlns="urn:schemas-microsoft.com:vml" class="rvml">');
2332
+ };
2333
+ }
2334
+ var create = function () {
2335
+ var con = getContainer[apply](null, arguments),
2336
+ container = con.container,
2337
+ height = con.height,
2338
+ s,
2339
+ width = con.width,
2340
+ x = con.x,
2341
+ y = con.y;
2342
+ if (!container) {
2343
+ throw new Error("VML container not found.");
2344
+ }
2345
+ var res = new Paper,
2346
+ c = res.canvas = doc.createElement("div"),
2347
+ cs = c.style;
2348
+ width = width || 512;
2349
+ height = height || 342;
2350
+ width == +width && (width += "px");
2351
+ height == +height && (height += "px");
2352
+ res.width = 1e3;
2353
+ res.height = 1e3;
2354
+ res.coordsize = "1000 1000";
2355
+ res.coordorigin = "0 0";
2356
+ res.span = doc.createElement("span");
2357
+ res.span.style.cssText = "position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;";
2358
+ c[appendChild](res.span);
2359
+ cs.cssText = R.format("width:{0};height:{1};position:absolute;clip:rect(0 {0} {1} 0);overflow:hidden", width, height);
2360
+ if (container == 1) {
2361
+ doc.body[appendChild](c);
2362
+ cs.left = x + "px";
2363
+ cs.top = y + "px";
2364
+ } else {
2365
+ container.style.width = width;
2366
+ container.style.height = height;
2367
+ if (container.firstChild) {
2368
+ container.insertBefore(c, container.firstChild);
2369
+ } else {
2370
+ container[appendChild](c);
2371
+ }
2372
+ }
2373
+ plugins.call(res, res, R.fn);
2374
+ return res;
2375
+ };
2376
+ Paper[proto].clear = function () {
2377
+ this.canvas.innerHTML = E;
2378
+ this.span = doc.createElement("span");
2379
+ this.span.style.cssText = "position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;";
2380
+ this.canvas[appendChild](this.span);
2381
+ this.bottom = this.top = null;
2382
+ };
2383
+ Paper[proto].remove = function () {
2384
+ this.canvas.parentNode.removeChild(this.canvas);
2385
+ for (var i in this) {
2386
+ this[i] = removed(i);
2387
+ }
2388
+ };
2389
+ }
2390
+
2391
+ // rest
2392
+ // Safari or Chrome (WebKit) rendering bug workaround method
2393
+ if ((/^Apple|^Google/).test(navigator.vendor) && !(navigator.userAgent.indexOf("Version/4.0") + 1)) {
2394
+ Paper[proto].safari = function () {
2395
+ var rect = this.rect(-99, -99, this.width + 99, this.height + 99);
2396
+ setTimeout(function () {rect.remove();});
2397
+ };
2398
+ } else {
2399
+ Paper[proto].safari = function () {};
2400
+ }
2401
+
2402
+ // Events
2403
+ var addEvent = (function () {
2404
+ if (doc.addEventListener) {
2405
+ return function (obj, type, fn, element) {
2406
+ var f = function (e) {
2407
+ return fn.call(element, e);
2408
+ };
2409
+ obj.addEventListener(type, f, false);
2410
+ return function () {
2411
+ obj.removeEventListener(type, f, false);
2412
+ return true;
2413
+ };
2414
+ };
2415
+ } else if (doc.attachEvent) {
2416
+ return function (obj, type, fn, element) {
2417
+ var f = function (e) {
2418
+ return fn.call(element, e || win.event);
2419
+ };
2420
+ obj.attachEvent("on" + type, f);
2421
+ var detacher = function () {
2422
+ obj.detachEvent("on" + type, f);
2423
+ return true;
2424
+ };
2425
+ return detacher;
2426
+ };
2427
+ }
2428
+ })();
2429
+ for (var i = events[length]; i--;) {
2430
+ (function (eventName) {
2431
+ Element[proto][eventName] = function (fn) {
2432
+ if (R.is(fn, "function")) {
2433
+ this.events = this.events || [];
2434
+ this.events.push({name: eventName, f: fn, unbind: addEvent(this.shape || this.node, eventName, fn, this)});
2435
+ }
2436
+ return this;
2437
+ };
2438
+ Element[proto]["un" + eventName] = function (fn) {
2439
+ var events = this.events,
2440
+ l = events[length];
2441
+ while (l--) if (events[l].name == eventName && events[l].f == fn) {
2442
+ events[l].unbind();
2443
+ events.splice(l, 1);
2444
+ !events.length && delete this.events;
2445
+ return this;
2446
+ }
2447
+ return this;
2448
+ };
2449
+ })(events[i]);
2450
+ }
2451
+ Element[proto].hover = function (f_in, f_out) {
2452
+ return this.mouseover(f_in).mouseout(f_out);
2453
+ };
2454
+ Element[proto].unhover = function (f_in, f_out) {
2455
+ return this.unmouseover(f_in).unmouseout(f_out);
2456
+ };
2457
+ Paper[proto].circle = function (x, y, r) {
2458
+ return theCircle(this, x || 0, y || 0, r || 0);
2459
+ };
2460
+ Paper[proto].rect = function (x, y, w, h, r) {
2461
+ return theRect(this, x || 0, y || 0, w || 0, h || 0, r || 0);
2462
+ };
2463
+ Paper[proto].ellipse = function (x, y, rx, ry) {
2464
+ return theEllipse(this, x || 0, y || 0, rx || 0, ry || 0);
2465
+ };
2466
+ Paper[proto].path = function (pathString) {
2467
+ pathString && !R.is(pathString, "string") && !R.is(pathString[0], "array") && (pathString += E);
2468
+ return thePath(R.format[apply](R, arguments), this);
2469
+ };
2470
+ Paper[proto].image = function (src, x, y, w, h) {
2471
+ return theImage(this, src || "about:blank", x || 0, y || 0, w || 0, h || 0);
2472
+ };
2473
+ Paper[proto].text = function (x, y, text) {
2474
+ return theText(this, x || 0, y || 0, text || E);
2475
+ };
2476
+ Paper[proto].set = function (itemsArray) {
2477
+ arguments[length] > 1 && (itemsArray = Array[proto].splice.call(arguments, 0, arguments[length]));
2478
+ return new Set(itemsArray);
2479
+ };
2480
+ Paper[proto].setSize = setSize;
2481
+ Paper[proto].top = Paper[proto].bottom = null;
2482
+ Paper[proto].raphael = R;
2483
+ function x_y() {
2484
+ return this.x + S + this.y;
2485
+ };
2486
+ Element[proto].scale = function (x, y, cx, cy) {
2487
+ if (x == null && y == null) {
2488
+ return {
2489
+ x: this._.sx,
2490
+ y: this._.sy,
2491
+ toString: x_y
2492
+ };
2493
+ }
2494
+ y = y || x;
2495
+ !+y && (y = x);
2496
+ var dx,
2497
+ dy,
2498
+ dcx,
2499
+ dcy,
2500
+ a = this.attrs;
2501
+ if (x != 0) {
2502
+ var bb = this.getBBox(),
2503
+ rcx = bb.x + bb.width / 2,
2504
+ rcy = bb.y + bb.height / 2,
2505
+ kx = x / this._.sx,
2506
+ ky = y / this._.sy;
2507
+ cx = (+cx || cx == 0) ? cx : rcx;
2508
+ cy = (+cy || cy == 0) ? cy : rcy;
2509
+ var dirx = ~~(x / math.abs(x)),
2510
+ diry = ~~(y / math.abs(y)),
2511
+ s = this.node.style,
2512
+ ncx = cx + (rcx - cx) * kx,
2513
+ ncy = cy + (rcy - cy) * ky;
2514
+ switch (this.type) {
2515
+ case "rect":
2516
+ case "image":
2517
+ var neww = a.width * dirx * kx,
2518
+ newh = a.height * diry * ky;
2519
+ this.attr({
2520
+ height: newh,
2521
+ r: a.r * mmin(dirx * kx, diry * ky),
2522
+ width: neww,
2523
+ x: ncx - neww / 2,
2524
+ y: ncy - newh / 2
2525
+ });
2526
+ break;
2527
+ case "circle":
2528
+ case "ellipse":
2529
+ this.attr({
2530
+ rx: a.rx * dirx * kx,
2531
+ ry: a.ry * diry * ky,
2532
+ r: a.r * mmin(dirx * kx, diry * ky),
2533
+ cx: ncx,
2534
+ cy: ncy
2535
+ });
2536
+ break;
2537
+ case "path":
2538
+ var path = pathToRelative(a.path),
2539
+ skip = true;
2540
+ for (var i = 0, ii = path[length]; i < ii; i++) {
2541
+ var p = path[i],
2542
+ j,
2543
+ P0 = upperCase.call(p[0]);
2544
+ if (P0 == "M" && skip) {
2545
+ continue;
2546
+ } else {
2547
+ skip = false;
2548
+ }
2549
+ if (P0 == "A") {
2550
+ p[path[i][length] - 2] *= kx;
2551
+ p[path[i][length] - 1] *= ky;
2552
+ p[1] *= dirx * kx;
2553
+ p[2] *= diry * ky;
2554
+ p[5] = +(dirx + diry ? !!+p[5] : !+p[5]);
2555
+ } else if (P0 == "H") {
2556
+ for (j = 1, jj = p[length]; j < jj; j++) {
2557
+ p[j] *= kx;
2558
+ }
2559
+ } else if (P0 == "V") {
2560
+ for (j = 1, jj = p[length]; j < jj; j++) {
2561
+ p[j] *= ky;
2562
+ }
2563
+ } else {
2564
+ for (j = 1, jj = p[length]; j < jj; j++) {
2565
+ p[j] *= (j % 2) ? kx : ky;
2566
+ }
2567
+ }
2568
+ }
2569
+ var dim2 = pathDimensions(path),
2570
+ dx = ncx - dim2.x - dim2.width / 2,
2571
+ dy = ncy - dim2.y - dim2.height / 2;
2572
+ path[0][1] += dx;
2573
+ path[0][2] += dy;
2574
+ this.attr({path: path});
2575
+ break;
2576
+ }
2577
+ if (this.type in {text: 1, image:1} && (dirx != 1 || diry != 1)) {
2578
+ if (this.transformations) {
2579
+ this.transformations[2] = "scale("[concat](dirx, ",", diry, ")");
2580
+ this.node[setAttribute]("transform", this.transformations[join](S));
2581
+ dx = (dirx == -1) ? -a.x - (neww || 0) : a.x;
2582
+ dy = (diry == -1) ? -a.y - (newh || 0) : a.y;
2583
+ this.attr({x: dx, y: dy});
2584
+ a.fx = dirx - 1;
2585
+ a.fy = diry - 1;
2586
+ } else {
2587
+ this.node.filterMatrix = " progid:DXImageTransform.Microsoft.Matrix(M11="[concat](dirx,
2588
+ ", M12=0, M21=0, M22=", diry,
2589
+ ", Dx=0, Dy=0, sizingmethod='auto expand', filtertype='bilinear')");
2590
+ s.filter = (this.node.filterMatrix || E) + (this.node.filterOpacity || E);
2591
+ }
2592
+ } else {
2593
+ if (this.transformations) {
2594
+ this.transformations[2] = E;
2595
+ this.node[setAttribute]("transform", this.transformations[join](S));
2596
+ a.fx = 0;
2597
+ a.fy = 0;
2598
+ } else {
2599
+ this.node.filterMatrix = E;
2600
+ s.filter = (this.node.filterMatrix || E) + (this.node.filterOpacity || E);
2601
+ }
2602
+ }
2603
+ a.scale = [x, y, cx, cy][join](S);
2604
+ this._.sx = x;
2605
+ this._.sy = y;
2606
+ }
2607
+ return this;
2608
+ };
2609
+ Element[proto].clone = function () {
2610
+ var attr = this.attr();
2611
+ delete attr.scale;
2612
+ delete attr.translation;
2613
+ return this.paper[this.type]().attr(attr);
2614
+ };
2615
+ var getLengthFactory = function (istotal, subpath) {
2616
+ return function (path, length, onlystart) {
2617
+ path = path2curve(path);
2618
+ var x, y, p, l, sp = "", subpaths = {}, point,
2619
+ len = 0;
2620
+ for (var i = 0, ii = path.length; i < ii; i++) {
2621
+ p = path[i];
2622
+ if (p[0] == "M") {
2623
+ x = +p[1];
2624
+ y = +p[2];
2625
+ } else {
2626
+ l = segmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6]);
2627
+ if (len + l > length) {
2628
+ if (subpath && !subpaths.start) {
2629
+ point = R.findDotsAtSegment(x, y, p[1], p[2], p[3], p[4], p[5], p[6], (length - len) / l);
2630
+ sp += ["C", point.start.x, point.start.y, point.m.x, point.m.y, point.x, point.y];
2631
+ if (onlystart) {
2632
+ return sp;
2633
+ }
2634
+ subpaths.start = sp;
2635
+ sp = ["M", point.x, point.y, "C", point.n.x, point.n.y, point.end.x, point.end.y, p[5], p[6]][join]();
2636
+ len += l;
2637
+ x = +p[5];
2638
+ y = +p[6];
2639
+ continue;
2640
+ }
2641
+ if (!istotal && !subpath) {
2642
+ point = R.findDotsAtSegment(x, y, p[1], p[2], p[3], p[4], p[5], p[6], (length - len) / l);
2643
+ return {x: point.x, y: point.y, alpha: point.alpha};
2644
+ }
2645
+ }
2646
+ len += l;
2647
+ x = +p[5];
2648
+ y = +p[6];
2649
+ }
2650
+ sp += p;
2651
+ }
2652
+ subpaths.end = sp;
2653
+ point = istotal ? len : subpath ? subpaths : R.findDotsAtSegment(x, y, p[1], p[2], p[3], p[4], p[5], p[6], 1);
2654
+ point.alpha && (point = {x: point.x, y: point.y, alpha: point.alpha});
2655
+ return point;
2656
+ };
2657
+ },
2658
+ segmentLength = cacher(function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) {
2659
+ var old = {x: 0, y: 0},
2660
+ len = 0;
2661
+ for (var i = 0; i < 1.01; i+=.01) {
2662
+ var dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, i);
2663
+ i && (len += math.sqrt(pow(old.x - dot.x, 2) + pow(old.y - dot.y, 2)));
2664
+ old = dot;
2665
+ }
2666
+ return len;
2667
+ });
2668
+ var getTotalLength = getLengthFactory(1),
2669
+ getPointAtLength = getLengthFactory(),
2670
+ getSubpathsAtLength = getLengthFactory(0, 1);
2671
+ Element[proto].getTotalLength = function () {
2672
+ if (this.type != "path") return;
2673
+ return getTotalLength(this.attrs.path);
2674
+ };
2675
+ Element[proto].getPointAtLength = function (length) {
2676
+ if (this.type != "path") return;
2677
+ return getPointAtLength(this.attrs.path, length);
2678
+ };
2679
+ Element[proto].getSubpath = function (from, to) {
2680
+ if (this.type != "path") return;
2681
+ var a = getSubpathsAtLength(this.attrs.path, to, 1);
2682
+ return from ? getSubpathsAtLength(a, from).end : a;
2683
+ };
2684
+
2685
+ // animation easing formulas
2686
+ R.easing_formulas = {
2687
+ linear: function (n) {
2688
+ return n;
2689
+ },
2690
+ "<": function (n) {
2691
+ return pow(n, 3);
2692
+ },
2693
+ ">": function (n) {
2694
+ return pow(n - 1, 3) + 1;
2695
+ },
2696
+ "<>": function (n) {
2697
+ n = n * 2;
2698
+ if (n < 1) {
2699
+ return pow(n, 3) / 2;
2700
+ }
2701
+ n -= 2;
2702
+ return (pow(n, 3) + 2) / 2;
2703
+ },
2704
+ backIn: function (n) {
2705
+ var s = 1.70158;
2706
+ return n * n * ((s + 1) * n - s);
2707
+ },
2708
+ backOut: function (n) {
2709
+ n = n - 1;
2710
+ var s = 1.70158;
2711
+ return n * n * ((s + 1) * n + s) + 1;
2712
+ },
2713
+ elastic: function (n) {
2714
+ if (n == 0 || n == 1) {
2715
+ return n;
2716
+ }
2717
+ var p = .3,
2718
+ s = p / 4;
2719
+ return pow(2, -10 * n) * math.sin((n - s) * (2 * math.PI) / p) + 1;
2720
+ },
2721
+ bounce: function (n) {
2722
+ var s = 7.5625,
2723
+ p = 2.75,
2724
+ l;
2725
+ if (n < (1 / p)) {
2726
+ l = s * n * n;
2727
+ } else {
2728
+ if (n < (2 / p)) {
2729
+ n -= (1.5 / p);
2730
+ l = s * n * n + .75;
2731
+ } else {
2732
+ if (n < (2.5 / p)) {
2733
+ n -= (2.25 / p);
2734
+ l = s * n * n + .9375;
2735
+ } else {
2736
+ n -= (2.625 / p);
2737
+ l = s * n * n + .984375;
2738
+ }
2739
+ }
2740
+ }
2741
+ return l;
2742
+ }
2743
+ };
2744
+
2745
+ var animationElements = {length : 0},
2746
+ animation = function () {
2747
+ var Now = +new Date;
2748
+ for (var l in animationElements) if (l != "length" && animationElements[has](l)) {
2749
+ var e = animationElements[l];
2750
+ if (e.stop) {
2751
+ delete animationElements[l];
2752
+ animationElements[length]--;
2753
+ continue;
2754
+ }
2755
+ var time = Now - e.start,
2756
+ ms = e.ms,
2757
+ easing = e.easing,
2758
+ from = e.from,
2759
+ diff = e.diff,
2760
+ to = e.to,
2761
+ t = e.t,
2762
+ prev = e.prev || 0,
2763
+ that = e.el,
2764
+ callback = e.callback,
2765
+ set = {},
2766
+ now;
2767
+ if (time < ms) {
2768
+ var pos = R.easing_formulas[easing] ? R.easing_formulas[easing](time / ms) : time / ms;
2769
+ for (var attr in from) if (from[has](attr)) {
2770
+ switch (availableAnimAttrs[attr]) {
2771
+ case "along":
2772
+ now = pos * ms * diff[attr];
2773
+ to.back && (now = to.len - now);
2774
+ var point = getPointAtLength(to[attr], now);
2775
+ that.translate(diff.sx - diff.x || 0, diff.sy - diff.y || 0);
2776
+ diff.x = point.x;
2777
+ diff.y = point.y;
2778
+ that.translate(point.x - diff.sx, point.y - diff.sy);
2779
+ to.rot && that.rotate(diff.r + point.alpha, point.x, point.y);
2780
+ break;
2781
+ case "number":
2782
+ now = +from[attr] + pos * ms * diff[attr];
2783
+ break;
2784
+ case "colour":
2785
+ now = "rgb(" + [
2786
+ upto255(round(from[attr].r + pos * ms * diff[attr].r)),
2787
+ upto255(round(from[attr].g + pos * ms * diff[attr].g)),
2788
+ upto255(round(from[attr].b + pos * ms * diff[attr].b))
2789
+ ][join](",") + ")";
2790
+ break;
2791
+ case "path":
2792
+ now = [];
2793
+ for (var i = 0, ii = from[attr][length]; i < ii; i++) {
2794
+ now[i] = [from[attr][i][0]];
2795
+ for (var j = 1, jj = from[attr][i][length]; j < jj; j++) {
2796
+ now[i][j] = +from[attr][i][j] + pos * ms * diff[attr][i][j];
2797
+ }
2798
+ now[i] = now[i][join](S);
2799
+ }
2800
+ now = now[join](S);
2801
+ break;
2802
+ case "csv":
2803
+ switch (attr) {
2804
+ case "translation":
2805
+ var x = diff[attr][0] * (time - prev),
2806
+ y = diff[attr][1] * (time - prev);
2807
+ t.x += x;
2808
+ t.y += y;
2809
+ now = x + S + y;
2810
+ break;
2811
+ case "rotation":
2812
+ now = +from[attr][0] + pos * ms * diff[attr][0];
2813
+ from[attr][1] && (now += "," + from[attr][1] + "," + from[attr][2]);
2814
+ break;
2815
+ case "scale":
2816
+ now = [+from[attr][0] + pos * ms * diff[attr][0], +from[attr][1] + pos * ms * diff[attr][1], (2 in to[attr] ? to[attr][2] : E), (3 in to[attr] ? to[attr][3] : E)][join](S);
2817
+ break;
2818
+ case "clip-rect":
2819
+ now = [];
2820
+ var i = 4;
2821
+ while (i--) {
2822
+ now[i] = +from[attr][i] + pos * ms * diff[attr][i];
2823
+ }
2824
+ break;
2825
+ }
2826
+ break;
2827
+ }
2828
+ set[attr] = now;
2829
+ }
2830
+ that.attr(set);
2831
+ that._run && that._run.call(that);
2832
+ } else {
2833
+ if (to.along) {
2834
+ var point = getPointAtLength(to.along, to.len * !to.back);
2835
+ that.translate(diff.sx - (diff.x || 0) + point.x - diff.sx, diff.sy - (diff.y || 0) + point.y - diff.sy);
2836
+ to.rot && that.rotate(diff.r + point.alpha, point.x, point.y);
2837
+ }
2838
+ (t.x || t.y) && that.translate(-t.x, -t.y);
2839
+ to.scale && (to.scale = to.scale + E);
2840
+ that.attr(to);
2841
+ delete animationElements[l];
2842
+ animationElements[length]--;
2843
+ that.in_animation = null;
2844
+ R.is(callback, "function") && callback.call(that);
2845
+ }
2846
+ e.prev = time;
2847
+ }
2848
+ R.svg && that && that.paper.safari();
2849
+ animationElements[length] && setTimeout(animation);
2850
+ },
2851
+ upto255 = function (color) {
2852
+ return color > 255 ? 255 : (color < 0 ? 0 : color);
2853
+ },
2854
+ translate = function (x, y) {
2855
+ if (x == null) {
2856
+ return {x: this._.tx, y: this._.ty, toString: x_y};
2857
+ }
2858
+ this._.tx += +x;
2859
+ this._.ty += +y;
2860
+ switch (this.type) {
2861
+ case "circle":
2862
+ case "ellipse":
2863
+ this.attr({cx: +x + this.attrs.cx, cy: +y + this.attrs.cy});
2864
+ break;
2865
+ case "rect":
2866
+ case "image":
2867
+ case "text":
2868
+ this.attr({x: +x + this.attrs.x, y: +y + this.attrs.y});
2869
+ break;
2870
+ case "path":
2871
+ var path = pathToRelative(this.attrs.path);
2872
+ path[0][1] += +x;
2873
+ path[0][2] += +y;
2874
+ this.attr({path: path});
2875
+ break;
2876
+ }
2877
+ return this;
2878
+ };
2879
+ Element[proto].animateWith = function (element, params, ms, easing, callback) {
2880
+ animationElements[element.id] && (params.start = animationElements[element.id].start);
2881
+ return this.animate(params, ms, easing, callback);
2882
+ };
2883
+ Element[proto].animateAlong = along();
2884
+ Element[proto].animateAlongBack = along(1);
2885
+ function along(isBack) {
2886
+ return function (path, ms, rotate, callback) {
2887
+ var params = {back: isBack};
2888
+ R.is(rotate, "function") ? (callback = rotate) : (params.rot = rotate);
2889
+ path && path.constructor == Element && (path = path.attrs.path);
2890
+ path && (params.along = path);
2891
+ return this.animate(params, ms, callback);
2892
+ };
2893
+ }
2894
+ Element[proto].onAnimation = function (f) {
2895
+ this._run = f || 0;
2896
+ return this;
2897
+ };
2898
+ Element[proto].animate = function (params, ms, easing, callback) {
2899
+ if (R.is(easing, "function") || !easing) {
2900
+ callback = easing || null;
2901
+ }
2902
+ var from = {},
2903
+ to = {},
2904
+ diff = {};
2905
+ for (var attr in params) if (params[has](attr)) {
2906
+ if (availableAnimAttrs[has](attr)) {
2907
+ from[attr] = this.attr(attr);
2908
+ (from[attr] == null) && (from[attr] = availableAttrs[attr]);
2909
+ to[attr] = params[attr];
2910
+ switch (availableAnimAttrs[attr]) {
2911
+ case "along":
2912
+ var len = getTotalLength(params[attr]),
2913
+ point = getPointAtLength(params[attr], len * !!params.back),
2914
+ bb = this.getBBox();
2915
+ diff[attr] = len / ms;
2916
+ diff.tx = bb.x;
2917
+ diff.ty = bb.y;
2918
+ diff.sx = point.x;
2919
+ diff.sy = point.y;
2920
+ to.rot = params.rot;
2921
+ to.back = params.back;
2922
+ to.len = len;
2923
+ params.rot && (diff.r = toFloat(this.rotate()) || 0);
2924
+ break;
2925
+ case "number":
2926
+ diff[attr] = (to[attr] - from[attr]) / ms;
2927
+ break;
2928
+ case "colour":
2929
+ from[attr] = R.getRGB(from[attr]);
2930
+ var toColour = R.getRGB(to[attr]);
2931
+ diff[attr] = {
2932
+ r: (toColour.r - from[attr].r) / ms,
2933
+ g: (toColour.g - from[attr].g) / ms,
2934
+ b: (toColour.b - from[attr].b) / ms
2935
+ };
2936
+ break;
2937
+ case "path":
2938
+ var pathes = path2curve(from[attr], to[attr]);
2939
+ from[attr] = pathes[0];
2940
+ var toPath = pathes[1];
2941
+ diff[attr] = [];
2942
+ for (var i = 0, ii = from[attr][length]; i < ii; i++) {
2943
+ diff[attr][i] = [0];
2944
+ for (var j = 1, jj = from[attr][i][length]; j < jj; j++) {
2945
+ diff[attr][i][j] = (toPath[i][j] - from[attr][i][j]) / ms;
2946
+ }
2947
+ }
2948
+ break;
2949
+ case "csv":
2950
+ var values = (params[attr] + E)[split](separator),
2951
+ from2 = (from[attr] + E)[split](separator);
2952
+ switch (attr) {
2953
+ case "translation":
2954
+ from[attr] = [0, 0];
2955
+ diff[attr] = [values[0] / ms, values[1] / ms];
2956
+ break;
2957
+ case "rotation":
2958
+ from[attr] = (from2[1] == values[1] && from2[2] == values[2]) ? from2 : [0, values[1], values[2]];
2959
+ diff[attr] = [(values[0] - from[attr][0]) / ms, 0, 0];
2960
+ break;
2961
+ case "scale":
2962
+ params[attr] = values;
2963
+ from[attr] = (from[attr] + E)[split](separator);
2964
+ diff[attr] = [(values[0] - from[attr][0]) / ms, (values[1] - from[attr][1]) / ms, 0, 0];
2965
+ break;
2966
+ case "clip-rect":
2967
+ from[attr] = (from[attr] + E)[split](separator);
2968
+ diff[attr] = [];
2969
+ var i = 4;
2970
+ while (i--) {
2971
+ diff[attr][i] = (values[i] - from[attr][i]) / ms;
2972
+ }
2973
+ break;
2974
+ }
2975
+ to[attr] = values;
2976
+ }
2977
+ }
2978
+ }
2979
+ this.stop();
2980
+ this.in_animation = 1;
2981
+ animationElements[this.id] = {
2982
+ start: params.start || +new Date,
2983
+ ms: ms,
2984
+ easing: easing,
2985
+ from: from,
2986
+ diff: diff,
2987
+ to: to,
2988
+ el: this,
2989
+ callback: callback,
2990
+ t: {x: 0, y: 0}
2991
+ };
2992
+ ++animationElements[length] == 1 && animation();
2993
+ return this;
2994
+ };
2995
+ Element[proto].stop = function () {
2996
+ animationElements[this.id] && animationElements[length]--;
2997
+ delete animationElements[this.id];
2998
+ return this;
2999
+ };
3000
+ Element[proto].translate = function (x, y) {
3001
+ return this.attr({translation: x + " " + y});
3002
+ };
3003
+ Element[proto][toString] = function () {
3004
+ return "Rapha\xebl\u2019s object";
3005
+ };
3006
+ R.ae = animationElements;
3007
+
3008
+ // Set
3009
+ var Set = function (items) {
3010
+ this.items = [];
3011
+ this[length] = 0;
3012
+ if (items) {
3013
+ for (var i = 0, ii = items[length]; i < ii; i++) {
3014
+ if (items[i] && (items[i].constructor == Element || items[i].constructor == Set)) {
3015
+ this[this.items[length]] = this.items[this.items[length]] = items[i];
3016
+ this[length]++;
3017
+ }
3018
+ }
3019
+ }
3020
+ };
3021
+ Set[proto][push] = function () {
3022
+ var item,
3023
+ len;
3024
+ for (var i = 0, ii = arguments[length]; i < ii; i++) {
3025
+ item = arguments[i];
3026
+ if (item && (item.constructor == Element || item.constructor == Set)) {
3027
+ len = this.items[length];
3028
+ this[len] = this.items[len] = item;
3029
+ this[length]++;
3030
+ }
3031
+ }
3032
+ return this;
3033
+ };
3034
+ Set[proto].pop = function () {
3035
+ delete this[this[length]--];
3036
+ return this.items.pop();
3037
+ };
3038
+ for (var method in Element[proto]) if (Element[proto][has](method)) {
3039
+ Set[proto][method] = (function (methodname) {
3040
+ return function () {
3041
+ for (var i = 0, ii = this.items[length]; i < ii; i++) {
3042
+ this.items[i][methodname][apply](this.items[i], arguments);
3043
+ }
3044
+ return this;
3045
+ };
3046
+ })(method);
3047
+ }
3048
+ Set[proto].attr = function (name, value) {
3049
+ if (name && R.is(name, "array") && R.is(name[0], "object")) {
3050
+ for (var j = 0, jj = name[length]; j < jj; j++) {
3051
+ this.items[j].attr(name[j]);
3052
+ }
3053
+ } else {
3054
+ for (var i = 0, ii = this.items[length]; i < ii; i++) {
3055
+ this.items[i].attr[apply](this.items[i], arguments);
3056
+ }
3057
+ }
3058
+ return this;
3059
+ };
3060
+ Set[proto].animate = function (params, ms, easing, callback) {
3061
+ (R.is(easing, "function") || !easing) && (callback = easing || null);
3062
+ var len = this.items[length],
3063
+ i = len,
3064
+ set = this,
3065
+ collector;
3066
+ callback && (collector = function () {
3067
+ !--len && callback.call(set);
3068
+ });
3069
+ this.items[--i].animate(params, ms, easing || collector, collector);
3070
+ while (i--) {
3071
+ this.items[i].animateWith(this.items[len - 1], params, ms, easing || collector, collector);
3072
+ }
3073
+ return this;
3074
+ };
3075
+ Set[proto].insertAfter = function (el) {
3076
+ var i = this.items[length];
3077
+ while (i--) {
3078
+ this.items[i].insertAfter(el);
3079
+ }
3080
+ return this;
3081
+ };
3082
+ Set[proto].getBBox = function () {
3083
+ var x = [],
3084
+ y = [],
3085
+ w = [],
3086
+ h = [];
3087
+ for (var i = this.items[length]; i--;) {
3088
+ var box = this.items[i].getBBox();
3089
+ x[push](box.x);
3090
+ y[push](box.y);
3091
+ w[push](box.x + box.width);
3092
+ h[push](box.y + box.height);
3093
+ }
3094
+ x = mmin[apply](0, x);
3095
+ y = mmin[apply](0, y);
3096
+ return {
3097
+ x: x,
3098
+ y: y,
3099
+ width: mmax[apply](0, w) - x,
3100
+ height: mmax[apply](0, h) - y
3101
+ };
3102
+ };
3103
+
3104
+ R.registerFont = function (font) {
3105
+ if (!font.face) {
3106
+ return font;
3107
+ }
3108
+ this.fonts = this.fonts || {};
3109
+ var fontcopy = {
3110
+ w: font.w,
3111
+ face: {},
3112
+ glyphs: {}
3113
+ },
3114
+ family = font.face["font-family"];
3115
+ for (var prop in font.face) if (font.face[has](prop)) {
3116
+ fontcopy.face[prop] = font.face[prop];
3117
+ }
3118
+ if (this.fonts[family]) {
3119
+ this.fonts[family][push](fontcopy);
3120
+ } else {
3121
+ this.fonts[family] = [fontcopy];
3122
+ }
3123
+ if (!font.svg) {
3124
+ fontcopy.face["units-per-em"] = toInt(font.face["units-per-em"], 10);
3125
+ for (var glyph in font.glyphs) if (font.glyphs[has](glyph)) {
3126
+ var path = font.glyphs[glyph];
3127
+ fontcopy.glyphs[glyph] = {
3128
+ w: path.w,
3129
+ k: {},
3130
+ d: path.d && "M" + path.d[rp](/[mlcxtrv]/g, function (command) {
3131
+ return {l: "L", c: "C", x: "z", t: "m", r: "l", v: "c"}[command] || "M";
3132
+ }) + "z"
3133
+ };
3134
+ if (path.k) {
3135
+ for (var k in path.k) if (path[has](k)) {
3136
+ fontcopy.glyphs[glyph].k[k] = path.k[k];
3137
+ }
3138
+ }
3139
+ }
3140
+ }
3141
+ return font;
3142
+ };
3143
+ Paper[proto].getFont = function (family, weight, style, stretch) {
3144
+ stretch = stretch || "normal";
3145
+ style = style || "normal";
3146
+ weight = +weight || {normal: 400, bold: 700, lighter: 300, bolder: 800}[weight] || 400;
3147
+ var font = R.fonts[family];
3148
+ if (!font) {
3149
+ var name = new RegExp("(^|\\s)" + family[rp](/[^\w\d\s+!~.:_-]/g, E) + "(\\s|$)", "i");
3150
+ for (var fontName in R.fonts) if (R.fonts[has](fontName)) {
3151
+ if (name.test(fontName)) {
3152
+ font = R.fonts[fontName];
3153
+ break;
3154
+ }
3155
+ }
3156
+ }
3157
+ var thefont;
3158
+ if (font) {
3159
+ for (var i = 0, ii = font[length]; i < ii; i++) {
3160
+ thefont = font[i];
3161
+ if (thefont.face["font-weight"] == weight && (thefont.face["font-style"] == style || !thefont.face["font-style"]) && thefont.face["font-stretch"] == stretch) {
3162
+ break;
3163
+ }
3164
+ }
3165
+ }
3166
+ return thefont;
3167
+ };
3168
+ Paper[proto].print = function (x, y, string, font, size, origin) {
3169
+ origin = origin || "middle"; // baseline|middle
3170
+ var out = this.set(),
3171
+ letters = (string + E)[split](E),
3172
+ shift = 0,
3173
+ path = E,
3174
+ scale;
3175
+ R.is(font, "string") && (font = this.getFont(font));
3176
+ if (font) {
3177
+ scale = (size || 16) / font.face["units-per-em"];
3178
+ var bb = font.face.bbox.split(separator),
3179
+ top = +bb[0],
3180
+ height = +bb[1] + (origin == "baseline" ? bb[3] - bb[1] + (+font.face.descent) : (bb[3] - bb[1]) / 2);
3181
+ for (var i = 0, ii = letters[length]; i < ii; i++) {
3182
+ var prev = i && font.glyphs[letters[i - 1]] || {},
3183
+ curr = font.glyphs[letters[i]];
3184
+ shift += i ? (prev.w || font.w) + (prev.k && prev.k[letters[i]] || 0) : 0;
3185
+ curr && curr.d && out[push](this.path(curr.d).attr({fill: "#000", stroke: "none", translation: [shift, 0]}));
3186
+ }
3187
+ out.scale(scale, scale, top, height).translate(x - top, y - height);
3188
+ }
3189
+ return out;
3190
+ };
3191
+
3192
+ R.format = function (token) {
3193
+ var args = R.is(arguments[1], "array") ? [0][concat](arguments[1]) : arguments,
3194
+ rg = /\{(\d+)\}/g;
3195
+ token && R.is(token, "string") && args[length] - 1 && (token = token[rp](rg, function (str, i) {
3196
+ return args[++i] == null ? E : args[i];
3197
+ }));
3198
+ return token || E;
3199
+ };
3200
+ R.ninja = function () {
3201
+ var r = win.Raphael, u;
3202
+ if (oldRaphael.was) {
3203
+ win.Raphael = oldRaphael.is;
3204
+ } else {
3205
+ try {
3206
+ delete win.Raphael;
3207
+ } catch (e) {
3208
+ win.Raphael = u;
3209
+ }
3210
+ }
3211
+ return r;
3212
+ };
3213
+ R.el = Element[proto];
3214
+ return R;
3215
+ })();