d2/d2renderers/d2sketch/rough.js

1674 lines
47 KiB
JavaScript
Raw Normal View History

2022-12-21 07:43:45 +00:00
/*eslint-disable */
// This is a slightly modified version of rough.js for D2
//
// rough.js is from https://github.com/rough-stuff/rough.
// Attribution for this file is as follows:
//
// MIT License
//
// Copyright (c) 2019 Preet Shihn
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
const t = "http://www.w3.org/2000/svg";
function e(t, e, s) {
if (t && t.length) {
const [n, i] = e,
a = (Math.PI / 180) * s,
o = Math.cos(a),
h = Math.sin(a);
t.forEach((t) => {
const [e, s] = t;
(t[0] = (e - n) * o - (s - i) * h + n), (t[1] = (e - n) * h + (s - i) * o + i);
});
}
}
function s(t) {
const e = t[0],
s = t[1];
return Math.sqrt(Math.pow(e[0] - s[0], 2) + Math.pow(e[1] - s[1], 2));
}
function n(t, e) {
return t.type === e;
}
const i = {
A: 7,
a: 7,
C: 6,
c: 6,
H: 1,
h: 1,
L: 2,
l: 2,
M: 2,
m: 2,
Q: 4,
q: 4,
S: 4,
s: 4,
T: 4,
t: 2,
V: 1,
v: 1,
Z: 0,
z: 0,
};
class a {
constructor(t) {
(this.COMMAND = 0),
(this.NUMBER = 1),
(this.EOD = 2),
(this.segments = []),
this.parseData(t),
this.processPoints();
}
tokenize(t) {
const e = new Array();
for (; "" !== t; ) {
const a = t.match(/^([ \t\r\n,]+)/);
const b = t.match(/^([aAcChHlLmMqQsStTvVzZ])/);
const c = t.match(/^(([-+]?[0-9]+(\.[0-9]*)?|[-+]?\.[0-9]+)([eE][-+]?[0-9]+)?)/);
if (a) t = t.substr(a[0].length);
else if (b)
(e[e.length] = { type: this.COMMAND, text: b[0] }), (t = t.substr(b[0].length));
else {
if (!c) return [];
(e[e.length] = { type: this.NUMBER, text: `${parseFloat(c[0])}` }),
(t = t.substr(c[0].length));
}
}
return (e[e.length] = { type: this.EOD, text: "" }), e;
}
parseData(t) {
const e = this.tokenize(t);
let s = 0,
a = e[s],
o = "BOD";
for (this.segments = new Array(); !n(a, this.EOD); ) {
let h;
const r = new Array();
if ("BOD" === o) {
if ("M" !== a.text && "m" !== a.text) return void this.parseData("M0,0" + t);
s++, (h = i[a.text]), (o = a.text);
} else n(a, this.NUMBER) ? (h = i[o]) : (s++, (h = i[a.text]), (o = a.text));
if (s + h < e.length) {
for (let t = s; t < s + h; t++) {
const s = e[t];
if (!n(s, this.NUMBER))
return void console.error("Param not a number: " + o + "," + s.text);
r[r.length] = +s.text;
}
if ("number" != typeof i[o]) return void console.error("Bad segment: " + o);
{
const t = { key: o, data: r };
this.segments.push(t),
(s += h),
(a = e[s]),
"M" === o && (o = "L"),
"m" === o && (o = "l");
}
} else console.error("Path data ended short");
}
}
get closed() {
if (void 0 === this._closed) {
this._closed = !1;
for (const t of this.segments) "z" === t.key.toLowerCase() && (this._closed = !0);
}
return this._closed;
}
processPoints() {
let t = null,
e = [0, 0];
for (let s = 0; s < this.segments.length; s++) {
const n = this.segments[s];
switch (n.key) {
case "M":
case "L":
case "T":
n.point = [n.data[0], n.data[1]];
break;
case "m":
case "l":
case "t":
n.point = [n.data[0] + e[0], n.data[1] + e[1]];
break;
case "H":
n.point = [n.data[0], e[1]];
break;
case "h":
n.point = [n.data[0] + e[0], e[1]];
break;
case "V":
n.point = [e[0], n.data[0]];
break;
case "v":
n.point = [e[0], n.data[0] + e[1]];
break;
case "z":
case "Z":
t && (n.point = [t[0], t[1]]);
break;
case "C":
n.point = [n.data[4], n.data[5]];
break;
case "c":
n.point = [n.data[4] + e[0], n.data[5] + e[1]];
break;
case "S":
n.point = [n.data[2], n.data[3]];
break;
case "s":
n.point = [n.data[2] + e[0], n.data[3] + e[1]];
break;
case "Q":
n.point = [n.data[2], n.data[3]];
break;
case "q":
n.point = [n.data[2] + e[0], n.data[3] + e[1]];
break;
case "A":
n.point = [n.data[5], n.data[6]];
break;
case "a":
n.point = [n.data[5] + e[0], n.data[6] + e[1]];
}
("m" !== n.key && "M" !== n.key) || (t = null),
n.point && ((e = n.point), t || (t = n.point)),
("z" !== n.key && "Z" !== n.key) || (t = null);
}
}
}
class o {
constructor(t) {
(this._position = [0, 0]),
(this._first = null),
(this.bezierReflectionPoint = null),
(this.quadReflectionPoint = null),
(this.parsed = new a(t));
}
get segments() {
return this.parsed.segments;
}
get closed() {
return this.parsed.closed;
}
get linearPoints() {
if (!this._linearPoints) {
const t = [];
let e = [];
for (const s of this.parsed.segments) {
const n = s.key.toLowerCase();
(("m" !== n && "z" !== n) || (e.length && (t.push(e), (e = [])), "z" !== n)) &&
s.point &&
e.push(s.point);
}
e.length && (t.push(e), (e = [])), (this._linearPoints = t);
}
return this._linearPoints;
}
get first() {
return this._first;
}
set first(t) {
this._first = t;
}
setPosition(t, e) {
(this._position = [t, e]), this._first || (this._first = [t, e]);
}
get position() {
return this._position;
}
get x() {
return this._position[0];
}
get y() {
return this._position[1];
}
}
class h {
constructor(t, e, s, n, i, a) {
if (
((this._segIndex = 0),
(this._numSegs = 0),
(this._rx = 0),
(this._ry = 0),
(this._sinPhi = 0),
(this._cosPhi = 0),
(this._C = [0, 0]),
(this._theta = 0),
(this._delta = 0),
(this._T = 0),
(this._from = t),
t[0] === e[0] && t[1] === e[1])
)
return;
const o = Math.PI / 180;
(this._rx = Math.abs(s[0])),
(this._ry = Math.abs(s[1])),
(this._sinPhi = Math.sin(n * o)),
(this._cosPhi = Math.cos(n * o));
const h = (this._cosPhi * (t[0] - e[0])) / 2 + (this._sinPhi * (t[1] - e[1])) / 2,
r = (-this._sinPhi * (t[0] - e[0])) / 2 + (this._cosPhi * (t[1] - e[1])) / 2;
let c = 0;
const l =
this._rx * this._rx * this._ry * this._ry -
this._rx * this._rx * r * r -
this._ry * this._ry * h * h;
if (l < 0) {
const t = Math.sqrt(1 - l / (this._rx * this._rx * this._ry * this._ry));
(this._rx = this._rx * t), (this._ry = this._ry * t), (c = 0);
} else
c =
(i === a ? -1 : 1) *
Math.sqrt(l / (this._rx * this._rx * r * r + this._ry * this._ry * h * h));
const u = (c * this._rx * r) / this._ry,
p = (-c * this._ry * h) / this._rx;
(this._C = [0, 0]),
(this._C[0] = this._cosPhi * u - this._sinPhi * p + (t[0] + e[0]) / 2),
(this._C[1] = this._sinPhi * u + this._cosPhi * p + (t[1] + e[1]) / 2),
(this._theta = this.calculateVectorAngle(
1,
0,
(h - u) / this._rx,
(r - p) / this._ry
));
let d = this.calculateVectorAngle(
(h - u) / this._rx,
(r - p) / this._ry,
(-h - u) / this._rx,
(-r - p) / this._ry
);
!a && d > 0 ? (d -= 2 * Math.PI) : a && d < 0 && (d += 2 * Math.PI),
(this._numSegs = Math.ceil(Math.abs(d / (Math.PI / 2)))),
(this._delta = d / this._numSegs),
(this._T =
((8 / 3) * Math.sin(this._delta / 4) * Math.sin(this._delta / 4)) /
Math.sin(this._delta / 2));
}
getNextSegment() {
if (this._segIndex === this._numSegs) return null;
const t = Math.cos(this._theta),
e = Math.sin(this._theta),
s = this._theta + this._delta,
n = Math.cos(s),
i = Math.sin(s),
a = [
this._cosPhi * this._rx * n - this._sinPhi * this._ry * i + this._C[0],
this._sinPhi * this._rx * n + this._cosPhi * this._ry * i + this._C[1],
],
o = [
this._from[0] +
this._T * (-this._cosPhi * this._rx * e - this._sinPhi * this._ry * t),
this._from[1] +
this._T * (-this._sinPhi * this._rx * e + this._cosPhi * this._ry * t),
],
h = [
a[0] + this._T * (this._cosPhi * this._rx * i + this._sinPhi * this._ry * n),
a[1] + this._T * (this._sinPhi * this._rx * i - this._cosPhi * this._ry * n),
];
return (
(this._theta = s),
(this._from = [a[0], a[1]]),
this._segIndex++,
{ cp1: o, cp2: h, to: a }
);
}
calculateVectorAngle(t, e, s, n) {
const i = Math.atan2(e, t),
a = Math.atan2(n, s);
return a >= i ? a - i : 2 * Math.PI - (i - a);
}
}
class r {
constructor(t, e) {
(this.sets = t), (this.closed = e);
}
fit(t) {
const e = [];
for (const s of this.sets) {
const n = s.length;
let i = Math.floor(t * n);
if (i < 5) {
if (n <= 5) continue;
i = 5;
}
e.push(this.reduce(s, i));
}
let s = "";
for (const t of e) {
for (let e = 0; e < t.length; e++) {
const n = t[e];
s += 0 === e ? "M" + n[0] + "," + n[1] : "L" + n[0] + "," + n[1];
}
this.closed && (s += "z ");
}
return s;
}
reduce(t, e) {
if (t.length <= e) return t;
const n = t.slice(0);
for (; n.length > e; ) {
let t = -1,
e = -1;
for (let i = 1; i < n.length - 1; i++) {
const a = s([n[i - 1], n[i]]),
o = s([n[i], n[i + 1]]),
h = s([n[i - 1], n[i + 1]]),
r = (a + o + h) / 2,
c = Math.sqrt(r * (r - a) * (r - o) * (r - h));
(t < 0 || c < t) && ((t = c), (e = i));
}
if (!(e > 0)) break;
n.splice(e, 1);
}
return n;
}
}
function c(t, s) {
const n = [0, 0],
i = Math.round(s.hachureAngle + 90);
i && e(t, n, i);
const a = (function (t, e) {
const s = [...t];
s[0].join(",") !== s[s.length - 1].join(",") && s.push([s[0][0], s[0][1]]);
const n = [];
if (s && s.length > 2) {
let t = e.hachureGap;
t < 0 && (t = 4 * e.strokeWidth), (t = Math.max(t, 0.1));
const i = [];
for (let t = 0; t < s.length - 1; t++) {
const e = s[t],
n = s[t + 1];
if (e[1] !== n[1]) {
const t = Math.min(e[1], n[1]);
i.push({
ymin: t,
ymax: Math.max(e[1], n[1]),
x: t === e[1] ? e[0] : n[0],
islope: (n[0] - e[0]) / (n[1] - e[1]),
});
}
}
if (
(i.sort((t, e) =>
t.ymin < e.ymin
? -1
: t.ymin > e.ymin
? 1
: t.x < e.x
? -1
: t.x > e.x
? 1
: t.ymax === e.ymax
? 0
: (t.ymax - e.ymax) / Math.abs(t.ymax - e.ymax)
),
!i.length)
)
return n;
let a = [],
o = i[0].ymin;
for (; a.length || i.length; ) {
if (i.length) {
let t = -1;
for (let e = 0; e < i.length && !(i[e].ymin > o); e++) t = e;
i.splice(0, t + 1).forEach((t) => {
a.push({ s: o, edge: t });
});
}
if (
((a = a.filter((t) => !(t.edge.ymax <= o))),
a.sort((t, e) =>
t.edge.x === e.edge.x
? 0
: (t.edge.x - e.edge.x) / Math.abs(t.edge.x - e.edge.x)
),
a.length > 1)
)
for (let t = 0; t < a.length; t += 2) {
const e = t + 1;
if (e >= a.length) break;
const s = a[t].edge,
i = a[e].edge;
n.push([
[Math.round(s.x), o],
[Math.round(i.x), o],
]);
}
(o += t),
a.forEach((e) => {
e.edge.x = e.edge.x + t * e.edge.islope;
});
}
}
return n;
})(t, s);
return (
i &&
(e(t, n, -i),
(function (t, s, n) {
const i = [];
t.forEach((t) => i.push(...t)), e(i, s, n);
})(a, n, -i)),
a
);
}
class l {
constructor(t) {
this.helper = t;
}
fillPolygon(t, e) {
return this._fillPolygon(t, e);
}
_fillPolygon(t, e, s = !1) {
const n = c(t, e);
return { type: "fillSketch", ops: this.renderLines(n, e, s) };
}
renderLines(t, e, s) {
let n = [],
i = null;
for (const a of t)
(n = n.concat(this.helper.doubleLineOps(a[0][0], a[0][1], a[1][0], a[1][1], e))),
s &&
i &&
(n = n.concat(this.helper.doubleLineOps(i[0], i[1], a[0][0], a[0][1], e))),
(i = a[1]);
return n;
}
}
class u extends l {
fillPolygon(t, e) {
return this._fillPolygon(t, e, !0);
}
}
class p extends l {
fillPolygon(t, e) {
const s = this._fillPolygon(t, e),
n = Object.assign({}, e, { hachureAngle: e.hachureAngle + 90 }),
i = this._fillPolygon(t, n);
return (s.ops = s.ops.concat(i.ops)), s;
}
}
class d {
constructor(t) {
this.helper = t;
}
fillPolygon(t, e) {
const s = c(
t,
(e = Object.assign({}, e, {
curveStepCount: 4,
hachureAngle: 0,
roughness: 1,
}))
);
return this.dotsOnLines(s, e);
}
dotsOnLines(t, e) {
let n = [],
i = e.hachureGap;
i < 0 && (i = 4 * e.strokeWidth), (i = Math.max(i, 0.1));
let a = e.fillWeight;
a < 0 && (a = e.strokeWidth / 2);
for (const o of t) {
const t = s(o) / i,
h = Math.ceil(t) - 1,
r = Math.atan((o[1][1] - o[0][1]) / (o[1][0] - o[0][0]));
for (let t = 0; t < h; t++) {
const s = i * (t + 1),
h = s * Math.sin(r),
c = s * Math.cos(r),
l = [o[0][0] - c, o[0][1] + h],
u = this.helper.randOffsetWithRange(l[0] - i / 4, l[0] + i / 4, e),
p = this.helper.randOffsetWithRange(l[1] - i / 4, l[1] + i / 4, e),
d = this.helper.ellipse(u, p, a, a, e);
n = n.concat(d.ops);
}
}
return { type: "fillSketch", ops: n };
}
}
class f {
constructor(t) {
this.helper = t;
}
fillPolygon(t, e) {
const s = c(t, e);
return { type: "fillSketch", ops: this.dashedLine(s, e) };
}
dashedLine(t, e) {
const n =
e.dashOffset < 0
? e.hachureGap < 0
? 4 * e.strokeWidth
: e.hachureGap
: e.dashOffset,
i =
e.dashGap < 0 ? (e.hachureGap < 0 ? 4 * e.strokeWidth : e.hachureGap) : e.dashGap;
let a = [];
return (
t.forEach((t) => {
const o = s(t),
h = Math.floor(o / (n + i)),
r = (o + i - h * (n + i)) / 2;
let c = t[0],
l = t[1];
c[0] > l[0] && ((c = t[1]), (l = t[0]));
const u = Math.atan((l[1] - c[1]) / (l[0] - c[0]));
for (let t = 0; t < h; t++) {
const s = t * (n + i),
o = s + n,
h = [
c[0] + s * Math.cos(u) + r * Math.cos(u),
c[1] + s * Math.sin(u) + r * Math.sin(u),
],
l = [
c[0] + o * Math.cos(u) + r * Math.cos(u),
c[1] + o * Math.sin(u) + r * Math.sin(u),
];
a = a.concat(this.helper.doubleLineOps(h[0], h[1], l[0], l[1], e));
}
}),
a
);
}
}
class g {
constructor(t) {
this.helper = t;
}
fillPolygon(t, e) {
const s = e.hachureGap < 0 ? 4 * e.strokeWidth : e.hachureGap,
n = e.zigzagOffset < 0 ? s : e.zigzagOffset,
i = c(t, (e = Object.assign({}, e, { hachureGap: s + n })));
return { type: "fillSketch", ops: this.zigzagLines(i, n, e) };
}
zigzagLines(t, e, n) {
let i = [];
return (
t.forEach((t) => {
const a = s(t),
o = Math.round(a / (2 * e));
let h = t[0],
r = t[1];
h[0] > r[0] && ((h = t[1]), (r = t[0]));
const c = Math.atan((r[1] - h[1]) / (r[0] - h[0]));
for (let t = 0; t < o; t++) {
const s = 2 * t * e,
a = 2 * (t + 1) * e,
o = Math.sqrt(2 * Math.pow(e, 2)),
r = [h[0] + s * Math.cos(c), h[1] + s * Math.sin(c)],
l = [h[0] + a * Math.cos(c), h[1] + a * Math.sin(c)],
u = [
r[0] + o * Math.cos(c + Math.PI / 4),
r[1] + o * Math.sin(c + Math.PI / 4),
];
(i = i.concat(this.helper.doubleLineOps(r[0], r[1], u[0], u[1], n))),
(i = i.concat(this.helper.doubleLineOps(u[0], u[1], l[0], l[1], n)));
}
}),
i
);
}
}
const y = {};
class _ {
constructor(t) {
this.seed = t;
}
next() {
return this.seed
? ((Math.pow(2, 31) - 1) & (this.seed = Math.imul(48271, this.seed))) /
Math.pow(2, 31)
: Math.random();
}
}
const M = {
randOffset: function (t, e) {
return z(t, e);
},
randOffsetWithRange: function (t, e, s) {
return C(t, e, s);
},
ellipse: function (t, e, s, n, i) {
const a = P(s, n, i);
return w(t, e, i, a).opset;
},
doubleLineOps: function (t, e, s, n, i) {
return A(t, e, s, n, i);
},
};
function x(t, e, s, n, i) {
return { type: "path", ops: A(t, e, s, n, i) };
}
function m(t, e, s) {
const n = (t || []).length;
if (n > 2) {
let i = [];
for (let e = 0; e < n - 1; e++)
i = i.concat(A(t[e][0], t[e][1], t[e + 1][0], t[e + 1][1], s));
return (
e && (i = i.concat(A(t[n - 1][0], t[n - 1][1], t[0][0], t[0][1], s))),
{ type: "path", ops: i }
);
}
return 2 === n ? x(t[0][0], t[0][1], t[1][0], t[1][1], s) : { type: "path", ops: [] };
}
function k(t, e, s, n, i) {
return (function (t, e) {
return m(t, !0, e);
})(
[
[t, e],
[t + s, e],
[t + s, e + n],
[t, e + n],
],
i
);
}
function b(t, e) {
const s = W(t, 1 * (1 + 0.2 * e.roughness), e),
n = W(t, 1.5 * (1 + 0.22 * e.roughness), e);
return { type: "path", ops: s.concat(n) };
}
function P(t, e, s) {
const n = Math.sqrt(
2 * Math.PI * Math.sqrt((Math.pow(t / 2, 2) + Math.pow(e / 2, 2)) / 2)
),
i = Math.max(s.curveStepCount, (s.curveStepCount / Math.sqrt(200)) * n),
a = (2 * Math.PI) / i;
let o = Math.abs(t / 2),
h = Math.abs(e / 2);
const r = 1 - s.curveFitting;
return (o += z(o * r, s)), (h += z(h * r, s)), { increment: a, rx: o, ry: h };
}
function w(t, e, s, n) {
const [i, a] = D(
n.increment,
t,
e,
n.rx,
n.ry,
1,
n.increment * C(0.1, C(0.4, 1, s), s),
s
),
[o] = D(n.increment, t, e, n.rx, n.ry, 1.5, 0, s),
h = R(i, null, s),
r = R(o, null, s);
return { estimatedPoints: a, opset: { type: "path", ops: h.concat(r) } };
}
function v(t, e, s, n, i, a, o, h, r) {
const c = t,
l = e;
let u = Math.abs(s / 2),
p = Math.abs(n / 2);
(u += z(0.01 * u, r)), (p += z(0.01 * p, r));
let d = i,
f = a;
for (; d < 0; ) (d += 2 * Math.PI), (f += 2 * Math.PI);
f - d > 2 * Math.PI && ((d = 0), (f = 2 * Math.PI));
const g = (2 * Math.PI) / r.curveStepCount,
y = Math.min(g / 2, (f - d) / 2),
_ = I(y, c, l, u, p, d, f, 1, r),
M = I(y, c, l, u, p, d, f, 1.5, r);
let x = _.concat(M);
return (
o &&
(h
? ((x = x.concat(A(c, l, c + u * Math.cos(d), l + p * Math.sin(d), r))),
(x = x.concat(A(c, l, c + u * Math.cos(f), l + p * Math.sin(f), r))))
: (x.push({ op: "lineTo", data: [c, l] }),
x.push({
op: "lineTo",
data: [c + u * Math.cos(d), l + p * Math.sin(d)],
}))),
{ type: "path", ops: x }
);
}
function S(t, e) {
const s = [];
if (t.length) {
const n = e.maxRandomnessOffset || 0,
i = t.length;
if (i > 2) {
s.push({ op: "move", data: [t[0][0] + z(n, e), t[0][1] + z(n, e)] });
for (let a = 1; a < i; a++)
s.push({ op: "lineTo", data: [t[a][0] + z(n, e), t[a][1] + z(n, e)] });
}
}
return { type: "fillPath", ops: s };
}
function O(t, e) {
return (function (t, e) {
let s = t.fillStyle || "hachure";
if (!y[s])
switch (s) {
case "zigzag":
y[s] || (y[s] = new u(e));
break;
case "cross-hatch":
y[s] || (y[s] = new p(e));
break;
case "dots":
y[s] || (y[s] = new d(e));
break;
case "dashed":
y[s] || (y[s] = new f(e));
break;
case "zigzag-line":
y[s] || (y[s] = new g(e));
break;
case "hachure":
default:
(s = "hachure"), y[s] || (y[s] = new l(e));
}
return y[s];
})(e, M).fillPolygon(t, e);
}
function T(t) {
return t.randomizer || (t.randomizer = new _(t.seed || 0)), t.randomizer.next();
}
function C(t, e, s) {
return s.roughness * s.roughnessGain * (T(s) * (e - t) + t);
}
function z(t, e) {
return C(-t, t, e);
}
function A(t, e, s, n, i) {
const a = E(t, e, s, n, i, !0, !1),
o = E(t, e, s, n, i, !0, !0);
return a.concat(o);
}
function E(t, e, s, n, i, a, o) {
const h = Math.pow(t - s, 2) + Math.pow(e - n, 2),
r = Math.sqrt(h);
i.roughnessGain = r < 200 ? 1 : r > 500 ? 0.4 : -0.0016668 * r + 1.233334;
let c = i.maxRandomnessOffset || 0;
c * c * 100 > h && (c = r / 10);
const l = c / 2,
u = 0.2 + 0.2 * T(i);
let p = (i.bowing * i.maxRandomnessOffset * (n - e)) / 200,
d = (i.bowing * i.maxRandomnessOffset * (t - s)) / 200;
(p = z(p, i)), (d = z(d, i));
const f = [],
g = () => z(l, i),
y = () => z(c, i);
return (
a &&
(o
? f.push({ op: "move", data: [t + g(), e + g()] })
: f.push({ op: "move", data: [t + z(c, i), e + z(c, i)] })),
o
? f.push({
op: "bcurveTo",
data: [
p + t + (s - t) * u + g(),
d + e + (n - e) * u + g(),
p + t + 2 * (s - t) * u + g(),
d + e + 2 * (n - e) * u + g(),
s + g(),
n + g(),
],
})
: f.push({
op: "bcurveTo",
data: [
p + t + (s - t) * u + y(),
d + e + (n - e) * u + y(),
p + t + 2 * (s - t) * u + y(),
d + e + 2 * (n - e) * u + y(),
s + y(),
n + y(),
],
}),
f
);
}
function W(t, e, s) {
const n = [];
n.push([t[0][0] + z(e, s), t[0][1] + z(e, s)]),
n.push([t[0][0] + z(e, s), t[0][1] + z(e, s)]);
for (let i = 1; i < t.length; i++)
n.push([t[i][0] + z(e, s), t[i][1] + z(e, s)]),
i === t.length - 1 && n.push([t[i][0] + z(e, s), t[i][1] + z(e, s)]);
return R(n, null, s);
}
function R(t, e, s) {
const n = t.length;
let i = [];
if (n > 3) {
const a = [],
o = 1 - s.curveTightness;
i.push({ op: "move", data: [t[1][0], t[1][1]] });
for (let e = 1; e + 2 < n; e++) {
const s = t[e];
(a[0] = [s[0], s[1]]),
(a[1] = [
s[0] + (o * t[e + 1][0] - o * t[e - 1][0]) / 6,
s[1] + (o * t[e + 1][1] - o * t[e - 1][1]) / 6,
]),
(a[2] = [
t[e + 1][0] + (o * t[e][0] - o * t[e + 2][0]) / 6,
t[e + 1][1] + (o * t[e][1] - o * t[e + 2][1]) / 6,
]),
(a[3] = [t[e + 1][0], t[e + 1][1]]),
i.push({
op: "bcurveTo",
data: [a[1][0], a[1][1], a[2][0], a[2][1], a[3][0], a[3][1]],
});
}
if (e && 2 === e.length) {
const t = s.maxRandomnessOffset;
i.push({ op: "lineTo", data: [e[0] + z(t, s), e[1] + z(t, s)] });
}
} else
3 === n
? (i.push({ op: "move", data: [t[1][0], t[1][1]] }),
i.push({
op: "bcurveTo",
data: [t[1][0], t[1][1], t[2][0], t[2][1], t[2][0], t[2][1]],
}))
: 2 === n && (i = i.concat(A(t[0][0], t[0][1], t[1][0], t[1][1], s)));
return i;
}
function D(t, e, s, n, i, a, o, h) {
const r = [],
c = [],
l = z(0.5, h) - Math.PI / 2;
c.push([
z(a, h) + e + 0.9 * n * Math.cos(l - t),
z(a, h) + s + 0.9 * i * Math.sin(l - t),
]);
for (let o = l; o < 2 * Math.PI + l - 0.01; o += t) {
const t = [z(a, h) + e + n * Math.cos(o), z(a, h) + s + i * Math.sin(o)];
r.push(t), c.push(t);
}
return (
c.push([
z(a, h) + e + n * Math.cos(l + 2 * Math.PI + 0.5 * o),
z(a, h) + s + i * Math.sin(l + 2 * Math.PI + 0.5 * o),
]),
c.push([
z(a, h) + e + 0.98 * n * Math.cos(l + o),
z(a, h) + s + 0.98 * i * Math.sin(l + o),
]),
c.push([
z(a, h) + e + 0.9 * n * Math.cos(l + 0.5 * o),
z(a, h) + s + 0.9 * i * Math.sin(l + 0.5 * o),
]),
[c, r]
);
}
function I(t, e, s, n, i, a, o, h, r) {
const c = a + z(0.1, r),
l = [];
l.push([
z(h, r) + e + 0.9 * n * Math.cos(c - t),
z(h, r) + s + 0.9 * i * Math.sin(c - t),
]);
for (let a = c; a <= o; a += t)
l.push([z(h, r) + e + n * Math.cos(a), z(h, r) + s + i * Math.sin(a)]);
return (
l.push([e + n * Math.cos(o), s + i * Math.sin(o)]),
l.push([e + n * Math.cos(o), s + i * Math.sin(o)]),
R(l, null, r)
);
}
function q(t, e, s, n, i, a, o, h) {
const r = [],
c = [h.maxRandomnessOffset || 1, (h.maxRandomnessOffset || 1) + 0.5];
let l = [0, 0];
for (let u = 0; u < 2; u++)
0 === u
? r.push({ op: "move", data: [o.x, o.y] })
: r.push({ op: "move", data: [o.x + z(c[0], h), o.y + z(c[0], h)] }),
(l = [i + z(c[u], h), a + z(c[u], h)]),
r.push({
op: "bcurveTo",
data: [
t + z(c[u], h),
e + z(c[u], h),
s + z(c[u], h),
n + z(c[u], h),
l[0],
l[1],
],
});
return o.setPosition(l[0], l[1]), r;
}
function $(t, e, s, n) {
let i = [];
switch (e.key) {
case "M":
case "m": {
const s = "m" === e.key;
if (e.data.length >= 2) {
let a = +e.data[0],
o = +e.data[1];
s && ((a += t.x), (o += t.y));
const h = 1 * (n.maxRandomnessOffset || 0);
(a += z(h, n)),
(o += z(h, n)),
t.setPosition(a, o),
i.push({ op: "move", data: [a, o] });
}
break;
}
case "L":
case "l": {
const s = "l" === e.key;
if (e.data.length >= 2) {
let a = +e.data[0],
o = +e.data[1];
s && ((a += t.x), (o += t.y)),
(i = i.concat(A(t.x, t.y, a, o, n))),
t.setPosition(a, o);
}
break;
}
case "H":
case "h": {
const s = "h" === e.key;
if (e.data.length) {
let a = +e.data[0];
s && (a += t.x), (i = i.concat(A(t.x, t.y, a, t.y, n))), t.setPosition(a, t.y);
}
break;
}
case "V":
case "v": {
const s = "v" === e.key;
if (e.data.length) {
let a = +e.data[0];
s && (a += t.y), (i = i.concat(A(t.x, t.y, t.x, a, n))), t.setPosition(t.x, a);
}
break;
}
case "Z":
case "z":
t.first &&
((i = i.concat(A(t.x, t.y, t.first[0], t.first[1], n))),
t.setPosition(t.first[0], t.first[1]),
(t.first = null));
break;
case "C":
case "c": {
const s = "c" === e.key;
if (e.data.length >= 6) {
let a = +e.data[0],
o = +e.data[1],
h = +e.data[2],
r = +e.data[3],
c = +e.data[4],
l = +e.data[5];
s && ((a += t.x), (h += t.x), (c += t.x), (o += t.y), (r += t.y), (l += t.y));
const u = q(a, o, h, r, c, l, t, n);
(i = i.concat(u)), (t.bezierReflectionPoint = [c + (c - h), l + (l - r)]);
}
break;
}
case "S":
case "s": {
const a = "s" === e.key;
if (e.data.length >= 4) {
let o = +e.data[0],
h = +e.data[1],
r = +e.data[2],
c = +e.data[3];
a && ((o += t.x), (r += t.x), (h += t.y), (c += t.y));
let l = o,
u = h;
const p = s ? s.key : "";
let d = null;
("c" !== p && "C" !== p && "s" !== p && "S" !== p) ||
(d = t.bezierReflectionPoint),
d && ((l = d[0]), (u = d[1]));
const f = q(l, u, o, h, r, c, t, n);
(i = i.concat(f)), (t.bezierReflectionPoint = [r + (r - o), c + (c - h)]);
}
break;
}
case "Q":
case "q": {
const s = "q" === e.key;
if (e.data.length >= 4) {
let a = +e.data[0],
o = +e.data[1],
h = +e.data[2],
r = +e.data[3];
s && ((a += t.x), (h += t.x), (o += t.y), (r += t.y));
const c = 1 * (1 + 0.2 * n.roughness),
l = 1.5 * (1 + 0.22 * n.roughness);
i.push({ op: "move", data: [t.x + z(c, n), t.y + z(c, n)] });
let u = [h + z(c, n), r + z(c, n)];
i.push({
op: "qcurveTo",
data: [a + z(c, n), o + z(c, n), u[0], u[1]],
}),
i.push({ op: "move", data: [t.x + z(l, n), t.y + z(l, n)] }),
(u = [h + z(l, n), r + z(l, n)]),
i.push({
op: "qcurveTo",
data: [a + z(l, n), o + z(l, n), u[0], u[1]],
}),
t.setPosition(u[0], u[1]),
(t.quadReflectionPoint = [h + (h - a), r + (r - o)]);
}
break;
}
case "T":
case "t": {
const a = "t" === e.key;
if (e.data.length >= 2) {
let o = +e.data[0],
h = +e.data[1];
a && ((o += t.x), (h += t.y));
let r = o,
c = h;
const l = s ? s.key : "";
let u = null;
("q" !== l && "Q" !== l && "t" !== l && "T" !== l) || (u = t.quadReflectionPoint),
u && ((r = u[0]), (c = u[1]));
const p = 1 * (1 + 0.2 * n.roughness),
d = 1.5 * (1 + 0.22 * n.roughness);
i.push({ op: "move", data: [t.x + z(p, n), t.y + z(p, n)] });
let f = [o + z(p, n), h + z(p, n)];
i.push({
op: "qcurveTo",
data: [r + z(p, n), c + z(p, n), f[0], f[1]],
}),
i.push({ op: "move", data: [t.x + z(d, n), t.y + z(d, n)] }),
(f = [o + z(d, n), h + z(d, n)]),
i.push({
op: "qcurveTo",
data: [r + z(d, n), c + z(d, n), f[0], f[1]],
}),
t.setPosition(f[0], f[1]),
(t.quadReflectionPoint = [o + (o - r), h + (h - c)]);
}
break;
}
case "A":
case "a": {
const s = "a" === e.key;
if (e.data.length >= 7) {
const a = +e.data[0],
o = +e.data[1],
r = +e.data[2],
c = +e.data[3],
l = +e.data[4];
let u = +e.data[5],
p = +e.data[6];
if ((s && ((u += t.x), (p += t.y)), u === t.x && p === t.y)) break;
if (0 === a || 0 === o) (i = i.concat(A(t.x, t.y, u, p, n))), t.setPosition(u, p);
else
for (let e = 0; e < 1; e++) {
const e = new h([t.x, t.y], [u, p], [a, o], r, !!c, !!l);
let s = e.getNextSegment();
for (; s; ) {
const a = q(s.cp1[0], s.cp1[1], s.cp2[0], s.cp2[1], s.to[0], s.to[1], t, n);
(i = i.concat(a)), (s = e.getNextSegment());
}
}
}
break;
}
}
return i;
}
const N = "undefined" != typeof self,
L = "none";
class B {
constructor(t, e) {
(this.defaultOptions = {
maxRandomnessOffset: 2,
roughness: 1,
bowing: 1,
stroke: "#000",
strokeWidth: 1,
curveTightness: 0,
curveFitting: 0.95,
curveStepCount: 9,
fillStyle: "hachure",
fillWeight: -1,
hachureAngle: -41,
hachureGap: -1,
dashOffset: -1,
dashGap: -1,
zigzagOffset: -1,
seed: 0,
roughnessGain: 1,
}),
(this.config = t || {}),
(this.surface = e),
this.config.options && (this.defaultOptions = this._options(this.config.options));
}
static newSeed() {
return Math.floor(Math.random() * Math.pow(2, 31));
}
_options(t) {
return t ? Object.assign({}, this.defaultOptions, t) : this.defaultOptions;
}
_drawable(t, e, s) {
return { shape: t, sets: e || [], options: s || this.defaultOptions };
}
line(t, e, s, n, i) {
const a = this._options(i);
return this._drawable("line", [x(t, e, s, n, a)], a);
}
rectangle(t, e, s, n, i) {
const a = this._options(i),
o = [],
h = k(t, e, s, n, a);
if (a.fill) {
const i = [
[t, e],
[t + s, e],
[t + s, e + n],
[t, e + n],
];
"solid" === a.fillStyle ? o.push(S(i, a)) : o.push(O(i, a));
}
return a.stroke !== L && o.push(h), this._drawable("rectangle", o, a);
}
ellipse(t, e, s, n, i) {
const a = this._options(i),
o = [],
h = P(s, n, a),
r = w(t, e, a, h);
if (a.fill)
if ("solid" === a.fillStyle) {
const s = w(t, e, a, h).opset;
(s.type = "fillPath"), o.push(s);
} else o.push(O(r.estimatedPoints, a));
return a.stroke !== L && o.push(r.opset), this._drawable("ellipse", o, a);
}
circle(t, e, s, n) {
const i = this.ellipse(t, e, s, s, n);
return (i.shape = "circle"), i;
}
linearPath(t, e) {
const s = this._options(e);
return this._drawable("linearPath", [m(t, !1, s)], s);
}
arc(t, e, s, n, i, a, o = !1, h) {
const r = this._options(h),
c = [],
l = v(t, e, s, n, i, a, o, !0, r);
if (o && r.fill)
if ("solid" === r.fillStyle) {
const o = v(t, e, s, n, i, a, !0, !1, r);
(o.type = "fillPath"), c.push(o);
} else
c.push(
(function (t, e, s, n, i, a, o) {
const h = t,
r = e;
let c = Math.abs(s / 2),
l = Math.abs(n / 2);
(c += z(0.01 * c, o)), (l += z(0.01 * l, o));
let u = i,
p = a;
for (; u < 0; ) (u += 2 * Math.PI), (p += 2 * Math.PI);
p - u > 2 * Math.PI && ((u = 0), (p = 2 * Math.PI));
const d = (p - u) / o.curveStepCount,
f = [];
for (let t = u; t <= p; t += d)
f.push([h + c * Math.cos(t), r + l * Math.sin(t)]);
return (
f.push([h + c * Math.cos(p), r + l * Math.sin(p)]), f.push([h, r]), O(f, o)
);
})(t, e, s, n, i, a, r)
);
return r.stroke !== L && c.push(l), this._drawable("arc", c, r);
}
curve(t, e) {
const s = this._options(e);
return this._drawable("curve", [b(t, s)], s);
}
polygon(t, e) {
const s = this._options(e),
n = [],
i = m(t, !0, s);
return (
s.fill && ("solid" === s.fillStyle ? n.push(S(t, s)) : n.push(O(t, s))),
s.stroke !== L && n.push(i),
this._drawable("polygon", n, s)
);
}
path(t, e) {
const s = this._options(e),
n = [];
if (!t) return this._drawable("path", n, s);
const i = (function (t, e) {
t = (t || "").replace(/\n/g, " ").replace(/(-\s)/g, "-").replace("/(ss)/g", " ");
let s = new o(t);
if (e.simplification) {
const t = new r(s.linearPoints, s.closed).fit(e.simplification);
s = new o(t);
}
let n = [];
const i = s.segments || [];
for (let t = 0; t < i.length; t++) {
const a = $(s, i[t], t > 0 ? i[t - 1] : null, e);
a && a.length && (n = n.concat(a));
}
return { type: "path", ops: n };
})(t, s);
if (s.fill)
if ("solid" === s.fillStyle) {
const e = { type: "path2Dfill", path: t, ops: [] };
n.push(e);
} else {
const e = this.computePathSize(t),
i = O(
[
[0, 0],
[e[0], 0],
[e[0], e[1]],
[0, e[1]],
],
s
);
(i.type = "path2Dpattern"), (i.size = e), (i.path = t), n.push(i);
}
return s.stroke !== L && n.push(i), this._drawable("path", n, s);
}
computePathSize(e) {
let s = [0, 0];
if (N && self.document)
try {
const n = self.document.createElementNS(t, "svg");
n.setAttribute("width", "0"), n.setAttribute("height", "0");
const i = self.document.createElementNS(t, "path");
i.setAttribute("d", e), n.appendChild(i), self.document.body.appendChild(n);
const a = i.getBBox();
a && ((s[0] = a.width || 0), (s[1] = a.height || 0)),
self.document.body.removeChild(n);
} catch (t) {}
const n = this.getCanvasSize();
return s[0] * s[1] || (s = n), s;
}
getCanvasSize() {
const t = (t) =>
t && "object" == typeof t && t.baseVal && t.baseVal.value
? t.baseVal.value
: t || 100;
return this.surface ? [t(this.surface.width), t(this.surface.height)] : [100, 100];
}
opsToPath(t) {
let e = "";
for (const s of t.ops) {
const t = s.data;
switch (s.op) {
case "move":
e += `M${t[0]} ${t[1]} `;
break;
case "bcurveTo":
e += `C${t[0]} ${t[1]}, ${t[2]} ${t[3]}, ${t[4]} ${t[5]} `;
break;
case "qcurveTo":
e += `Q${t[0]} ${t[1]}, ${t[2]} ${t[3]} `;
break;
case "lineTo":
e += `L${t[0]} ${t[1]} `;
}
}
return e.trim();
}
toPaths(t) {
const e = t.sets || [],
s = t.options || this.defaultOptions,
n = [];
for (const t of e) {
let e = null;
switch (t.type) {
case "path":
e = {
d: this.opsToPath(t),
stroke: s.stroke,
strokeWidth: s.strokeWidth,
fill: L,
};
break;
case "fillPath":
e = {
d: this.opsToPath(t),
stroke: L,
strokeWidth: 0,
fill: s.fill || L,
};
break;
case "fillSketch":
e = this.fillSketch(t, s);
break;
case "path2Dfill":
e = { d: t.path || "", stroke: L, strokeWidth: 0, fill: s.fill || L };
break;
case "path2Dpattern": {
const n = t.size,
i = {
x: 0,
y: 0,
width: 1,
height: 1,
viewBox: `0 0 ${Math.round(n[0])} ${Math.round(n[1])}`,
patternUnits: "objectBoundingBox",
path: this.fillSketch(t, s),
};
e = { d: t.path, stroke: L, strokeWidth: 0, pattern: i };
break;
}
}
e && n.push(e);
}
return n;
}
fillSketch(t, e) {
let s = e.fillWeight;
return (
s < 0 && (s = e.strokeWidth / 2),
{ d: this.opsToPath(t), stroke: e.fill || L, strokeWidth: s, fill: L }
);
}
}
const G = "undefined" != typeof document;
class V {
constructor(t, e) {
(this.canvas = t),
(this.ctx = this.canvas.getContext("2d")),
(this.gen = new B(e, this.canvas));
}
draw(t) {
const e = t.sets || [],
s = t.options || this.getDefaultOptions(),
n = this.ctx;
for (const t of e)
switch (t.type) {
case "path":
n.save(),
(n.strokeStyle = "none" === s.stroke ? "transparent" : s.stroke),
(n.lineWidth = s.strokeWidth),
this._drawToContext(n, t),
n.restore();
break;
case "fillPath":
n.save(), (n.fillStyle = s.fill || ""), this._drawToContext(n, t), n.restore();
break;
case "fillSketch":
this.fillSketch(n, t, s);
break;
case "path2Dfill": {
this.ctx.save(), (this.ctx.fillStyle = s.fill || "");
const e = new Path2D(t.path);
this.ctx.fill(e), this.ctx.restore();
break;
}
case "path2Dpattern": {
const e = this.canvas.ownerDocument || (G && document);
if (e) {
const n = t.size,
i = e.createElement("canvas"),
a = i.getContext("2d"),
o = this.computeBBox(t.path);
o && (o.width || o.height)
? ((i.width = this.canvas.width),
(i.height = this.canvas.height),
a.translate(o.x || 0, o.y || 0))
: ((i.width = n[0]), (i.height = n[1])),
this.fillSketch(a, t, s),
this.ctx.save(),
(this.ctx.fillStyle = this.ctx.createPattern(i, "repeat"));
const h = new Path2D(t.path);
this.ctx.fill(h), this.ctx.restore();
} else console.error("Pattern fill fail: No defs");
break;
}
}
}
computeBBox(e) {
if (G)
try {
const s = document.createElementNS(t, "svg");
s.setAttribute("width", "0"), s.setAttribute("height", "0");
const n = self.document.createElementNS(t, "path");
n.setAttribute("d", e), s.appendChild(n), document.body.appendChild(s);
const i = n.getBBox();
return document.body.removeChild(s), i;
} catch (t) {}
return null;
}
fillSketch(t, e, s) {
let n = s.fillWeight;
n < 0 && (n = s.strokeWidth / 2),
t.save(),
(t.strokeStyle = s.fill || ""),
(t.lineWidth = n),
this._drawToContext(t, e),
t.restore();
}
_drawToContext(t, e) {
t.beginPath();
for (const s of e.ops) {
const e = s.data;
switch (s.op) {
case "move":
t.moveTo(e[0], e[1]);
break;
case "bcurveTo":
t.bezierCurveTo(e[0], e[1], e[2], e[3], e[4], e[5]);
break;
case "qcurveTo":
t.quadraticCurveTo(e[0], e[1], e[2], e[3]);
break;
case "lineTo":
t.lineTo(e[0], e[1]);
}
}
"fillPath" === e.type ? t.fill() : t.stroke();
}
get generator() {
return this.gen;
}
getDefaultOptions() {
return this.gen.defaultOptions;
}
line(t, e, s, n, i) {
const a = this.gen.line(t, e, s, n, i);
return this.draw(a), a;
}
rectangle(t, e, s, n, i) {
const a = this.gen.rectangle(t, e, s, n, i);
return this.draw(a), a;
}
ellipse(t, e, s, n, i) {
const a = this.gen.ellipse(t, e, s, n, i);
return this.draw(a), a;
}
circle(t, e, s, n) {
const i = this.gen.circle(t, e, s, n);
return this.draw(i), i;
}
linearPath(t, e) {
const s = this.gen.linearPath(t, e);
return this.draw(s), s;
}
polygon(t, e) {
const s = this.gen.polygon(t, e);
return this.draw(s), s;
}
arc(t, e, s, n, i, a, o = !1, h) {
const r = this.gen.arc(t, e, s, n, i, a, o, h);
return this.draw(r), r;
}
curve(t, e) {
const s = this.gen.curve(t, e);
return this.draw(s), s;
}
path(t, e) {
const s = this.gen.path(t, e);
return this.draw(s), s;
}
}
const j = "undefined" != typeof document;
class Q {
constructor(t, e) {
(this.svg = t), (this.gen = new B(e, this.svg));
}
get defs() {
const e = this.svg.ownerDocument || (j && document);
if (e && !this._defs) {
const s = e.createElementNS(t, "defs");
this.svg.firstChild
? this.svg.insertBefore(s, this.svg.firstChild)
: this.svg.appendChild(s),
(this._defs = s);
}
return this._defs || null;
}
draw(e) {
const s = e.sets || [],
n = e.options || this.getDefaultOptions(),
i = this.svg.ownerDocument || window.document,
a = i.createElementNS(t, "g");
for (const e of s) {
let s = null;
switch (e.type) {
case "path":
(s = i.createElementNS(t, "path")),
s.setAttribute("d", this.opsToPath(e)),
(s.style.stroke = n.stroke),
(s.style.strokeWidth = n.strokeWidth + ""),
(s.style.fill = "none");
break;
case "fillPath":
(s = i.createElementNS(t, "path")),
s.setAttribute("d", this.opsToPath(e)),
(s.style.stroke = "none"),
(s.style.strokeWidth = "0"),
(s.style.fill = n.fill || "");
break;
case "fillSketch":
s = this.fillSketch(i, e, n);
break;
case "path2Dfill":
(s = i.createElementNS(t, "path")),
s.setAttribute("d", e.path || ""),
(s.style.stroke = "none"),
(s.style.strokeWidth = "0"),
(s.style.fill = n.fill || "");
break;
case "path2Dpattern":
if (this.defs) {
const a = e.size,
o = i.createElementNS(t, "pattern"),
h = `rough-${Math.floor(
Math.random() * (Number.MAX_SAFE_INTEGER || 999999)
)}`;
o.setAttribute("id", h),
o.setAttribute("x", "0"),
o.setAttribute("y", "0"),
o.setAttribute("width", "1"),
o.setAttribute("height", "1"),
o.setAttribute("height", "1"),
o.setAttribute("viewBox", `0 0 ${Math.round(a[0])} ${Math.round(a[1])}`),
o.setAttribute("patternUnits", "objectBoundingBox");
const r = this.fillSketch(i, e, n);
o.appendChild(r),
this.defs.appendChild(o),
(s = i.createElementNS(t, "path")),
s.setAttribute("d", e.path || ""),
(s.style.stroke = "none"),
(s.style.strokeWidth = "0"),
(s.style.fill = `url(#${h})`);
} else console.error("Pattern fill fail: No defs");
}
s && a.appendChild(s);
}
return a;
}
fillSketch(e, s, n) {
let i = n.fillWeight;
i < 0 && (i = n.strokeWidth / 2);
const a = e.createElementNS(t, "path");
return (
a.setAttribute("d", this.opsToPath(s)),
(a.style.stroke = n.fill || ""),
(a.style.strokeWidth = i + ""),
(a.style.fill = "none"),
a
);
}
get generator() {
return this.gen;
}
getDefaultOptions() {
return this.gen.defaultOptions;
}
opsToPath(t) {
return this.gen.opsToPath(t);
}
line(t, e, s, n, i) {
const a = this.gen.line(t, e, s, n, i);
return this.draw(a);
}
rectangle(t, e, s, n, i) {
const a = this.gen.rectangle(t, e, s, n, i);
return this.draw(a);
}
ellipse(t, e, s, n, i) {
const a = this.gen.ellipse(t, e, s, n, i);
return this.draw(a);
}
circle(t, e, s, n) {
const i = this.gen.circle(t, e, s, n);
return this.draw(i);
}
linearPath(t, e) {
const s = this.gen.linearPath(t, e);
return this.draw(s);
}
polygon(t, e) {
const s = this.gen.polygon(t, e);
return this.draw(s);
}
arc(t, e, s, n, i, a, o = !1, h) {
const r = this.gen.arc(t, e, s, n, i, a, o, h);
return this.draw(r);
}
curve(t, e) {
const s = this.gen.curve(t, e);
return this.draw(s);
}
path(t, e) {
const s = this.gen.path(t, e);
return this.draw(s);
}
}
var rough = {
canvas: (t, e) => new V(t, e),
svg: (t, e) => new Q(t, e),
generator: (t, e) => new B(t, e),
newSeed: () => B.newSeed(),
};