@embedthis/devcore
Version:
Devcore UI Framework
1,831 lines • 729 kB
JavaScript
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
import { reactive, ref, onMounted, onBeforeUnmount, openBlock, createElementBlock, createElementVNode, normalizeClass } from "vue";
/*!
* @kurkle/color v0.3.4
* https://github.com/kurkle/color#readme
* (c) 2024 Jukka Kurkela
* Released under the MIT License
*/
function round(v) {
return v + 0.5 | 0;
}
const lim = (v, l, h4) => Math.max(Math.min(v, h4), l);
function p2b(v) {
return lim(round(v * 2.55), 0, 255);
}
function n2b(v) {
return lim(round(v * 255), 0, 255);
}
function b2n(v) {
return lim(round(v / 2.55) / 100, 0, 1);
}
function n2p(v) {
return lim(round(v * 100), 0, 100);
}
const map$1 = { 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, A: 10, B: 11, C: 12, D: 13, E: 14, F: 15, a: 10, b: 11, c: 12, d: 13, e: 14, f: 15 };
const hex = [..."0123456789ABCDEF"];
const h1 = (b2) => hex[b2 & 15];
const h2 = (b2) => hex[(b2 & 240) >> 4] + hex[b2 & 15];
const eq = (b2) => (b2 & 240) >> 4 === (b2 & 15);
const isShort = (v) => eq(v.r) && eq(v.g) && eq(v.b) && eq(v.a);
function hexParse(str) {
var len = str.length;
var ret;
if (str[0] === "#") {
if (len === 4 || len === 5) {
ret = {
r: 255 & map$1[str[1]] * 17,
g: 255 & map$1[str[2]] * 17,
b: 255 & map$1[str[3]] * 17,
a: len === 5 ? map$1[str[4]] * 17 : 255
};
} else if (len === 7 || len === 9) {
ret = {
r: map$1[str[1]] << 4 | map$1[str[2]],
g: map$1[str[3]] << 4 | map$1[str[4]],
b: map$1[str[5]] << 4 | map$1[str[6]],
a: len === 9 ? map$1[str[7]] << 4 | map$1[str[8]] : 255
};
}
}
return ret;
}
const alpha = (a3, f) => a3 < 255 ? f(a3) : "";
function hexString(v) {
var f = isShort(v) ? h1 : h2;
return v ? "#" + f(v.r) + f(v.g) + f(v.b) + alpha(v.a, f) : void 0;
}
const HUE_RE = /^(hsla?|hwb|hsv)\(\s*([-+.e\d]+)(?:deg)?[\s,]+([-+.e\d]+)%[\s,]+([-+.e\d]+)%(?:[\s,]+([-+.e\d]+)(%)?)?\s*\)$/;
function hsl2rgbn(h4, s3, l) {
const a3 = s3 * Math.min(l, 1 - l);
const f = (n, k2 = (n + h4 / 30) % 12) => l - a3 * Math.max(Math.min(k2 - 3, 9 - k2, 1), -1);
return [f(0), f(8), f(4)];
}
function hsv2rgbn(h4, s3, v) {
const f = (n, k2 = (n + h4 / 60) % 6) => v - v * s3 * Math.max(Math.min(k2, 4 - k2, 1), 0);
return [f(5), f(3), f(1)];
}
function hwb2rgbn(h4, w2, b2) {
const rgb = hsl2rgbn(h4, 1, 0.5);
let i2;
if (w2 + b2 > 1) {
i2 = 1 / (w2 + b2);
w2 *= i2;
b2 *= i2;
}
for (i2 = 0; i2 < 3; i2++) {
rgb[i2] *= 1 - w2 - b2;
rgb[i2] += w2;
}
return rgb;
}
function hueValue(r, g, b2, d3, max) {
if (r === max) {
return (g - b2) / d3 + (g < b2 ? 6 : 0);
}
if (g === max) {
return (b2 - r) / d3 + 2;
}
return (r - g) / d3 + 4;
}
function rgb2hsl(v) {
const range = 255;
const r = v.r / range;
const g = v.g / range;
const b2 = v.b / range;
const max = Math.max(r, g, b2);
const min = Math.min(r, g, b2);
const l = (max + min) / 2;
let h4, s3, d3;
if (max !== min) {
d3 = max - min;
s3 = l > 0.5 ? d3 / (2 - max - min) : d3 / (max + min);
h4 = hueValue(r, g, b2, d3, max);
h4 = h4 * 60 + 0.5;
}
return [h4 | 0, s3 || 0, l];
}
function calln(f, a3, b2, c2) {
return (Array.isArray(a3) ? f(a3[0], a3[1], a3[2]) : f(a3, b2, c2)).map(n2b);
}
function hsl2rgb(h4, s3, l) {
return calln(hsl2rgbn, h4, s3, l);
}
function hwb2rgb(h4, w2, b2) {
return calln(hwb2rgbn, h4, w2, b2);
}
function hsv2rgb(h4, s3, v) {
return calln(hsv2rgbn, h4, s3, v);
}
function hue(h4) {
return (h4 % 360 + 360) % 360;
}
function hueParse(str) {
const m3 = HUE_RE.exec(str);
let a3 = 255;
let v;
if (!m3) {
return;
}
if (m3[5] !== v) {
a3 = m3[6] ? p2b(+m3[5]) : n2b(+m3[5]);
}
const h4 = hue(+m3[2]);
const p1 = +m3[3] / 100;
const p2 = +m3[4] / 100;
if (m3[1] === "hwb") {
v = hwb2rgb(h4, p1, p2);
} else if (m3[1] === "hsv") {
v = hsv2rgb(h4, p1, p2);
} else {
v = hsl2rgb(h4, p1, p2);
}
return {
r: v[0],
g: v[1],
b: v[2],
a: a3
};
}
function rotate(v, deg) {
var h4 = rgb2hsl(v);
h4[0] = hue(h4[0] + deg);
h4 = hsl2rgb(h4);
v.r = h4[0];
v.g = h4[1];
v.b = h4[2];
}
function hslString(v) {
if (!v) {
return;
}
const a3 = rgb2hsl(v);
const h4 = a3[0];
const s3 = n2p(a3[1]);
const l = n2p(a3[2]);
return v.a < 255 ? `hsla(${h4}, ${s3}%, ${l}%, ${b2n(v.a)})` : `hsl(${h4}, ${s3}%, ${l}%)`;
}
const map = {
x: "dark",
Z: "light",
Y: "re",
X: "blu",
W: "gr",
V: "medium",
U: "slate",
A: "ee",
T: "ol",
S: "or",
B: "ra",
C: "lateg",
D: "ights",
R: "in",
Q: "turquois",
E: "hi",
P: "ro",
O: "al",
N: "le",
M: "de",
L: "yello",
F: "en",
K: "ch",
G: "arks",
H: "ea",
I: "ightg",
J: "wh"
};
const names$1 = {
OiceXe: "f0f8ff",
antiquewEte: "faebd7",
aqua: "ffff",
aquamarRe: "7fffd4",
azuY: "f0ffff",
beige: "f5f5dc",
bisque: "ffe4c4",
black: "0",
blanKedOmond: "ffebcd",
Xe: "ff",
XeviTet: "8a2be2",
bPwn: "a52a2a",
burlywood: "deb887",
caMtXe: "5f9ea0",
KartYuse: "7fff00",
KocTate: "d2691e",
cSO: "ff7f50",
cSnflowerXe: "6495ed",
cSnsilk: "fff8dc",
crimson: "dc143c",
cyan: "ffff",
xXe: "8b",
xcyan: "8b8b",
xgTMnPd: "b8860b",
xWay: "a9a9a9",
xgYF: "6400",
xgYy: "a9a9a9",
xkhaki: "bdb76b",
xmagFta: "8b008b",
xTivegYF: "556b2f",
xSange: "ff8c00",
xScEd: "9932cc",
xYd: "8b0000",
xsOmon: "e9967a",
xsHgYF: "8fbc8f",
xUXe: "483d8b",
xUWay: "2f4f4f",
xUgYy: "2f4f4f",
xQe: "ced1",
xviTet: "9400d3",
dAppRk: "ff1493",
dApskyXe: "bfff",
dimWay: "696969",
dimgYy: "696969",
dodgerXe: "1e90ff",
fiYbrick: "b22222",
flSOwEte: "fffaf0",
foYstWAn: "228b22",
fuKsia: "ff00ff",
gaRsbSo: "dcdcdc",
ghostwEte: "f8f8ff",
gTd: "ffd700",
gTMnPd: "daa520",
Way: "808080",
gYF: "8000",
gYFLw: "adff2f",
gYy: "808080",
honeyMw: "f0fff0",
hotpRk: "ff69b4",
RdianYd: "cd5c5c",
Rdigo: "4b0082",
ivSy: "fffff0",
khaki: "f0e68c",
lavFMr: "e6e6fa",
lavFMrXsh: "fff0f5",
lawngYF: "7cfc00",
NmoncEffon: "fffacd",
ZXe: "add8e6",
ZcSO: "f08080",
Zcyan: "e0ffff",
ZgTMnPdLw: "fafad2",
ZWay: "d3d3d3",
ZgYF: "90ee90",
ZgYy: "d3d3d3",
ZpRk: "ffb6c1",
ZsOmon: "ffa07a",
ZsHgYF: "20b2aa",
ZskyXe: "87cefa",
ZUWay: "778899",
ZUgYy: "778899",
ZstAlXe: "b0c4de",
ZLw: "ffffe0",
lime: "ff00",
limegYF: "32cd32",
lRF: "faf0e6",
magFta: "ff00ff",
maPon: "800000",
VaquamarRe: "66cdaa",
VXe: "cd",
VScEd: "ba55d3",
VpurpN: "9370db",
VsHgYF: "3cb371",
VUXe: "7b68ee",
VsprRggYF: "fa9a",
VQe: "48d1cc",
VviTetYd: "c71585",
midnightXe: "191970",
mRtcYam: "f5fffa",
mistyPse: "ffe4e1",
moccasR: "ffe4b5",
navajowEte: "ffdead",
navy: "80",
Tdlace: "fdf5e6",
Tive: "808000",
TivedBb: "6b8e23",
Sange: "ffa500",
SangeYd: "ff4500",
ScEd: "da70d6",
pOegTMnPd: "eee8aa",
pOegYF: "98fb98",
pOeQe: "afeeee",
pOeviTetYd: "db7093",
papayawEp: "ffefd5",
pHKpuff: "ffdab9",
peru: "cd853f",
pRk: "ffc0cb",
plum: "dda0dd",
powMrXe: "b0e0e6",
purpN: "800080",
YbeccapurpN: "663399",
Yd: "ff0000",
Psybrown: "bc8f8f",
PyOXe: "4169e1",
saddNbPwn: "8b4513",
sOmon: "fa8072",
sandybPwn: "f4a460",
sHgYF: "2e8b57",
sHshell: "fff5ee",
siFna: "a0522d",
silver: "c0c0c0",
skyXe: "87ceeb",
UXe: "6a5acd",
UWay: "708090",
UgYy: "708090",
snow: "fffafa",
sprRggYF: "ff7f",
stAlXe: "4682b4",
tan: "d2b48c",
teO: "8080",
tEstN: "d8bfd8",
tomato: "ff6347",
Qe: "40e0d0",
viTet: "ee82ee",
JHt: "f5deb3",
wEte: "ffffff",
wEtesmoke: "f5f5f5",
Lw: "ffff00",
LwgYF: "9acd32"
};
function unpack() {
const unpacked = {};
const keys = Object.keys(names$1);
const tkeys = Object.keys(map);
let i2, j, k2, ok, nk;
for (i2 = 0; i2 < keys.length; i2++) {
ok = nk = keys[i2];
for (j = 0; j < tkeys.length; j++) {
k2 = tkeys[j];
nk = nk.replace(k2, map[k2]);
}
k2 = parseInt(names$1[ok], 16);
unpacked[nk] = [k2 >> 16 & 255, k2 >> 8 & 255, k2 & 255];
}
return unpacked;
}
let names;
function nameParse(str) {
if (!names) {
names = unpack();
names.transparent = [0, 0, 0, 0];
}
const a3 = names[str.toLowerCase()];
return a3 && {
r: a3[0],
g: a3[1],
b: a3[2],
a: a3.length === 4 ? a3[3] : 255
};
}
const RGB_RE = /^rgba?\(\s*([-+.\d]+)(%)?[\s,]+([-+.e\d]+)(%)?[\s,]+([-+.e\d]+)(%)?(?:[\s,/]+([-+.e\d]+)(%)?)?\s*\)$/;
function rgbParse(str) {
const m3 = RGB_RE.exec(str);
let a3 = 255;
let r, g, b2;
if (!m3) {
return;
}
if (m3[7] !== r) {
const v = +m3[7];
a3 = m3[8] ? p2b(v) : lim(v * 255, 0, 255);
}
r = +m3[1];
g = +m3[3];
b2 = +m3[5];
r = 255 & (m3[2] ? p2b(r) : lim(r, 0, 255));
g = 255 & (m3[4] ? p2b(g) : lim(g, 0, 255));
b2 = 255 & (m3[6] ? p2b(b2) : lim(b2, 0, 255));
return {
r,
g,
b: b2,
a: a3
};
}
function rgbString(v) {
return v && (v.a < 255 ? `rgba(${v.r}, ${v.g}, ${v.b}, ${b2n(v.a)})` : `rgb(${v.r}, ${v.g}, ${v.b})`);
}
const to = (v) => v <= 31308e-7 ? v * 12.92 : Math.pow(v, 1 / 2.4) * 1.055 - 0.055;
const from = (v) => v <= 0.04045 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
function interpolate$1(rgb1, rgb2, t2) {
const r = from(b2n(rgb1.r));
const g = from(b2n(rgb1.g));
const b2 = from(b2n(rgb1.b));
return {
r: n2b(to(r + t2 * (from(b2n(rgb2.r)) - r))),
g: n2b(to(g + t2 * (from(b2n(rgb2.g)) - g))),
b: n2b(to(b2 + t2 * (from(b2n(rgb2.b)) - b2))),
a: rgb1.a + t2 * (rgb2.a - rgb1.a)
};
}
function modHSL(v, i2, ratio) {
if (v) {
let tmp = rgb2hsl(v);
tmp[i2] = Math.max(0, Math.min(tmp[i2] + tmp[i2] * ratio, i2 === 0 ? 360 : 1));
tmp = hsl2rgb(tmp);
v.r = tmp[0];
v.g = tmp[1];
v.b = tmp[2];
}
}
function clone$1(v, proto) {
return v ? Object.assign(proto || {}, v) : v;
}
function fromObject(input) {
var v = { r: 0, g: 0, b: 0, a: 255 };
if (Array.isArray(input)) {
if (input.length >= 3) {
v = { r: input[0], g: input[1], b: input[2], a: 255 };
if (input.length > 3) {
v.a = n2b(input[3]);
}
}
} else {
v = clone$1(input, { r: 0, g: 0, b: 0, a: 1 });
v.a = n2b(v.a);
}
return v;
}
function functionParse(str) {
if (str.charAt(0) === "r") {
return rgbParse(str);
}
return hueParse(str);
}
class Color {
constructor(input) {
if (input instanceof Color) {
return input;
}
const type = typeof input;
let v;
if (type === "object") {
v = fromObject(input);
} else if (type === "string") {
v = hexParse(input) || nameParse(input) || functionParse(input);
}
this._rgb = v;
this._valid = !!v;
}
get valid() {
return this._valid;
}
get rgb() {
var v = clone$1(this._rgb);
if (v) {
v.a = b2n(v.a);
}
return v;
}
set rgb(obj) {
this._rgb = fromObject(obj);
}
rgbString() {
return this._valid ? rgbString(this._rgb) : void 0;
}
hexString() {
return this._valid ? hexString(this._rgb) : void 0;
}
hslString() {
return this._valid ? hslString(this._rgb) : void 0;
}
mix(color2, weight) {
if (color2) {
const c1 = this.rgb;
const c2 = color2.rgb;
let w2;
const p = weight === w2 ? 0.5 : weight;
const w3 = 2 * p - 1;
const a3 = c1.a - c2.a;
const w1 = ((w3 * a3 === -1 ? w3 : (w3 + a3) / (1 + w3 * a3)) + 1) / 2;
w2 = 1 - w1;
c1.r = 255 & w1 * c1.r + w2 * c2.r + 0.5;
c1.g = 255 & w1 * c1.g + w2 * c2.g + 0.5;
c1.b = 255 & w1 * c1.b + w2 * c2.b + 0.5;
c1.a = p * c1.a + (1 - p) * c2.a;
this.rgb = c1;
}
return this;
}
interpolate(color2, t2) {
if (color2) {
this._rgb = interpolate$1(this._rgb, color2._rgb, t2);
}
return this;
}
clone() {
return new Color(this.rgb);
}
alpha(a3) {
this._rgb.a = n2b(a3);
return this;
}
clearer(ratio) {
const rgb = this._rgb;
rgb.a *= 1 - ratio;
return this;
}
greyscale() {
const rgb = this._rgb;
const val = round(rgb.r * 0.3 + rgb.g * 0.59 + rgb.b * 0.11);
rgb.r = rgb.g = rgb.b = val;
return this;
}
opaquer(ratio) {
const rgb = this._rgb;
rgb.a *= 1 + ratio;
return this;
}
negate() {
const v = this._rgb;
v.r = 255 - v.r;
v.g = 255 - v.g;
v.b = 255 - v.b;
return this;
}
lighten(ratio) {
modHSL(this._rgb, 2, ratio);
return this;
}
darken(ratio) {
modHSL(this._rgb, 2, -ratio);
return this;
}
saturate(ratio) {
modHSL(this._rgb, 1, ratio);
return this;
}
desaturate(ratio) {
modHSL(this._rgb, 1, -ratio);
return this;
}
rotate(deg) {
rotate(this._rgb, deg);
return this;
}
}
/*!
* Chart.js v4.4.7
* https://www.chartjs.org
* (c) 2024 Chart.js Contributors
* Released under the MIT License
*/
function noop() {
}
const uid = /* @__PURE__ */ (() => {
let id = 0;
return () => id++;
})();
function isNullOrUndef(value) {
return value === null || value === void 0;
}
function isArray(value) {
if (Array.isArray && Array.isArray(value)) {
return true;
}
const type = Object.prototype.toString.call(value);
if (type.slice(0, 7) === "[object" && type.slice(-6) === "Array]") {
return true;
}
return false;
}
function isObject(value) {
return value !== null && Object.prototype.toString.call(value) === "[object Object]";
}
function isNumberFinite(value) {
return (typeof value === "number" || value instanceof Number) && isFinite(+value);
}
function finiteOrDefault(value, defaultValue) {
return isNumberFinite(value) ? value : defaultValue;
}
function valueOrDefault(value, defaultValue) {
return typeof value === "undefined" ? defaultValue : value;
}
const toDimension = (value, dimension) => typeof value === "string" && value.endsWith("%") ? parseFloat(value) / 100 * dimension : +value;
function callback(fn, args, thisArg) {
if (fn && typeof fn.call === "function") {
return fn.apply(thisArg, args);
}
}
function each(loopable, fn, thisArg, reverse) {
let i2, len, keys;
if (isArray(loopable)) {
len = loopable.length;
{
for (i2 = 0; i2 < len; i2++) {
fn.call(thisArg, loopable[i2], i2);
}
}
} else if (isObject(loopable)) {
keys = Object.keys(loopable);
len = keys.length;
for (i2 = 0; i2 < len; i2++) {
fn.call(thisArg, loopable[keys[i2]], keys[i2]);
}
}
}
function _elementsEqual(a0, a1) {
let i2, ilen, v0, v1;
if (!a0 || !a1 || a0.length !== a1.length) {
return false;
}
for (i2 = 0, ilen = a0.length; i2 < ilen; ++i2) {
v0 = a0[i2];
v1 = a1[i2];
if (v0.datasetIndex !== v1.datasetIndex || v0.index !== v1.index) {
return false;
}
}
return true;
}
function clone(source) {
if (isArray(source)) {
return source.map(clone);
}
if (isObject(source)) {
const target = /* @__PURE__ */ Object.create(null);
const keys = Object.keys(source);
const klen = keys.length;
let k2 = 0;
for (; k2 < klen; ++k2) {
target[keys[k2]] = clone(source[keys[k2]]);
}
return target;
}
return source;
}
function isValidKey(key) {
return [
"__proto__",
"prototype",
"constructor"
].indexOf(key) === -1;
}
function _merger(key, target, source, options) {
if (!isValidKey(key)) {
return;
}
const tval = target[key];
const sval = source[key];
if (isObject(tval) && isObject(sval)) {
merge(tval, sval, options);
} else {
target[key] = clone(sval);
}
}
function merge(target, source, options) {
const sources = isArray(source) ? source : [
source
];
const ilen = sources.length;
if (!isObject(target)) {
return target;
}
options = options || {};
const merger = options.merger || _merger;
let current;
for (let i2 = 0; i2 < ilen; ++i2) {
current = sources[i2];
if (!isObject(current)) {
continue;
}
const keys = Object.keys(current);
for (let k2 = 0, klen = keys.length; k2 < klen; ++k2) {
merger(keys[k2], target, current, options);
}
}
return target;
}
function mergeIf(target, source) {
return merge(target, source, {
merger: _mergerIf
});
}
function _mergerIf(key, target, source) {
if (!isValidKey(key)) {
return;
}
const tval = target[key];
const sval = source[key];
if (isObject(tval) && isObject(sval)) {
mergeIf(tval, sval);
} else if (!Object.prototype.hasOwnProperty.call(target, key)) {
target[key] = clone(sval);
}
}
const keyResolvers = {
// Chart.helpers.core resolveObjectKey should resolve empty key to root object
"": (v) => v,
// default resolvers
x: (o) => o.x,
y: (o) => o.y
};
function _splitKey(key) {
const parts = key.split(".");
const keys = [];
let tmp = "";
for (const part of parts) {
tmp += part;
if (tmp.endsWith("\\")) {
tmp = tmp.slice(0, -1) + ".";
} else {
keys.push(tmp);
tmp = "";
}
}
return keys;
}
function _getKeyResolver(key) {
const keys = _splitKey(key);
return (obj) => {
for (const k2 of keys) {
if (k2 === "") {
break;
}
obj = obj && obj[k2];
}
return obj;
};
}
function resolveObjectKey(obj, key) {
const resolver = keyResolvers[key] || (keyResolvers[key] = _getKeyResolver(key));
return resolver(obj);
}
function _capitalize(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
const defined = (value) => typeof value !== "undefined";
const isFunction = (value) => typeof value === "function";
const setsEqual = (a3, b2) => {
if (a3.size !== b2.size) {
return false;
}
for (const item of a3) {
if (!b2.has(item)) {
return false;
}
}
return true;
};
function _isClickEvent(e2) {
return e2.type === "mouseup" || e2.type === "click" || e2.type === "contextmenu";
}
const PI = Math.PI;
const TAU = 2 * PI;
const PITAU = TAU + PI;
const INFINITY = Number.POSITIVE_INFINITY;
const RAD_PER_DEG = PI / 180;
const HALF_PI = PI / 2;
const QUARTER_PI = PI / 4;
const TWO_THIRDS_PI = PI * 2 / 3;
const log10 = Math.log10;
const sign = Math.sign;
function almostEquals(x2, y3, epsilon) {
return Math.abs(x2 - y3) < epsilon;
}
function niceNum(range) {
const roundedRange = Math.round(range);
range = almostEquals(range, roundedRange, range / 1e3) ? roundedRange : range;
const niceRange = Math.pow(10, Math.floor(log10(range)));
const fraction = range / niceRange;
const niceFraction = fraction <= 1 ? 1 : fraction <= 2 ? 2 : fraction <= 5 ? 5 : 10;
return niceFraction * niceRange;
}
function _factorize(value) {
const result = [];
const sqrt = Math.sqrt(value);
let i2;
for (i2 = 1; i2 < sqrt; i2++) {
if (value % i2 === 0) {
result.push(i2);
result.push(value / i2);
}
}
if (sqrt === (sqrt | 0)) {
result.push(sqrt);
}
result.sort((a3, b2) => a3 - b2).pop();
return result;
}
function isNumber(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
function almostWhole(x2, epsilon) {
const rounded = Math.round(x2);
return rounded - epsilon <= x2 && rounded + epsilon >= x2;
}
function _setMinAndMaxByKey(array, target, property) {
let i2, ilen, value;
for (i2 = 0, ilen = array.length; i2 < ilen; i2++) {
value = array[i2][property];
if (!isNaN(value)) {
target.min = Math.min(target.min, value);
target.max = Math.max(target.max, value);
}
}
}
function toRadians(degrees) {
return degrees * (PI / 180);
}
function toDegrees(radians) {
return radians * (180 / PI);
}
function _decimalPlaces(x2) {
if (!isNumberFinite(x2)) {
return;
}
let e2 = 1;
let p = 0;
while (Math.round(x2 * e2) / e2 !== x2) {
e2 *= 10;
p++;
}
return p;
}
function getAngleFromPoint(centrePoint, anglePoint) {
const distanceFromXCenter = anglePoint.x - centrePoint.x;
const distanceFromYCenter = anglePoint.y - centrePoint.y;
const radialDistanceFromCenter = Math.sqrt(distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter);
let angle = Math.atan2(distanceFromYCenter, distanceFromXCenter);
if (angle < -0.5 * PI) {
angle += TAU;
}
return {
angle,
distance: radialDistanceFromCenter
};
}
function distanceBetweenPoints(pt1, pt2) {
return Math.sqrt(Math.pow(pt2.x - pt1.x, 2) + Math.pow(pt2.y - pt1.y, 2));
}
function _angleDiff(a3, b2) {
return (a3 - b2 + PITAU) % TAU - PI;
}
function _normalizeAngle(a3) {
return (a3 % TAU + TAU) % TAU;
}
function _angleBetween(angle, start, end, sameAngleIsFullCircle) {
const a3 = _normalizeAngle(angle);
const s3 = _normalizeAngle(start);
const e2 = _normalizeAngle(end);
const angleToStart = _normalizeAngle(s3 - a3);
const angleToEnd = _normalizeAngle(e2 - a3);
const startToAngle = _normalizeAngle(a3 - s3);
const endToAngle = _normalizeAngle(a3 - e2);
return a3 === s3 || a3 === e2 || sameAngleIsFullCircle && s3 === e2 || angleToStart > angleToEnd && startToAngle < endToAngle;
}
function _limitValue(value, min, max) {
return Math.max(min, Math.min(max, value));
}
function _int16Range(value) {
return _limitValue(value, -32768, 32767);
}
function _isBetween(value, start, end, epsilon = 1e-6) {
return value >= Math.min(start, end) - epsilon && value <= Math.max(start, end) + epsilon;
}
function _lookup(table, value, cmp) {
cmp = cmp || ((index2) => table[index2] < value);
let hi = table.length - 1;
let lo = 0;
let mid;
while (hi - lo > 1) {
mid = lo + hi >> 1;
if (cmp(mid)) {
lo = mid;
} else {
hi = mid;
}
}
return {
lo,
hi
};
}
const _lookupByKey = (table, key, value, last) => _lookup(table, value, last ? (index2) => {
const ti = table[index2][key];
return ti < value || ti === value && table[index2 + 1][key] === value;
} : (index2) => table[index2][key] < value);
const _rlookupByKey = (table, key, value) => _lookup(table, value, (index2) => table[index2][key] >= value);
function _filterBetween(values, min, max) {
let start = 0;
let end = values.length;
while (start < end && values[start] < min) {
start++;
}
while (end > start && values[end - 1] > max) {
end--;
}
return start > 0 || end < values.length ? values.slice(start, end) : values;
}
const arrayEvents = [
"push",
"pop",
"shift",
"splice",
"unshift"
];
function listenArrayEvents(array, listener) {
if (array._chartjs) {
array._chartjs.listeners.push(listener);
return;
}
Object.defineProperty(array, "_chartjs", {
configurable: true,
enumerable: false,
value: {
listeners: [
listener
]
}
});
arrayEvents.forEach((key) => {
const method = "_onData" + _capitalize(key);
const base = array[key];
Object.defineProperty(array, key, {
configurable: true,
enumerable: false,
value(...args) {
const res = base.apply(this, args);
array._chartjs.listeners.forEach((object) => {
if (typeof object[method] === "function") {
object[method](...args);
}
});
return res;
}
});
});
}
function unlistenArrayEvents(array, listener) {
const stub = array._chartjs;
if (!stub) {
return;
}
const listeners = stub.listeners;
const index2 = listeners.indexOf(listener);
if (index2 !== -1) {
listeners.splice(index2, 1);
}
if (listeners.length > 0) {
return;
}
arrayEvents.forEach((key) => {
delete array[key];
});
delete array._chartjs;
}
function _arrayUnique(items) {
const set2 = new Set(items);
if (set2.size === items.length) {
return items;
}
return Array.from(set2);
}
const requestAnimFrame = function() {
if (typeof window === "undefined") {
return function(callback2) {
return callback2();
};
}
return window.requestAnimationFrame;
}();
function throttled(fn, thisArg) {
let argsToUse = [];
let ticking = false;
return function(...args) {
argsToUse = args;
if (!ticking) {
ticking = true;
requestAnimFrame.call(window, () => {
ticking = false;
fn.apply(thisArg, argsToUse);
});
}
};
}
function debounce(fn, delay) {
let timeout;
return function(...args) {
if (delay) {
clearTimeout(timeout);
timeout = setTimeout(fn, delay, args);
} else {
fn.apply(this, args);
}
return delay;
};
}
const _toLeftRightCenter = (align) => align === "start" ? "left" : align === "end" ? "right" : "center";
const _alignStartEnd = (align, start, end) => align === "start" ? start : align === "end" ? end : (start + end) / 2;
function _getStartAndCountOfVisiblePoints(meta, points, animationsDisabled) {
const pointCount = points.length;
let start = 0;
let count = pointCount;
if (meta._sorted) {
const { iScale, _parsed } = meta;
const axis = iScale.axis;
const { min, max, minDefined, maxDefined } = iScale.getUserBounds();
if (minDefined) {
start = _limitValue(Math.min(
// @ts-expect-error Need to type _parsed
_lookupByKey(_parsed, axis, min).lo,
// @ts-expect-error Need to fix types on _lookupByKey
animationsDisabled ? pointCount : _lookupByKey(points, axis, iScale.getPixelForValue(min)).lo
), 0, pointCount - 1);
}
if (maxDefined) {
count = _limitValue(Math.max(
// @ts-expect-error Need to type _parsed
_lookupByKey(_parsed, iScale.axis, max, true).hi + 1,
// @ts-expect-error Need to fix types on _lookupByKey
animationsDisabled ? 0 : _lookupByKey(points, axis, iScale.getPixelForValue(max), true).hi + 1
), start, pointCount) - start;
} else {
count = pointCount - start;
}
}
return {
start,
count
};
}
function _scaleRangesChanged(meta) {
const { xScale, yScale, _scaleRanges } = meta;
const newRanges = {
xmin: xScale.min,
xmax: xScale.max,
ymin: yScale.min,
ymax: yScale.max
};
if (!_scaleRanges) {
meta._scaleRanges = newRanges;
return true;
}
const changed = _scaleRanges.xmin !== xScale.min || _scaleRanges.xmax !== xScale.max || _scaleRanges.ymin !== yScale.min || _scaleRanges.ymax !== yScale.max;
Object.assign(_scaleRanges, newRanges);
return changed;
}
const atEdge = (t2) => t2 === 0 || t2 === 1;
const elasticIn = (t2, s3, p) => -(Math.pow(2, 10 * (t2 -= 1)) * Math.sin((t2 - s3) * TAU / p));
const elasticOut = (t2, s3, p) => Math.pow(2, -10 * t2) * Math.sin((t2 - s3) * TAU / p) + 1;
const effects = {
linear: (t2) => t2,
easeInQuad: (t2) => t2 * t2,
easeOutQuad: (t2) => -t2 * (t2 - 2),
easeInOutQuad: (t2) => (t2 /= 0.5) < 1 ? 0.5 * t2 * t2 : -0.5 * (--t2 * (t2 - 2) - 1),
easeInCubic: (t2) => t2 * t2 * t2,
easeOutCubic: (t2) => (t2 -= 1) * t2 * t2 + 1,
easeInOutCubic: (t2) => (t2 /= 0.5) < 1 ? 0.5 * t2 * t2 * t2 : 0.5 * ((t2 -= 2) * t2 * t2 + 2),
easeInQuart: (t2) => t2 * t2 * t2 * t2,
easeOutQuart: (t2) => -((t2 -= 1) * t2 * t2 * t2 - 1),
easeInOutQuart: (t2) => (t2 /= 0.5) < 1 ? 0.5 * t2 * t2 * t2 * t2 : -0.5 * ((t2 -= 2) * t2 * t2 * t2 - 2),
easeInQuint: (t2) => t2 * t2 * t2 * t2 * t2,
easeOutQuint: (t2) => (t2 -= 1) * t2 * t2 * t2 * t2 + 1,
easeInOutQuint: (t2) => (t2 /= 0.5) < 1 ? 0.5 * t2 * t2 * t2 * t2 * t2 : 0.5 * ((t2 -= 2) * t2 * t2 * t2 * t2 + 2),
easeInSine: (t2) => -Math.cos(t2 * HALF_PI) + 1,
easeOutSine: (t2) => Math.sin(t2 * HALF_PI),
easeInOutSine: (t2) => -0.5 * (Math.cos(PI * t2) - 1),
easeInExpo: (t2) => t2 === 0 ? 0 : Math.pow(2, 10 * (t2 - 1)),
easeOutExpo: (t2) => t2 === 1 ? 1 : -Math.pow(2, -10 * t2) + 1,
easeInOutExpo: (t2) => atEdge(t2) ? t2 : t2 < 0.5 ? 0.5 * Math.pow(2, 10 * (t2 * 2 - 1)) : 0.5 * (-Math.pow(2, -10 * (t2 * 2 - 1)) + 2),
easeInCirc: (t2) => t2 >= 1 ? t2 : -(Math.sqrt(1 - t2 * t2) - 1),
easeOutCirc: (t2) => Math.sqrt(1 - (t2 -= 1) * t2),
easeInOutCirc: (t2) => (t2 /= 0.5) < 1 ? -0.5 * (Math.sqrt(1 - t2 * t2) - 1) : 0.5 * (Math.sqrt(1 - (t2 -= 2) * t2) + 1),
easeInElastic: (t2) => atEdge(t2) ? t2 : elasticIn(t2, 0.075, 0.3),
easeOutElastic: (t2) => atEdge(t2) ? t2 : elasticOut(t2, 0.075, 0.3),
easeInOutElastic(t2) {
const s3 = 0.1125;
const p = 0.45;
return atEdge(t2) ? t2 : t2 < 0.5 ? 0.5 * elasticIn(t2 * 2, s3, p) : 0.5 + 0.5 * elasticOut(t2 * 2 - 1, s3, p);
},
easeInBack(t2) {
const s3 = 1.70158;
return t2 * t2 * ((s3 + 1) * t2 - s3);
},
easeOutBack(t2) {
const s3 = 1.70158;
return (t2 -= 1) * t2 * ((s3 + 1) * t2 + s3) + 1;
},
easeInOutBack(t2) {
let s3 = 1.70158;
if ((t2 /= 0.5) < 1) {
return 0.5 * (t2 * t2 * (((s3 *= 1.525) + 1) * t2 - s3));
}
return 0.5 * ((t2 -= 2) * t2 * (((s3 *= 1.525) + 1) * t2 + s3) + 2);
},
easeInBounce: (t2) => 1 - effects.easeOutBounce(1 - t2),
easeOutBounce(t2) {
const m3 = 7.5625;
const d3 = 2.75;
if (t2 < 1 / d3) {
return m3 * t2 * t2;
}
if (t2 < 2 / d3) {
return m3 * (t2 -= 1.5 / d3) * t2 + 0.75;
}
if (t2 < 2.5 / d3) {
return m3 * (t2 -= 2.25 / d3) * t2 + 0.9375;
}
return m3 * (t2 -= 2.625 / d3) * t2 + 0.984375;
},
easeInOutBounce: (t2) => t2 < 0.5 ? effects.easeInBounce(t2 * 2) * 0.5 : effects.easeOutBounce(t2 * 2 - 1) * 0.5 + 0.5
};
function isPatternOrGradient(value) {
if (value && typeof value === "object") {
const type = value.toString();
return type === "[object CanvasPattern]" || type === "[object CanvasGradient]";
}
return false;
}
function color(value) {
return isPatternOrGradient(value) ? value : new Color(value);
}
function getHoverColor(value) {
return isPatternOrGradient(value) ? value : new Color(value).saturate(0.5).darken(0.1).hexString();
}
const numbers = [
"x",
"y",
"borderWidth",
"radius",
"tension"
];
const colors = [
"color",
"borderColor",
"backgroundColor"
];
function applyAnimationsDefaults(defaults2) {
defaults2.set("animation", {
delay: void 0,
duration: 1e3,
easing: "easeOutQuart",
fn: void 0,
from: void 0,
loop: void 0,
to: void 0,
type: void 0
});
defaults2.describe("animation", {
_fallback: false,
_indexable: false,
_scriptable: (name) => name !== "onProgress" && name !== "onComplete" && name !== "fn"
});
defaults2.set("animations", {
colors: {
type: "color",
properties: colors
},
numbers: {
type: "number",
properties: numbers
}
});
defaults2.describe("animations", {
_fallback: "animation"
});
defaults2.set("transitions", {
active: {
animation: {
duration: 400
}
},
resize: {
animation: {
duration: 0
}
},
show: {
animations: {
colors: {
from: "transparent"
},
visible: {
type: "boolean",
duration: 0
}
}
},
hide: {
animations: {
colors: {
to: "transparent"
},
visible: {
type: "boolean",
easing: "linear",
fn: (v) => v | 0
}
}
}
});
}
function applyLayoutsDefaults(defaults2) {
defaults2.set("layout", {
autoPadding: true,
padding: {
top: 0,
right: 0,
bottom: 0,
left: 0
}
});
}
const intlCache = /* @__PURE__ */ new Map();
function getNumberFormat(locale2, options) {
options = options || {};
const cacheKey = locale2 + JSON.stringify(options);
let formatter = intlCache.get(cacheKey);
if (!formatter) {
formatter = new Intl.NumberFormat(locale2, options);
intlCache.set(cacheKey, formatter);
}
return formatter;
}
function formatNumber(num, locale2, options) {
return getNumberFormat(locale2, options).format(num);
}
const formatters$2 = {
values(value) {
return isArray(value) ? value : "" + value;
},
numeric(tickValue, index2, ticks) {
if (tickValue === 0) {
return "0";
}
const locale2 = this.chart.options.locale;
let notation;
let delta = tickValue;
if (ticks.length > 1) {
const maxTick = Math.max(Math.abs(ticks[0].value), Math.abs(ticks[ticks.length - 1].value));
if (maxTick < 1e-4 || maxTick > 1e15) {
notation = "scientific";
}
delta = calculateDelta(tickValue, ticks);
}
const logDelta = log10(Math.abs(delta));
const numDecimal = isNaN(logDelta) ? 1 : Math.max(Math.min(-1 * Math.floor(logDelta), 20), 0);
const options = {
notation,
minimumFractionDigits: numDecimal,
maximumFractionDigits: numDecimal
};
Object.assign(options, this.options.ticks.format);
return formatNumber(tickValue, locale2, options);
},
logarithmic(tickValue, index2, ticks) {
if (tickValue === 0) {
return "0";
}
const remain = ticks[index2].significand || tickValue / Math.pow(10, Math.floor(log10(tickValue)));
if ([
1,
2,
3,
5,
10,
15
].includes(remain) || index2 > 0.8 * ticks.length) {
return formatters$2.numeric.call(this, tickValue, index2, ticks);
}
return "";
}
};
function calculateDelta(tickValue, ticks) {
let delta = ticks.length > 3 ? ticks[2].value - ticks[1].value : ticks[1].value - ticks[0].value;
if (Math.abs(delta) >= 1 && tickValue !== Math.floor(tickValue)) {
delta = tickValue - Math.floor(tickValue);
}
return delta;
}
var Ticks = {
formatters: formatters$2
};
function applyScaleDefaults(defaults2) {
defaults2.set("scale", {
display: true,
offset: false,
reverse: false,
beginAtZero: false,
bounds: "ticks",
clip: true,
grace: 0,
grid: {
display: true,
lineWidth: 1,
drawOnChartArea: true,
drawTicks: true,
tickLength: 8,
tickWidth: (_ctx, options) => options.lineWidth,
tickColor: (_ctx, options) => options.color,
offset: false
},
border: {
display: true,
dash: [],
dashOffset: 0,
width: 1
},
title: {
display: false,
text: "",
padding: {
top: 4,
bottom: 4
}
},
ticks: {
minRotation: 0,
maxRotation: 50,
mirror: false,
textStrokeWidth: 0,
textStrokeColor: "",
padding: 3,
display: true,
autoSkip: true,
autoSkipPadding: 3,
labelOffset: 0,
callback: Ticks.formatters.values,
minor: {},
major: {},
align: "center",
crossAlign: "near",
showLabelBackdrop: false,
backdropColor: "rgba(255, 255, 255, 0.75)",
backdropPadding: 2
}
});
defaults2.route("scale.ticks", "color", "", "color");
defaults2.route("scale.grid", "color", "", "borderColor");
defaults2.route("scale.border", "color", "", "borderColor");
defaults2.route("scale.title", "color", "", "color");
defaults2.describe("scale", {
_fallback: false,
_scriptable: (name) => !name.startsWith("before") && !name.startsWith("after") && name !== "callback" && name !== "parser",
_indexable: (name) => name !== "borderDash" && name !== "tickBorderDash" && name !== "dash"
});
defaults2.describe("scales", {
_fallback: "scale"
});
defaults2.describe("scale.ticks", {
_scriptable: (name) => name !== "backdropPadding" && name !== "callback",
_indexable: (name) => name !== "backdropPadding"
});
}
const overrides = /* @__PURE__ */ Object.create(null);
const descriptors = /* @__PURE__ */ Object.create(null);
function getScope$1(node, key) {
if (!key) {
return node;
}
const keys = key.split(".");
for (let i2 = 0, n = keys.length; i2 < n; ++i2) {
const k2 = keys[i2];
node = node[k2] || (node[k2] = /* @__PURE__ */ Object.create(null));
}
return node;
}
function set(root, scope, values) {
if (typeof scope === "string") {
return merge(getScope$1(root, scope), values);
}
return merge(getScope$1(root, ""), scope);
}
class Defaults {
constructor(_descriptors2, _appliers) {
this.animation = void 0;
this.backgroundColor = "rgba(0,0,0,0.1)";
this.borderColor = "rgba(0,0,0,0.1)";
this.color = "#666";
this.datasets = {};
this.devicePixelRatio = (context) => context.chart.platform.getDevicePixelRatio();
this.elements = {};
this.events = [
"mousemove",
"mouseout",
"click",
"touchstart",
"touchmove"
];
this.font = {
family: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
size: 12,
style: "normal",
lineHeight: 1.2,
weight: null
};
this.hover = {};
this.hoverBackgroundColor = (ctx, options) => getHoverColor(options.backgroundColor);
this.hoverBorderColor = (ctx, options) => getHoverColor(options.borderColor);
this.hoverColor = (ctx, options) => getHoverColor(options.color);
this.indexAxis = "x";
this.interaction = {
mode: "nearest",
intersect: true,
includeInvisible: false
};
this.maintainAspectRatio = true;
this.onHover = null;
this.onClick = null;
this.parsing = true;
this.plugins = {};
this.responsive = true;
this.scale = void 0;
this.scales = {};
this.showLine = true;
this.drawActiveElementsOnTop = true;
this.describe(_descriptors2);
this.apply(_appliers);
}
set(scope, values) {
return set(this, scope, values);
}
get(scope) {
return getScope$1(this, scope);
}
describe(scope, values) {
return set(descriptors, scope, values);
}
override(scope, values) {
return set(overrides, scope, values);
}
route(scope, name, targetScope, targetName) {
const scopeObject = getScope$1(this, scope);
const targetScopeObject = getScope$1(this, targetScope);
const privateName = "_" + name;
Object.defineProperties(scopeObject, {
[privateName]: {
value: scopeObject[name],
writable: true
},
[name]: {
enumerable: true,
get() {
const local = this[privateName];
const target = targetScopeObject[targetName];
if (isObject(local)) {
return Object.assign({}, target, local);
}
return valueOrDefault(local, target);
},
set(value) {
this[privateName] = value;
}
}
});
}
apply(appliers) {
appliers.forEach((apply) => apply(this));
}
}
var defaults = /* @__PURE__ */ new Defaults({
_scriptable: (name) => !name.startsWith("on"),
_indexable: (name) => name !== "events",
hover: {
_fallback: "interaction"
},
interaction: {
_scriptable: false,
_indexable: false
}
}, [
applyAnimationsDefaults,
applyLayoutsDefaults,
applyScaleDefaults
]);
function toFontString(font) {
if (!font || isNullOrUndef(font.size) || isNullOrUndef(font.family)) {
return null;
}
return (font.style ? font.style + " " : "") + (font.weight ? font.weight + " " : "") + font.size + "px " + font.family;
}
function _measureText(ctx, data, gc, longest, string) {
let textWidth = data[string];
if (!textWidth) {
textWidth = data[string] = ctx.measureText(string).width;
gc.push(string);
}
if (textWidth > longest) {
longest = textWidth;
}
return longest;
}
function _alignPixel(chart, pixel, width) {
const devicePixelRatio = chart.currentDevicePixelRatio;
const halfWidth = width !== 0 ? Math.max(width / 2, 0.5) : 0;
return Math.round((pixel - halfWidth) * devicePixelRatio) / devicePixelRatio + halfWidth;
}
function clearCanvas(canvas, ctx) {
if (!ctx && !canvas) {
return;
}
ctx = ctx || canvas.getContext("2d");
ctx.save();
ctx.resetTransform();
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.restore();
}
function drawPoint(ctx, options, x2, y3) {
drawPointLegend(ctx, options, x2, y3);
}
function drawPointLegend(ctx, options, x2, y3, w2) {
let type, xOffset, yOffset, size, cornerRadius, width, xOffsetW, yOffsetW;
const style = options.pointStyle;
const rotation = options.rotation;
const radius = options.radius;
let rad = (rotation || 0) * RAD_PER_DEG;
if (style && typeof style === "object") {
type = style.toString();
if (type === "[object HTMLImageElement]" || type === "[object HTMLCanvasElement]") {
ctx.save();
ctx.translate(x2, y3);
ctx.rotate(rad);
ctx.drawImage(style, -style.width / 2, -style.height / 2, style.width, style.height);
ctx.restore();
return;
}
}
if (isNaN(radius) || radius <= 0) {
return;
}
ctx.beginPath();
switch (style) {
// Default includes circle
default:
{
ctx.arc(x2, y3, radius, 0, TAU);
}
ctx.closePath();
break;
case "triangle":
width = radius;
ctx.moveTo(x2 + Math.sin(rad) * width, y3 - Math.cos(rad) * radius);
rad += TWO_THIRDS_PI;
ctx.lineTo(x2 + Math.sin(rad) * width, y3 - Math.cos(rad) * radius);
rad += TWO_THIRDS_PI;
ctx.lineTo(x2 + Math.sin(rad) * width, y3 - Math.cos(rad) * radius);
ctx.closePath();
break;
case "rectRounded":
cornerRadius = radius * 0.516;
size = radius - cornerRadius;
xOffset = Math.cos(rad + QUARTER_PI) * size;
xOffsetW = Math.cos(rad + QUARTER_PI) * size;
yOffset = Math.sin(rad + QUARTER_PI) * size;
yOffsetW = Math.sin(rad + QUARTER_PI) * size;
ctx.arc(x2 - xOffsetW, y3 - yOffset, cornerRadius, rad - PI, rad - HALF_PI);
ctx.arc(x2 + yOffsetW, y3 - xOffset, cornerRadius, rad - HALF_PI, rad);
ctx.arc(x2 + xOffsetW, y3 + yOffset, cornerRadius, rad, rad + HALF_PI);
ctx.arc(x2 - yOffsetW, y3 + xOffset, cornerRadius, rad + HALF_PI, rad + PI);
ctx.closePath();
break;
case "rect":
if (!rotation) {
size = Math.SQRT1_2 * radius;
width = size;
ctx.rect(x2 - width, y3 - size, 2 * width, 2 * size);
break;
}
rad += QUARTER_PI;
/* falls through */
case "rectRot":
xOffsetW = Math.cos(rad) * radius;
xOffset = Math.cos(rad) * radius;
yOffset = Math.sin(rad) * radius;
yOffsetW = Math.sin(rad) * radius;
ctx.moveTo(x2 - xOffsetW, y3 - yOffset);
ctx.lineTo(x2 + yOffsetW, y3 - xOffset);
ctx.lineTo(x2 + xOffsetW, y3 + yOffset);
ctx.lineTo(x2 - yOffsetW, y3 + xOffset);
ctx.closePath();
break;
case "crossRot":
rad += QUARTER_PI;
/* falls through */
case "cross":
xOffsetW = Math.cos(rad) * radius;
xOffset = Math.cos(rad) * radius;
yOffset = Math.sin(rad) * radius;
yOffsetW = Math.sin(rad) * radius;
ctx.moveTo(x2 - xOffsetW, y3 - yOffset);
ctx.lineTo(x2 + xOffsetW, y3 + yOffset);
ctx.moveTo(x2 + yOffsetW, y3 - xOffset);
ctx.lineTo(x2 - yOffsetW, y3 + xOffset);
break;
case "star":
xOffsetW = Math.cos(rad) * radius;
xOffset = Math.cos(rad) * radius;
yOffset = Math.sin(rad) * radius;
yOffsetW = Math.sin(rad) * radius;
ctx.moveTo(x2 - xOffsetW, y3 - yOffset);
ctx.lineTo(x2 + xOffsetW, y3 + yOffset);
ctx.moveTo(x2 + yOffsetW, y3 - xOffset);
ctx.lineTo(x2 - yOffsetW, y3 + xOffset);
rad += QUARTER_PI;
xOffsetW = Math.cos(rad) * radius;
xOffset = Math.cos(rad) * radius;
yOffset = Math.sin(rad) * radius;
yOffsetW = Math.sin(rad) * radius;
ctx.moveTo(x2 - xOffsetW, y3 - yOffset);
ctx.lineTo(x2 + xOffsetW, y3 + yOffset);
ctx.moveTo(x2 + yOffsetW, y3 - xOffset);
ctx.lineTo(x2 - yOffsetW, y3 + xOffset);
break;
case "line":
xOffset = Math.cos(rad) * radius;
yOffset = Math.sin(rad) * radius;
ctx.moveTo(x2 - xOffset, y3 - yOffset);
ctx.lineTo(x2 + xOffset, y3 + yOffset);
break;
case "dash":
ctx.moveTo(x2, y3);
ctx.lineTo(x2 + Math.cos(rad) * radius, y3 + Math.sin(rad) * radius);
break;
case false:
ctx.closePath();
break;
}
ctx.fill();
if (options.borderWidth > 0) {
ctx.stroke();
}
}
function _isPointInArea(point, area, margin) {
margin = margin || 0.5;
return !area || point && point.x > area.left - margin && point.x < area.right + margin && point.y > area.top - margin && point.y < area.bottom + margin;
}
function clipArea(ctx, area) {
ctx.save();
ctx.beginPath();
ctx.rect(area.left, area.top, area.right - area.left, area.bottom - area.top);
ctx.clip();
}
function unclipArea(ctx) {
ctx.restore();
}
function _steppedLineTo(ctx, previous, target, flip, mode) {
if (!previous) {
return ctx.lineTo(target.x, target.y);
}
if (mode === "middle") {
const midpoint = (previous.x + target.x) / 2;
ctx.lineTo(midpoint, previous.y);
ctx.lineTo(midpoint, target.y);
} else if (mode === "after" !== !!flip) {
ctx.lineTo(previous.x, target.y);
} else {
ctx.lineTo(target.x, previous.y);
}
ctx.lineTo(target.x, target.y);
}
function _bezierCurveTo(ctx, previous, target, flip) {
if (!previous) {
return ctx.lineTo(target.x, target.y);
}
ctx.bezierCurveTo(flip ? previous.cp1x : previous.cp2x, flip ? previous.cp1y : previous.cp2y, flip ? target.cp2x : target.cp1x, flip ? target.cp2y : target.cp1y, target.x, target.y);
}
function setRenderOpts(ctx, opts) {
if (opts.translation) {
ctx.translate(opts.translation[0], opts.translation[1]);
}
if (!isNullOrUndef(opts.rotation)) {
ctx.rotate(opts.rotation);
}
if (opts.color) {
ctx.fillStyle = opts.color;
}
if (opts.textAlign) {
ctx.textAlign = opts.textAlign;
}
if (opts.textBaseline) {
ctx.textBaseline = opts.textBaseline;
}
}
function decorateText(ctx, x2, y3, line, opts) {
if (opts.strikethrough || opts.underline) {
const metrics = ctx.measureText(line);
const left = x2 - metrics.actualBoundingBoxLeft;
const right = x2 + metrics.actualBoundingBoxRight;
const top = y3 - metrics.actualBoundingBoxAscent;
const bottom = y3 + metrics.actualBoundingBoxDescent;
const yDecoration = opts.strikethrough ? (top + bottom) / 2 : bottom;
ctx.strokeStyle = ctx.fillStyle;
ctx.beginPath();
ctx.lineWidth = opts.decorationWidth || 2;
ctx.moveTo(left, yDecoration);
ctx.lineTo(right, yDecoration);
ctx.stroke();
}
}
function drawBackdrop(ctx, opts) {
const oldColor = ctx.fillStyle;
ctx.fillStyle = opts.color;
ctx.fillRect(opts.left, opts.top, opts.width, opts.height);
ctx.fillStyle = oldColor;
}
function renderText(ctx, text, x2, y3, font, opts = {}) {
const lines = isArray(text) ? text : [
text
];
const stroke = opts.strokeWidth > 0 && opts.strokeColor !== "";
let i2, line;
ctx.save();
ctx.font = font.string;
setRenderOpts(ctx, opts);
for (i2 = 0; i2 < lines.length; ++i2) {
line = lines[i2];
if (opts.backdrop) {
drawBackdrop(ctx, opts.backdrop);
}
if (stroke) {
if (opts.strokeColor) {
ctx.strokeStyle = opts.strokeColor;
}
if (!isNullOrUndef(opts.strokeWidth)) {
ctx.lineWidth = opts.strokeWidth;
}
ctx.strokeText(line, x2, y3, opts.maxWidth);
}
ctx.fillText(line, x2, y3, opts.maxWidth);
decorateText(ctx, x2, y3, line, opts);
y3 += Number(font.lineHeight);
}
ctx.restore();
}
function addRoundedRectPath(ctx, rect) {
const { x: x2, y: y3, w: w2, h: h4, radius } = rect;
ctx.arc(x2 + radius.topLeft, y3 + radius.topLeft, radius.topLeft, 1.5 * PI, PI, true);
ctx.lineTo(x2, y3 + h4 - radius.bottomLeft);
ctx.arc(x2 + radius.bottomLeft, y3 + h4 - radius.bottomLeft, radius.bottomLeft, PI, HALF_PI, true);
ctx.lineTo(x2 + w2 - radius.bottomRight, y3 + h4);
ctx.arc(x2 + w2 - radius.bottomRight, y3 + h4 - radius.bottomRight, radius.bottomRight, HALF_PI, 0, true);
ctx.lineTo(x2 + w2, y3 + radius.topRight);
ctx.arc(x2 + w2 - radius.topRight, y3 + radius.topRight, radius.topRight, 0, -HALF_PI, true);
ctx.lineTo(x2 + radius.topLeft, y3);
}
const LINE_HEIGHT = /^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/;
const FONT_STYLE = /^(normal|italic|initial|inherit|unset|(oblique( -?[0-9]?[0-9]deg)?))$/;
function toLineHeight(value, size) {
const matches = ("" + value).match(LINE_HEIGHT);
if (!matches || matches[1] === "normal") {
return size * 1.2;
}
value = +matches[2];
switch (matches[3]) {
case "px":
return value;
case "%":
value /= 100;
break;
}
return size * value;
}
const numberOrZero = (v) => +v || 0;
function _readValueToProps(value, props) {
const ret = {};
const objProps = isObject(props);
const keys = objProps ? Object.keys(props) : props;
const read = isObject(value) ? objProps ? (prop) => valueOrDefault(value[prop], value[props[prop]]) : (prop) => value[prop] : () => value;
for (const prop of keys) {
ret[prop] = numberOrZero(read(prop));
}
return ret;
}
function toTRBL(value) {
return _readValueToProps(value, {
top: "y",
right: "x",
bottom: "y",
left: "x"
});
}
function toTRBLCorners(value) {
return _readValueToProps(value, [
"topLeft",
"topRight",
"bottomLeft",
"bottomRight"
]);
}
function toPadding(value) {
const obj = toTRBL(value);
obj.width = obj.left + obj.right;
obj.height = obj.top + obj.bottom;
return obj;
}
function toFont(options, fallback) {
options = options || {};
fallback = fallback || defaults.font;
let size = valueOrDefault(options.size, fallback.size);
if (typeof size === "string") {
size = parseInt(size, 10);
}
let style = valueOrDefault(options.style, fallback.style);
if (style && !("" + style).match(FONT_STYLE)) {
console.warn('Invalid font style specified: "' + style + '"');
style = void 0;
}
const font = {
family: valueOrDefault(options.family, fallback.family),
lineHeight: toLineHeight(valueOrDefault(options.lineHeight, fallback.lineHeight), size),
size,
style,