var _120 = PI * 120 / 180,
rad = PI / 180 * (+angle || 0),
res = [],
xy,
rotate = cacher(function (x, y, rad) {
var X = x * math.cos(rad) - y * math.sin(rad),
Y = x * math.sin(rad) + y * math.cos(rad);
return {x: X, y: Y};
});
if (!recursive) {
xy = rotate(x1, y1, -rad);
x1 = xy.x;
y1 = xy.y;
xy = rotate(x2, y2, -rad);
x2 = xy.x;
y2 = xy.y;
var cos = math.cos(PI / 180 * angle),
sin = math.sin(PI / 180 * angle),
x = (x1 - x2) / 2,
y = (y1 - y2) / 2;
var h = (x * x) / (rx * rx) + (y * y) / (ry * ry);
if (h > 1) {
h = math.sqrt(h);
rx = h * rx;
ry = h * ry;
}
var rx2 = rx * rx,
ry2 = ry * ry,
k = (large_arc_flag == sweep_flag ? -1 : 1) *
math.sqrt(abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x))),
cx = k * rx * y / ry + (x1 + x2) / 2,
cy = k * -ry * x / rx + (y1 + y2) / 2,
f1 = math.asin(((y1 - cy) / ry).toFixed(9)),
f2 = math.asin(((y2 - cy) / ry).toFixed(9));
f1 = x1 < cx ? PI - f1 : f1;
f2 = x2 < cx ? PI - f2 : f2;
f1 < 0 && (f1 = PI * 2 + f1);
f2 < 0 && (f2 = PI * 2 + f2);
if (sweep_flag && f1 > f2) {
f1 = f1 - PI * 2;
}
if (!sweep_flag && f2 > f1) {
f2 = f2 - PI * 2;
}
} else {
f1 = recursive[0];
f2 = recursive[1];
cx = recursive[2];
cy = recursive[3];
}
var df = f2 - f1;
if (abs(df) > _120) {
var f2old = f2,
x2old = x2,
y2old = y2;
f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1);
x2 = cx + rx * math.cos(f2);
y2 = cy + ry * math.sin(f2);
res = a2c(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [f2, f2old, cx, cy]);
}
df = f2 - f1;
var c1 = math.cos(f1),
s1 = math.sin(f1),
c2 = math.cos(f2),
s2 = math.sin(f2),
t = math.tan(df / 4),
hx = 4 / 3 * rx * t,
hy = 4 / 3 * ry * t,
m1 = [x1, y1],
m2 = [x1 + hx * s1, y1 - hy * c1],
m3 = [x2 + hx * s2, y2 - hy * c2],
m4 = [x2, y2];
m2[0] = 2 * m1[0] - m2[0];
m2[1] = 2 * m1[1] - m2[1];
if (recursive) {
return [m2, m3, m4][concat](res);
} else {
res = [m2, m3, m4][concat](res).join()[split](",");
var newres = [];
for (var i = 0, ii = res.length; i < ii; i++) {
newres[i] = i % 2 ? rotate(res[i - 1], res[i], rad).y : rotate(res[i], res[i + 1], rad).x;
}
return newres;
}
},
findDotAtSegment = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) {
var t1 = 1 - t;
return {
x: pow(t1, 3) * p1x + pow(t1, 2) * 3 * t * c1x + t1 * 3 * t * t * c2x + pow(t, 3) * p2x,
y: pow(t1, 3) * p1y + pow(t1, 2) * 3 * t * c1y + t1 * 3 * t * t * c2y + pow(t, 3) * p2y
};
},
curveDim = cacher(function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) {
var a = (c2x - 2 * c1x + p1x) - (p2x - 2 * c2x + c1x),
b = 2 * (c1x - p1x) - 2 * (c2x - c1x),
c = p1x - c1x,
t1 = (-b + math.sqrt(b * b - 4 * a * c)) / 2 / a,
t2 = (-b - math.sqrt(b * b - 4 * a * c)) / 2 / a,
y = [p1y, p2y],
x = [p1x, p2x],
dot;
abs(t1) > "1e12" && (t1 = .5);
abs(t2) > "1e12" && (t2 = .5);
if (t1 > 0 && t1 < 1) {
dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t1);
x.push(dot.x);
y.push(dot.y);
}
if (t2 > 0 && t2 < 1) {
dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t2);
x.push(dot.x);
y.push(dot.y);
}
a = (c2y - 2 * c1y + p1y) - (p2y - 2 * c2y + c1y);
b = 2 * (c1y - p1y) - 2 * (c2y - c1y);
c = p1y - c1y;
t1 = (-b + math.sqrt(b * b - 4 * a * c)) / 2 / a;
t2 = (-b - math.sqrt(b * b - 4 * a * c)) / 2 / a;
abs(t1) > "1e12" && (t1 = .5);
abs(t2) > "1e12" && (t2 = .5);
if (t1 > 0 && t1 < 1) {
dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t1);
x.push(dot.x);
y.push(dot.y);
}
if (t2 > 0 && t2 < 1) {
dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t2);
x.push(dot.x);
y.push(dot.y);
}
return {
min: {x: mmin[apply](0, x), y: mmin[apply](0, y)},
max: {x: mmax[apply](0, x), y: mmax[apply](0, y)}
};
}),
path2curve = R._path2curve = cacher(function (path, path2) {
var pth = !path2 && paths(path);
if (!path2 && pth.curve) {
return pathClone(pth.curve);
}
var p = pathToAbsolute(path),
p2 = path2 && pathToAbsolute(path2),
attrs = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null},
attrs2 = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null},
processPath = function (path, d) {
var nx, ny;
if (!path) {
return ["C", d.x, d.y, d.x, d.y, d.x, d.y];
}
!(path[0] in {T:1, Q:1}) && (d.qx = d.qy = null);
switch (path[0]) {
case "M":
d.X = path[1];
d.Y = path[2];
break;
case "A":
path = ["C"][concat](a2c[apply](0, [d.x, d.y][concat](path.slice(1))));
break;
case "S":
nx = d.x + (d.x - (d.bx || d.x));
ny = d.y + (d.y - (d.by || d.y));
path = ["C", nx, ny][concat](path.slice(1));
break;
case "T":
d.qx = d.x + (d.x - (d.qx || d.x));
d.qy = d.y + (d.y - (d.qy || d.y));
path = ["C"][concat](q2c(d.x, d.y, d.qx, d.qy, path[1], path[2]));
break;
case "Q":
d.qx = path[1];
d.qy = path[2];
path = ["C"][concat](q2c(d.x, d.y, path[1], path[2], path[3], path[4]));
break;
case "L":
path = ["C"][concat](l2c(d.x, d.y, path[1], path[2]));
break;
case "H":
path = ["C"][concat](l2c(d.x, d.y, path[1], d.y));
break;
case "V":
path = ["C"][concat](l2c(d.x, d.y, d.x, path[1]));
break;
case "Z":
path = ["C"][concat](l2c(d.x, d.y, d.X, d.Y));
break;
}
return path;
},
fixArc = function (pp, i) {
if (pp[i].length > 7) {
pp[i].shift();
var pi = pp[i];
while (pi.length) {
pp.splice(i++, 0, ["C"][concat](pi.splice(0, 6)));
}
pp.splice(i, 1);
ii = mmax(p.length, p2 && p2.length || 0);
}
},
fixM = function (path1, path2, a1, a2, i) {
if (path1 && path2 && path1[i][0] == "M" && path2[i][0] != "M") {
path2.splice(i, 0, ["M", a2.x, a2.y]);
a1.bx = 0;
a1.by = 0;
a1.x = path1[i][1];
a1.y = path1[i][2];
ii = mmax(p.length, p2 && p2.length || 0);
}
};
for (var i = 0, ii = mmax(p.length, p2 && p2.length || 0); i < ii; i++) {
p[i] = processPath(p[i], attrs);
fixArc(p, i);
p2 && (p2[i] = processPath(p2[i], attrs2));
p2 && fixArc(p2, i);
fixM(p, p2, attrs, attrs2, i);
fixM(p2, p, attrs2, attrs, i);
var seg = p[i],
seg2 = p2 && p2[i],
seglen = seg.length,
seg2len = p2 && seg2.length;
attrs.x = seg[seglen - 2];
attrs.y = seg[seglen - 1];
attrs.bx = toFloat(seg[seglen - 4]) || attrs.x;
attrs.by = toFloat(seg[seglen - 3]) || attrs.y;
attrs2.bx = p2 && (toFloat(seg2[seg2len - 4]) || attrs2.x);
attrs2.by = p2 && (toFloat(seg2[seg2len - 3]) || attrs2.y);
attrs2.x = p2 && seg2[seg2len - 2];
attrs2.y = p2 && seg2[seg2len - 1];
}
if (!p2) {
pth.curve = pathClone(p);
}
return p2 ? [p, p2] : p;
}, null, pathClone),
parseDots = R._parseDots = cacher(function (gradient) {
var dots = [];
for (var i = 0, ii = gradient.length; i < ii; i++) {
var dot = {},
par = gradient[i].match(/^([^:]*):?([\d\.]*)/);
dot.color = R.getRGB(par[1]);
if (dot.color.error) {
return null;
}
dot.color = dot.color.hex;
par[2] && (dot.offset = par[2] + "%");
dots.push(dot);
}
for (i = 1, ii = dots.length - 1; i < ii; i++) {
if (!dots[i].offset) {
var start = toFloat(dots[i - 1].offset || 0),
end = 0;
for (var j = i + 1; j < ii; j++) {
if (dots[j].offset) {
end = dots[j].offset;
break;
}
}
if (!end) {
end = 100;
j = ii;
}
end = toFloat(end);
var d = (end - start) / (j - i + 1);
for (; i < j; i++) {
start += d;
dots[i].offset = start + "%";
}
}
}
return dots;
}),
tear = R._tear = function (el, paper) {
el == paper.top && (paper.top = el.prev);
el == paper.bottom && (paper.bottom = el.next);
el.next && (el.next.prev = el.prev);
el.prev && (el.prev.next = el.next);
},
tofront = R._tofront = function (el, paper) {
if (paper.top === el) {
return;
}
tear(el, paper);
el.next = null;
el.prev = paper.top;
paper.top.next = el;
paper.top = el;
},
toback = R._toback = function (el, paper) {
if (paper.bottom === el) {
return;
}
tear(el, paper);
el.next = paper.bottom;
el.prev = null;
paper.bottom.prev = el;
paper.bottom = el;
},
insertafter = R._insertafter = function (el, el2, paper) {
tear(el, paper);
el2 == paper.top && (paper.top = el);
el2.next && (el2.next.prev = el);
el.next = el2.next;
el.prev = el2;
el2.next = el;
},
insertbefore = R._insertbefore = function (el, el2, paper) {
tear(el, paper);
el2 == paper.bottom && (paper.bottom = el);
el2.prev && (el2.prev.next = el);
el.prev = el2.prev;
el2.prev = el;
el.next = el2;
},
toMatrix = R.toMatrix = function (path, transform) {
var bb = pathDimensions(path),
el = {
_: {
transform: E
},
getBBox: function () {
return bb;
}
};
extractTransform(el, transform);
return el.matrix;
},
transformPath = R.transformPath = function (path, transform) {
return mapPath(path, toMatrix(path, transform));
},
extractTransform = R._extractTransform = function (el, tstr) {
if (tstr == null) {
return el._.transform;
}
tstr = Str(tstr).replace(/\.{3}|\u2026/g, el._.transform || E);
var tdata = R.parseTransformString(tstr),
deg = 0,
dx = 0,
dy = 0,
sx = 1,
sy = 1,
_ = el._,
m = new Matrix;
_.transform = tdata || [];
if (tdata) {
for (var i = 0, ii = tdata.length; i < ii; i++) {
var t = tdata[i],
tlen = t.length,
command = Str(t[0]).toLowerCase(),
absolute = t[0] != command,
inver = absolute ? m.invert() : 0,
x1,
y1,
x2,
y2,
bb;
if (command == "t" && tlen == 3) {
if (absolute) {
x1 = inver.x(0, 0);
y1 = inver.y(0, 0);
x2 = inver.x(t[1], t[2]);
y2 = inver.y(t[1], t[2]);
m.translate(x2 - x1, y2 - y1);
} else {
m.translate(t[1], t[2]);
}
} else if (command == "r") {
if (tlen == 2) {
bb = bb || el.getBBox(1);
m.rotate(t[1], bb.x + bb.width / 2, bb.y + bb.height / 2);
deg += t[1];
} else if (tlen == 4) {
if (absolute) {
x2 = inver.x(t[2], t[3]);
y2 = inver.y(t[2], t[3]);
m.rotate(t[1], x2, y2);
} else {
m.rotate(t[1], t[2], t[3]);
}
deg += t[1];
}
} else if (command == "s") {
if (tlen == 2 || tlen == 3) {
bb = bb || el.getBBox(1);
m.scale(t[1], t[tlen - 1], bb.x + bb.width / 2, bb.y + bb.height / 2);
sx *= t[1];
sy *= t[tlen - 1];
} else if (tlen == 5) {
if (absolute) {
x2 = inver.x(t[3], t[4]);
y2 = inver.y(t[3], t[4]);
m.scale(t[1], t[2], x2, y2);
} else {
m.scale(t[1], t[2], t[3], t[4]);
}
sx *= t[1];
sy *= t[2];
}
} else if (command == "m" && tlen == 7) {
m.add(t[1], t[2], t[3], t[4], t[5], t[6]);
}
_.dirtyT = 1;
el.matrix = m;
}
}
el.matrix = m;
_.sx = sx;
_.sy = sy;
_.deg = deg;
_.dx = dx = m.e;
_.dy = dy = m.f;
if (sx == 1 && sy == 1 && !deg && _.bbox) {
_.bbox.x += +dx;
_.bbox.y += +dy;
} else {
_.dirtyT = 1;
}
},
getEmpty = function (item) {
var l = item[0];
switch (l.toLowerCase()) {
case "t": return [l, 0, 0];
case "m": return [l, 1, 0, 0, 1, 0, 0];
case "r": if (item.length == 4) {
return [l, 0, item[2], item[3]];
} else {
return [l, 0];
}
case "s": if (item.length == 5) {
return [l, 1, 1, item[3], item[4]];
} else if (item.length == 3) {
return [l, 1, 1];
} else {
return [l, 1];
}
}
},
equaliseTransform = R._equaliseTransform = function (t1, t2) {
t2 = Str(t2).replace(/\.{3}|\u2026/g, t1);
t1 = R.parseTransformString(t1) || [];
t2 = R.parseTransformString(t2) || [];
var maxlength = mmax(t1.length, t2.length),
from = [],
to = [],
i = 0, j, jj,
tt1, tt2;
for (; i < maxlength; i++) {
tt1 = t1[i] || getEmpty(t2[i]);
tt2 = t2[i] || getEmpty(tt1);
if ((tt1[0] != tt2[0]) ||
(tt1[0].toLowerCase() == "r" && (tt1[2] != tt2[2] || tt1[3] != tt2[3])) ||
(tt1[0].toLowerCase() == "s" && (tt1[3] != tt2[3] || tt1[4] != tt2[4]))
) {
return;
}
from[i] = [];
to[i] = [];
for (j = 0, jj = mmax(tt1.length, tt2.length); j < jj; j++) {
j in tt1 && (from[i][j] = tt1[j]);
j in tt2 && (to[i][j] = tt2[j]);
}
}
return {
from: from,
to: to
};
};
R._getContainer = function (x, y, w, h) {
var container;
container = h == null && !R.is(x, "object") ? g.doc.getElementById(x) : x;
if (container == null) {
return;
}
if (container.tagName) {
if (y == null) {
return {
container: container,
width: container.style.pixelWidth || container.offsetWidth,
height: container.style.pixelHeight || container.offsetHeight
};
} else {
return {
container: container,
width: y,
height: w
};
}
}
return {
container: 1,
x: x,
y: y,
width: w,
height: h
};
};
R.pathToRelative = pathToRelative;
R._engine = {};
R.path2curve = path2curve;
R.matrix = function (a, b, c, d, e, f) {
return new Matrix(a, b, c, d, e, f);
};
function Matrix(a, b, c, d, e, f) {
if (a != null) {
this.a = +a;
this.b = +b;
this.c = +c;
this.d = +d;
this.e = +e;
this.f = +f;
} else {
this.a = 1;
this.b = 0;
this.c = 0;
this.d = 1;
this.e = 0;
this.f = 0;
}
}
(function (matrixproto) {
matrixproto.add = function (a, b, c, d, e, f) {
var out = [[], [], []],
m = [[this.a, this.c, this.e], [this.b, this.d, this.f], [0, 0, 1]],
matrix = [[a, c, e], [b, d, f], [0, 0, 1]],
x, y, z, res;
if (a && a instanceof Matrix) {
matrix = [[a.a, a.c, a.e], [a.b, a.d, a.f], [0, 0, 1]];
}
for (x = 0; x < 3; x++) {
for (y = 0; y < 3; y++) {
res = 0;
for (z = 0; z < 3; z++) {
res += m[x][z] * matrix[z][y];
}
out[x][y] = res;
}
}
this.a = out[0][0];
this.b = out[1][0];
this.c = out[0][1];
this.d = out[1][1];
this.e = out[0][2];
this.f = out[1][2];
};
matrixproto.invert = function () {
var me = this,
x = me.a * me.d - me.b * me.c;
return new Matrix(me.d / x, -me.b / x, -me.c / x, me.a / x, (me.c * me.f - me.d * me.e) / x, (me.b * me.e - me.a * me.f) / x);
};
matrixproto.clone = function () {
return new Matrix(this.a, this.b, this.c, this.d, this.e, this.f);
};
matrixproto.translate = function (x, y) {
this.add(1, 0, 0, 1, x, y);
};
matrixproto.scale = function (x, y, cx, cy) {
y == null && (y = x);
(cx || cy) && this.add(1, 0, 0, 1, cx, cy);
this.add(x, 0, 0, y, 0, 0);
(cx || cy) && this.add(1, 0, 0, 1, -cx, -cy);
};
matrixproto.rotate = function (a, x, y) {
a = R.rad(a);
x = x || 0;
y = y || 0;
var cos = +math.cos(a).toFixed(9),
sin = +math.sin(a).toFixed(9);
this.add(cos, sin, -sin, cos, x, y);
this.add(1, 0, 0, 1, -x, -y);
};
matrixproto.x = function (x, y) {
return x * this.a + y * this.c + this.e;
};
matrixproto.y = function (x, y) {
return x * this.b + y * this.d + this.f;
};
matrixproto.get = function (i) {
return +this[Str.fromCharCode(97 + i)].toFixed(4);
};
matrixproto.toString = function () {
return R.svg ?
"matrix(" + [this.get(0), this.get(1), this.get(2), this.get(3), this.get(4), this.get(5)].join() + ")" :
[this.get(0), this.get(2), this.get(1), this.get(3), 0, 0].join();
};
matrixproto.toFilter = function () {
return "progid:DXImageTransform.Microsoft.Matrix(M11=" + this.get(0) +
", M12=" + this.get(2) + ", M21=" + this.get(1) + ", M22=" + this.get(3) +
", Dx=" + this.get(4) + ", Dy=" + this.get(5) + ", sizingmethod='auto expand')";
};
matrixproto.offset = function () {
return [this.e.toFixed(4), this.f.toFixed(4)];
};
function norm(a) {
return a[0] * a[0] + a[1] * a[1];
}
function normalize(a) {
var mag = math.sqrt(norm(a));
a[0] && (a[0] /= mag);
a[1] && (a[1] /= mag);
}
matrixproto.split = function () {
var out = {};