26337 lines
1.3 MiB
26337 lines
1.3 MiB
"use strict";
|
|
(() => {
|
|
var __create = Object.create;
|
|
var __defProp = Object.defineProperty;
|
|
var __defProps = Object.defineProperties;
|
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
var __getProtoOf = Object.getPrototypeOf;
|
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
var __spreadValues = (a, b) => {
|
|
for (var prop in b || (b = {}))
|
|
if (__hasOwnProp.call(b, prop))
|
|
__defNormalProp(a, prop, b[prop]);
|
|
if (__getOwnPropSymbols)
|
|
for (var prop of __getOwnPropSymbols(b)) {
|
|
if (__propIsEnum.call(b, prop))
|
|
__defNormalProp(a, prop, b[prop]);
|
|
}
|
|
return a;
|
|
};
|
|
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
var __commonJS = (cb, mod) => function __require() {
|
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
};
|
|
var __copyProps = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames(from))
|
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
// If the importer is in node compatibility mode or this is not an ESM
|
|
// file that has been converted to a CommonJS file using a Babel-
|
|
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
mod
|
|
));
|
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
|
|
// vendor/topbar.js
|
|
var require_topbar = __commonJS({
|
|
"vendor/topbar.js"(exports, module) {
|
|
"use strict";
|
|
(function(window2, document2) {
|
|
"use strict";
|
|
var canvas, currentProgress, showing, progressTimerId = null, fadeTimerId = null, delayTimerId = null, addEvent = function(elem, type, handler) {
|
|
if (elem.addEventListener) elem.addEventListener(type, handler, false);
|
|
else if (elem.attachEvent) elem.attachEvent("on" + type, handler);
|
|
else elem["on" + type] = handler;
|
|
}, options = {
|
|
autoRun: true,
|
|
barThickness: 3,
|
|
barColors: {
|
|
0: "rgba(26, 188, 156, .9)",
|
|
".25": "rgba(52, 152, 219, .9)",
|
|
".50": "rgba(241, 196, 15, .9)",
|
|
".75": "rgba(230, 126, 34, .9)",
|
|
"1.0": "rgba(211, 84, 0, .9)"
|
|
},
|
|
shadowBlur: 10,
|
|
shadowColor: "rgba(0, 0, 0, .6)",
|
|
className: null
|
|
}, repaint = function() {
|
|
canvas.width = window2.innerWidth;
|
|
canvas.height = options.barThickness * 5;
|
|
var ctx = canvas.getContext("2d");
|
|
ctx.shadowBlur = options.shadowBlur;
|
|
ctx.shadowColor = options.shadowColor;
|
|
var lineGradient = ctx.createLinearGradient(0, 0, canvas.width, 0);
|
|
for (var stop in options.barColors)
|
|
lineGradient.addColorStop(stop, options.barColors[stop]);
|
|
ctx.lineWidth = options.barThickness;
|
|
ctx.beginPath();
|
|
ctx.moveTo(0, options.barThickness / 2);
|
|
ctx.lineTo(
|
|
Math.ceil(currentProgress * canvas.width),
|
|
options.barThickness / 2
|
|
);
|
|
ctx.strokeStyle = lineGradient;
|
|
ctx.stroke();
|
|
}, createCanvas = function() {
|
|
canvas = document2.createElement("canvas");
|
|
var style = canvas.style;
|
|
style.position = "fixed";
|
|
style.top = style.left = style.right = style.margin = style.padding = 0;
|
|
style.zIndex = 100001;
|
|
style.display = "none";
|
|
if (options.className) canvas.classList.add(options.className);
|
|
addEvent(window2, "resize", repaint);
|
|
}, topbar2 = {
|
|
config: function(opts) {
|
|
for (var key in opts)
|
|
if (options.hasOwnProperty(key)) options[key] = opts[key];
|
|
},
|
|
show: function(delay) {
|
|
if (showing) return;
|
|
if (delay) {
|
|
if (delayTimerId) return;
|
|
delayTimerId = setTimeout(() => topbar2.show(), delay);
|
|
} else {
|
|
showing = true;
|
|
if (fadeTimerId !== null) window2.cancelAnimationFrame(fadeTimerId);
|
|
if (!canvas) createCanvas();
|
|
if (!canvas.parentElement) document2.body.appendChild(canvas);
|
|
canvas.style.opacity = 1;
|
|
canvas.style.display = "block";
|
|
topbar2.progress(0);
|
|
if (options.autoRun) {
|
|
(function loop() {
|
|
progressTimerId = window2.requestAnimationFrame(loop);
|
|
topbar2.progress(
|
|
"+" + 0.05 * Math.pow(1 - Math.sqrt(currentProgress), 2)
|
|
);
|
|
})();
|
|
}
|
|
}
|
|
},
|
|
progress: function(to) {
|
|
if (typeof to === "undefined") return currentProgress;
|
|
if (typeof to === "string") {
|
|
to = (to.indexOf("+") >= 0 || to.indexOf("-") >= 0 ? currentProgress : 0) + parseFloat(to);
|
|
}
|
|
currentProgress = to > 1 ? 1 : to;
|
|
repaint();
|
|
return currentProgress;
|
|
},
|
|
hide: function() {
|
|
clearTimeout(delayTimerId);
|
|
delayTimerId = null;
|
|
if (!showing) return;
|
|
showing = false;
|
|
if (progressTimerId != null) {
|
|
window2.cancelAnimationFrame(progressTimerId);
|
|
progressTimerId = null;
|
|
}
|
|
(function loop() {
|
|
if (topbar2.progress("+.1") >= 1) {
|
|
canvas.style.opacity -= 0.05;
|
|
if (canvas.style.opacity <= 0.05) {
|
|
canvas.style.display = "none";
|
|
fadeTimerId = null;
|
|
return;
|
|
}
|
|
}
|
|
fadeTimerId = window2.requestAnimationFrame(loop);
|
|
})();
|
|
}
|
|
};
|
|
if (typeof module === "object" && typeof module.exports === "object") {
|
|
module.exports = topbar2;
|
|
} else if (typeof define === "function" && define.amd) {
|
|
define(function() {
|
|
return topbar2;
|
|
});
|
|
} else {
|
|
this.topbar = topbar2;
|
|
}
|
|
}).call(exports, window, document);
|
|
}
|
|
});
|
|
|
|
// vendor/chart.js
|
|
var require_chart = __commonJS({
|
|
"vendor/chart.js"(exports, module) {
|
|
"use strict";
|
|
!function(t, e) {
|
|
"object" == typeof exports && "undefined" != typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define(e) : (t = "undefined" != typeof globalThis ? globalThis : t || self).Chart = e();
|
|
}(exports, function() {
|
|
"use strict";
|
|
var _a3, _b, _c, _d, _e2, _f, _g, _h, _i2, _j, _k;
|
|
var t = Object.freeze({ __proto__: null, get Colors() {
|
|
return Go;
|
|
}, get Decimation() {
|
|
return Qo;
|
|
}, get Filler() {
|
|
return ma;
|
|
}, get Legend() {
|
|
return ya;
|
|
}, get SubTitle() {
|
|
return ka;
|
|
}, get Title() {
|
|
return Ma;
|
|
}, get Tooltip() {
|
|
return Ba;
|
|
} });
|
|
function e() {
|
|
}
|
|
const i = /* @__PURE__ */ (() => {
|
|
let t2 = 0;
|
|
return () => t2++;
|
|
})();
|
|
function s(t2) {
|
|
return null == t2;
|
|
}
|
|
function n(t2) {
|
|
if (Array.isArray && Array.isArray(t2)) return true;
|
|
const e2 = Object.prototype.toString.call(t2);
|
|
return "[object" === e2.slice(0, 7) && "Array]" === e2.slice(-6);
|
|
}
|
|
function o(t2) {
|
|
return null !== t2 && "[object Object]" === Object.prototype.toString.call(t2);
|
|
}
|
|
function a(t2) {
|
|
return ("number" == typeof t2 || t2 instanceof Number) && isFinite(+t2);
|
|
}
|
|
function r(t2, e2) {
|
|
return a(t2) ? t2 : e2;
|
|
}
|
|
function l(t2, e2) {
|
|
return void 0 === t2 ? e2 : t2;
|
|
}
|
|
const h = (t2, e2) => "string" == typeof t2 && t2.endsWith("%") ? parseFloat(t2) / 100 : +t2 / e2, c = (t2, e2) => "string" == typeof t2 && t2.endsWith("%") ? parseFloat(t2) / 100 * e2 : +t2;
|
|
function d(t2, e2, i2) {
|
|
if (t2 && "function" == typeof t2.call) return t2.apply(i2, e2);
|
|
}
|
|
function u(t2, e2, i2, s2) {
|
|
let a2, r2, l2;
|
|
if (n(t2)) if (r2 = t2.length, s2) for (a2 = r2 - 1; a2 >= 0; a2--) e2.call(i2, t2[a2], a2);
|
|
else for (a2 = 0; a2 < r2; a2++) e2.call(i2, t2[a2], a2);
|
|
else if (o(t2)) for (l2 = Object.keys(t2), r2 = l2.length, a2 = 0; a2 < r2; a2++) e2.call(i2, t2[l2[a2]], l2[a2]);
|
|
}
|
|
function f(t2, e2) {
|
|
let i2, s2, n2, o2;
|
|
if (!t2 || !e2 || t2.length !== e2.length) return false;
|
|
for (i2 = 0, s2 = t2.length; i2 < s2; ++i2) if (n2 = t2[i2], o2 = e2[i2], n2.datasetIndex !== o2.datasetIndex || n2.index !== o2.index) return false;
|
|
return true;
|
|
}
|
|
function g(t2) {
|
|
if (n(t2)) return t2.map(g);
|
|
if (o(t2)) {
|
|
const e2 = /* @__PURE__ */ Object.create(null), i2 = Object.keys(t2), s2 = i2.length;
|
|
let n2 = 0;
|
|
for (; n2 < s2; ++n2) e2[i2[n2]] = g(t2[i2[n2]]);
|
|
return e2;
|
|
}
|
|
return t2;
|
|
}
|
|
function p(t2) {
|
|
return -1 === ["__proto__", "prototype", "constructor"].indexOf(t2);
|
|
}
|
|
function m(t2, e2, i2, s2) {
|
|
if (!p(t2)) return;
|
|
const n2 = e2[t2], a2 = i2[t2];
|
|
o(n2) && o(a2) ? b(n2, a2, s2) : e2[t2] = g(a2);
|
|
}
|
|
function b(t2, e2, i2) {
|
|
const s2 = n(e2) ? e2 : [e2], a2 = s2.length;
|
|
if (!o(t2)) return t2;
|
|
const r2 = (i2 = i2 || {}).merger || m;
|
|
let l2;
|
|
for (let e3 = 0; e3 < a2; ++e3) {
|
|
if (l2 = s2[e3], !o(l2)) continue;
|
|
const n2 = Object.keys(l2);
|
|
for (let e4 = 0, s3 = n2.length; e4 < s3; ++e4) r2(n2[e4], t2, l2, i2);
|
|
}
|
|
return t2;
|
|
}
|
|
function x(t2, e2) {
|
|
return b(t2, e2, { merger: _ });
|
|
}
|
|
function _(t2, e2, i2) {
|
|
if (!p(t2)) return;
|
|
const s2 = e2[t2], n2 = i2[t2];
|
|
o(s2) && o(n2) ? x(s2, n2) : Object.prototype.hasOwnProperty.call(e2, t2) || (e2[t2] = g(n2));
|
|
}
|
|
const y = { "": (t2) => t2, x: (t2) => t2.x, y: (t2) => t2.y };
|
|
function v(t2) {
|
|
const e2 = t2.split("."), i2 = [];
|
|
let s2 = "";
|
|
for (const t3 of e2) s2 += t3, s2.endsWith("\\") ? s2 = s2.slice(0, -1) + "." : (i2.push(s2), s2 = "");
|
|
return i2;
|
|
}
|
|
function M(t2, e2) {
|
|
const i2 = y[e2] || (y[e2] = function(t3) {
|
|
const e3 = v(t3);
|
|
return (t4) => {
|
|
for (const i3 of e3) {
|
|
if ("" === i3) break;
|
|
t4 = t4 && t4[i3];
|
|
}
|
|
return t4;
|
|
};
|
|
}(e2));
|
|
return i2(t2);
|
|
}
|
|
function w(t2) {
|
|
return t2.charAt(0).toUpperCase() + t2.slice(1);
|
|
}
|
|
const k = (t2) => void 0 !== t2, S = (t2) => "function" == typeof t2, P = (t2, e2) => {
|
|
if (t2.size !== e2.size) return false;
|
|
for (const i2 of t2) if (!e2.has(i2)) return false;
|
|
return true;
|
|
};
|
|
function D(t2) {
|
|
return "mouseup" === t2.type || "click" === t2.type || "contextmenu" === t2.type;
|
|
}
|
|
const C = Math.PI, O = 2 * C, A = O + C, T = Number.POSITIVE_INFINITY, L2 = C / 180, E = C / 2, R = C / 4, I = 2 * C / 3, z = Math.log10, F = Math.sign;
|
|
function V(t2, e2, i2) {
|
|
return Math.abs(t2 - e2) < i2;
|
|
}
|
|
function B(t2) {
|
|
const e2 = Math.round(t2);
|
|
t2 = V(t2, e2, t2 / 1e3) ? e2 : t2;
|
|
const i2 = Math.pow(10, Math.floor(z(t2))), s2 = t2 / i2;
|
|
return (s2 <= 1 ? 1 : s2 <= 2 ? 2 : s2 <= 5 ? 5 : 10) * i2;
|
|
}
|
|
function W(t2) {
|
|
const e2 = [], i2 = Math.sqrt(t2);
|
|
let s2;
|
|
for (s2 = 1; s2 < i2; s2++) t2 % s2 == 0 && (e2.push(s2), e2.push(t2 / s2));
|
|
return i2 === (0 | i2) && e2.push(i2), e2.sort((t3, e3) => t3 - e3).pop(), e2;
|
|
}
|
|
function N(t2) {
|
|
return !isNaN(parseFloat(t2)) && isFinite(t2);
|
|
}
|
|
function H(t2, e2) {
|
|
const i2 = Math.round(t2);
|
|
return i2 - e2 <= t2 && i2 + e2 >= t2;
|
|
}
|
|
function j(t2, e2, i2) {
|
|
let s2, n2, o2;
|
|
for (s2 = 0, n2 = t2.length; s2 < n2; s2++) o2 = t2[s2][i2], isNaN(o2) || (e2.min = Math.min(e2.min, o2), e2.max = Math.max(e2.max, o2));
|
|
}
|
|
function $(t2) {
|
|
return t2 * (C / 180);
|
|
}
|
|
function Y(t2) {
|
|
return t2 * (180 / C);
|
|
}
|
|
function U(t2) {
|
|
if (!a(t2)) return;
|
|
let e2 = 1, i2 = 0;
|
|
for (; Math.round(t2 * e2) / e2 !== t2; ) e2 *= 10, i2++;
|
|
return i2;
|
|
}
|
|
function X(t2, e2) {
|
|
const i2 = e2.x - t2.x, s2 = e2.y - t2.y, n2 = Math.sqrt(i2 * i2 + s2 * s2);
|
|
let o2 = Math.atan2(s2, i2);
|
|
return o2 < -0.5 * C && (o2 += O), { angle: o2, distance: n2 };
|
|
}
|
|
function q(t2, e2) {
|
|
return Math.sqrt(Math.pow(e2.x - t2.x, 2) + Math.pow(e2.y - t2.y, 2));
|
|
}
|
|
function K(t2, e2) {
|
|
return (t2 - e2 + A) % O - C;
|
|
}
|
|
function G(t2) {
|
|
return (t2 % O + O) % O;
|
|
}
|
|
function Z(t2, e2, i2, s2) {
|
|
const n2 = G(t2), o2 = G(e2), a2 = G(i2), r2 = G(o2 - n2), l2 = G(a2 - n2), h2 = G(n2 - o2), c2 = G(n2 - a2);
|
|
return n2 === o2 || n2 === a2 || s2 && o2 === a2 || r2 > l2 && h2 < c2;
|
|
}
|
|
function J(t2, e2, i2) {
|
|
return Math.max(e2, Math.min(i2, t2));
|
|
}
|
|
function Q(t2) {
|
|
return J(t2, -32768, 32767);
|
|
}
|
|
function tt(t2, e2, i2, s2 = 1e-6) {
|
|
return t2 >= Math.min(e2, i2) - s2 && t2 <= Math.max(e2, i2) + s2;
|
|
}
|
|
function et(t2, e2, i2) {
|
|
i2 = i2 || ((i3) => t2[i3] < e2);
|
|
let s2, n2 = t2.length - 1, o2 = 0;
|
|
for (; n2 - o2 > 1; ) s2 = o2 + n2 >> 1, i2(s2) ? o2 = s2 : n2 = s2;
|
|
return { lo: o2, hi: n2 };
|
|
}
|
|
const it = (t2, e2, i2, s2) => et(t2, i2, s2 ? (s3) => {
|
|
const n2 = t2[s3][e2];
|
|
return n2 < i2 || n2 === i2 && t2[s3 + 1][e2] === i2;
|
|
} : (s3) => t2[s3][e2] < i2), st = (t2, e2, i2) => et(t2, i2, (s2) => t2[s2][e2] >= i2);
|
|
function nt(t2, e2, i2) {
|
|
let s2 = 0, n2 = t2.length;
|
|
for (; s2 < n2 && t2[s2] < e2; ) s2++;
|
|
for (; n2 > s2 && t2[n2 - 1] > i2; ) n2--;
|
|
return s2 > 0 || n2 < t2.length ? t2.slice(s2, n2) : t2;
|
|
}
|
|
const ot = ["push", "pop", "shift", "splice", "unshift"];
|
|
function at(t2, e2) {
|
|
t2._chartjs ? t2._chartjs.listeners.push(e2) : (Object.defineProperty(t2, "_chartjs", { configurable: true, enumerable: false, value: { listeners: [e2] } }), ot.forEach((e3) => {
|
|
const i2 = "_onData" + w(e3), s2 = t2[e3];
|
|
Object.defineProperty(t2, e3, { configurable: true, enumerable: false, value(...e4) {
|
|
const n2 = s2.apply(this, e4);
|
|
return t2._chartjs.listeners.forEach((t3) => {
|
|
"function" == typeof t3[i2] && t3[i2](...e4);
|
|
}), n2;
|
|
} });
|
|
}));
|
|
}
|
|
function rt(t2, e2) {
|
|
const i2 = t2._chartjs;
|
|
if (!i2) return;
|
|
const s2 = i2.listeners, n2 = s2.indexOf(e2);
|
|
-1 !== n2 && s2.splice(n2, 1), s2.length > 0 || (ot.forEach((e3) => {
|
|
delete t2[e3];
|
|
}), delete t2._chartjs);
|
|
}
|
|
function lt(t2) {
|
|
const e2 = new Set(t2);
|
|
return e2.size === t2.length ? t2 : Array.from(e2);
|
|
}
|
|
const ht = "undefined" == typeof window ? function(t2) {
|
|
return t2();
|
|
} : window.requestAnimationFrame;
|
|
function ct(t2, e2) {
|
|
let i2 = [], s2 = false;
|
|
return function(...n2) {
|
|
i2 = n2, s2 || (s2 = true, ht.call(window, () => {
|
|
s2 = false, t2.apply(e2, i2);
|
|
}));
|
|
};
|
|
}
|
|
function dt(t2, e2) {
|
|
let i2;
|
|
return function(...s2) {
|
|
return e2 ? (clearTimeout(i2), i2 = setTimeout(t2, e2, s2)) : t2.apply(this, s2), e2;
|
|
};
|
|
}
|
|
const ut = (t2) => "start" === t2 ? "left" : "end" === t2 ? "right" : "center", ft = (t2, e2, i2) => "start" === t2 ? e2 : "end" === t2 ? i2 : (e2 + i2) / 2, gt = (t2, e2, i2, s2) => t2 === (s2 ? "left" : "right") ? i2 : "center" === t2 ? (e2 + i2) / 2 : e2;
|
|
function pt(t2, e2, i2) {
|
|
const s2 = e2.length;
|
|
let n2 = 0, o2 = s2;
|
|
if (t2._sorted) {
|
|
const { iScale: a2, _parsed: r2 } = t2, l2 = a2.axis, { min: h2, max: c2, minDefined: d2, maxDefined: u2 } = a2.getUserBounds();
|
|
d2 && (n2 = J(Math.min(it(r2, l2, h2).lo, i2 ? s2 : it(e2, l2, a2.getPixelForValue(h2)).lo), 0, s2 - 1)), o2 = u2 ? J(Math.max(it(r2, a2.axis, c2, true).hi + 1, i2 ? 0 : it(e2, l2, a2.getPixelForValue(c2), true).hi + 1), n2, s2) - n2 : s2 - n2;
|
|
}
|
|
return { start: n2, count: o2 };
|
|
}
|
|
function mt(t2) {
|
|
const { xScale: e2, yScale: i2, _scaleRanges: s2 } = t2, n2 = { xmin: e2.min, xmax: e2.max, ymin: i2.min, ymax: i2.max };
|
|
if (!s2) return t2._scaleRanges = n2, true;
|
|
const o2 = s2.xmin !== e2.min || s2.xmax !== e2.max || s2.ymin !== i2.min || s2.ymax !== i2.max;
|
|
return Object.assign(s2, n2), o2;
|
|
}
|
|
class bt {
|
|
constructor() {
|
|
this._request = null, this._charts = /* @__PURE__ */ new Map(), this._running = false, this._lastDate = void 0;
|
|
}
|
|
_notify(t2, e2, i2, s2) {
|
|
const n2 = e2.listeners[s2], o2 = e2.duration;
|
|
n2.forEach((s3) => s3({ chart: t2, initial: e2.initial, numSteps: o2, currentStep: Math.min(i2 - e2.start, o2) }));
|
|
}
|
|
_refresh() {
|
|
this._request || (this._running = true, this._request = ht.call(window, () => {
|
|
this._update(), this._request = null, this._running && this._refresh();
|
|
}));
|
|
}
|
|
_update(t2 = Date.now()) {
|
|
let e2 = 0;
|
|
this._charts.forEach((i2, s2) => {
|
|
if (!i2.running || !i2.items.length) return;
|
|
const n2 = i2.items;
|
|
let o2, a2 = n2.length - 1, r2 = false;
|
|
for (; a2 >= 0; --a2) o2 = n2[a2], o2._active ? (o2._total > i2.duration && (i2.duration = o2._total), o2.tick(t2), r2 = true) : (n2[a2] = n2[n2.length - 1], n2.pop());
|
|
r2 && (s2.draw(), this._notify(s2, i2, t2, "progress")), n2.length || (i2.running = false, this._notify(s2, i2, t2, "complete"), i2.initial = false), e2 += n2.length;
|
|
}), this._lastDate = t2, 0 === e2 && (this._running = false);
|
|
}
|
|
_getAnims(t2) {
|
|
const e2 = this._charts;
|
|
let i2 = e2.get(t2);
|
|
return i2 || (i2 = { running: false, initial: true, items: [], listeners: { complete: [], progress: [] } }, e2.set(t2, i2)), i2;
|
|
}
|
|
listen(t2, e2, i2) {
|
|
this._getAnims(t2).listeners[e2].push(i2);
|
|
}
|
|
add(t2, e2) {
|
|
e2 && e2.length && this._getAnims(t2).items.push(...e2);
|
|
}
|
|
has(t2) {
|
|
return this._getAnims(t2).items.length > 0;
|
|
}
|
|
start(t2) {
|
|
const e2 = this._charts.get(t2);
|
|
e2 && (e2.running = true, e2.start = Date.now(), e2.duration = e2.items.reduce((t3, e3) => Math.max(t3, e3._duration), 0), this._refresh());
|
|
}
|
|
running(t2) {
|
|
if (!this._running) return false;
|
|
const e2 = this._charts.get(t2);
|
|
return !!(e2 && e2.running && e2.items.length);
|
|
}
|
|
stop(t2) {
|
|
const e2 = this._charts.get(t2);
|
|
if (!e2 || !e2.items.length) return;
|
|
const i2 = e2.items;
|
|
let s2 = i2.length - 1;
|
|
for (; s2 >= 0; --s2) i2[s2].cancel();
|
|
e2.items = [], this._notify(t2, e2, Date.now(), "complete");
|
|
}
|
|
remove(t2) {
|
|
return this._charts.delete(t2);
|
|
}
|
|
}
|
|
var xt = new bt();
|
|
function _t(t2) {
|
|
return t2 + 0.5 | 0;
|
|
}
|
|
const yt = (t2, e2, i2) => Math.max(Math.min(t2, i2), e2);
|
|
function vt(t2) {
|
|
return yt(_t(2.55 * t2), 0, 255);
|
|
}
|
|
function Mt(t2) {
|
|
return yt(_t(255 * t2), 0, 255);
|
|
}
|
|
function wt(t2) {
|
|
return yt(_t(t2 / 2.55) / 100, 0, 1);
|
|
}
|
|
function kt(t2) {
|
|
return yt(_t(100 * t2), 0, 100);
|
|
}
|
|
const St = { 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 }, Pt = [..."0123456789ABCDEF"], Dt = (t2) => Pt[15 & t2], Ct = (t2) => Pt[(240 & t2) >> 4] + Pt[15 & t2], Ot = (t2) => (240 & t2) >> 4 == (15 & t2);
|
|
function At(t2) {
|
|
var e2 = ((t3) => Ot(t3.r) && Ot(t3.g) && Ot(t3.b) && Ot(t3.a))(t2) ? Dt : Ct;
|
|
return t2 ? "#" + e2(t2.r) + e2(t2.g) + e2(t2.b) + ((t3, e3) => t3 < 255 ? e3(t3) : "")(t2.a, e2) : void 0;
|
|
}
|
|
const Tt = /^(hsla?|hwb|hsv)\(\s*([-+.e\d]+)(?:deg)?[\s,]+([-+.e\d]+)%[\s,]+([-+.e\d]+)%(?:[\s,]+([-+.e\d]+)(%)?)?\s*\)$/;
|
|
function Lt(t2, e2, i2) {
|
|
const s2 = e2 * Math.min(i2, 1 - i2), n2 = (e3, n3 = (e3 + t2 / 30) % 12) => i2 - s2 * Math.max(Math.min(n3 - 3, 9 - n3, 1), -1);
|
|
return [n2(0), n2(8), n2(4)];
|
|
}
|
|
function Et(t2, e2, i2) {
|
|
const s2 = (s3, n2 = (s3 + t2 / 60) % 6) => i2 - i2 * e2 * Math.max(Math.min(n2, 4 - n2, 1), 0);
|
|
return [s2(5), s2(3), s2(1)];
|
|
}
|
|
function Rt(t2, e2, i2) {
|
|
const s2 = Lt(t2, 1, 0.5);
|
|
let n2;
|
|
for (e2 + i2 > 1 && (n2 = 1 / (e2 + i2), e2 *= n2, i2 *= n2), n2 = 0; n2 < 3; n2++) s2[n2] *= 1 - e2 - i2, s2[n2] += e2;
|
|
return s2;
|
|
}
|
|
function It(t2) {
|
|
const e2 = t2.r / 255, i2 = t2.g / 255, s2 = t2.b / 255, n2 = Math.max(e2, i2, s2), o2 = Math.min(e2, i2, s2), a2 = (n2 + o2) / 2;
|
|
let r2, l2, h2;
|
|
return n2 !== o2 && (h2 = n2 - o2, l2 = a2 > 0.5 ? h2 / (2 - n2 - o2) : h2 / (n2 + o2), r2 = function(t3, e3, i3, s3, n3) {
|
|
return t3 === n3 ? (e3 - i3) / s3 + (e3 < i3 ? 6 : 0) : e3 === n3 ? (i3 - t3) / s3 + 2 : (t3 - e3) / s3 + 4;
|
|
}(e2, i2, s2, h2, n2), r2 = 60 * r2 + 0.5), [0 | r2, l2 || 0, a2];
|
|
}
|
|
function zt(t2, e2, i2, s2) {
|
|
return (Array.isArray(e2) ? t2(e2[0], e2[1], e2[2]) : t2(e2, i2, s2)).map(Mt);
|
|
}
|
|
function Ft(t2, e2, i2) {
|
|
return zt(Lt, t2, e2, i2);
|
|
}
|
|
function Vt(t2) {
|
|
return (t2 % 360 + 360) % 360;
|
|
}
|
|
function Bt(t2) {
|
|
const e2 = Tt.exec(t2);
|
|
let i2, s2 = 255;
|
|
if (!e2) return;
|
|
e2[5] !== i2 && (s2 = e2[6] ? vt(+e2[5]) : Mt(+e2[5]));
|
|
const n2 = Vt(+e2[2]), o2 = +e2[3] / 100, a2 = +e2[4] / 100;
|
|
return i2 = "hwb" === e2[1] ? function(t3, e3, i3) {
|
|
return zt(Rt, t3, e3, i3);
|
|
}(n2, o2, a2) : "hsv" === e2[1] ? function(t3, e3, i3) {
|
|
return zt(Et, t3, e3, i3);
|
|
}(n2, o2, a2) : Ft(n2, o2, a2), { r: i2[0], g: i2[1], b: i2[2], a: s2 };
|
|
}
|
|
const Wt = { 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" }, Nt = { 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" };
|
|
let Ht;
|
|
function jt(t2) {
|
|
Ht || (Ht = function() {
|
|
const t3 = {}, e3 = Object.keys(Nt), i2 = Object.keys(Wt);
|
|
let s2, n2, o2, a2, r2;
|
|
for (s2 = 0; s2 < e3.length; s2++) {
|
|
for (a2 = r2 = e3[s2], n2 = 0; n2 < i2.length; n2++) o2 = i2[n2], r2 = r2.replace(o2, Wt[o2]);
|
|
o2 = parseInt(Nt[a2], 16), t3[r2] = [o2 >> 16 & 255, o2 >> 8 & 255, 255 & o2];
|
|
}
|
|
return t3;
|
|
}(), Ht.transparent = [0, 0, 0, 0]);
|
|
const e2 = Ht[t2.toLowerCase()];
|
|
return e2 && { r: e2[0], g: e2[1], b: e2[2], a: 4 === e2.length ? e2[3] : 255 };
|
|
}
|
|
const $t = /^rgba?\(\s*([-+.\d]+)(%)?[\s,]+([-+.e\d]+)(%)?[\s,]+([-+.e\d]+)(%)?(?:[\s,/]+([-+.e\d]+)(%)?)?\s*\)$/;
|
|
const Yt = (t2) => t2 <= 31308e-7 ? 12.92 * t2 : 1.055 * Math.pow(t2, 1 / 2.4) - 0.055, Ut = (t2) => t2 <= 0.04045 ? t2 / 12.92 : Math.pow((t2 + 0.055) / 1.055, 2.4);
|
|
function Xt(t2, e2, i2) {
|
|
if (t2) {
|
|
let s2 = It(t2);
|
|
s2[e2] = Math.max(0, Math.min(s2[e2] + s2[e2] * i2, 0 === e2 ? 360 : 1)), s2 = Ft(s2), t2.r = s2[0], t2.g = s2[1], t2.b = s2[2];
|
|
}
|
|
}
|
|
function qt(t2, e2) {
|
|
return t2 ? Object.assign(e2 || {}, t2) : t2;
|
|
}
|
|
function Kt(t2) {
|
|
var e2 = { r: 0, g: 0, b: 0, a: 255 };
|
|
return Array.isArray(t2) ? t2.length >= 3 && (e2 = { r: t2[0], g: t2[1], b: t2[2], a: 255 }, t2.length > 3 && (e2.a = Mt(t2[3]))) : (e2 = qt(t2, { r: 0, g: 0, b: 0, a: 1 })).a = Mt(e2.a), e2;
|
|
}
|
|
function Gt(t2) {
|
|
return "r" === t2.charAt(0) ? function(t3) {
|
|
const e2 = $t.exec(t3);
|
|
let i2, s2, n2, o2 = 255;
|
|
if (e2) {
|
|
if (e2[7] !== i2) {
|
|
const t4 = +e2[7];
|
|
o2 = e2[8] ? vt(t4) : yt(255 * t4, 0, 255);
|
|
}
|
|
return i2 = +e2[1], s2 = +e2[3], n2 = +e2[5], i2 = 255 & (e2[2] ? vt(i2) : yt(i2, 0, 255)), s2 = 255 & (e2[4] ? vt(s2) : yt(s2, 0, 255)), n2 = 255 & (e2[6] ? vt(n2) : yt(n2, 0, 255)), { r: i2, g: s2, b: n2, a: o2 };
|
|
}
|
|
}(t2) : Bt(t2);
|
|
}
|
|
class Zt {
|
|
constructor(t2) {
|
|
if (t2 instanceof Zt) return t2;
|
|
const e2 = typeof t2;
|
|
let i2;
|
|
var s2, n2, o2;
|
|
"object" === e2 ? i2 = Kt(t2) : "string" === e2 && (o2 = (s2 = t2).length, "#" === s2[0] && (4 === o2 || 5 === o2 ? n2 = { r: 255 & 17 * St[s2[1]], g: 255 & 17 * St[s2[2]], b: 255 & 17 * St[s2[3]], a: 5 === o2 ? 17 * St[s2[4]] : 255 } : 7 !== o2 && 9 !== o2 || (n2 = { r: St[s2[1]] << 4 | St[s2[2]], g: St[s2[3]] << 4 | St[s2[4]], b: St[s2[5]] << 4 | St[s2[6]], a: 9 === o2 ? St[s2[7]] << 4 | St[s2[8]] : 255 })), i2 = n2 || jt(t2) || Gt(t2)), this._rgb = i2, this._valid = !!i2;
|
|
}
|
|
get valid() {
|
|
return this._valid;
|
|
}
|
|
get rgb() {
|
|
var t2 = qt(this._rgb);
|
|
return t2 && (t2.a = wt(t2.a)), t2;
|
|
}
|
|
set rgb(t2) {
|
|
this._rgb = Kt(t2);
|
|
}
|
|
rgbString() {
|
|
return this._valid ? (t2 = this._rgb) && (t2.a < 255 ? `rgba(${t2.r}, ${t2.g}, ${t2.b}, ${wt(t2.a)})` : `rgb(${t2.r}, ${t2.g}, ${t2.b})`) : void 0;
|
|
var t2;
|
|
}
|
|
hexString() {
|
|
return this._valid ? At(this._rgb) : void 0;
|
|
}
|
|
hslString() {
|
|
return this._valid ? function(t2) {
|
|
if (!t2) return;
|
|
const e2 = It(t2), i2 = e2[0], s2 = kt(e2[1]), n2 = kt(e2[2]);
|
|
return t2.a < 255 ? `hsla(${i2}, ${s2}%, ${n2}%, ${wt(t2.a)})` : `hsl(${i2}, ${s2}%, ${n2}%)`;
|
|
}(this._rgb) : void 0;
|
|
}
|
|
mix(t2, e2) {
|
|
if (t2) {
|
|
const i2 = this.rgb, s2 = t2.rgb;
|
|
let n2;
|
|
const o2 = e2 === n2 ? 0.5 : e2, a2 = 2 * o2 - 1, r2 = i2.a - s2.a, l2 = ((a2 * r2 == -1 ? a2 : (a2 + r2) / (1 + a2 * r2)) + 1) / 2;
|
|
n2 = 1 - l2, i2.r = 255 & l2 * i2.r + n2 * s2.r + 0.5, i2.g = 255 & l2 * i2.g + n2 * s2.g + 0.5, i2.b = 255 & l2 * i2.b + n2 * s2.b + 0.5, i2.a = o2 * i2.a + (1 - o2) * s2.a, this.rgb = i2;
|
|
}
|
|
return this;
|
|
}
|
|
interpolate(t2, e2) {
|
|
return t2 && (this._rgb = function(t3, e3, i2) {
|
|
const s2 = Ut(wt(t3.r)), n2 = Ut(wt(t3.g)), o2 = Ut(wt(t3.b));
|
|
return { r: Mt(Yt(s2 + i2 * (Ut(wt(e3.r)) - s2))), g: Mt(Yt(n2 + i2 * (Ut(wt(e3.g)) - n2))), b: Mt(Yt(o2 + i2 * (Ut(wt(e3.b)) - o2))), a: t3.a + i2 * (e3.a - t3.a) };
|
|
}(this._rgb, t2._rgb, e2)), this;
|
|
}
|
|
clone() {
|
|
return new Zt(this.rgb);
|
|
}
|
|
alpha(t2) {
|
|
return this._rgb.a = Mt(t2), this;
|
|
}
|
|
clearer(t2) {
|
|
return this._rgb.a *= 1 - t2, this;
|
|
}
|
|
greyscale() {
|
|
const t2 = this._rgb, e2 = _t(0.3 * t2.r + 0.59 * t2.g + 0.11 * t2.b);
|
|
return t2.r = t2.g = t2.b = e2, this;
|
|
}
|
|
opaquer(t2) {
|
|
return this._rgb.a *= 1 + t2, this;
|
|
}
|
|
negate() {
|
|
const t2 = this._rgb;
|
|
return t2.r = 255 - t2.r, t2.g = 255 - t2.g, t2.b = 255 - t2.b, this;
|
|
}
|
|
lighten(t2) {
|
|
return Xt(this._rgb, 2, t2), this;
|
|
}
|
|
darken(t2) {
|
|
return Xt(this._rgb, 2, -t2), this;
|
|
}
|
|
saturate(t2) {
|
|
return Xt(this._rgb, 1, t2), this;
|
|
}
|
|
desaturate(t2) {
|
|
return Xt(this._rgb, 1, -t2), this;
|
|
}
|
|
rotate(t2) {
|
|
return function(t3, e2) {
|
|
var i2 = It(t3);
|
|
i2[0] = Vt(i2[0] + e2), i2 = Ft(i2), t3.r = i2[0], t3.g = i2[1], t3.b = i2[2];
|
|
}(this._rgb, t2), this;
|
|
}
|
|
}
|
|
function Jt(t2) {
|
|
if (t2 && "object" == typeof t2) {
|
|
const e2 = t2.toString();
|
|
return "[object CanvasPattern]" === e2 || "[object CanvasGradient]" === e2;
|
|
}
|
|
return false;
|
|
}
|
|
function Qt(t2) {
|
|
return Jt(t2) ? t2 : new Zt(t2);
|
|
}
|
|
function te(t2) {
|
|
return Jt(t2) ? t2 : new Zt(t2).saturate(0.5).darken(0.1).hexString();
|
|
}
|
|
const ee = ["x", "y", "borderWidth", "radius", "tension"], ie = ["color", "borderColor", "backgroundColor"];
|
|
const se = /* @__PURE__ */ new Map();
|
|
function ne(t2, e2, i2) {
|
|
return function(t3, e3) {
|
|
e3 = e3 || {};
|
|
const i3 = t3 + JSON.stringify(e3);
|
|
let s2 = se.get(i3);
|
|
return s2 || (s2 = new Intl.NumberFormat(t3, e3), se.set(i3, s2)), s2;
|
|
}(e2, i2).format(t2);
|
|
}
|
|
const oe = { values: (t2) => n(t2) ? t2 : "" + t2, numeric(t2, e2, i2) {
|
|
if (0 === t2) return "0";
|
|
const s2 = this.chart.options.locale;
|
|
let n2, o2 = t2;
|
|
if (i2.length > 1) {
|
|
const e3 = Math.max(Math.abs(i2[0].value), Math.abs(i2[i2.length - 1].value));
|
|
(e3 < 1e-4 || e3 > 1e15) && (n2 = "scientific"), o2 = function(t3, e4) {
|
|
let i3 = e4.length > 3 ? e4[2].value - e4[1].value : e4[1].value - e4[0].value;
|
|
Math.abs(i3) >= 1 && t3 !== Math.floor(t3) && (i3 = t3 - Math.floor(t3));
|
|
return i3;
|
|
}(t2, i2);
|
|
}
|
|
const a2 = z(Math.abs(o2)), r2 = isNaN(a2) ? 1 : Math.max(Math.min(-1 * Math.floor(a2), 20), 0), l2 = { notation: n2, minimumFractionDigits: r2, maximumFractionDigits: r2 };
|
|
return Object.assign(l2, this.options.ticks.format), ne(t2, s2, l2);
|
|
}, logarithmic(t2, e2, i2) {
|
|
if (0 === t2) return "0";
|
|
const s2 = i2[e2].significand || t2 / Math.pow(10, Math.floor(z(t2)));
|
|
return [1, 2, 3, 5, 10, 15].includes(s2) || e2 > 0.8 * i2.length ? oe.numeric.call(this, t2, e2, i2) : "";
|
|
} };
|
|
var ae = { formatters: oe };
|
|
const re = /* @__PURE__ */ Object.create(null), le = /* @__PURE__ */ Object.create(null);
|
|
function he(t2, e2) {
|
|
if (!e2) return t2;
|
|
const i2 = e2.split(".");
|
|
for (let e3 = 0, s2 = i2.length; e3 < s2; ++e3) {
|
|
const s3 = i2[e3];
|
|
t2 = t2[s3] || (t2[s3] = /* @__PURE__ */ Object.create(null));
|
|
}
|
|
return t2;
|
|
}
|
|
function ce(t2, e2, i2) {
|
|
return "string" == typeof e2 ? b(he(t2, e2), i2) : b(he(t2, ""), e2);
|
|
}
|
|
class de {
|
|
constructor(t2, e2) {
|
|
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 = (t3) => t3.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 = (t3, e3) => te(e3.backgroundColor), this.hoverBorderColor = (t3, e3) => te(e3.borderColor), this.hoverColor = (t3, e3) => te(e3.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(t2), this.apply(e2);
|
|
}
|
|
set(t2, e2) {
|
|
return ce(this, t2, e2);
|
|
}
|
|
get(t2) {
|
|
return he(this, t2);
|
|
}
|
|
describe(t2, e2) {
|
|
return ce(le, t2, e2);
|
|
}
|
|
override(t2, e2) {
|
|
return ce(re, t2, e2);
|
|
}
|
|
route(t2, e2, i2, s2) {
|
|
const n2 = he(this, t2), a2 = he(this, i2), r2 = "_" + e2;
|
|
Object.defineProperties(n2, { [r2]: { value: n2[e2], writable: true }, [e2]: { enumerable: true, get() {
|
|
const t3 = this[r2], e3 = a2[s2];
|
|
return o(t3) ? Object.assign({}, e3, t3) : l(t3, e3);
|
|
}, set(t3) {
|
|
this[r2] = t3;
|
|
} } });
|
|
}
|
|
apply(t2) {
|
|
t2.forEach((t3) => t3(this));
|
|
}
|
|
}
|
|
var ue = new de({ _scriptable: (t2) => !t2.startsWith("on"), _indexable: (t2) => "events" !== t2, hover: { _fallback: "interaction" }, interaction: { _scriptable: false, _indexable: false } }, [function(t2) {
|
|
t2.set("animation", { delay: void 0, duration: 1e3, easing: "easeOutQuart", fn: void 0, from: void 0, loop: void 0, to: void 0, type: void 0 }), t2.describe("animation", { _fallback: false, _indexable: false, _scriptable: (t3) => "onProgress" !== t3 && "onComplete" !== t3 && "fn" !== t3 }), t2.set("animations", { colors: { type: "color", properties: ie }, numbers: { type: "number", properties: ee } }), t2.describe("animations", { _fallback: "animation" }), t2.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: (t3) => 0 | t3 } } } });
|
|
}, function(t2) {
|
|
t2.set("layout", { autoPadding: true, padding: { top: 0, right: 0, bottom: 0, left: 0 } });
|
|
}, function(t2) {
|
|
t2.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: (t3, e2) => e2.lineWidth, tickColor: (t3, e2) => e2.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: ae.formatters.values, minor: {}, major: {}, align: "center", crossAlign: "near", showLabelBackdrop: false, backdropColor: "rgba(255, 255, 255, 0.75)", backdropPadding: 2 } }), t2.route("scale.ticks", "color", "", "color"), t2.route("scale.grid", "color", "", "borderColor"), t2.route("scale.border", "color", "", "borderColor"), t2.route("scale.title", "color", "", "color"), t2.describe("scale", { _fallback: false, _scriptable: (t3) => !t3.startsWith("before") && !t3.startsWith("after") && "callback" !== t3 && "parser" !== t3, _indexable: (t3) => "borderDash" !== t3 && "tickBorderDash" !== t3 && "dash" !== t3 }), t2.describe("scales", { _fallback: "scale" }), t2.describe("scale.ticks", { _scriptable: (t3) => "backdropPadding" !== t3 && "callback" !== t3, _indexable: (t3) => "backdropPadding" !== t3 });
|
|
}]);
|
|
function fe() {
|
|
return "undefined" != typeof window && "undefined" != typeof document;
|
|
}
|
|
function ge(t2) {
|
|
let e2 = t2.parentNode;
|
|
return e2 && "[object ShadowRoot]" === e2.toString() && (e2 = e2.host), e2;
|
|
}
|
|
function pe(t2, e2, i2) {
|
|
let s2;
|
|
return "string" == typeof t2 ? (s2 = parseInt(t2, 10), -1 !== t2.indexOf("%") && (s2 = s2 / 100 * e2.parentNode[i2])) : s2 = t2, s2;
|
|
}
|
|
const me = (t2) => t2.ownerDocument.defaultView.getComputedStyle(t2, null);
|
|
function be(t2, e2) {
|
|
return me(t2).getPropertyValue(e2);
|
|
}
|
|
const xe = ["top", "right", "bottom", "left"];
|
|
function _e(t2, e2, i2) {
|
|
const s2 = {};
|
|
i2 = i2 ? "-" + i2 : "";
|
|
for (let n2 = 0; n2 < 4; n2++) {
|
|
const o2 = xe[n2];
|
|
s2[o2] = parseFloat(t2[e2 + "-" + o2 + i2]) || 0;
|
|
}
|
|
return s2.width = s2.left + s2.right, s2.height = s2.top + s2.bottom, s2;
|
|
}
|
|
const ye = (t2, e2, i2) => (t2 > 0 || e2 > 0) && (!i2 || !i2.shadowRoot);
|
|
function ve(t2, e2) {
|
|
if ("native" in t2) return t2;
|
|
const { canvas: i2, currentDevicePixelRatio: s2 } = e2, n2 = me(i2), o2 = "border-box" === n2.boxSizing, a2 = _e(n2, "padding"), r2 = _e(n2, "border", "width"), { x: l2, y: h2, box: c2 } = function(t3, e3) {
|
|
const i3 = t3.touches, s3 = i3 && i3.length ? i3[0] : t3, { offsetX: n3, offsetY: o3 } = s3;
|
|
let a3, r3, l3 = false;
|
|
if (ye(n3, o3, t3.target)) a3 = n3, r3 = o3;
|
|
else {
|
|
const t4 = e3.getBoundingClientRect();
|
|
a3 = s3.clientX - t4.left, r3 = s3.clientY - t4.top, l3 = true;
|
|
}
|
|
return { x: a3, y: r3, box: l3 };
|
|
}(t2, i2), d2 = a2.left + (c2 && r2.left), u2 = a2.top + (c2 && r2.top);
|
|
let { width: f2, height: g2 } = e2;
|
|
return o2 && (f2 -= a2.width + r2.width, g2 -= a2.height + r2.height), { x: Math.round((l2 - d2) / f2 * i2.width / s2), y: Math.round((h2 - u2) / g2 * i2.height / s2) };
|
|
}
|
|
const Me = (t2) => Math.round(10 * t2) / 10;
|
|
function we(t2, e2, i2, s2) {
|
|
const n2 = me(t2), o2 = _e(n2, "margin"), a2 = pe(n2.maxWidth, t2, "clientWidth") || T, r2 = pe(n2.maxHeight, t2, "clientHeight") || T, l2 = function(t3, e3, i3) {
|
|
let s3, n3;
|
|
if (void 0 === e3 || void 0 === i3) {
|
|
const o3 = ge(t3);
|
|
if (o3) {
|
|
const t4 = o3.getBoundingClientRect(), a3 = me(o3), r3 = _e(a3, "border", "width"), l3 = _e(a3, "padding");
|
|
e3 = t4.width - l3.width - r3.width, i3 = t4.height - l3.height - r3.height, s3 = pe(a3.maxWidth, o3, "clientWidth"), n3 = pe(a3.maxHeight, o3, "clientHeight");
|
|
} else e3 = t3.clientWidth, i3 = t3.clientHeight;
|
|
}
|
|
return { width: e3, height: i3, maxWidth: s3 || T, maxHeight: n3 || T };
|
|
}(t2, e2, i2);
|
|
let { width: h2, height: c2 } = l2;
|
|
if ("content-box" === n2.boxSizing) {
|
|
const t3 = _e(n2, "border", "width"), e3 = _e(n2, "padding");
|
|
h2 -= e3.width + t3.width, c2 -= e3.height + t3.height;
|
|
}
|
|
h2 = Math.max(0, h2 - o2.width), c2 = Math.max(0, s2 ? h2 / s2 : c2 - o2.height), h2 = Me(Math.min(h2, a2, l2.maxWidth)), c2 = Me(Math.min(c2, r2, l2.maxHeight)), h2 && !c2 && (c2 = Me(h2 / 2));
|
|
return (void 0 !== e2 || void 0 !== i2) && s2 && l2.height && c2 > l2.height && (c2 = l2.height, h2 = Me(Math.floor(c2 * s2))), { width: h2, height: c2 };
|
|
}
|
|
function ke(t2, e2, i2) {
|
|
const s2 = e2 || 1, n2 = Math.floor(t2.height * s2), o2 = Math.floor(t2.width * s2);
|
|
t2.height = Math.floor(t2.height), t2.width = Math.floor(t2.width);
|
|
const a2 = t2.canvas;
|
|
return a2.style && (i2 || !a2.style.height && !a2.style.width) && (a2.style.height = `${t2.height}px`, a2.style.width = `${t2.width}px`), (t2.currentDevicePixelRatio !== s2 || a2.height !== n2 || a2.width !== o2) && (t2.currentDevicePixelRatio = s2, a2.height = n2, a2.width = o2, t2.ctx.setTransform(s2, 0, 0, s2, 0, 0), true);
|
|
}
|
|
const Se = function() {
|
|
let t2 = false;
|
|
try {
|
|
const e2 = { get passive() {
|
|
return t2 = true, false;
|
|
} };
|
|
fe() && (window.addEventListener("test", null, e2), window.removeEventListener("test", null, e2));
|
|
} catch (t3) {
|
|
}
|
|
return t2;
|
|
}();
|
|
function Pe(t2, e2) {
|
|
const i2 = be(t2, e2), s2 = i2 && i2.match(/^(\d+)(\.\d+)?px$/);
|
|
return s2 ? +s2[1] : void 0;
|
|
}
|
|
function De(t2) {
|
|
return !t2 || s(t2.size) || s(t2.family) ? null : (t2.style ? t2.style + " " : "") + (t2.weight ? t2.weight + " " : "") + t2.size + "px " + t2.family;
|
|
}
|
|
function Ce(t2, e2, i2, s2, n2) {
|
|
let o2 = e2[n2];
|
|
return o2 || (o2 = e2[n2] = t2.measureText(n2).width, i2.push(n2)), o2 > s2 && (s2 = o2), s2;
|
|
}
|
|
function Oe(t2, e2, i2, s2) {
|
|
let o2 = (s2 = s2 || {}).data = s2.data || {}, a2 = s2.garbageCollect = s2.garbageCollect || [];
|
|
s2.font !== e2 && (o2 = s2.data = {}, a2 = s2.garbageCollect = [], s2.font = e2), t2.save(), t2.font = e2;
|
|
let r2 = 0;
|
|
const l2 = i2.length;
|
|
let h2, c2, d2, u2, f2;
|
|
for (h2 = 0; h2 < l2; h2++) if (u2 = i2[h2], null == u2 || n(u2)) {
|
|
if (n(u2)) for (c2 = 0, d2 = u2.length; c2 < d2; c2++) f2 = u2[c2], null == f2 || n(f2) || (r2 = Ce(t2, o2, a2, r2, f2));
|
|
} else r2 = Ce(t2, o2, a2, r2, u2);
|
|
t2.restore();
|
|
const g2 = a2.length / 2;
|
|
if (g2 > i2.length) {
|
|
for (h2 = 0; h2 < g2; h2++) delete o2[a2[h2]];
|
|
a2.splice(0, g2);
|
|
}
|
|
return r2;
|
|
}
|
|
function Ae(t2, e2, i2) {
|
|
const s2 = t2.currentDevicePixelRatio, n2 = 0 !== i2 ? Math.max(i2 / 2, 0.5) : 0;
|
|
return Math.round((e2 - n2) * s2) / s2 + n2;
|
|
}
|
|
function Te(t2, e2) {
|
|
(e2 = e2 || t2.getContext("2d")).save(), e2.resetTransform(), e2.clearRect(0, 0, t2.width, t2.height), e2.restore();
|
|
}
|
|
function Le(t2, e2, i2, s2) {
|
|
Ee(t2, e2, i2, s2, null);
|
|
}
|
|
function Ee(t2, e2, i2, s2, n2) {
|
|
let o2, a2, r2, l2, h2, c2, d2, u2;
|
|
const f2 = e2.pointStyle, g2 = e2.rotation, p2 = e2.radius;
|
|
let m2 = (g2 || 0) * L2;
|
|
if (f2 && "object" == typeof f2 && (o2 = f2.toString(), "[object HTMLImageElement]" === o2 || "[object HTMLCanvasElement]" === o2)) return t2.save(), t2.translate(i2, s2), t2.rotate(m2), t2.drawImage(f2, -f2.width / 2, -f2.height / 2, f2.width, f2.height), void t2.restore();
|
|
if (!(isNaN(p2) || p2 <= 0)) {
|
|
switch (t2.beginPath(), f2) {
|
|
default:
|
|
n2 ? t2.ellipse(i2, s2, n2 / 2, p2, 0, 0, O) : t2.arc(i2, s2, p2, 0, O), t2.closePath();
|
|
break;
|
|
case "triangle":
|
|
c2 = n2 ? n2 / 2 : p2, t2.moveTo(i2 + Math.sin(m2) * c2, s2 - Math.cos(m2) * p2), m2 += I, t2.lineTo(i2 + Math.sin(m2) * c2, s2 - Math.cos(m2) * p2), m2 += I, t2.lineTo(i2 + Math.sin(m2) * c2, s2 - Math.cos(m2) * p2), t2.closePath();
|
|
break;
|
|
case "rectRounded":
|
|
h2 = 0.516 * p2, l2 = p2 - h2, a2 = Math.cos(m2 + R) * l2, d2 = Math.cos(m2 + R) * (n2 ? n2 / 2 - h2 : l2), r2 = Math.sin(m2 + R) * l2, u2 = Math.sin(m2 + R) * (n2 ? n2 / 2 - h2 : l2), t2.arc(i2 - d2, s2 - r2, h2, m2 - C, m2 - E), t2.arc(i2 + u2, s2 - a2, h2, m2 - E, m2), t2.arc(i2 + d2, s2 + r2, h2, m2, m2 + E), t2.arc(i2 - u2, s2 + a2, h2, m2 + E, m2 + C), t2.closePath();
|
|
break;
|
|
case "rect":
|
|
if (!g2) {
|
|
l2 = Math.SQRT1_2 * p2, c2 = n2 ? n2 / 2 : l2, t2.rect(i2 - c2, s2 - l2, 2 * c2, 2 * l2);
|
|
break;
|
|
}
|
|
m2 += R;
|
|
case "rectRot":
|
|
d2 = Math.cos(m2) * (n2 ? n2 / 2 : p2), a2 = Math.cos(m2) * p2, r2 = Math.sin(m2) * p2, u2 = Math.sin(m2) * (n2 ? n2 / 2 : p2), t2.moveTo(i2 - d2, s2 - r2), t2.lineTo(i2 + u2, s2 - a2), t2.lineTo(i2 + d2, s2 + r2), t2.lineTo(i2 - u2, s2 + a2), t2.closePath();
|
|
break;
|
|
case "crossRot":
|
|
m2 += R;
|
|
case "cross":
|
|
d2 = Math.cos(m2) * (n2 ? n2 / 2 : p2), a2 = Math.cos(m2) * p2, r2 = Math.sin(m2) * p2, u2 = Math.sin(m2) * (n2 ? n2 / 2 : p2), t2.moveTo(i2 - d2, s2 - r2), t2.lineTo(i2 + d2, s2 + r2), t2.moveTo(i2 + u2, s2 - a2), t2.lineTo(i2 - u2, s2 + a2);
|
|
break;
|
|
case "star":
|
|
d2 = Math.cos(m2) * (n2 ? n2 / 2 : p2), a2 = Math.cos(m2) * p2, r2 = Math.sin(m2) * p2, u2 = Math.sin(m2) * (n2 ? n2 / 2 : p2), t2.moveTo(i2 - d2, s2 - r2), t2.lineTo(i2 + d2, s2 + r2), t2.moveTo(i2 + u2, s2 - a2), t2.lineTo(i2 - u2, s2 + a2), m2 += R, d2 = Math.cos(m2) * (n2 ? n2 / 2 : p2), a2 = Math.cos(m2) * p2, r2 = Math.sin(m2) * p2, u2 = Math.sin(m2) * (n2 ? n2 / 2 : p2), t2.moveTo(i2 - d2, s2 - r2), t2.lineTo(i2 + d2, s2 + r2), t2.moveTo(i2 + u2, s2 - a2), t2.lineTo(i2 - u2, s2 + a2);
|
|
break;
|
|
case "line":
|
|
a2 = n2 ? n2 / 2 : Math.cos(m2) * p2, r2 = Math.sin(m2) * p2, t2.moveTo(i2 - a2, s2 - r2), t2.lineTo(i2 + a2, s2 + r2);
|
|
break;
|
|
case "dash":
|
|
t2.moveTo(i2, s2), t2.lineTo(i2 + Math.cos(m2) * (n2 ? n2 / 2 : p2), s2 + Math.sin(m2) * p2);
|
|
break;
|
|
case false:
|
|
t2.closePath();
|
|
}
|
|
t2.fill(), e2.borderWidth > 0 && t2.stroke();
|
|
}
|
|
}
|
|
function Re(t2, e2, i2) {
|
|
return i2 = i2 || 0.5, !e2 || t2 && t2.x > e2.left - i2 && t2.x < e2.right + i2 && t2.y > e2.top - i2 && t2.y < e2.bottom + i2;
|
|
}
|
|
function Ie(t2, e2) {
|
|
t2.save(), t2.beginPath(), t2.rect(e2.left, e2.top, e2.right - e2.left, e2.bottom - e2.top), t2.clip();
|
|
}
|
|
function ze(t2) {
|
|
t2.restore();
|
|
}
|
|
function Fe(t2, e2, i2, s2, n2) {
|
|
if (!e2) return t2.lineTo(i2.x, i2.y);
|
|
if ("middle" === n2) {
|
|
const s3 = (e2.x + i2.x) / 2;
|
|
t2.lineTo(s3, e2.y), t2.lineTo(s3, i2.y);
|
|
} else "after" === n2 != !!s2 ? t2.lineTo(e2.x, i2.y) : t2.lineTo(i2.x, e2.y);
|
|
t2.lineTo(i2.x, i2.y);
|
|
}
|
|
function Ve(t2, e2, i2, s2) {
|
|
if (!e2) return t2.lineTo(i2.x, i2.y);
|
|
t2.bezierCurveTo(s2 ? e2.cp1x : e2.cp2x, s2 ? e2.cp1y : e2.cp2y, s2 ? i2.cp2x : i2.cp1x, s2 ? i2.cp2y : i2.cp1y, i2.x, i2.y);
|
|
}
|
|
function Be(t2, e2, i2, s2, n2) {
|
|
if (n2.strikethrough || n2.underline) {
|
|
const o2 = t2.measureText(s2), a2 = e2 - o2.actualBoundingBoxLeft, r2 = e2 + o2.actualBoundingBoxRight, l2 = i2 - o2.actualBoundingBoxAscent, h2 = i2 + o2.actualBoundingBoxDescent, c2 = n2.strikethrough ? (l2 + h2) / 2 : h2;
|
|
t2.strokeStyle = t2.fillStyle, t2.beginPath(), t2.lineWidth = n2.decorationWidth || 2, t2.moveTo(a2, c2), t2.lineTo(r2, c2), t2.stroke();
|
|
}
|
|
}
|
|
function We(t2, e2) {
|
|
const i2 = t2.fillStyle;
|
|
t2.fillStyle = e2.color, t2.fillRect(e2.left, e2.top, e2.width, e2.height), t2.fillStyle = i2;
|
|
}
|
|
function Ne(t2, e2, i2, o2, a2, r2 = {}) {
|
|
const l2 = n(e2) ? e2 : [e2], h2 = r2.strokeWidth > 0 && "" !== r2.strokeColor;
|
|
let c2, d2;
|
|
for (t2.save(), t2.font = a2.string, function(t3, e3) {
|
|
e3.translation && t3.translate(e3.translation[0], e3.translation[1]), s(e3.rotation) || t3.rotate(e3.rotation), e3.color && (t3.fillStyle = e3.color), e3.textAlign && (t3.textAlign = e3.textAlign), e3.textBaseline && (t3.textBaseline = e3.textBaseline);
|
|
}(t2, r2), c2 = 0; c2 < l2.length; ++c2) d2 = l2[c2], r2.backdrop && We(t2, r2.backdrop), h2 && (r2.strokeColor && (t2.strokeStyle = r2.strokeColor), s(r2.strokeWidth) || (t2.lineWidth = r2.strokeWidth), t2.strokeText(d2, i2, o2, r2.maxWidth)), t2.fillText(d2, i2, o2, r2.maxWidth), Be(t2, i2, o2, d2, r2), o2 += Number(a2.lineHeight);
|
|
t2.restore();
|
|
}
|
|
function He(t2, e2) {
|
|
const { x: i2, y: s2, w: n2, h: o2, radius: a2 } = e2;
|
|
t2.arc(i2 + a2.topLeft, s2 + a2.topLeft, a2.topLeft, 1.5 * C, C, true), t2.lineTo(i2, s2 + o2 - a2.bottomLeft), t2.arc(i2 + a2.bottomLeft, s2 + o2 - a2.bottomLeft, a2.bottomLeft, C, E, true), t2.lineTo(i2 + n2 - a2.bottomRight, s2 + o2), t2.arc(i2 + n2 - a2.bottomRight, s2 + o2 - a2.bottomRight, a2.bottomRight, E, 0, true), t2.lineTo(i2 + n2, s2 + a2.topRight), t2.arc(i2 + n2 - a2.topRight, s2 + a2.topRight, a2.topRight, 0, -E, true), t2.lineTo(i2 + a2.topLeft, s2);
|
|
}
|
|
function je(t2, e2 = [""], i2, s2, n2 = () => t2[0]) {
|
|
const o2 = i2 || t2;
|
|
void 0 === s2 && (s2 = ti("_fallback", t2));
|
|
const a2 = { [Symbol.toStringTag]: "Object", _cacheable: true, _scopes: t2, _rootScopes: o2, _fallback: s2, _getTarget: n2, override: (i3) => je([i3, ...t2], e2, o2, s2) };
|
|
return new Proxy(a2, { deleteProperty: (e3, i3) => (delete e3[i3], delete e3._keys, delete t2[0][i3], true), get: (i3, s3) => qe(i3, s3, () => function(t3, e3, i4, s4) {
|
|
let n3;
|
|
for (const o3 of e3) if (n3 = ti(Ue(o3, t3), i4), void 0 !== n3) return Xe(t3, n3) ? Je(i4, s4, t3, n3) : n3;
|
|
}(s3, e2, t2, i3)), getOwnPropertyDescriptor: (t3, e3) => Reflect.getOwnPropertyDescriptor(t3._scopes[0], e3), getPrototypeOf: () => Reflect.getPrototypeOf(t2[0]), has: (t3, e3) => ei(t3).includes(e3), ownKeys: (t3) => ei(t3), set(t3, e3, i3) {
|
|
const s3 = t3._storage || (t3._storage = n2());
|
|
return t3[e3] = s3[e3] = i3, delete t3._keys, true;
|
|
} });
|
|
}
|
|
function $e(t2, e2, i2, s2) {
|
|
const a2 = { _cacheable: false, _proxy: t2, _context: e2, _subProxy: i2, _stack: /* @__PURE__ */ new Set(), _descriptors: Ye(t2, s2), setContext: (e3) => $e(t2, e3, i2, s2), override: (n2) => $e(t2.override(n2), e2, i2, s2) };
|
|
return new Proxy(a2, { deleteProperty: (e3, i3) => (delete e3[i3], delete t2[i3], true), get: (t3, e3, i3) => qe(t3, e3, () => function(t4, e4, i4) {
|
|
const { _proxy: s3, _context: a3, _subProxy: r2, _descriptors: l2 } = t4;
|
|
let h2 = s3[e4];
|
|
S(h2) && l2.isScriptable(e4) && (h2 = function(t5, e5, i5, s4) {
|
|
const { _proxy: n2, _context: o2, _subProxy: a4, _stack: r3 } = i5;
|
|
if (r3.has(t5)) throw new Error("Recursion detected: " + Array.from(r3).join("->") + "->" + t5);
|
|
r3.add(t5);
|
|
let l3 = e5(o2, a4 || s4);
|
|
r3.delete(t5), Xe(t5, l3) && (l3 = Je(n2._scopes, n2, t5, l3));
|
|
return l3;
|
|
}(e4, h2, t4, i4));
|
|
n(h2) && h2.length && (h2 = function(t5, e5, i5, s4) {
|
|
const { _proxy: n2, _context: a4, _subProxy: r3, _descriptors: l3 } = i5;
|
|
if (void 0 !== a4.index && s4(t5)) return e5[a4.index % e5.length];
|
|
if (o(e5[0])) {
|
|
const i6 = e5, s5 = n2._scopes.filter((t6) => t6 !== i6);
|
|
e5 = [];
|
|
for (const o2 of i6) {
|
|
const i7 = Je(s5, n2, t5, o2);
|
|
e5.push($e(i7, a4, r3 && r3[t5], l3));
|
|
}
|
|
}
|
|
return e5;
|
|
}(e4, h2, t4, l2.isIndexable));
|
|
Xe(e4, h2) && (h2 = $e(h2, a3, r2 && r2[e4], l2));
|
|
return h2;
|
|
}(t3, e3, i3)), getOwnPropertyDescriptor: (e3, i3) => e3._descriptors.allKeys ? Reflect.has(t2, i3) ? { enumerable: true, configurable: true } : void 0 : Reflect.getOwnPropertyDescriptor(t2, i3), getPrototypeOf: () => Reflect.getPrototypeOf(t2), has: (e3, i3) => Reflect.has(t2, i3), ownKeys: () => Reflect.ownKeys(t2), set: (e3, i3, s3) => (t2[i3] = s3, delete e3[i3], true) });
|
|
}
|
|
function Ye(t2, e2 = { scriptable: true, indexable: true }) {
|
|
const { _scriptable: i2 = e2.scriptable, _indexable: s2 = e2.indexable, _allKeys: n2 = e2.allKeys } = t2;
|
|
return { allKeys: n2, scriptable: i2, indexable: s2, isScriptable: S(i2) ? i2 : () => i2, isIndexable: S(s2) ? s2 : () => s2 };
|
|
}
|
|
const Ue = (t2, e2) => t2 ? t2 + w(e2) : e2, Xe = (t2, e2) => o(e2) && "adapters" !== t2 && (null === Object.getPrototypeOf(e2) || e2.constructor === Object);
|
|
function qe(t2, e2, i2) {
|
|
if (Object.prototype.hasOwnProperty.call(t2, e2)) return t2[e2];
|
|
const s2 = i2();
|
|
return t2[e2] = s2, s2;
|
|
}
|
|
function Ke(t2, e2, i2) {
|
|
return S(t2) ? t2(e2, i2) : t2;
|
|
}
|
|
const Ge = (t2, e2) => true === t2 ? e2 : "string" == typeof t2 ? M(e2, t2) : void 0;
|
|
function Ze(t2, e2, i2, s2, n2) {
|
|
for (const o2 of e2) {
|
|
const e3 = Ge(i2, o2);
|
|
if (e3) {
|
|
t2.add(e3);
|
|
const o3 = Ke(e3._fallback, i2, n2);
|
|
if (void 0 !== o3 && o3 !== i2 && o3 !== s2) return o3;
|
|
} else if (false === e3 && void 0 !== s2 && i2 !== s2) return null;
|
|
}
|
|
return false;
|
|
}
|
|
function Je(t2, e2, i2, s2) {
|
|
const a2 = e2._rootScopes, r2 = Ke(e2._fallback, i2, s2), l2 = [...t2, ...a2], h2 = /* @__PURE__ */ new Set();
|
|
h2.add(s2);
|
|
let c2 = Qe(h2, l2, i2, r2 || i2, s2);
|
|
return null !== c2 && ((void 0 === r2 || r2 === i2 || (c2 = Qe(h2, l2, r2, c2, s2), null !== c2)) && je(Array.from(h2), [""], a2, r2, () => function(t3, e3, i3) {
|
|
const s3 = t3._getTarget();
|
|
e3 in s3 || (s3[e3] = {});
|
|
const a3 = s3[e3];
|
|
if (n(a3) && o(i3)) return i3;
|
|
return a3 || {};
|
|
}(e2, i2, s2)));
|
|
}
|
|
function Qe(t2, e2, i2, s2, n2) {
|
|
for (; i2; ) i2 = Ze(t2, e2, i2, s2, n2);
|
|
return i2;
|
|
}
|
|
function ti(t2, e2) {
|
|
for (const i2 of e2) {
|
|
if (!i2) continue;
|
|
const e3 = i2[t2];
|
|
if (void 0 !== e3) return e3;
|
|
}
|
|
}
|
|
function ei(t2) {
|
|
let e2 = t2._keys;
|
|
return e2 || (e2 = t2._keys = function(t3) {
|
|
const e3 = /* @__PURE__ */ new Set();
|
|
for (const i2 of t3) for (const t4 of Object.keys(i2).filter((t5) => !t5.startsWith("_"))) e3.add(t4);
|
|
return Array.from(e3);
|
|
}(t2._scopes)), e2;
|
|
}
|
|
function ii(t2, e2, i2, s2) {
|
|
const { iScale: n2 } = t2, { key: o2 = "r" } = this._parsing, a2 = new Array(s2);
|
|
let r2, l2, h2, c2;
|
|
for (r2 = 0, l2 = s2; r2 < l2; ++r2) h2 = r2 + i2, c2 = e2[h2], a2[r2] = { r: n2.parse(M(c2, o2), h2) };
|
|
return a2;
|
|
}
|
|
const si = Number.EPSILON || 1e-14, ni = (t2, e2) => e2 < t2.length && !t2[e2].skip && t2[e2], oi = (t2) => "x" === t2 ? "y" : "x";
|
|
function ai(t2, e2, i2, s2) {
|
|
const n2 = t2.skip ? e2 : t2, o2 = e2, a2 = i2.skip ? e2 : i2, r2 = q(o2, n2), l2 = q(a2, o2);
|
|
let h2 = r2 / (r2 + l2), c2 = l2 / (r2 + l2);
|
|
h2 = isNaN(h2) ? 0 : h2, c2 = isNaN(c2) ? 0 : c2;
|
|
const d2 = s2 * h2, u2 = s2 * c2;
|
|
return { previous: { x: o2.x - d2 * (a2.x - n2.x), y: o2.y - d2 * (a2.y - n2.y) }, next: { x: o2.x + u2 * (a2.x - n2.x), y: o2.y + u2 * (a2.y - n2.y) } };
|
|
}
|
|
function ri(t2, e2 = "x") {
|
|
const i2 = oi(e2), s2 = t2.length, n2 = Array(s2).fill(0), o2 = Array(s2);
|
|
let a2, r2, l2, h2 = ni(t2, 0);
|
|
for (a2 = 0; a2 < s2; ++a2) if (r2 = l2, l2 = h2, h2 = ni(t2, a2 + 1), l2) {
|
|
if (h2) {
|
|
const t3 = h2[e2] - l2[e2];
|
|
n2[a2] = 0 !== t3 ? (h2[i2] - l2[i2]) / t3 : 0;
|
|
}
|
|
o2[a2] = r2 ? h2 ? F(n2[a2 - 1]) !== F(n2[a2]) ? 0 : (n2[a2 - 1] + n2[a2]) / 2 : n2[a2 - 1] : n2[a2];
|
|
}
|
|
!function(t3, e3, i3) {
|
|
const s3 = t3.length;
|
|
let n3, o3, a3, r3, l3, h3 = ni(t3, 0);
|
|
for (let c2 = 0; c2 < s3 - 1; ++c2) l3 = h3, h3 = ni(t3, c2 + 1), l3 && h3 && (V(e3[c2], 0, si) ? i3[c2] = i3[c2 + 1] = 0 : (n3 = i3[c2] / e3[c2], o3 = i3[c2 + 1] / e3[c2], r3 = Math.pow(n3, 2) + Math.pow(o3, 2), r3 <= 9 || (a3 = 3 / Math.sqrt(r3), i3[c2] = n3 * a3 * e3[c2], i3[c2 + 1] = o3 * a3 * e3[c2])));
|
|
}(t2, n2, o2), function(t3, e3, i3 = "x") {
|
|
const s3 = oi(i3), n3 = t3.length;
|
|
let o3, a3, r3, l3 = ni(t3, 0);
|
|
for (let h3 = 0; h3 < n3; ++h3) {
|
|
if (a3 = r3, r3 = l3, l3 = ni(t3, h3 + 1), !r3) continue;
|
|
const n4 = r3[i3], c2 = r3[s3];
|
|
a3 && (o3 = (n4 - a3[i3]) / 3, r3[`cp1${i3}`] = n4 - o3, r3[`cp1${s3}`] = c2 - o3 * e3[h3]), l3 && (o3 = (l3[i3] - n4) / 3, r3[`cp2${i3}`] = n4 + o3, r3[`cp2${s3}`] = c2 + o3 * e3[h3]);
|
|
}
|
|
}(t2, o2, e2);
|
|
}
|
|
function li(t2, e2, i2) {
|
|
return Math.max(Math.min(t2, i2), e2);
|
|
}
|
|
function hi(t2, e2, i2, s2, n2) {
|
|
let o2, a2, r2, l2;
|
|
if (e2.spanGaps && (t2 = t2.filter((t3) => !t3.skip)), "monotone" === e2.cubicInterpolationMode) ri(t2, n2);
|
|
else {
|
|
let i3 = s2 ? t2[t2.length - 1] : t2[0];
|
|
for (o2 = 0, a2 = t2.length; o2 < a2; ++o2) r2 = t2[o2], l2 = ai(i3, r2, t2[Math.min(o2 + 1, a2 - (s2 ? 0 : 1)) % a2], e2.tension), r2.cp1x = l2.previous.x, r2.cp1y = l2.previous.y, r2.cp2x = l2.next.x, r2.cp2y = l2.next.y, i3 = r2;
|
|
}
|
|
e2.capBezierPoints && function(t3, e3) {
|
|
let i3, s3, n3, o3, a3, r3 = Re(t3[0], e3);
|
|
for (i3 = 0, s3 = t3.length; i3 < s3; ++i3) a3 = o3, o3 = r3, r3 = i3 < s3 - 1 && Re(t3[i3 + 1], e3), o3 && (n3 = t3[i3], a3 && (n3.cp1x = li(n3.cp1x, e3.left, e3.right), n3.cp1y = li(n3.cp1y, e3.top, e3.bottom)), r3 && (n3.cp2x = li(n3.cp2x, e3.left, e3.right), n3.cp2y = li(n3.cp2y, e3.top, e3.bottom)));
|
|
}(t2, i2);
|
|
}
|
|
const ci = (t2) => 0 === t2 || 1 === t2, di = (t2, e2, i2) => -Math.pow(2, 10 * (t2 -= 1)) * Math.sin((t2 - e2) * O / i2), ui = (t2, e2, i2) => Math.pow(2, -10 * t2) * Math.sin((t2 - e2) * O / i2) + 1, fi = { 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) => 1 - Math.cos(t2 * E), easeOutSine: (t2) => Math.sin(t2 * E), easeInOutSine: (t2) => -0.5 * (Math.cos(C * t2) - 1), easeInExpo: (t2) => 0 === t2 ? 0 : Math.pow(2, 10 * (t2 - 1)), easeOutExpo: (t2) => 1 === t2 ? 1 : 1 - Math.pow(2, -10 * t2), easeInOutExpo: (t2) => ci(t2) ? t2 : t2 < 0.5 ? 0.5 * Math.pow(2, 10 * (2 * t2 - 1)) : 0.5 * (2 - Math.pow(2, -10 * (2 * t2 - 1))), 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) => ci(t2) ? t2 : di(t2, 0.075, 0.3), easeOutElastic: (t2) => ci(t2) ? t2 : ui(t2, 0.075, 0.3), easeInOutElastic(t2) {
|
|
const e2 = 0.1125;
|
|
return ci(t2) ? t2 : t2 < 0.5 ? 0.5 * di(2 * t2, e2, 0.45) : 0.5 + 0.5 * ui(2 * t2 - 1, e2, 0.45);
|
|
}, easeInBack(t2) {
|
|
const e2 = 1.70158;
|
|
return t2 * t2 * ((e2 + 1) * t2 - e2);
|
|
}, easeOutBack(t2) {
|
|
const e2 = 1.70158;
|
|
return (t2 -= 1) * t2 * ((e2 + 1) * t2 + e2) + 1;
|
|
}, easeInOutBack(t2) {
|
|
let e2 = 1.70158;
|
|
return (t2 /= 0.5) < 1 ? t2 * t2 * ((1 + (e2 *= 1.525)) * t2 - e2) * 0.5 : 0.5 * ((t2 -= 2) * t2 * ((1 + (e2 *= 1.525)) * t2 + e2) + 2);
|
|
}, easeInBounce: (t2) => 1 - fi.easeOutBounce(1 - t2), easeOutBounce(t2) {
|
|
const e2 = 7.5625, i2 = 2.75;
|
|
return t2 < 1 / i2 ? e2 * t2 * t2 : t2 < 2 / i2 ? e2 * (t2 -= 1.5 / i2) * t2 + 0.75 : t2 < 2.5 / i2 ? e2 * (t2 -= 2.25 / i2) * t2 + 0.9375 : e2 * (t2 -= 2.625 / i2) * t2 + 0.984375;
|
|
}, easeInOutBounce: (t2) => t2 < 0.5 ? 0.5 * fi.easeInBounce(2 * t2) : 0.5 * fi.easeOutBounce(2 * t2 - 1) + 0.5 };
|
|
function gi(t2, e2, i2, s2) {
|
|
return { x: t2.x + i2 * (e2.x - t2.x), y: t2.y + i2 * (e2.y - t2.y) };
|
|
}
|
|
function pi(t2, e2, i2, s2) {
|
|
return { x: t2.x + i2 * (e2.x - t2.x), y: "middle" === s2 ? i2 < 0.5 ? t2.y : e2.y : "after" === s2 ? i2 < 1 ? t2.y : e2.y : i2 > 0 ? e2.y : t2.y };
|
|
}
|
|
function mi(t2, e2, i2, s2) {
|
|
const n2 = { x: t2.cp2x, y: t2.cp2y }, o2 = { x: e2.cp1x, y: e2.cp1y }, a2 = gi(t2, n2, i2), r2 = gi(n2, o2, i2), l2 = gi(o2, e2, i2), h2 = gi(a2, r2, i2), c2 = gi(r2, l2, i2);
|
|
return gi(h2, c2, i2);
|
|
}
|
|
const bi = /^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/, xi = /^(normal|italic|initial|inherit|unset|(oblique( -?[0-9]?[0-9]deg)?))$/;
|
|
function _i(t2, e2) {
|
|
const i2 = ("" + t2).match(bi);
|
|
if (!i2 || "normal" === i2[1]) return 1.2 * e2;
|
|
switch (t2 = +i2[2], i2[3]) {
|
|
case "px":
|
|
return t2;
|
|
case "%":
|
|
t2 /= 100;
|
|
}
|
|
return e2 * t2;
|
|
}
|
|
const yi = (t2) => +t2 || 0;
|
|
function vi(t2, e2) {
|
|
const i2 = {}, s2 = o(e2), n2 = s2 ? Object.keys(e2) : e2, a2 = o(t2) ? s2 ? (i3) => l(t2[i3], t2[e2[i3]]) : (e3) => t2[e3] : () => t2;
|
|
for (const t3 of n2) i2[t3] = yi(a2(t3));
|
|
return i2;
|
|
}
|
|
function Mi(t2) {
|
|
return vi(t2, { top: "y", right: "x", bottom: "y", left: "x" });
|
|
}
|
|
function wi(t2) {
|
|
return vi(t2, ["topLeft", "topRight", "bottomLeft", "bottomRight"]);
|
|
}
|
|
function ki(t2) {
|
|
const e2 = Mi(t2);
|
|
return e2.width = e2.left + e2.right, e2.height = e2.top + e2.bottom, e2;
|
|
}
|
|
function Si(t2, e2) {
|
|
t2 = t2 || {}, e2 = e2 || ue.font;
|
|
let i2 = l(t2.size, e2.size);
|
|
"string" == typeof i2 && (i2 = parseInt(i2, 10));
|
|
let s2 = l(t2.style, e2.style);
|
|
s2 && !("" + s2).match(xi) && (console.warn('Invalid font style specified: "' + s2 + '"'), s2 = void 0);
|
|
const n2 = { family: l(t2.family, e2.family), lineHeight: _i(l(t2.lineHeight, e2.lineHeight), i2), size: i2, style: s2, weight: l(t2.weight, e2.weight), string: "" };
|
|
return n2.string = De(n2), n2;
|
|
}
|
|
function Pi(t2, e2, i2, s2) {
|
|
let o2, a2, r2, l2 = true;
|
|
for (o2 = 0, a2 = t2.length; o2 < a2; ++o2) if (r2 = t2[o2], void 0 !== r2 && (void 0 !== e2 && "function" == typeof r2 && (r2 = r2(e2), l2 = false), void 0 !== i2 && n(r2) && (r2 = r2[i2 % r2.length], l2 = false), void 0 !== r2)) return s2 && !l2 && (s2.cacheable = false), r2;
|
|
}
|
|
function Di(t2, e2, i2) {
|
|
const { min: s2, max: n2 } = t2, o2 = c(e2, (n2 - s2) / 2), a2 = (t3, e3) => i2 && 0 === t3 ? 0 : t3 + e3;
|
|
return { min: a2(s2, -Math.abs(o2)), max: a2(n2, o2) };
|
|
}
|
|
function Ci(t2, e2) {
|
|
return Object.assign(Object.create(t2), e2);
|
|
}
|
|
function Oi(t2, e2, i2) {
|
|
return t2 ? /* @__PURE__ */ function(t3, e3) {
|
|
return { x: (i3) => t3 + t3 + e3 - i3, setWidth(t4) {
|
|
e3 = t4;
|
|
}, textAlign: (t4) => "center" === t4 ? t4 : "right" === t4 ? "left" : "right", xPlus: (t4, e4) => t4 - e4, leftForLtr: (t4, e4) => t4 - e4 };
|
|
}(e2, i2) : { x: (t3) => t3, setWidth(t3) {
|
|
}, textAlign: (t3) => t3, xPlus: (t3, e3) => t3 + e3, leftForLtr: (t3, e3) => t3 };
|
|
}
|
|
function Ai(t2, e2) {
|
|
let i2, s2;
|
|
"ltr" !== e2 && "rtl" !== e2 || (i2 = t2.canvas.style, s2 = [i2.getPropertyValue("direction"), i2.getPropertyPriority("direction")], i2.setProperty("direction", e2, "important"), t2.prevTextDirection = s2);
|
|
}
|
|
function Ti(t2, e2) {
|
|
void 0 !== e2 && (delete t2.prevTextDirection, t2.canvas.style.setProperty("direction", e2[0], e2[1]));
|
|
}
|
|
function Li(t2) {
|
|
return "angle" === t2 ? { between: Z, compare: K, normalize: G } : { between: tt, compare: (t3, e2) => t3 - e2, normalize: (t3) => t3 };
|
|
}
|
|
function Ei({ start: t2, end: e2, count: i2, loop: s2, style: n2 }) {
|
|
return { start: t2 % i2, end: e2 % i2, loop: s2 && (e2 - t2 + 1) % i2 == 0, style: n2 };
|
|
}
|
|
function Ri(t2, e2, i2) {
|
|
if (!i2) return [t2];
|
|
const { property: s2, start: n2, end: o2 } = i2, a2 = e2.length, { compare: r2, between: l2, normalize: h2 } = Li(s2), { start: c2, end: d2, loop: u2, style: f2 } = function(t3, e3, i3) {
|
|
const { property: s3, start: n3, end: o3 } = i3, { between: a3, normalize: r3 } = Li(s3), l3 = e3.length;
|
|
let h3, c3, { start: d3, end: u3, loop: f3 } = t3;
|
|
if (f3) {
|
|
for (d3 += l3, u3 += l3, h3 = 0, c3 = l3; h3 < c3 && a3(r3(e3[d3 % l3][s3]), n3, o3); ++h3) d3--, u3--;
|
|
d3 %= l3, u3 %= l3;
|
|
}
|
|
return u3 < d3 && (u3 += l3), { start: d3, end: u3, loop: f3, style: t3.style };
|
|
}(t2, e2, i2), g2 = [];
|
|
let p2, m2, b2, x2 = false, _2 = null;
|
|
const y2 = () => x2 || l2(n2, b2, p2) && 0 !== r2(n2, b2), v2 = () => !x2 || 0 === r2(o2, p2) || l2(o2, b2, p2);
|
|
for (let t3 = c2, i3 = c2; t3 <= d2; ++t3) m2 = e2[t3 % a2], m2.skip || (p2 = h2(m2[s2]), p2 !== b2 && (x2 = l2(p2, n2, o2), null === _2 && y2() && (_2 = 0 === r2(p2, n2) ? t3 : i3), null !== _2 && v2() && (g2.push(Ei({ start: _2, end: t3, loop: u2, count: a2, style: f2 })), _2 = null), i3 = t3, b2 = p2));
|
|
return null !== _2 && g2.push(Ei({ start: _2, end: d2, loop: u2, count: a2, style: f2 })), g2;
|
|
}
|
|
function Ii(t2, e2) {
|
|
const i2 = [], s2 = t2.segments;
|
|
for (let n2 = 0; n2 < s2.length; n2++) {
|
|
const o2 = Ri(s2[n2], t2.points, e2);
|
|
o2.length && i2.push(...o2);
|
|
}
|
|
return i2;
|
|
}
|
|
function zi(t2, e2) {
|
|
const i2 = t2.points, s2 = t2.options.spanGaps, n2 = i2.length;
|
|
if (!n2) return [];
|
|
const o2 = !!t2._loop, { start: a2, end: r2 } = function(t3, e3, i3, s3) {
|
|
let n3 = 0, o3 = e3 - 1;
|
|
if (i3 && !s3) for (; n3 < e3 && !t3[n3].skip; ) n3++;
|
|
for (; n3 < e3 && t3[n3].skip; ) n3++;
|
|
for (n3 %= e3, i3 && (o3 += n3); o3 > n3 && t3[o3 % e3].skip; ) o3--;
|
|
return o3 %= e3, { start: n3, end: o3 };
|
|
}(i2, n2, o2, s2);
|
|
if (true === s2) return Fi(t2, [{ start: a2, end: r2, loop: o2 }], i2, e2);
|
|
return Fi(t2, function(t3, e3, i3, s3) {
|
|
const n3 = t3.length, o3 = [];
|
|
let a3, r3 = e3, l2 = t3[e3];
|
|
for (a3 = e3 + 1; a3 <= i3; ++a3) {
|
|
const i4 = t3[a3 % n3];
|
|
i4.skip || i4.stop ? l2.skip || (s3 = false, o3.push({ start: e3 % n3, end: (a3 - 1) % n3, loop: s3 }), e3 = r3 = i4.stop ? a3 : null) : (r3 = a3, l2.skip && (e3 = a3)), l2 = i4;
|
|
}
|
|
return null !== r3 && o3.push({ start: e3 % n3, end: r3 % n3, loop: s3 }), o3;
|
|
}(i2, a2, r2 < a2 ? r2 + n2 : r2, !!t2._fullLoop && 0 === a2 && r2 === n2 - 1), i2, e2);
|
|
}
|
|
function Fi(t2, e2, i2, s2) {
|
|
return s2 && s2.setContext && i2 ? function(t3, e3, i3, s3) {
|
|
const n2 = t3._chart.getContext(), o2 = Vi(t3.options), { _datasetIndex: a2, options: { spanGaps: r2 } } = t3, l2 = i3.length, h2 = [];
|
|
let c2 = o2, d2 = e3[0].start, u2 = d2;
|
|
function f2(t4, e4, s4, n3) {
|
|
const o3 = r2 ? -1 : 1;
|
|
if (t4 !== e4) {
|
|
for (t4 += l2; i3[t4 % l2].skip; ) t4 -= o3;
|
|
for (; i3[e4 % l2].skip; ) e4 += o3;
|
|
t4 % l2 != e4 % l2 && (h2.push({ start: t4 % l2, end: e4 % l2, loop: s4, style: n3 }), c2 = n3, d2 = e4 % l2);
|
|
}
|
|
}
|
|
for (const t4 of e3) {
|
|
d2 = r2 ? d2 : t4.start;
|
|
let e4, o3 = i3[d2 % l2];
|
|
for (u2 = d2 + 1; u2 <= t4.end; u2++) {
|
|
const r3 = i3[u2 % l2];
|
|
e4 = Vi(s3.setContext(Ci(n2, { type: "segment", p0: o3, p1: r3, p0DataIndex: (u2 - 1) % l2, p1DataIndex: u2 % l2, datasetIndex: a2 }))), Bi(e4, c2) && f2(d2, u2 - 1, t4.loop, c2), o3 = r3, c2 = e4;
|
|
}
|
|
d2 < u2 - 1 && f2(d2, u2 - 1, t4.loop, c2);
|
|
}
|
|
return h2;
|
|
}(t2, e2, i2, s2) : e2;
|
|
}
|
|
function Vi(t2) {
|
|
return { backgroundColor: t2.backgroundColor, borderCapStyle: t2.borderCapStyle, borderDash: t2.borderDash, borderDashOffset: t2.borderDashOffset, borderJoinStyle: t2.borderJoinStyle, borderWidth: t2.borderWidth, borderColor: t2.borderColor };
|
|
}
|
|
function Bi(t2, e2) {
|
|
if (!e2) return false;
|
|
const i2 = [], s2 = function(t3, e3) {
|
|
return Jt(e3) ? (i2.includes(e3) || i2.push(e3), i2.indexOf(e3)) : e3;
|
|
};
|
|
return JSON.stringify(t2, s2) !== JSON.stringify(e2, s2);
|
|
}
|
|
var Wi = Object.freeze({ __proto__: null, HALF_PI: E, INFINITY: T, PI: C, PITAU: A, QUARTER_PI: R, RAD_PER_DEG: L2, TAU: O, TWO_THIRDS_PI: I, _addGrace: Di, _alignPixel: Ae, _alignStartEnd: ft, _angleBetween: Z, _angleDiff: K, _arrayUnique: lt, _attachContext: $e, _bezierCurveTo: Ve, _bezierInterpolation: mi, _boundSegment: Ri, _boundSegments: Ii, _capitalize: w, _computeSegments: zi, _createResolver: je, _decimalPlaces: U, _deprecated: function(t2, e2, i2, s2) {
|
|
void 0 !== e2 && console.warn(t2 + ': "' + i2 + '" is deprecated. Please use "' + s2 + '" instead');
|
|
}, _descriptors: Ye, _elementsEqual: f, _factorize: W, _filterBetween: nt, _getParentNode: ge, _getStartAndCountOfVisiblePoints: pt, _int16Range: Q, _isBetween: tt, _isClickEvent: D, _isDomSupported: fe, _isPointInArea: Re, _limitValue: J, _longestText: Oe, _lookup: et, _lookupByKey: it, _measureText: Ce, _merger: m, _mergerIf: _, _normalizeAngle: G, _parseObjectDataRadialScale: ii, _pointInLine: gi, _readValueToProps: vi, _rlookupByKey: st, _scaleRangesChanged: mt, _setMinAndMaxByKey: j, _splitKey: v, _steppedInterpolation: pi, _steppedLineTo: Fe, _textX: gt, _toLeftRightCenter: ut, _updateBezierControlPoints: hi, addRoundedRectPath: He, almostEquals: V, almostWhole: H, callback: d, clearCanvas: Te, clipArea: Ie, clone: g, color: Qt, createContext: Ci, debounce: dt, defined: k, distanceBetweenPoints: q, drawPoint: Le, drawPointLegend: Ee, each: u, easingEffects: fi, finiteOrDefault: r, fontString: function(t2, e2, i2) {
|
|
return e2 + " " + t2 + "px " + i2;
|
|
}, formatNumber: ne, getAngleFromPoint: X, getHoverColor: te, getMaximumSize: we, getRelativePosition: ve, getRtlAdapter: Oi, getStyle: be, isArray: n, isFinite: a, isFunction: S, isNullOrUndef: s, isNumber: N, isObject: o, isPatternOrGradient: Jt, listenArrayEvents: at, log10: z, merge: b, mergeIf: x, niceNum: B, noop: e, overrideTextDirection: Ai, readUsedSize: Pe, renderText: Ne, requestAnimFrame: ht, resolve: Pi, resolveObjectKey: M, restoreTextDirection: Ti, retinaScale: ke, setsEqual: P, sign: F, splineCurve: ai, splineCurveMonotone: ri, supportsEventListenerOptions: Se, throttled: ct, toDegrees: Y, toDimension: c, toFont: Si, toFontString: De, toLineHeight: _i, toPadding: ki, toPercentage: h, toRadians: $, toTRBL: Mi, toTRBLCorners: wi, uid: i, unclipArea: ze, unlistenArrayEvents: rt, valueOrDefault: l });
|
|
function Ni(t2, e2, i2, s2) {
|
|
const { controller: n2, data: o2, _sorted: a2 } = t2, r2 = n2._cachedMeta.iScale;
|
|
if (r2 && e2 === r2.axis && "r" !== e2 && a2 && o2.length) {
|
|
const t3 = r2._reversePixels ? st : it;
|
|
if (!s2) return t3(o2, e2, i2);
|
|
if (n2._sharedOptions) {
|
|
const s3 = o2[0], n3 = "function" == typeof s3.getRange && s3.getRange(e2);
|
|
if (n3) {
|
|
const s4 = t3(o2, e2, i2 - n3), a3 = t3(o2, e2, i2 + n3);
|
|
return { lo: s4.lo, hi: a3.hi };
|
|
}
|
|
}
|
|
}
|
|
return { lo: 0, hi: o2.length - 1 };
|
|
}
|
|
function Hi(t2, e2, i2, s2, n2) {
|
|
const o2 = t2.getSortedVisibleDatasetMetas(), a2 = i2[e2];
|
|
for (let t3 = 0, i3 = o2.length; t3 < i3; ++t3) {
|
|
const { index: i4, data: r2 } = o2[t3], { lo: l2, hi: h2 } = Ni(o2[t3], e2, a2, n2);
|
|
for (let t4 = l2; t4 <= h2; ++t4) {
|
|
const e3 = r2[t4];
|
|
e3.skip || s2(e3, i4, t4);
|
|
}
|
|
}
|
|
}
|
|
function ji(t2, e2, i2, s2, n2) {
|
|
const o2 = [];
|
|
if (!n2 && !t2.isPointInArea(e2)) return o2;
|
|
return Hi(t2, i2, e2, function(i3, a2, r2) {
|
|
(n2 || Re(i3, t2.chartArea, 0)) && i3.inRange(e2.x, e2.y, s2) && o2.push({ element: i3, datasetIndex: a2, index: r2 });
|
|
}, true), o2;
|
|
}
|
|
function $i(t2, e2, i2, s2, n2, o2) {
|
|
let a2 = [];
|
|
const r2 = function(t3) {
|
|
const e3 = -1 !== t3.indexOf("x"), i3 = -1 !== t3.indexOf("y");
|
|
return function(t4, s3) {
|
|
const n3 = e3 ? Math.abs(t4.x - s3.x) : 0, o3 = i3 ? Math.abs(t4.y - s3.y) : 0;
|
|
return Math.sqrt(Math.pow(n3, 2) + Math.pow(o3, 2));
|
|
};
|
|
}(i2);
|
|
let l2 = Number.POSITIVE_INFINITY;
|
|
return Hi(t2, i2, e2, function(i3, h2, c2) {
|
|
const d2 = i3.inRange(e2.x, e2.y, n2);
|
|
if (s2 && !d2) return;
|
|
const u2 = i3.getCenterPoint(n2);
|
|
if (!(!!o2 || t2.isPointInArea(u2)) && !d2) return;
|
|
const f2 = r2(e2, u2);
|
|
f2 < l2 ? (a2 = [{ element: i3, datasetIndex: h2, index: c2 }], l2 = f2) : f2 === l2 && a2.push({ element: i3, datasetIndex: h2, index: c2 });
|
|
}), a2;
|
|
}
|
|
function Yi(t2, e2, i2, s2, n2, o2) {
|
|
return o2 || t2.isPointInArea(e2) ? "r" !== i2 || s2 ? $i(t2, e2, i2, s2, n2, o2) : function(t3, e3, i3, s3) {
|
|
let n3 = [];
|
|
return Hi(t3, i3, e3, function(t4, i4, o3) {
|
|
const { startAngle: a2, endAngle: r2 } = t4.getProps(["startAngle", "endAngle"], s3), { angle: l2 } = X(t4, { x: e3.x, y: e3.y });
|
|
Z(l2, a2, r2) && n3.push({ element: t4, datasetIndex: i4, index: o3 });
|
|
}), n3;
|
|
}(t2, e2, i2, n2) : [];
|
|
}
|
|
function Ui(t2, e2, i2, s2, n2) {
|
|
const o2 = [], a2 = "x" === i2 ? "inXRange" : "inYRange";
|
|
let r2 = false;
|
|
return Hi(t2, i2, e2, (t3, s3, l2) => {
|
|
t3[a2](e2[i2], n2) && (o2.push({ element: t3, datasetIndex: s3, index: l2 }), r2 = r2 || t3.inRange(e2.x, e2.y, n2));
|
|
}), s2 && !r2 ? [] : o2;
|
|
}
|
|
var Xi = { evaluateInteractionItems: Hi, modes: { index(t2, e2, i2, s2) {
|
|
const n2 = ve(e2, t2), o2 = i2.axis || "x", a2 = i2.includeInvisible || false, r2 = i2.intersect ? ji(t2, n2, o2, s2, a2) : Yi(t2, n2, o2, false, s2, a2), l2 = [];
|
|
return r2.length ? (t2.getSortedVisibleDatasetMetas().forEach((t3) => {
|
|
const e3 = r2[0].index, i3 = t3.data[e3];
|
|
i3 && !i3.skip && l2.push({ element: i3, datasetIndex: t3.index, index: e3 });
|
|
}), l2) : [];
|
|
}, dataset(t2, e2, i2, s2) {
|
|
const n2 = ve(e2, t2), o2 = i2.axis || "xy", a2 = i2.includeInvisible || false;
|
|
let r2 = i2.intersect ? ji(t2, n2, o2, s2, a2) : Yi(t2, n2, o2, false, s2, a2);
|
|
if (r2.length > 0) {
|
|
const e3 = r2[0].datasetIndex, i3 = t2.getDatasetMeta(e3).data;
|
|
r2 = [];
|
|
for (let t3 = 0; t3 < i3.length; ++t3) r2.push({ element: i3[t3], datasetIndex: e3, index: t3 });
|
|
}
|
|
return r2;
|
|
}, point: (t2, e2, i2, s2) => ji(t2, ve(e2, t2), i2.axis || "xy", s2, i2.includeInvisible || false), nearest(t2, e2, i2, s2) {
|
|
const n2 = ve(e2, t2), o2 = i2.axis || "xy", a2 = i2.includeInvisible || false;
|
|
return Yi(t2, n2, o2, i2.intersect, s2, a2);
|
|
}, x: (t2, e2, i2, s2) => Ui(t2, ve(e2, t2), "x", i2.intersect, s2), y: (t2, e2, i2, s2) => Ui(t2, ve(e2, t2), "y", i2.intersect, s2) } };
|
|
const qi = ["left", "top", "right", "bottom"];
|
|
function Ki(t2, e2) {
|
|
return t2.filter((t3) => t3.pos === e2);
|
|
}
|
|
function Gi(t2, e2) {
|
|
return t2.filter((t3) => -1 === qi.indexOf(t3.pos) && t3.box.axis === e2);
|
|
}
|
|
function Zi(t2, e2) {
|
|
return t2.sort((t3, i2) => {
|
|
const s2 = e2 ? i2 : t3, n2 = e2 ? t3 : i2;
|
|
return s2.weight === n2.weight ? s2.index - n2.index : s2.weight - n2.weight;
|
|
});
|
|
}
|
|
function Ji(t2, e2) {
|
|
const i2 = function(t3) {
|
|
const e3 = {};
|
|
for (const i3 of t3) {
|
|
const { stack: t4, pos: s3, stackWeight: n3 } = i3;
|
|
if (!t4 || !qi.includes(s3)) continue;
|
|
const o3 = e3[t4] || (e3[t4] = { count: 0, placed: 0, weight: 0, size: 0 });
|
|
o3.count++, o3.weight += n3;
|
|
}
|
|
return e3;
|
|
}(t2), { vBoxMaxWidth: s2, hBoxMaxHeight: n2 } = e2;
|
|
let o2, a2, r2;
|
|
for (o2 = 0, a2 = t2.length; o2 < a2; ++o2) {
|
|
r2 = t2[o2];
|
|
const { fullSize: a3 } = r2.box, l2 = i2[r2.stack], h2 = l2 && r2.stackWeight / l2.weight;
|
|
r2.horizontal ? (r2.width = h2 ? h2 * s2 : a3 && e2.availableWidth, r2.height = n2) : (r2.width = s2, r2.height = h2 ? h2 * n2 : a3 && e2.availableHeight);
|
|
}
|
|
return i2;
|
|
}
|
|
function Qi(t2, e2, i2, s2) {
|
|
return Math.max(t2[i2], e2[i2]) + Math.max(t2[s2], e2[s2]);
|
|
}
|
|
function ts(t2, e2) {
|
|
t2.top = Math.max(t2.top, e2.top), t2.left = Math.max(t2.left, e2.left), t2.bottom = Math.max(t2.bottom, e2.bottom), t2.right = Math.max(t2.right, e2.right);
|
|
}
|
|
function es(t2, e2, i2, s2) {
|
|
const { pos: n2, box: a2 } = i2, r2 = t2.maxPadding;
|
|
if (!o(n2)) {
|
|
i2.size && (t2[n2] -= i2.size);
|
|
const e3 = s2[i2.stack] || { size: 0, count: 1 };
|
|
e3.size = Math.max(e3.size, i2.horizontal ? a2.height : a2.width), i2.size = e3.size / e3.count, t2[n2] += i2.size;
|
|
}
|
|
a2.getPadding && ts(r2, a2.getPadding());
|
|
const l2 = Math.max(0, e2.outerWidth - Qi(r2, t2, "left", "right")), h2 = Math.max(0, e2.outerHeight - Qi(r2, t2, "top", "bottom")), c2 = l2 !== t2.w, d2 = h2 !== t2.h;
|
|
return t2.w = l2, t2.h = h2, i2.horizontal ? { same: c2, other: d2 } : { same: d2, other: c2 };
|
|
}
|
|
function is(t2, e2) {
|
|
const i2 = e2.maxPadding;
|
|
function s2(t3) {
|
|
const s3 = { left: 0, top: 0, right: 0, bottom: 0 };
|
|
return t3.forEach((t4) => {
|
|
s3[t4] = Math.max(e2[t4], i2[t4]);
|
|
}), s3;
|
|
}
|
|
return s2(t2 ? ["left", "right"] : ["top", "bottom"]);
|
|
}
|
|
function ss(t2, e2, i2, s2) {
|
|
const n2 = [];
|
|
let o2, a2, r2, l2, h2, c2;
|
|
for (o2 = 0, a2 = t2.length, h2 = 0; o2 < a2; ++o2) {
|
|
r2 = t2[o2], l2 = r2.box, l2.update(r2.width || e2.w, r2.height || e2.h, is(r2.horizontal, e2));
|
|
const { same: a3, other: d2 } = es(e2, i2, r2, s2);
|
|
h2 |= a3 && n2.length, c2 = c2 || d2, l2.fullSize || n2.push(r2);
|
|
}
|
|
return h2 && ss(n2, e2, i2, s2) || c2;
|
|
}
|
|
function ns(t2, e2, i2, s2, n2) {
|
|
t2.top = i2, t2.left = e2, t2.right = e2 + s2, t2.bottom = i2 + n2, t2.width = s2, t2.height = n2;
|
|
}
|
|
function os(t2, e2, i2, s2) {
|
|
const n2 = i2.padding;
|
|
let { x: o2, y: a2 } = e2;
|
|
for (const r2 of t2) {
|
|
const t3 = r2.box, l2 = s2[r2.stack] || { count: 1, placed: 0, weight: 1 }, h2 = r2.stackWeight / l2.weight || 1;
|
|
if (r2.horizontal) {
|
|
const s3 = e2.w * h2, o3 = l2.size || t3.height;
|
|
k(l2.start) && (a2 = l2.start), t3.fullSize ? ns(t3, n2.left, a2, i2.outerWidth - n2.right - n2.left, o3) : ns(t3, e2.left + l2.placed, a2, s3, o3), l2.start = a2, l2.placed += s3, a2 = t3.bottom;
|
|
} else {
|
|
const s3 = e2.h * h2, a3 = l2.size || t3.width;
|
|
k(l2.start) && (o2 = l2.start), t3.fullSize ? ns(t3, o2, n2.top, a3, i2.outerHeight - n2.bottom - n2.top) : ns(t3, o2, e2.top + l2.placed, a3, s3), l2.start = o2, l2.placed += s3, o2 = t3.right;
|
|
}
|
|
}
|
|
e2.x = o2, e2.y = a2;
|
|
}
|
|
var as = { addBox(t2, e2) {
|
|
t2.boxes || (t2.boxes = []), e2.fullSize = e2.fullSize || false, e2.position = e2.position || "top", e2.weight = e2.weight || 0, e2._layers = e2._layers || function() {
|
|
return [{ z: 0, draw(t3) {
|
|
e2.draw(t3);
|
|
} }];
|
|
}, t2.boxes.push(e2);
|
|
}, removeBox(t2, e2) {
|
|
const i2 = t2.boxes ? t2.boxes.indexOf(e2) : -1;
|
|
-1 !== i2 && t2.boxes.splice(i2, 1);
|
|
}, configure(t2, e2, i2) {
|
|
e2.fullSize = i2.fullSize, e2.position = i2.position, e2.weight = i2.weight;
|
|
}, update(t2, e2, i2, s2) {
|
|
if (!t2) return;
|
|
const n2 = ki(t2.options.layout.padding), o2 = Math.max(e2 - n2.width, 0), a2 = Math.max(i2 - n2.height, 0), r2 = function(t3) {
|
|
const e3 = function(t4) {
|
|
const e4 = [];
|
|
let i4, s4, n4, o4, a4, r4;
|
|
for (i4 = 0, s4 = (t4 || []).length; i4 < s4; ++i4) n4 = t4[i4], { position: o4, options: { stack: a4, stackWeight: r4 = 1 } } = n4, e4.push({ index: i4, box: n4, pos: o4, horizontal: n4.isHorizontal(), weight: n4.weight, stack: a4 && o4 + a4, stackWeight: r4 });
|
|
return e4;
|
|
}(t3), i3 = Zi(e3.filter((t4) => t4.box.fullSize), true), s3 = Zi(Ki(e3, "left"), true), n3 = Zi(Ki(e3, "right")), o3 = Zi(Ki(e3, "top"), true), a3 = Zi(Ki(e3, "bottom")), r3 = Gi(e3, "x"), l3 = Gi(e3, "y");
|
|
return { fullSize: i3, leftAndTop: s3.concat(o3), rightAndBottom: n3.concat(l3).concat(a3).concat(r3), chartArea: Ki(e3, "chartArea"), vertical: s3.concat(n3).concat(l3), horizontal: o3.concat(a3).concat(r3) };
|
|
}(t2.boxes), l2 = r2.vertical, h2 = r2.horizontal;
|
|
u(t2.boxes, (t3) => {
|
|
"function" == typeof t3.beforeLayout && t3.beforeLayout();
|
|
});
|
|
const c2 = l2.reduce((t3, e3) => e3.box.options && false === e3.box.options.display ? t3 : t3 + 1, 0) || 1, d2 = Object.freeze({ outerWidth: e2, outerHeight: i2, padding: n2, availableWidth: o2, availableHeight: a2, vBoxMaxWidth: o2 / 2 / c2, hBoxMaxHeight: a2 / 2 }), f2 = Object.assign({}, n2);
|
|
ts(f2, ki(s2));
|
|
const g2 = Object.assign({ maxPadding: f2, w: o2, h: a2, x: n2.left, y: n2.top }, n2), p2 = Ji(l2.concat(h2), d2);
|
|
ss(r2.fullSize, g2, d2, p2), ss(l2, g2, d2, p2), ss(h2, g2, d2, p2) && ss(l2, g2, d2, p2), function(t3) {
|
|
const e3 = t3.maxPadding;
|
|
function i3(i4) {
|
|
const s3 = Math.max(e3[i4] - t3[i4], 0);
|
|
return t3[i4] += s3, s3;
|
|
}
|
|
t3.y += i3("top"), t3.x += i3("left"), i3("right"), i3("bottom");
|
|
}(g2), os(r2.leftAndTop, g2, d2, p2), g2.x += g2.w, g2.y += g2.h, os(r2.rightAndBottom, g2, d2, p2), t2.chartArea = { left: g2.left, top: g2.top, right: g2.left + g2.w, bottom: g2.top + g2.h, height: g2.h, width: g2.w }, u(r2.chartArea, (e3) => {
|
|
const i3 = e3.box;
|
|
Object.assign(i3, t2.chartArea), i3.update(g2.w, g2.h, { left: 0, top: 0, right: 0, bottom: 0 });
|
|
});
|
|
} };
|
|
class rs {
|
|
acquireContext(t2, e2) {
|
|
}
|
|
releaseContext(t2) {
|
|
return false;
|
|
}
|
|
addEventListener(t2, e2, i2) {
|
|
}
|
|
removeEventListener(t2, e2, i2) {
|
|
}
|
|
getDevicePixelRatio() {
|
|
return 1;
|
|
}
|
|
getMaximumSize(t2, e2, i2, s2) {
|
|
return e2 = Math.max(0, e2 || t2.width), i2 = i2 || t2.height, { width: e2, height: Math.max(0, s2 ? Math.floor(e2 / s2) : i2) };
|
|
}
|
|
isAttached(t2) {
|
|
return true;
|
|
}
|
|
updateConfig(t2) {
|
|
}
|
|
}
|
|
class ls extends rs {
|
|
acquireContext(t2) {
|
|
return t2 && t2.getContext && t2.getContext("2d") || null;
|
|
}
|
|
updateConfig(t2) {
|
|
t2.options.animation = false;
|
|
}
|
|
}
|
|
const hs = "$chartjs", cs = { touchstart: "mousedown", touchmove: "mousemove", touchend: "mouseup", pointerenter: "mouseenter", pointerdown: "mousedown", pointermove: "mousemove", pointerup: "mouseup", pointerleave: "mouseout", pointerout: "mouseout" }, ds = (t2) => null === t2 || "" === t2;
|
|
const us = !!Se && { passive: true };
|
|
function fs(t2, e2, i2) {
|
|
t2.canvas.removeEventListener(e2, i2, us);
|
|
}
|
|
function gs(t2, e2) {
|
|
for (const i2 of t2) if (i2 === e2 || i2.contains(e2)) return true;
|
|
}
|
|
function ps(t2, e2, i2) {
|
|
const s2 = t2.canvas, n2 = new MutationObserver((t3) => {
|
|
let e3 = false;
|
|
for (const i3 of t3) e3 = e3 || gs(i3.addedNodes, s2), e3 = e3 && !gs(i3.removedNodes, s2);
|
|
e3 && i2();
|
|
});
|
|
return n2.observe(document, { childList: true, subtree: true }), n2;
|
|
}
|
|
function ms(t2, e2, i2) {
|
|
const s2 = t2.canvas, n2 = new MutationObserver((t3) => {
|
|
let e3 = false;
|
|
for (const i3 of t3) e3 = e3 || gs(i3.removedNodes, s2), e3 = e3 && !gs(i3.addedNodes, s2);
|
|
e3 && i2();
|
|
});
|
|
return n2.observe(document, { childList: true, subtree: true }), n2;
|
|
}
|
|
const bs = /* @__PURE__ */ new Map();
|
|
let xs = 0;
|
|
function _s() {
|
|
const t2 = window.devicePixelRatio;
|
|
t2 !== xs && (xs = t2, bs.forEach((e2, i2) => {
|
|
i2.currentDevicePixelRatio !== t2 && e2();
|
|
}));
|
|
}
|
|
function ys(t2, e2, i2) {
|
|
const s2 = t2.canvas, n2 = s2 && ge(s2);
|
|
if (!n2) return;
|
|
const o2 = ct((t3, e3) => {
|
|
const s3 = n2.clientWidth;
|
|
i2(t3, e3), s3 < n2.clientWidth && i2();
|
|
}, window), a2 = new ResizeObserver((t3) => {
|
|
const e3 = t3[0], i3 = e3.contentRect.width, s3 = e3.contentRect.height;
|
|
0 === i3 && 0 === s3 || o2(i3, s3);
|
|
});
|
|
return a2.observe(n2), function(t3, e3) {
|
|
bs.size || window.addEventListener("resize", _s), bs.set(t3, e3);
|
|
}(t2, o2), a2;
|
|
}
|
|
function vs(t2, e2, i2) {
|
|
i2 && i2.disconnect(), "resize" === e2 && function(t3) {
|
|
bs.delete(t3), bs.size || window.removeEventListener("resize", _s);
|
|
}(t2);
|
|
}
|
|
function Ms(t2, e2, i2) {
|
|
const s2 = t2.canvas, n2 = ct((e3) => {
|
|
null !== t2.ctx && i2(function(t3, e4) {
|
|
const i3 = cs[t3.type] || t3.type, { x: s3, y: n3 } = ve(t3, e4);
|
|
return { type: i3, chart: e4, native: t3, x: void 0 !== s3 ? s3 : null, y: void 0 !== n3 ? n3 : null };
|
|
}(e3, t2));
|
|
}, t2);
|
|
return function(t3, e3, i3) {
|
|
t3.addEventListener(e3, i3, us);
|
|
}(s2, e2, n2), n2;
|
|
}
|
|
class ws extends rs {
|
|
acquireContext(t2, e2) {
|
|
const i2 = t2 && t2.getContext && t2.getContext("2d");
|
|
return i2 && i2.canvas === t2 ? (function(t3, e3) {
|
|
const i3 = t3.style, s2 = t3.getAttribute("height"), n2 = t3.getAttribute("width");
|
|
if (t3[hs] = { initial: { height: s2, width: n2, style: { display: i3.display, height: i3.height, width: i3.width } } }, i3.display = i3.display || "block", i3.boxSizing = i3.boxSizing || "border-box", ds(n2)) {
|
|
const e4 = Pe(t3, "width");
|
|
void 0 !== e4 && (t3.width = e4);
|
|
}
|
|
if (ds(s2)) if ("" === t3.style.height) t3.height = t3.width / (e3 || 2);
|
|
else {
|
|
const e4 = Pe(t3, "height");
|
|
void 0 !== e4 && (t3.height = e4);
|
|
}
|
|
}(t2, e2), i2) : null;
|
|
}
|
|
releaseContext(t2) {
|
|
const e2 = t2.canvas;
|
|
if (!e2[hs]) return false;
|
|
const i2 = e2[hs].initial;
|
|
["height", "width"].forEach((t3) => {
|
|
const n3 = i2[t3];
|
|
s(n3) ? e2.removeAttribute(t3) : e2.setAttribute(t3, n3);
|
|
});
|
|
const n2 = i2.style || {};
|
|
return Object.keys(n2).forEach((t3) => {
|
|
e2.style[t3] = n2[t3];
|
|
}), e2.width = e2.width, delete e2[hs], true;
|
|
}
|
|
addEventListener(t2, e2, i2) {
|
|
this.removeEventListener(t2, e2);
|
|
const s2 = t2.$proxies || (t2.$proxies = {}), n2 = { attach: ps, detach: ms, resize: ys }[e2] || Ms;
|
|
s2[e2] = n2(t2, e2, i2);
|
|
}
|
|
removeEventListener(t2, e2) {
|
|
const i2 = t2.$proxies || (t2.$proxies = {}), s2 = i2[e2];
|
|
if (!s2) return;
|
|
({ attach: vs, detach: vs, resize: vs }[e2] || fs)(t2, e2, s2), i2[e2] = void 0;
|
|
}
|
|
getDevicePixelRatio() {
|
|
return window.devicePixelRatio;
|
|
}
|
|
getMaximumSize(t2, e2, i2, s2) {
|
|
return we(t2, e2, i2, s2);
|
|
}
|
|
isAttached(t2) {
|
|
const e2 = ge(t2);
|
|
return !(!e2 || !e2.isConnected);
|
|
}
|
|
}
|
|
function ks(t2) {
|
|
return !fe() || "undefined" != typeof OffscreenCanvas && t2 instanceof OffscreenCanvas ? ls : ws;
|
|
}
|
|
var Ss = Object.freeze({ __proto__: null, BasePlatform: rs, BasicPlatform: ls, DomPlatform: ws, _detectPlatform: ks });
|
|
const Ps = "transparent", Ds = { boolean: (t2, e2, i2) => i2 > 0.5 ? e2 : t2, color(t2, e2, i2) {
|
|
const s2 = Qt(t2 || Ps), n2 = s2.valid && Qt(e2 || Ps);
|
|
return n2 && n2.valid ? n2.mix(s2, i2).hexString() : e2;
|
|
}, number: (t2, e2, i2) => t2 + (e2 - t2) * i2 };
|
|
class Cs {
|
|
constructor(t2, e2, i2, s2) {
|
|
const n2 = e2[i2];
|
|
s2 = Pi([t2.to, s2, n2, t2.from]);
|
|
const o2 = Pi([t2.from, n2, s2]);
|
|
this._active = true, this._fn = t2.fn || Ds[t2.type || typeof o2], this._easing = fi[t2.easing] || fi.linear, this._start = Math.floor(Date.now() + (t2.delay || 0)), this._duration = this._total = Math.floor(t2.duration), this._loop = !!t2.loop, this._target = e2, this._prop = i2, this._from = o2, this._to = s2, this._promises = void 0;
|
|
}
|
|
active() {
|
|
return this._active;
|
|
}
|
|
update(t2, e2, i2) {
|
|
if (this._active) {
|
|
this._notify(false);
|
|
const s2 = this._target[this._prop], n2 = i2 - this._start, o2 = this._duration - n2;
|
|
this._start = i2, this._duration = Math.floor(Math.max(o2, t2.duration)), this._total += n2, this._loop = !!t2.loop, this._to = Pi([t2.to, e2, s2, t2.from]), this._from = Pi([t2.from, s2, e2]);
|
|
}
|
|
}
|
|
cancel() {
|
|
this._active && (this.tick(Date.now()), this._active = false, this._notify(false));
|
|
}
|
|
tick(t2) {
|
|
const e2 = t2 - this._start, i2 = this._duration, s2 = this._prop, n2 = this._from, o2 = this._loop, a2 = this._to;
|
|
let r2;
|
|
if (this._active = n2 !== a2 && (o2 || e2 < i2), !this._active) return this._target[s2] = a2, void this._notify(true);
|
|
e2 < 0 ? this._target[s2] = n2 : (r2 = e2 / i2 % 2, r2 = o2 && r2 > 1 ? 2 - r2 : r2, r2 = this._easing(Math.min(1, Math.max(0, r2))), this._target[s2] = this._fn(n2, a2, r2));
|
|
}
|
|
wait() {
|
|
const t2 = this._promises || (this._promises = []);
|
|
return new Promise((e2, i2) => {
|
|
t2.push({ res: e2, rej: i2 });
|
|
});
|
|
}
|
|
_notify(t2) {
|
|
const e2 = t2 ? "res" : "rej", i2 = this._promises || [];
|
|
for (let t3 = 0; t3 < i2.length; t3++) i2[t3][e2]();
|
|
}
|
|
}
|
|
class Os {
|
|
constructor(t2, e2) {
|
|
this._chart = t2, this._properties = /* @__PURE__ */ new Map(), this.configure(e2);
|
|
}
|
|
configure(t2) {
|
|
if (!o(t2)) return;
|
|
const e2 = Object.keys(ue.animation), i2 = this._properties;
|
|
Object.getOwnPropertyNames(t2).forEach((s2) => {
|
|
const a2 = t2[s2];
|
|
if (!o(a2)) return;
|
|
const r2 = {};
|
|
for (const t3 of e2) r2[t3] = a2[t3];
|
|
(n(a2.properties) && a2.properties || [s2]).forEach((t3) => {
|
|
t3 !== s2 && i2.has(t3) || i2.set(t3, r2);
|
|
});
|
|
});
|
|
}
|
|
_animateOptions(t2, e2) {
|
|
const i2 = e2.options, s2 = function(t3, e3) {
|
|
if (!e3) return;
|
|
let i3 = t3.options;
|
|
if (!i3) return void (t3.options = e3);
|
|
i3.$shared && (t3.options = i3 = Object.assign({}, i3, { $shared: false, $animations: {} }));
|
|
return i3;
|
|
}(t2, i2);
|
|
if (!s2) return [];
|
|
const n2 = this._createAnimations(s2, i2);
|
|
return i2.$shared && function(t3, e3) {
|
|
const i3 = [], s3 = Object.keys(e3);
|
|
for (let e4 = 0; e4 < s3.length; e4++) {
|
|
const n3 = t3[s3[e4]];
|
|
n3 && n3.active() && i3.push(n3.wait());
|
|
}
|
|
return Promise.all(i3);
|
|
}(t2.options.$animations, i2).then(() => {
|
|
t2.options = i2;
|
|
}, () => {
|
|
}), n2;
|
|
}
|
|
_createAnimations(t2, e2) {
|
|
const i2 = this._properties, s2 = [], n2 = t2.$animations || (t2.$animations = {}), o2 = Object.keys(e2), a2 = Date.now();
|
|
let r2;
|
|
for (r2 = o2.length - 1; r2 >= 0; --r2) {
|
|
const l2 = o2[r2];
|
|
if ("$" === l2.charAt(0)) continue;
|
|
if ("options" === l2) {
|
|
s2.push(...this._animateOptions(t2, e2));
|
|
continue;
|
|
}
|
|
const h2 = e2[l2];
|
|
let c2 = n2[l2];
|
|
const d2 = i2.get(l2);
|
|
if (c2) {
|
|
if (d2 && c2.active()) {
|
|
c2.update(d2, h2, a2);
|
|
continue;
|
|
}
|
|
c2.cancel();
|
|
}
|
|
d2 && d2.duration ? (n2[l2] = c2 = new Cs(d2, t2, l2, h2), s2.push(c2)) : t2[l2] = h2;
|
|
}
|
|
return s2;
|
|
}
|
|
update(t2, e2) {
|
|
if (0 === this._properties.size) return void Object.assign(t2, e2);
|
|
const i2 = this._createAnimations(t2, e2);
|
|
return i2.length ? (xt.add(this._chart, i2), true) : void 0;
|
|
}
|
|
}
|
|
function As(t2, e2) {
|
|
const i2 = t2 && t2.options || {}, s2 = i2.reverse, n2 = void 0 === i2.min ? e2 : 0, o2 = void 0 === i2.max ? e2 : 0;
|
|
return { start: s2 ? o2 : n2, end: s2 ? n2 : o2 };
|
|
}
|
|
function Ts(t2, e2) {
|
|
const i2 = [], s2 = t2._getSortedDatasetMetas(e2);
|
|
let n2, o2;
|
|
for (n2 = 0, o2 = s2.length; n2 < o2; ++n2) i2.push(s2[n2].index);
|
|
return i2;
|
|
}
|
|
function Ls(t2, e2, i2, s2 = {}) {
|
|
const n2 = t2.keys, o2 = "single" === s2.mode;
|
|
let r2, l2, h2, c2;
|
|
if (null !== e2) {
|
|
for (r2 = 0, l2 = n2.length; r2 < l2; ++r2) {
|
|
if (h2 = +n2[r2], h2 === i2) {
|
|
if (s2.all) continue;
|
|
break;
|
|
}
|
|
c2 = t2.values[h2], a(c2) && (o2 || 0 === e2 || F(e2) === F(c2)) && (e2 += c2);
|
|
}
|
|
return e2;
|
|
}
|
|
}
|
|
function Es(t2, e2) {
|
|
const i2 = t2 && t2.options.stacked;
|
|
return i2 || void 0 === i2 && void 0 !== e2.stack;
|
|
}
|
|
function Rs(t2, e2, i2) {
|
|
const s2 = t2[e2] || (t2[e2] = {});
|
|
return s2[i2] || (s2[i2] = {});
|
|
}
|
|
function Is(t2, e2, i2, s2) {
|
|
for (const n2 of e2.getMatchingVisibleMetas(s2).reverse()) {
|
|
const e3 = t2[n2.index];
|
|
if (i2 && e3 > 0 || !i2 && e3 < 0) return n2.index;
|
|
}
|
|
return null;
|
|
}
|
|
function zs(t2, e2) {
|
|
const { chart: i2, _cachedMeta: s2 } = t2, n2 = i2._stacks || (i2._stacks = {}), { iScale: o2, vScale: a2, index: r2 } = s2, l2 = o2.axis, h2 = a2.axis, c2 = function(t3, e3, i3) {
|
|
return `${t3.id}.${e3.id}.${i3.stack || i3.type}`;
|
|
}(o2, a2, s2), d2 = e2.length;
|
|
let u2;
|
|
for (let t3 = 0; t3 < d2; ++t3) {
|
|
const i3 = e2[t3], { [l2]: o3, [h2]: d3 } = i3;
|
|
u2 = (i3._stacks || (i3._stacks = {}))[h2] = Rs(n2, c2, o3), u2[r2] = d3, u2._top = Is(u2, a2, true, s2.type), u2._bottom = Is(u2, a2, false, s2.type);
|
|
(u2._visualValues || (u2._visualValues = {}))[r2] = d3;
|
|
}
|
|
}
|
|
function Fs(t2, e2) {
|
|
const i2 = t2.scales;
|
|
return Object.keys(i2).filter((t3) => i2[t3].axis === e2).shift();
|
|
}
|
|
function Vs(t2, e2) {
|
|
const i2 = t2.controller.index, s2 = t2.vScale && t2.vScale.axis;
|
|
if (s2) {
|
|
e2 = e2 || t2._parsed;
|
|
for (const t3 of e2) {
|
|
const e3 = t3._stacks;
|
|
if (!e3 || void 0 === e3[s2] || void 0 === e3[s2][i2]) return;
|
|
delete e3[s2][i2], void 0 !== e3[s2]._visualValues && void 0 !== e3[s2]._visualValues[i2] && delete e3[s2]._visualValues[i2];
|
|
}
|
|
}
|
|
}
|
|
const Bs = (t2) => "reset" === t2 || "none" === t2, Ws = (t2, e2) => e2 ? t2 : Object.assign({}, t2);
|
|
class Ns {
|
|
constructor(t2, e2) {
|
|
this.chart = t2, this._ctx = t2.ctx, this.index = e2, this._cachedDataOpts = {}, this._cachedMeta = this.getMeta(), this._type = this._cachedMeta.type, this.options = void 0, this._parsing = false, this._data = void 0, this._objectData = void 0, this._sharedOptions = void 0, this._drawStart = void 0, this._drawCount = void 0, this.enableOptionSharing = false, this.supportsDecimation = false, this.$context = void 0, this._syncList = [], this.datasetElementType = new.target.datasetElementType, this.dataElementType = new.target.dataElementType, this.initialize();
|
|
}
|
|
initialize() {
|
|
const t2 = this._cachedMeta;
|
|
this.configure(), this.linkScales(), t2._stacked = Es(t2.vScale, t2), this.addElements(), this.options.fill && !this.chart.isPluginEnabled("filler") && console.warn("Tried to use the 'fill' option without the 'Filler' plugin enabled. Please import and register the 'Filler' plugin and make sure it is not disabled in the options");
|
|
}
|
|
updateIndex(t2) {
|
|
this.index !== t2 && Vs(this._cachedMeta), this.index = t2;
|
|
}
|
|
linkScales() {
|
|
const t2 = this.chart, e2 = this._cachedMeta, i2 = this.getDataset(), s2 = (t3, e3, i3, s3) => "x" === t3 ? e3 : "r" === t3 ? s3 : i3, n2 = e2.xAxisID = l(i2.xAxisID, Fs(t2, "x")), o2 = e2.yAxisID = l(i2.yAxisID, Fs(t2, "y")), a2 = e2.rAxisID = l(i2.rAxisID, Fs(t2, "r")), r2 = e2.indexAxis, h2 = e2.iAxisID = s2(r2, n2, o2, a2), c2 = e2.vAxisID = s2(r2, o2, n2, a2);
|
|
e2.xScale = this.getScaleForId(n2), e2.yScale = this.getScaleForId(o2), e2.rScale = this.getScaleForId(a2), e2.iScale = this.getScaleForId(h2), e2.vScale = this.getScaleForId(c2);
|
|
}
|
|
getDataset() {
|
|
return this.chart.data.datasets[this.index];
|
|
}
|
|
getMeta() {
|
|
return this.chart.getDatasetMeta(this.index);
|
|
}
|
|
getScaleForId(t2) {
|
|
return this.chart.scales[t2];
|
|
}
|
|
_getOtherScale(t2) {
|
|
const e2 = this._cachedMeta;
|
|
return t2 === e2.iScale ? e2.vScale : e2.iScale;
|
|
}
|
|
reset() {
|
|
this._update("reset");
|
|
}
|
|
_destroy() {
|
|
const t2 = this._cachedMeta;
|
|
this._data && rt(this._data, this), t2._stacked && Vs(t2);
|
|
}
|
|
_dataCheck() {
|
|
const t2 = this.getDataset(), e2 = t2.data || (t2.data = []), i2 = this._data;
|
|
if (o(e2)) this._data = function(t3) {
|
|
const e3 = Object.keys(t3), i3 = new Array(e3.length);
|
|
let s2, n2, o2;
|
|
for (s2 = 0, n2 = e3.length; s2 < n2; ++s2) o2 = e3[s2], i3[s2] = { x: o2, y: t3[o2] };
|
|
return i3;
|
|
}(e2);
|
|
else if (i2 !== e2) {
|
|
if (i2) {
|
|
rt(i2, this);
|
|
const t3 = this._cachedMeta;
|
|
Vs(t3), t3._parsed = [];
|
|
}
|
|
e2 && Object.isExtensible(e2) && at(e2, this), this._syncList = [], this._data = e2;
|
|
}
|
|
}
|
|
addElements() {
|
|
const t2 = this._cachedMeta;
|
|
this._dataCheck(), this.datasetElementType && (t2.dataset = new this.datasetElementType());
|
|
}
|
|
buildOrUpdateElements(t2) {
|
|
const e2 = this._cachedMeta, i2 = this.getDataset();
|
|
let s2 = false;
|
|
this._dataCheck();
|
|
const n2 = e2._stacked;
|
|
e2._stacked = Es(e2.vScale, e2), e2.stack !== i2.stack && (s2 = true, Vs(e2), e2.stack = i2.stack), this._resyncElements(t2), (s2 || n2 !== e2._stacked) && zs(this, e2._parsed);
|
|
}
|
|
configure() {
|
|
const t2 = this.chart.config, e2 = t2.datasetScopeKeys(this._type), i2 = t2.getOptionScopes(this.getDataset(), e2, true);
|
|
this.options = t2.createResolver(i2, this.getContext()), this._parsing = this.options.parsing, this._cachedDataOpts = {};
|
|
}
|
|
parse(t2, e2) {
|
|
const { _cachedMeta: i2, _data: s2 } = this, { iScale: a2, _stacked: r2 } = i2, l2 = a2.axis;
|
|
let h2, c2, d2, u2 = 0 === t2 && e2 === s2.length || i2._sorted, f2 = t2 > 0 && i2._parsed[t2 - 1];
|
|
if (false === this._parsing) i2._parsed = s2, i2._sorted = true, d2 = s2;
|
|
else {
|
|
d2 = n(s2[t2]) ? this.parseArrayData(i2, s2, t2, e2) : o(s2[t2]) ? this.parseObjectData(i2, s2, t2, e2) : this.parsePrimitiveData(i2, s2, t2, e2);
|
|
const a3 = () => null === c2[l2] || f2 && c2[l2] < f2[l2];
|
|
for (h2 = 0; h2 < e2; ++h2) i2._parsed[h2 + t2] = c2 = d2[h2], u2 && (a3() && (u2 = false), f2 = c2);
|
|
i2._sorted = u2;
|
|
}
|
|
r2 && zs(this, d2);
|
|
}
|
|
parsePrimitiveData(t2, e2, i2, s2) {
|
|
const { iScale: n2, vScale: o2 } = t2, a2 = n2.axis, r2 = o2.axis, l2 = n2.getLabels(), h2 = n2 === o2, c2 = new Array(s2);
|
|
let d2, u2, f2;
|
|
for (d2 = 0, u2 = s2; d2 < u2; ++d2) f2 = d2 + i2, c2[d2] = { [a2]: h2 || n2.parse(l2[f2], f2), [r2]: o2.parse(e2[f2], f2) };
|
|
return c2;
|
|
}
|
|
parseArrayData(t2, e2, i2, s2) {
|
|
const { xScale: n2, yScale: o2 } = t2, a2 = new Array(s2);
|
|
let r2, l2, h2, c2;
|
|
for (r2 = 0, l2 = s2; r2 < l2; ++r2) h2 = r2 + i2, c2 = e2[h2], a2[r2] = { x: n2.parse(c2[0], h2), y: o2.parse(c2[1], h2) };
|
|
return a2;
|
|
}
|
|
parseObjectData(t2, e2, i2, s2) {
|
|
const { xScale: n2, yScale: o2 } = t2, { xAxisKey: a2 = "x", yAxisKey: r2 = "y" } = this._parsing, l2 = new Array(s2);
|
|
let h2, c2, d2, u2;
|
|
for (h2 = 0, c2 = s2; h2 < c2; ++h2) d2 = h2 + i2, u2 = e2[d2], l2[h2] = { x: n2.parse(M(u2, a2), d2), y: o2.parse(M(u2, r2), d2) };
|
|
return l2;
|
|
}
|
|
getParsed(t2) {
|
|
return this._cachedMeta._parsed[t2];
|
|
}
|
|
getDataElement(t2) {
|
|
return this._cachedMeta.data[t2];
|
|
}
|
|
applyStack(t2, e2, i2) {
|
|
const s2 = this.chart, n2 = this._cachedMeta, o2 = e2[t2.axis];
|
|
return Ls({ keys: Ts(s2, true), values: e2._stacks[t2.axis]._visualValues }, o2, n2.index, { mode: i2 });
|
|
}
|
|
updateRangeFromParsed(t2, e2, i2, s2) {
|
|
const n2 = i2[e2.axis];
|
|
let o2 = null === n2 ? NaN : n2;
|
|
const a2 = s2 && i2._stacks[e2.axis];
|
|
s2 && a2 && (s2.values = a2, o2 = Ls(s2, n2, this._cachedMeta.index)), t2.min = Math.min(t2.min, o2), t2.max = Math.max(t2.max, o2);
|
|
}
|
|
getMinMax(t2, e2) {
|
|
const i2 = this._cachedMeta, s2 = i2._parsed, n2 = i2._sorted && t2 === i2.iScale, o2 = s2.length, r2 = this._getOtherScale(t2), l2 = ((t3, e3, i3) => t3 && !e3.hidden && e3._stacked && { keys: Ts(i3, true), values: null })(e2, i2, this.chart), h2 = { min: Number.POSITIVE_INFINITY, max: Number.NEGATIVE_INFINITY }, { min: c2, max: d2 } = function(t3) {
|
|
const { min: e3, max: i3, minDefined: s3, maxDefined: n3 } = t3.getUserBounds();
|
|
return { min: s3 ? e3 : Number.NEGATIVE_INFINITY, max: n3 ? i3 : Number.POSITIVE_INFINITY };
|
|
}(r2);
|
|
let u2, f2;
|
|
function g2() {
|
|
f2 = s2[u2];
|
|
const e3 = f2[r2.axis];
|
|
return !a(f2[t2.axis]) || c2 > e3 || d2 < e3;
|
|
}
|
|
for (u2 = 0; u2 < o2 && (g2() || (this.updateRangeFromParsed(h2, t2, f2, l2), !n2)); ++u2) ;
|
|
if (n2) {
|
|
for (u2 = o2 - 1; u2 >= 0; --u2) if (!g2()) {
|
|
this.updateRangeFromParsed(h2, t2, f2, l2);
|
|
break;
|
|
}
|
|
}
|
|
return h2;
|
|
}
|
|
getAllParsedValues(t2) {
|
|
const e2 = this._cachedMeta._parsed, i2 = [];
|
|
let s2, n2, o2;
|
|
for (s2 = 0, n2 = e2.length; s2 < n2; ++s2) o2 = e2[s2][t2.axis], a(o2) && i2.push(o2);
|
|
return i2;
|
|
}
|
|
getMaxOverflow() {
|
|
return false;
|
|
}
|
|
getLabelAndValue(t2) {
|
|
const e2 = this._cachedMeta, i2 = e2.iScale, s2 = e2.vScale, n2 = this.getParsed(t2);
|
|
return { label: i2 ? "" + i2.getLabelForValue(n2[i2.axis]) : "", value: s2 ? "" + s2.getLabelForValue(n2[s2.axis]) : "" };
|
|
}
|
|
_update(t2) {
|
|
const e2 = this._cachedMeta;
|
|
this.update(t2 || "default"), e2._clip = function(t3) {
|
|
let e3, i2, s2, n2;
|
|
return o(t3) ? (e3 = t3.top, i2 = t3.right, s2 = t3.bottom, n2 = t3.left) : e3 = i2 = s2 = n2 = t3, { top: e3, right: i2, bottom: s2, left: n2, disabled: false === t3 };
|
|
}(l(this.options.clip, function(t3, e3, i2) {
|
|
if (false === i2) return false;
|
|
const s2 = As(t3, i2), n2 = As(e3, i2);
|
|
return { top: n2.end, right: s2.end, bottom: n2.start, left: s2.start };
|
|
}(e2.xScale, e2.yScale, this.getMaxOverflow())));
|
|
}
|
|
update(t2) {
|
|
}
|
|
draw() {
|
|
const t2 = this._ctx, e2 = this.chart, i2 = this._cachedMeta, s2 = i2.data || [], n2 = e2.chartArea, o2 = [], a2 = this._drawStart || 0, r2 = this._drawCount || s2.length - a2, l2 = this.options.drawActiveElementsOnTop;
|
|
let h2;
|
|
for (i2.dataset && i2.dataset.draw(t2, n2, a2, r2), h2 = a2; h2 < a2 + r2; ++h2) {
|
|
const e3 = s2[h2];
|
|
e3.hidden || (e3.active && l2 ? o2.push(e3) : e3.draw(t2, n2));
|
|
}
|
|
for (h2 = 0; h2 < o2.length; ++h2) o2[h2].draw(t2, n2);
|
|
}
|
|
getStyle(t2, e2) {
|
|
const i2 = e2 ? "active" : "default";
|
|
return void 0 === t2 && this._cachedMeta.dataset ? this.resolveDatasetElementOptions(i2) : this.resolveDataElementOptions(t2 || 0, i2);
|
|
}
|
|
getContext(t2, e2, i2) {
|
|
const s2 = this.getDataset();
|
|
let n2;
|
|
if (t2 >= 0 && t2 < this._cachedMeta.data.length) {
|
|
const e3 = this._cachedMeta.data[t2];
|
|
n2 = e3.$context || (e3.$context = function(t3, e4, i3) {
|
|
return Ci(t3, { active: false, dataIndex: e4, parsed: void 0, raw: void 0, element: i3, index: e4, mode: "default", type: "data" });
|
|
}(this.getContext(), t2, e3)), n2.parsed = this.getParsed(t2), n2.raw = s2.data[t2], n2.index = n2.dataIndex = t2;
|
|
} else n2 = this.$context || (this.$context = function(t3, e3) {
|
|
return Ci(t3, { active: false, dataset: void 0, datasetIndex: e3, index: e3, mode: "default", type: "dataset" });
|
|
}(this.chart.getContext(), this.index)), n2.dataset = s2, n2.index = n2.datasetIndex = this.index;
|
|
return n2.active = !!e2, n2.mode = i2, n2;
|
|
}
|
|
resolveDatasetElementOptions(t2) {
|
|
return this._resolveElementOptions(this.datasetElementType.id, t2);
|
|
}
|
|
resolveDataElementOptions(t2, e2) {
|
|
return this._resolveElementOptions(this.dataElementType.id, e2, t2);
|
|
}
|
|
_resolveElementOptions(t2, e2 = "default", i2) {
|
|
const s2 = "active" === e2, n2 = this._cachedDataOpts, o2 = t2 + "-" + e2, a2 = n2[o2], r2 = this.enableOptionSharing && k(i2);
|
|
if (a2) return Ws(a2, r2);
|
|
const l2 = this.chart.config, h2 = l2.datasetElementScopeKeys(this._type, t2), c2 = s2 ? [`${t2}Hover`, "hover", t2, ""] : [t2, ""], d2 = l2.getOptionScopes(this.getDataset(), h2), u2 = Object.keys(ue.elements[t2]), f2 = l2.resolveNamedOptions(d2, u2, () => this.getContext(i2, s2, e2), c2);
|
|
return f2.$shared && (f2.$shared = r2, n2[o2] = Object.freeze(Ws(f2, r2))), f2;
|
|
}
|
|
_resolveAnimations(t2, e2, i2) {
|
|
const s2 = this.chart, n2 = this._cachedDataOpts, o2 = `animation-${e2}`, a2 = n2[o2];
|
|
if (a2) return a2;
|
|
let r2;
|
|
if (false !== s2.options.animation) {
|
|
const s3 = this.chart.config, n3 = s3.datasetAnimationScopeKeys(this._type, e2), o3 = s3.getOptionScopes(this.getDataset(), n3);
|
|
r2 = s3.createResolver(o3, this.getContext(t2, i2, e2));
|
|
}
|
|
const l2 = new Os(s2, r2 && r2.animations);
|
|
return r2 && r2._cacheable && (n2[o2] = Object.freeze(l2)), l2;
|
|
}
|
|
getSharedOptions(t2) {
|
|
if (t2.$shared) return this._sharedOptions || (this._sharedOptions = Object.assign({}, t2));
|
|
}
|
|
includeOptions(t2, e2) {
|
|
return !e2 || Bs(t2) || this.chart._animationsDisabled;
|
|
}
|
|
_getSharedOptions(t2, e2) {
|
|
const i2 = this.resolveDataElementOptions(t2, e2), s2 = this._sharedOptions, n2 = this.getSharedOptions(i2), o2 = this.includeOptions(e2, n2) || n2 !== s2;
|
|
return this.updateSharedOptions(n2, e2, i2), { sharedOptions: n2, includeOptions: o2 };
|
|
}
|
|
updateElement(t2, e2, i2, s2) {
|
|
Bs(s2) ? Object.assign(t2, i2) : this._resolveAnimations(e2, s2).update(t2, i2);
|
|
}
|
|
updateSharedOptions(t2, e2, i2) {
|
|
t2 && !Bs(e2) && this._resolveAnimations(void 0, e2).update(t2, i2);
|
|
}
|
|
_setStyle(t2, e2, i2, s2) {
|
|
t2.active = s2;
|
|
const n2 = this.getStyle(e2, s2);
|
|
this._resolveAnimations(e2, i2, s2).update(t2, { options: !s2 && this.getSharedOptions(n2) || n2 });
|
|
}
|
|
removeHoverStyle(t2, e2, i2) {
|
|
this._setStyle(t2, i2, "active", false);
|
|
}
|
|
setHoverStyle(t2, e2, i2) {
|
|
this._setStyle(t2, i2, "active", true);
|
|
}
|
|
_removeDatasetHoverStyle() {
|
|
const t2 = this._cachedMeta.dataset;
|
|
t2 && this._setStyle(t2, void 0, "active", false);
|
|
}
|
|
_setDatasetHoverStyle() {
|
|
const t2 = this._cachedMeta.dataset;
|
|
t2 && this._setStyle(t2, void 0, "active", true);
|
|
}
|
|
_resyncElements(t2) {
|
|
const e2 = this._data, i2 = this._cachedMeta.data;
|
|
for (const [t3, e3, i3] of this._syncList) this[t3](e3, i3);
|
|
this._syncList = [];
|
|
const s2 = i2.length, n2 = e2.length, o2 = Math.min(n2, s2);
|
|
o2 && this.parse(0, o2), n2 > s2 ? this._insertElements(s2, n2 - s2, t2) : n2 < s2 && this._removeElements(n2, s2 - n2);
|
|
}
|
|
_insertElements(t2, e2, i2 = true) {
|
|
const s2 = this._cachedMeta, n2 = s2.data, o2 = t2 + e2;
|
|
let a2;
|
|
const r2 = (t3) => {
|
|
for (t3.length += e2, a2 = t3.length - 1; a2 >= o2; a2--) t3[a2] = t3[a2 - e2];
|
|
};
|
|
for (r2(n2), a2 = t2; a2 < o2; ++a2) n2[a2] = new this.dataElementType();
|
|
this._parsing && r2(s2._parsed), this.parse(t2, e2), i2 && this.updateElements(n2, t2, e2, "reset");
|
|
}
|
|
updateElements(t2, e2, i2, s2) {
|
|
}
|
|
_removeElements(t2, e2) {
|
|
const i2 = this._cachedMeta;
|
|
if (this._parsing) {
|
|
const s2 = i2._parsed.splice(t2, e2);
|
|
i2._stacked && Vs(i2, s2);
|
|
}
|
|
i2.data.splice(t2, e2);
|
|
}
|
|
_sync(t2) {
|
|
if (this._parsing) this._syncList.push(t2);
|
|
else {
|
|
const [e2, i2, s2] = t2;
|
|
this[e2](i2, s2);
|
|
}
|
|
this.chart._dataChanges.push([this.index, ...t2]);
|
|
}
|
|
_onDataPush() {
|
|
const t2 = arguments.length;
|
|
this._sync(["_insertElements", this.getDataset().data.length - t2, t2]);
|
|
}
|
|
_onDataPop() {
|
|
this._sync(["_removeElements", this._cachedMeta.data.length - 1, 1]);
|
|
}
|
|
_onDataShift() {
|
|
this._sync(["_removeElements", 0, 1]);
|
|
}
|
|
_onDataSplice(t2, e2) {
|
|
e2 && this._sync(["_removeElements", t2, e2]);
|
|
const i2 = arguments.length - 2;
|
|
i2 && this._sync(["_insertElements", t2, i2]);
|
|
}
|
|
_onDataUnshift() {
|
|
this._sync(["_insertElements", 0, arguments.length]);
|
|
}
|
|
}
|
|
__publicField(Ns, "defaults", {});
|
|
__publicField(Ns, "datasetElementType", null);
|
|
__publicField(Ns, "dataElementType", null);
|
|
class Hs {
|
|
constructor() {
|
|
__publicField(this, "x");
|
|
__publicField(this, "y");
|
|
__publicField(this, "active", false);
|
|
__publicField(this, "options");
|
|
__publicField(this, "$animations");
|
|
}
|
|
tooltipPosition(t2) {
|
|
const { x: e2, y: i2 } = this.getProps(["x", "y"], t2);
|
|
return { x: e2, y: i2 };
|
|
}
|
|
hasValue() {
|
|
return N(this.x) && N(this.y);
|
|
}
|
|
getProps(t2, e2) {
|
|
const i2 = this.$animations;
|
|
if (!e2 || !i2) return this;
|
|
const s2 = {};
|
|
return t2.forEach((t3) => {
|
|
s2[t3] = i2[t3] && i2[t3].active() ? i2[t3]._to : this[t3];
|
|
}), s2;
|
|
}
|
|
}
|
|
__publicField(Hs, "defaults", {});
|
|
__publicField(Hs, "defaultRoutes");
|
|
function js(t2, e2) {
|
|
const i2 = t2.options.ticks, n2 = function(t3) {
|
|
const e3 = t3.options.offset, i3 = t3._tickSize(), s2 = t3._length / i3 + (e3 ? 0 : 1), n3 = t3._maxLength / i3;
|
|
return Math.floor(Math.min(s2, n3));
|
|
}(t2), o2 = Math.min(i2.maxTicksLimit || n2, n2), a2 = i2.major.enabled ? function(t3) {
|
|
const e3 = [];
|
|
let i3, s2;
|
|
for (i3 = 0, s2 = t3.length; i3 < s2; i3++) t3[i3].major && e3.push(i3);
|
|
return e3;
|
|
}(e2) : [], r2 = a2.length, l2 = a2[0], h2 = a2[r2 - 1], c2 = [];
|
|
if (r2 > o2) return function(t3, e3, i3, s2) {
|
|
let n3, o3 = 0, a3 = i3[0];
|
|
for (s2 = Math.ceil(s2), n3 = 0; n3 < t3.length; n3++) n3 === a3 && (e3.push(t3[n3]), o3++, a3 = i3[o3 * s2]);
|
|
}(e2, c2, a2, r2 / o2), c2;
|
|
const d2 = function(t3, e3, i3) {
|
|
const s2 = function(t4) {
|
|
const e4 = t4.length;
|
|
let i4, s3;
|
|
if (e4 < 2) return false;
|
|
for (s3 = t4[0], i4 = 1; i4 < e4; ++i4) if (t4[i4] - t4[i4 - 1] !== s3) return false;
|
|
return s3;
|
|
}(t3), n3 = e3.length / i3;
|
|
if (!s2) return Math.max(n3, 1);
|
|
const o3 = W(s2);
|
|
for (let t4 = 0, e4 = o3.length - 1; t4 < e4; t4++) {
|
|
const e5 = o3[t4];
|
|
if (e5 > n3) return e5;
|
|
}
|
|
return Math.max(n3, 1);
|
|
}(a2, e2, o2);
|
|
if (r2 > 0) {
|
|
let t3, i3;
|
|
const n3 = r2 > 1 ? Math.round((h2 - l2) / (r2 - 1)) : null;
|
|
for ($s(e2, c2, d2, s(n3) ? 0 : l2 - n3, l2), t3 = 0, i3 = r2 - 1; t3 < i3; t3++) $s(e2, c2, d2, a2[t3], a2[t3 + 1]);
|
|
return $s(e2, c2, d2, h2, s(n3) ? e2.length : h2 + n3), c2;
|
|
}
|
|
return $s(e2, c2, d2), c2;
|
|
}
|
|
function $s(t2, e2, i2, s2, n2) {
|
|
const o2 = l(s2, 0), a2 = Math.min(l(n2, t2.length), t2.length);
|
|
let r2, h2, c2, d2 = 0;
|
|
for (i2 = Math.ceil(i2), n2 && (r2 = n2 - s2, i2 = r2 / Math.floor(r2 / i2)), c2 = o2; c2 < 0; ) d2++, c2 = Math.round(o2 + d2 * i2);
|
|
for (h2 = Math.max(o2, 0); h2 < a2; h2++) h2 === c2 && (e2.push(t2[h2]), d2++, c2 = Math.round(o2 + d2 * i2));
|
|
}
|
|
const Ys = (t2, e2, i2) => "top" === e2 || "left" === e2 ? t2[e2] + i2 : t2[e2] - i2, Us = (t2, e2) => Math.min(e2 || t2, t2);
|
|
function Xs(t2, e2) {
|
|
const i2 = [], s2 = t2.length / e2, n2 = t2.length;
|
|
let o2 = 0;
|
|
for (; o2 < n2; o2 += s2) i2.push(t2[Math.floor(o2)]);
|
|
return i2;
|
|
}
|
|
function qs(t2, e2, i2) {
|
|
const s2 = t2.ticks.length, n2 = Math.min(e2, s2 - 1), o2 = t2._startPixel, a2 = t2._endPixel, r2 = 1e-6;
|
|
let l2, h2 = t2.getPixelForTick(n2);
|
|
if (!(i2 && (l2 = 1 === s2 ? Math.max(h2 - o2, a2 - h2) : 0 === e2 ? (t2.getPixelForTick(1) - h2) / 2 : (h2 - t2.getPixelForTick(n2 - 1)) / 2, h2 += n2 < e2 ? l2 : -l2, h2 < o2 - r2 || h2 > a2 + r2))) return h2;
|
|
}
|
|
function Ks(t2) {
|
|
return t2.drawTicks ? t2.tickLength : 0;
|
|
}
|
|
function Gs(t2, e2) {
|
|
if (!t2.display) return 0;
|
|
const i2 = Si(t2.font, e2), s2 = ki(t2.padding);
|
|
return (n(t2.text) ? t2.text.length : 1) * i2.lineHeight + s2.height;
|
|
}
|
|
function Zs(t2, e2, i2) {
|
|
let s2 = ut(t2);
|
|
return (i2 && "right" !== e2 || !i2 && "right" === e2) && (s2 = /* @__PURE__ */ ((t3) => "left" === t3 ? "right" : "right" === t3 ? "left" : t3)(s2)), s2;
|
|
}
|
|
class Js extends Hs {
|
|
constructor(t2) {
|
|
super(), this.id = t2.id, this.type = t2.type, this.options = void 0, this.ctx = t2.ctx, this.chart = t2.chart, this.top = void 0, this.bottom = void 0, this.left = void 0, this.right = void 0, this.width = void 0, this.height = void 0, this._margins = { left: 0, right: 0, top: 0, bottom: 0 }, this.maxWidth = void 0, this.maxHeight = void 0, this.paddingTop = void 0, this.paddingBottom = void 0, this.paddingLeft = void 0, this.paddingRight = void 0, this.axis = void 0, this.labelRotation = void 0, this.min = void 0, this.max = void 0, this._range = void 0, this.ticks = [], this._gridLineItems = null, this._labelItems = null, this._labelSizes = null, this._length = 0, this._maxLength = 0, this._longestTextCache = {}, this._startPixel = void 0, this._endPixel = void 0, this._reversePixels = false, this._userMax = void 0, this._userMin = void 0, this._suggestedMax = void 0, this._suggestedMin = void 0, this._ticksLength = 0, this._borderValue = 0, this._cache = {}, this._dataLimitsCached = false, this.$context = void 0;
|
|
}
|
|
init(t2) {
|
|
this.options = t2.setContext(this.getContext()), this.axis = t2.axis, this._userMin = this.parse(t2.min), this._userMax = this.parse(t2.max), this._suggestedMin = this.parse(t2.suggestedMin), this._suggestedMax = this.parse(t2.suggestedMax);
|
|
}
|
|
parse(t2, e2) {
|
|
return t2;
|
|
}
|
|
getUserBounds() {
|
|
let { _userMin: t2, _userMax: e2, _suggestedMin: i2, _suggestedMax: s2 } = this;
|
|
return t2 = r(t2, Number.POSITIVE_INFINITY), e2 = r(e2, Number.NEGATIVE_INFINITY), i2 = r(i2, Number.POSITIVE_INFINITY), s2 = r(s2, Number.NEGATIVE_INFINITY), { min: r(t2, i2), max: r(e2, s2), minDefined: a(t2), maxDefined: a(e2) };
|
|
}
|
|
getMinMax(t2) {
|
|
let e2, { min: i2, max: s2, minDefined: n2, maxDefined: o2 } = this.getUserBounds();
|
|
if (n2 && o2) return { min: i2, max: s2 };
|
|
const a2 = this.getMatchingVisibleMetas();
|
|
for (let r2 = 0, l2 = a2.length; r2 < l2; ++r2) e2 = a2[r2].controller.getMinMax(this, t2), n2 || (i2 = Math.min(i2, e2.min)), o2 || (s2 = Math.max(s2, e2.max));
|
|
return i2 = o2 && i2 > s2 ? s2 : i2, s2 = n2 && i2 > s2 ? i2 : s2, { min: r(i2, r(s2, i2)), max: r(s2, r(i2, s2)) };
|
|
}
|
|
getPadding() {
|
|
return { left: this.paddingLeft || 0, top: this.paddingTop || 0, right: this.paddingRight || 0, bottom: this.paddingBottom || 0 };
|
|
}
|
|
getTicks() {
|
|
return this.ticks;
|
|
}
|
|
getLabels() {
|
|
const t2 = this.chart.data;
|
|
return this.options.labels || (this.isHorizontal() ? t2.xLabels : t2.yLabels) || t2.labels || [];
|
|
}
|
|
getLabelItems(t2 = this.chart.chartArea) {
|
|
return this._labelItems || (this._labelItems = this._computeLabelItems(t2));
|
|
}
|
|
beforeLayout() {
|
|
this._cache = {}, this._dataLimitsCached = false;
|
|
}
|
|
beforeUpdate() {
|
|
d(this.options.beforeUpdate, [this]);
|
|
}
|
|
update(t2, e2, i2) {
|
|
const { beginAtZero: s2, grace: n2, ticks: o2 } = this.options, a2 = o2.sampleSize;
|
|
this.beforeUpdate(), this.maxWidth = t2, this.maxHeight = e2, this._margins = i2 = Object.assign({ left: 0, right: 0, top: 0, bottom: 0 }, i2), this.ticks = null, this._labelSizes = null, this._gridLineItems = null, this._labelItems = null, this.beforeSetDimensions(), this.setDimensions(), this.afterSetDimensions(), this._maxLength = this.isHorizontal() ? this.width + i2.left + i2.right : this.height + i2.top + i2.bottom, this._dataLimitsCached || (this.beforeDataLimits(), this.determineDataLimits(), this.afterDataLimits(), this._range = Di(this, n2, s2), this._dataLimitsCached = true), this.beforeBuildTicks(), this.ticks = this.buildTicks() || [], this.afterBuildTicks();
|
|
const r2 = a2 < this.ticks.length;
|
|
this._convertTicksToLabels(r2 ? Xs(this.ticks, a2) : this.ticks), this.configure(), this.beforeCalculateLabelRotation(), this.calculateLabelRotation(), this.afterCalculateLabelRotation(), o2.display && (o2.autoSkip || "auto" === o2.source) && (this.ticks = js(this, this.ticks), this._labelSizes = null, this.afterAutoSkip()), r2 && this._convertTicksToLabels(this.ticks), this.beforeFit(), this.fit(), this.afterFit(), this.afterUpdate();
|
|
}
|
|
configure() {
|
|
let t2, e2, i2 = this.options.reverse;
|
|
this.isHorizontal() ? (t2 = this.left, e2 = this.right) : (t2 = this.top, e2 = this.bottom, i2 = !i2), this._startPixel = t2, this._endPixel = e2, this._reversePixels = i2, this._length = e2 - t2, this._alignToPixels = this.options.alignToPixels;
|
|
}
|
|
afterUpdate() {
|
|
d(this.options.afterUpdate, [this]);
|
|
}
|
|
beforeSetDimensions() {
|
|
d(this.options.beforeSetDimensions, [this]);
|
|
}
|
|
setDimensions() {
|
|
this.isHorizontal() ? (this.width = this.maxWidth, this.left = 0, this.right = this.width) : (this.height = this.maxHeight, this.top = 0, this.bottom = this.height), this.paddingLeft = 0, this.paddingTop = 0, this.paddingRight = 0, this.paddingBottom = 0;
|
|
}
|
|
afterSetDimensions() {
|
|
d(this.options.afterSetDimensions, [this]);
|
|
}
|
|
_callHooks(t2) {
|
|
this.chart.notifyPlugins(t2, this.getContext()), d(this.options[t2], [this]);
|
|
}
|
|
beforeDataLimits() {
|
|
this._callHooks("beforeDataLimits");
|
|
}
|
|
determineDataLimits() {
|
|
}
|
|
afterDataLimits() {
|
|
this._callHooks("afterDataLimits");
|
|
}
|
|
beforeBuildTicks() {
|
|
this._callHooks("beforeBuildTicks");
|
|
}
|
|
buildTicks() {
|
|
return [];
|
|
}
|
|
afterBuildTicks() {
|
|
this._callHooks("afterBuildTicks");
|
|
}
|
|
beforeTickToLabelConversion() {
|
|
d(this.options.beforeTickToLabelConversion, [this]);
|
|
}
|
|
generateTickLabels(t2) {
|
|
const e2 = this.options.ticks;
|
|
let i2, s2, n2;
|
|
for (i2 = 0, s2 = t2.length; i2 < s2; i2++) n2 = t2[i2], n2.label = d(e2.callback, [n2.value, i2, t2], this);
|
|
}
|
|
afterTickToLabelConversion() {
|
|
d(this.options.afterTickToLabelConversion, [this]);
|
|
}
|
|
beforeCalculateLabelRotation() {
|
|
d(this.options.beforeCalculateLabelRotation, [this]);
|
|
}
|
|
calculateLabelRotation() {
|
|
const t2 = this.options, e2 = t2.ticks, i2 = Us(this.ticks.length, t2.ticks.maxTicksLimit), s2 = e2.minRotation || 0, n2 = e2.maxRotation;
|
|
let o2, a2, r2, l2 = s2;
|
|
if (!this._isVisible() || !e2.display || s2 >= n2 || i2 <= 1 || !this.isHorizontal()) return void (this.labelRotation = s2);
|
|
const h2 = this._getLabelSizes(), c2 = h2.widest.width, d2 = h2.highest.height, u2 = J(this.chart.width - c2, 0, this.maxWidth);
|
|
o2 = t2.offset ? this.maxWidth / i2 : u2 / (i2 - 1), c2 + 6 > o2 && (o2 = u2 / (i2 - (t2.offset ? 0.5 : 1)), a2 = this.maxHeight - Ks(t2.grid) - e2.padding - Gs(t2.title, this.chart.options.font), r2 = Math.sqrt(c2 * c2 + d2 * d2), l2 = Y(Math.min(Math.asin(J((h2.highest.height + 6) / o2, -1, 1)), Math.asin(J(a2 / r2, -1, 1)) - Math.asin(J(d2 / r2, -1, 1)))), l2 = Math.max(s2, Math.min(n2, l2))), this.labelRotation = l2;
|
|
}
|
|
afterCalculateLabelRotation() {
|
|
d(this.options.afterCalculateLabelRotation, [this]);
|
|
}
|
|
afterAutoSkip() {
|
|
}
|
|
beforeFit() {
|
|
d(this.options.beforeFit, [this]);
|
|
}
|
|
fit() {
|
|
const t2 = { width: 0, height: 0 }, { chart: e2, options: { ticks: i2, title: s2, grid: n2 } } = this, o2 = this._isVisible(), a2 = this.isHorizontal();
|
|
if (o2) {
|
|
const o3 = Gs(s2, e2.options.font);
|
|
if (a2 ? (t2.width = this.maxWidth, t2.height = Ks(n2) + o3) : (t2.height = this.maxHeight, t2.width = Ks(n2) + o3), i2.display && this.ticks.length) {
|
|
const { first: e3, last: s3, widest: n3, highest: o4 } = this._getLabelSizes(), r2 = 2 * i2.padding, l2 = $(this.labelRotation), h2 = Math.cos(l2), c2 = Math.sin(l2);
|
|
if (a2) {
|
|
const e4 = i2.mirror ? 0 : c2 * n3.width + h2 * o4.height;
|
|
t2.height = Math.min(this.maxHeight, t2.height + e4 + r2);
|
|
} else {
|
|
const e4 = i2.mirror ? 0 : h2 * n3.width + c2 * o4.height;
|
|
t2.width = Math.min(this.maxWidth, t2.width + e4 + r2);
|
|
}
|
|
this._calculatePadding(e3, s3, c2, h2);
|
|
}
|
|
}
|
|
this._handleMargins(), a2 ? (this.width = this._length = e2.width - this._margins.left - this._margins.right, this.height = t2.height) : (this.width = t2.width, this.height = this._length = e2.height - this._margins.top - this._margins.bottom);
|
|
}
|
|
_calculatePadding(t2, e2, i2, s2) {
|
|
const { ticks: { align: n2, padding: o2 }, position: a2 } = this.options, r2 = 0 !== this.labelRotation, l2 = "top" !== a2 && "x" === this.axis;
|
|
if (this.isHorizontal()) {
|
|
const a3 = this.getPixelForTick(0) - this.left, h2 = this.right - this.getPixelForTick(this.ticks.length - 1);
|
|
let c2 = 0, d2 = 0;
|
|
r2 ? l2 ? (c2 = s2 * t2.width, d2 = i2 * e2.height) : (c2 = i2 * t2.height, d2 = s2 * e2.width) : "start" === n2 ? d2 = e2.width : "end" === n2 ? c2 = t2.width : "inner" !== n2 && (c2 = t2.width / 2, d2 = e2.width / 2), this.paddingLeft = Math.max((c2 - a3 + o2) * this.width / (this.width - a3), 0), this.paddingRight = Math.max((d2 - h2 + o2) * this.width / (this.width - h2), 0);
|
|
} else {
|
|
let i3 = e2.height / 2, s3 = t2.height / 2;
|
|
"start" === n2 ? (i3 = 0, s3 = t2.height) : "end" === n2 && (i3 = e2.height, s3 = 0), this.paddingTop = i3 + o2, this.paddingBottom = s3 + o2;
|
|
}
|
|
}
|
|
_handleMargins() {
|
|
this._margins && (this._margins.left = Math.max(this.paddingLeft, this._margins.left), this._margins.top = Math.max(this.paddingTop, this._margins.top), this._margins.right = Math.max(this.paddingRight, this._margins.right), this._margins.bottom = Math.max(this.paddingBottom, this._margins.bottom));
|
|
}
|
|
afterFit() {
|
|
d(this.options.afterFit, [this]);
|
|
}
|
|
isHorizontal() {
|
|
const { axis: t2, position: e2 } = this.options;
|
|
return "top" === e2 || "bottom" === e2 || "x" === t2;
|
|
}
|
|
isFullSize() {
|
|
return this.options.fullSize;
|
|
}
|
|
_convertTicksToLabels(t2) {
|
|
let e2, i2;
|
|
for (this.beforeTickToLabelConversion(), this.generateTickLabels(t2), e2 = 0, i2 = t2.length; e2 < i2; e2++) s(t2[e2].label) && (t2.splice(e2, 1), i2--, e2--);
|
|
this.afterTickToLabelConversion();
|
|
}
|
|
_getLabelSizes() {
|
|
let t2 = this._labelSizes;
|
|
if (!t2) {
|
|
const e2 = this.options.ticks.sampleSize;
|
|
let i2 = this.ticks;
|
|
e2 < i2.length && (i2 = Xs(i2, e2)), this._labelSizes = t2 = this._computeLabelSizes(i2, i2.length, this.options.ticks.maxTicksLimit);
|
|
}
|
|
return t2;
|
|
}
|
|
_computeLabelSizes(t2, e2, i2) {
|
|
const { ctx: o2, _longestTextCache: a2 } = this, r2 = [], l2 = [], h2 = Math.floor(e2 / Us(e2, i2));
|
|
let c2, d2, f2, g2, p2, m2, b2, x2, _2, y2, v2, M2 = 0, w2 = 0;
|
|
for (c2 = 0; c2 < e2; c2 += h2) {
|
|
if (g2 = t2[c2].label, p2 = this._resolveTickFontOptions(c2), o2.font = m2 = p2.string, b2 = a2[m2] = a2[m2] || { data: {}, gc: [] }, x2 = p2.lineHeight, _2 = y2 = 0, s(g2) || n(g2)) {
|
|
if (n(g2)) for (d2 = 0, f2 = g2.length; d2 < f2; ++d2) v2 = g2[d2], s(v2) || n(v2) || (_2 = Ce(o2, b2.data, b2.gc, _2, v2), y2 += x2);
|
|
} else _2 = Ce(o2, b2.data, b2.gc, _2, g2), y2 = x2;
|
|
r2.push(_2), l2.push(y2), M2 = Math.max(_2, M2), w2 = Math.max(y2, w2);
|
|
}
|
|
!function(t3, e3) {
|
|
u(t3, (t4) => {
|
|
const i3 = t4.gc, s2 = i3.length / 2;
|
|
let n2;
|
|
if (s2 > e3) {
|
|
for (n2 = 0; n2 < s2; ++n2) delete t4.data[i3[n2]];
|
|
i3.splice(0, s2);
|
|
}
|
|
});
|
|
}(a2, e2);
|
|
const k2 = r2.indexOf(M2), S2 = l2.indexOf(w2), P2 = (t3) => ({ width: r2[t3] || 0, height: l2[t3] || 0 });
|
|
return { first: P2(0), last: P2(e2 - 1), widest: P2(k2), highest: P2(S2), widths: r2, heights: l2 };
|
|
}
|
|
getLabelForValue(t2) {
|
|
return t2;
|
|
}
|
|
getPixelForValue(t2, e2) {
|
|
return NaN;
|
|
}
|
|
getValueForPixel(t2) {
|
|
}
|
|
getPixelForTick(t2) {
|
|
const e2 = this.ticks;
|
|
return t2 < 0 || t2 > e2.length - 1 ? null : this.getPixelForValue(e2[t2].value);
|
|
}
|
|
getPixelForDecimal(t2) {
|
|
this._reversePixels && (t2 = 1 - t2);
|
|
const e2 = this._startPixel + t2 * this._length;
|
|
return Q(this._alignToPixels ? Ae(this.chart, e2, 0) : e2);
|
|
}
|
|
getDecimalForPixel(t2) {
|
|
const e2 = (t2 - this._startPixel) / this._length;
|
|
return this._reversePixels ? 1 - e2 : e2;
|
|
}
|
|
getBasePixel() {
|
|
return this.getPixelForValue(this.getBaseValue());
|
|
}
|
|
getBaseValue() {
|
|
const { min: t2, max: e2 } = this;
|
|
return t2 < 0 && e2 < 0 ? e2 : t2 > 0 && e2 > 0 ? t2 : 0;
|
|
}
|
|
getContext(t2) {
|
|
const e2 = this.ticks || [];
|
|
if (t2 >= 0 && t2 < e2.length) {
|
|
const i2 = e2[t2];
|
|
return i2.$context || (i2.$context = function(t3, e3, i3) {
|
|
return Ci(t3, { tick: i3, index: e3, type: "tick" });
|
|
}(this.getContext(), t2, i2));
|
|
}
|
|
return this.$context || (this.$context = Ci(this.chart.getContext(), { scale: this, type: "scale" }));
|
|
}
|
|
_tickSize() {
|
|
const t2 = this.options.ticks, e2 = $(this.labelRotation), i2 = Math.abs(Math.cos(e2)), s2 = Math.abs(Math.sin(e2)), n2 = this._getLabelSizes(), o2 = t2.autoSkipPadding || 0, a2 = n2 ? n2.widest.width + o2 : 0, r2 = n2 ? n2.highest.height + o2 : 0;
|
|
return this.isHorizontal() ? r2 * i2 > a2 * s2 ? a2 / i2 : r2 / s2 : r2 * s2 < a2 * i2 ? r2 / i2 : a2 / s2;
|
|
}
|
|
_isVisible() {
|
|
const t2 = this.options.display;
|
|
return "auto" !== t2 ? !!t2 : this.getMatchingVisibleMetas().length > 0;
|
|
}
|
|
_computeGridLineItems(t2) {
|
|
const e2 = this.axis, i2 = this.chart, s2 = this.options, { grid: n2, position: a2, border: r2 } = s2, h2 = n2.offset, c2 = this.isHorizontal(), d2 = this.ticks.length + (h2 ? 1 : 0), u2 = Ks(n2), f2 = [], g2 = r2.setContext(this.getContext()), p2 = g2.display ? g2.width : 0, m2 = p2 / 2, b2 = function(t3) {
|
|
return Ae(i2, t3, p2);
|
|
};
|
|
let x2, _2, y2, v2, M2, w2, k2, S2, P2, D2, C2, O2;
|
|
if ("top" === a2) x2 = b2(this.bottom), w2 = this.bottom - u2, S2 = x2 - m2, D2 = b2(t2.top) + m2, O2 = t2.bottom;
|
|
else if ("bottom" === a2) x2 = b2(this.top), D2 = t2.top, O2 = b2(t2.bottom) - m2, w2 = x2 + m2, S2 = this.top + u2;
|
|
else if ("left" === a2) x2 = b2(this.right), M2 = this.right - u2, k2 = x2 - m2, P2 = b2(t2.left) + m2, C2 = t2.right;
|
|
else if ("right" === a2) x2 = b2(this.left), P2 = t2.left, C2 = b2(t2.right) - m2, M2 = x2 + m2, k2 = this.left + u2;
|
|
else if ("x" === e2) {
|
|
if ("center" === a2) x2 = b2((t2.top + t2.bottom) / 2 + 0.5);
|
|
else if (o(a2)) {
|
|
const t3 = Object.keys(a2)[0], e3 = a2[t3];
|
|
x2 = b2(this.chart.scales[t3].getPixelForValue(e3));
|
|
}
|
|
D2 = t2.top, O2 = t2.bottom, w2 = x2 + m2, S2 = w2 + u2;
|
|
} else if ("y" === e2) {
|
|
if ("center" === a2) x2 = b2((t2.left + t2.right) / 2);
|
|
else if (o(a2)) {
|
|
const t3 = Object.keys(a2)[0], e3 = a2[t3];
|
|
x2 = b2(this.chart.scales[t3].getPixelForValue(e3));
|
|
}
|
|
M2 = x2 - m2, k2 = M2 - u2, P2 = t2.left, C2 = t2.right;
|
|
}
|
|
const A2 = l(s2.ticks.maxTicksLimit, d2), T2 = Math.max(1, Math.ceil(d2 / A2));
|
|
for (_2 = 0; _2 < d2; _2 += T2) {
|
|
const t3 = this.getContext(_2), e3 = n2.setContext(t3), s3 = r2.setContext(t3), o2 = e3.lineWidth, a3 = e3.color, l2 = s3.dash || [], d3 = s3.dashOffset, u3 = e3.tickWidth, g3 = e3.tickColor, p3 = e3.tickBorderDash || [], m3 = e3.tickBorderDashOffset;
|
|
y2 = qs(this, _2, h2), void 0 !== y2 && (v2 = Ae(i2, y2, o2), c2 ? M2 = k2 = P2 = C2 = v2 : w2 = S2 = D2 = O2 = v2, f2.push({ tx1: M2, ty1: w2, tx2: k2, ty2: S2, x1: P2, y1: D2, x2: C2, y2: O2, width: o2, color: a3, borderDash: l2, borderDashOffset: d3, tickWidth: u3, tickColor: g3, tickBorderDash: p3, tickBorderDashOffset: m3 }));
|
|
}
|
|
return this._ticksLength = d2, this._borderValue = x2, f2;
|
|
}
|
|
_computeLabelItems(t2) {
|
|
const e2 = this.axis, i2 = this.options, { position: s2, ticks: a2 } = i2, r2 = this.isHorizontal(), l2 = this.ticks, { align: h2, crossAlign: c2, padding: d2, mirror: u2 } = a2, f2 = Ks(i2.grid), g2 = f2 + d2, p2 = u2 ? -d2 : g2, m2 = -$(this.labelRotation), b2 = [];
|
|
let x2, _2, y2, v2, M2, w2, k2, S2, P2, D2, C2, O2, A2 = "middle";
|
|
if ("top" === s2) w2 = this.bottom - p2, k2 = this._getXAxisLabelAlignment();
|
|
else if ("bottom" === s2) w2 = this.top + p2, k2 = this._getXAxisLabelAlignment();
|
|
else if ("left" === s2) {
|
|
const t3 = this._getYAxisLabelAlignment(f2);
|
|
k2 = t3.textAlign, M2 = t3.x;
|
|
} else if ("right" === s2) {
|
|
const t3 = this._getYAxisLabelAlignment(f2);
|
|
k2 = t3.textAlign, M2 = t3.x;
|
|
} else if ("x" === e2) {
|
|
if ("center" === s2) w2 = (t2.top + t2.bottom) / 2 + g2;
|
|
else if (o(s2)) {
|
|
const t3 = Object.keys(s2)[0], e3 = s2[t3];
|
|
w2 = this.chart.scales[t3].getPixelForValue(e3) + g2;
|
|
}
|
|
k2 = this._getXAxisLabelAlignment();
|
|
} else if ("y" === e2) {
|
|
if ("center" === s2) M2 = (t2.left + t2.right) / 2 - g2;
|
|
else if (o(s2)) {
|
|
const t3 = Object.keys(s2)[0], e3 = s2[t3];
|
|
M2 = this.chart.scales[t3].getPixelForValue(e3);
|
|
}
|
|
k2 = this._getYAxisLabelAlignment(f2).textAlign;
|
|
}
|
|
"y" === e2 && ("start" === h2 ? A2 = "top" : "end" === h2 && (A2 = "bottom"));
|
|
const T2 = this._getLabelSizes();
|
|
for (x2 = 0, _2 = l2.length; x2 < _2; ++x2) {
|
|
y2 = l2[x2], v2 = y2.label;
|
|
const t3 = a2.setContext(this.getContext(x2));
|
|
S2 = this.getPixelForTick(x2) + a2.labelOffset, P2 = this._resolveTickFontOptions(x2), D2 = P2.lineHeight, C2 = n(v2) ? v2.length : 1;
|
|
const e3 = C2 / 2, i3 = t3.color, o2 = t3.textStrokeColor, h3 = t3.textStrokeWidth;
|
|
let d3, f3 = k2;
|
|
if (r2 ? (M2 = S2, "inner" === k2 && (f3 = x2 === _2 - 1 ? this.options.reverse ? "left" : "right" : 0 === x2 ? this.options.reverse ? "right" : "left" : "center"), O2 = "top" === s2 ? "near" === c2 || 0 !== m2 ? -C2 * D2 + D2 / 2 : "center" === c2 ? -T2.highest.height / 2 - e3 * D2 + D2 : -T2.highest.height + D2 / 2 : "near" === c2 || 0 !== m2 ? D2 / 2 : "center" === c2 ? T2.highest.height / 2 - e3 * D2 : T2.highest.height - C2 * D2, u2 && (O2 *= -1), 0 === m2 || t3.showLabelBackdrop || (M2 += D2 / 2 * Math.sin(m2))) : (w2 = S2, O2 = (1 - C2) * D2 / 2), t3.showLabelBackdrop) {
|
|
const e4 = ki(t3.backdropPadding), i4 = T2.heights[x2], s3 = T2.widths[x2];
|
|
let n2 = O2 - e4.top, o3 = 0 - e4.left;
|
|
switch (A2) {
|
|
case "middle":
|
|
n2 -= i4 / 2;
|
|
break;
|
|
case "bottom":
|
|
n2 -= i4;
|
|
}
|
|
switch (k2) {
|
|
case "center":
|
|
o3 -= s3 / 2;
|
|
break;
|
|
case "right":
|
|
o3 -= s3;
|
|
break;
|
|
case "inner":
|
|
x2 === _2 - 1 ? o3 -= s3 : x2 > 0 && (o3 -= s3 / 2);
|
|
}
|
|
d3 = { left: o3, top: n2, width: s3 + e4.width, height: i4 + e4.height, color: t3.backdropColor };
|
|
}
|
|
b2.push({ label: v2, font: P2, textOffset: O2, options: { rotation: m2, color: i3, strokeColor: o2, strokeWidth: h3, textAlign: f3, textBaseline: A2, translation: [M2, w2], backdrop: d3 } });
|
|
}
|
|
return b2;
|
|
}
|
|
_getXAxisLabelAlignment() {
|
|
const { position: t2, ticks: e2 } = this.options;
|
|
if (-$(this.labelRotation)) return "top" === t2 ? "left" : "right";
|
|
let i2 = "center";
|
|
return "start" === e2.align ? i2 = "left" : "end" === e2.align ? i2 = "right" : "inner" === e2.align && (i2 = "inner"), i2;
|
|
}
|
|
_getYAxisLabelAlignment(t2) {
|
|
const { position: e2, ticks: { crossAlign: i2, mirror: s2, padding: n2 } } = this.options, o2 = t2 + n2, a2 = this._getLabelSizes().widest.width;
|
|
let r2, l2;
|
|
return "left" === e2 ? s2 ? (l2 = this.right + n2, "near" === i2 ? r2 = "left" : "center" === i2 ? (r2 = "center", l2 += a2 / 2) : (r2 = "right", l2 += a2)) : (l2 = this.right - o2, "near" === i2 ? r2 = "right" : "center" === i2 ? (r2 = "center", l2 -= a2 / 2) : (r2 = "left", l2 = this.left)) : "right" === e2 ? s2 ? (l2 = this.left + n2, "near" === i2 ? r2 = "right" : "center" === i2 ? (r2 = "center", l2 -= a2 / 2) : (r2 = "left", l2 -= a2)) : (l2 = this.left + o2, "near" === i2 ? r2 = "left" : "center" === i2 ? (r2 = "center", l2 += a2 / 2) : (r2 = "right", l2 = this.right)) : r2 = "right", { textAlign: r2, x: l2 };
|
|
}
|
|
_computeLabelArea() {
|
|
if (this.options.ticks.mirror) return;
|
|
const t2 = this.chart, e2 = this.options.position;
|
|
return "left" === e2 || "right" === e2 ? { top: 0, left: this.left, bottom: t2.height, right: this.right } : "top" === e2 || "bottom" === e2 ? { top: this.top, left: 0, bottom: this.bottom, right: t2.width } : void 0;
|
|
}
|
|
drawBackground() {
|
|
const { ctx: t2, options: { backgroundColor: e2 }, left: i2, top: s2, width: n2, height: o2 } = this;
|
|
e2 && (t2.save(), t2.fillStyle = e2, t2.fillRect(i2, s2, n2, o2), t2.restore());
|
|
}
|
|
getLineWidthForValue(t2) {
|
|
const e2 = this.options.grid;
|
|
if (!this._isVisible() || !e2.display) return 0;
|
|
const i2 = this.ticks.findIndex((e3) => e3.value === t2);
|
|
if (i2 >= 0) {
|
|
return e2.setContext(this.getContext(i2)).lineWidth;
|
|
}
|
|
return 0;
|
|
}
|
|
drawGrid(t2) {
|
|
const e2 = this.options.grid, i2 = this.ctx, s2 = this._gridLineItems || (this._gridLineItems = this._computeGridLineItems(t2));
|
|
let n2, o2;
|
|
const a2 = (t3, e3, s3) => {
|
|
s3.width && s3.color && (i2.save(), i2.lineWidth = s3.width, i2.strokeStyle = s3.color, i2.setLineDash(s3.borderDash || []), i2.lineDashOffset = s3.borderDashOffset, i2.beginPath(), i2.moveTo(t3.x, t3.y), i2.lineTo(e3.x, e3.y), i2.stroke(), i2.restore());
|
|
};
|
|
if (e2.display) for (n2 = 0, o2 = s2.length; n2 < o2; ++n2) {
|
|
const t3 = s2[n2];
|
|
e2.drawOnChartArea && a2({ x: t3.x1, y: t3.y1 }, { x: t3.x2, y: t3.y2 }, t3), e2.drawTicks && a2({ x: t3.tx1, y: t3.ty1 }, { x: t3.tx2, y: t3.ty2 }, { color: t3.tickColor, width: t3.tickWidth, borderDash: t3.tickBorderDash, borderDashOffset: t3.tickBorderDashOffset });
|
|
}
|
|
}
|
|
drawBorder() {
|
|
const { chart: t2, ctx: e2, options: { border: i2, grid: s2 } } = this, n2 = i2.setContext(this.getContext()), o2 = i2.display ? n2.width : 0;
|
|
if (!o2) return;
|
|
const a2 = s2.setContext(this.getContext(0)).lineWidth, r2 = this._borderValue;
|
|
let l2, h2, c2, d2;
|
|
this.isHorizontal() ? (l2 = Ae(t2, this.left, o2) - o2 / 2, h2 = Ae(t2, this.right, a2) + a2 / 2, c2 = d2 = r2) : (c2 = Ae(t2, this.top, o2) - o2 / 2, d2 = Ae(t2, this.bottom, a2) + a2 / 2, l2 = h2 = r2), e2.save(), e2.lineWidth = n2.width, e2.strokeStyle = n2.color, e2.beginPath(), e2.moveTo(l2, c2), e2.lineTo(h2, d2), e2.stroke(), e2.restore();
|
|
}
|
|
drawLabels(t2) {
|
|
if (!this.options.ticks.display) return;
|
|
const e2 = this.ctx, i2 = this._computeLabelArea();
|
|
i2 && Ie(e2, i2);
|
|
const s2 = this.getLabelItems(t2);
|
|
for (const t3 of s2) {
|
|
const i3 = t3.options, s3 = t3.font;
|
|
Ne(e2, t3.label, 0, t3.textOffset, s3, i3);
|
|
}
|
|
i2 && ze(e2);
|
|
}
|
|
drawTitle() {
|
|
const { ctx: t2, options: { position: e2, title: i2, reverse: s2 } } = this;
|
|
if (!i2.display) return;
|
|
const a2 = Si(i2.font), r2 = ki(i2.padding), l2 = i2.align;
|
|
let h2 = a2.lineHeight / 2;
|
|
"bottom" === e2 || "center" === e2 || o(e2) ? (h2 += r2.bottom, n(i2.text) && (h2 += a2.lineHeight * (i2.text.length - 1))) : h2 += r2.top;
|
|
const { titleX: c2, titleY: d2, maxWidth: u2, rotation: f2 } = function(t3, e3, i3, s3) {
|
|
const { top: n2, left: a3, bottom: r3, right: l3, chart: h3 } = t3, { chartArea: c3, scales: d3 } = h3;
|
|
let u3, f3, g2, p2 = 0;
|
|
const m2 = r3 - n2, b2 = l3 - a3;
|
|
if (t3.isHorizontal()) {
|
|
if (f3 = ft(s3, a3, l3), o(i3)) {
|
|
const t4 = Object.keys(i3)[0], s4 = i3[t4];
|
|
g2 = d3[t4].getPixelForValue(s4) + m2 - e3;
|
|
} else g2 = "center" === i3 ? (c3.bottom + c3.top) / 2 + m2 - e3 : Ys(t3, i3, e3);
|
|
u3 = l3 - a3;
|
|
} else {
|
|
if (o(i3)) {
|
|
const t4 = Object.keys(i3)[0], s4 = i3[t4];
|
|
f3 = d3[t4].getPixelForValue(s4) - b2 + e3;
|
|
} else f3 = "center" === i3 ? (c3.left + c3.right) / 2 - b2 + e3 : Ys(t3, i3, e3);
|
|
g2 = ft(s3, r3, n2), p2 = "left" === i3 ? -E : E;
|
|
}
|
|
return { titleX: f3, titleY: g2, maxWidth: u3, rotation: p2 };
|
|
}(this, h2, e2, l2);
|
|
Ne(t2, i2.text, 0, 0, a2, { color: i2.color, maxWidth: u2, rotation: f2, textAlign: Zs(l2, e2, s2), textBaseline: "middle", translation: [c2, d2] });
|
|
}
|
|
draw(t2) {
|
|
this._isVisible() && (this.drawBackground(), this.drawGrid(t2), this.drawBorder(), this.drawTitle(), this.drawLabels(t2));
|
|
}
|
|
_layers() {
|
|
const t2 = this.options, e2 = t2.ticks && t2.ticks.z || 0, i2 = l(t2.grid && t2.grid.z, -1), s2 = l(t2.border && t2.border.z, 0);
|
|
return this._isVisible() && this.draw === Js.prototype.draw ? [{ z: i2, draw: (t3) => {
|
|
this.drawBackground(), this.drawGrid(t3), this.drawTitle();
|
|
} }, { z: s2, draw: () => {
|
|
this.drawBorder();
|
|
} }, { z: e2, draw: (t3) => {
|
|
this.drawLabels(t3);
|
|
} }] : [{ z: e2, draw: (t3) => {
|
|
this.draw(t3);
|
|
} }];
|
|
}
|
|
getMatchingVisibleMetas(t2) {
|
|
const e2 = this.chart.getSortedVisibleDatasetMetas(), i2 = this.axis + "AxisID", s2 = [];
|
|
let n2, o2;
|
|
for (n2 = 0, o2 = e2.length; n2 < o2; ++n2) {
|
|
const o3 = e2[n2];
|
|
o3[i2] !== this.id || t2 && o3.type !== t2 || s2.push(o3);
|
|
}
|
|
return s2;
|
|
}
|
|
_resolveTickFontOptions(t2) {
|
|
return Si(this.options.ticks.setContext(this.getContext(t2)).font);
|
|
}
|
|
_maxDigits() {
|
|
const t2 = this._resolveTickFontOptions(0).lineHeight;
|
|
return (this.isHorizontal() ? this.width : this.height) / t2;
|
|
}
|
|
}
|
|
class Qs {
|
|
constructor(t2, e2, i2) {
|
|
this.type = t2, this.scope = e2, this.override = i2, this.items = /* @__PURE__ */ Object.create(null);
|
|
}
|
|
isForType(t2) {
|
|
return Object.prototype.isPrototypeOf.call(this.type.prototype, t2.prototype);
|
|
}
|
|
register(t2) {
|
|
const e2 = Object.getPrototypeOf(t2);
|
|
let i2;
|
|
(function(t3) {
|
|
return "id" in t3 && "defaults" in t3;
|
|
})(e2) && (i2 = this.register(e2));
|
|
const s2 = this.items, n2 = t2.id, o2 = this.scope + "." + n2;
|
|
if (!n2) throw new Error("class does not have id: " + t2);
|
|
return n2 in s2 || (s2[n2] = t2, function(t3, e3, i3) {
|
|
const s3 = b(/* @__PURE__ */ Object.create(null), [i3 ? ue.get(i3) : {}, ue.get(e3), t3.defaults]);
|
|
ue.set(e3, s3), t3.defaultRoutes && function(t4, e4) {
|
|
Object.keys(e4).forEach((i4) => {
|
|
const s4 = i4.split("."), n3 = s4.pop(), o3 = [t4].concat(s4).join("."), a2 = e4[i4].split("."), r2 = a2.pop(), l2 = a2.join(".");
|
|
ue.route(o3, n3, l2, r2);
|
|
});
|
|
}(e3, t3.defaultRoutes);
|
|
t3.descriptors && ue.describe(e3, t3.descriptors);
|
|
}(t2, o2, i2), this.override && ue.override(t2.id, t2.overrides)), o2;
|
|
}
|
|
get(t2) {
|
|
return this.items[t2];
|
|
}
|
|
unregister(t2) {
|
|
const e2 = this.items, i2 = t2.id, s2 = this.scope;
|
|
i2 in e2 && delete e2[i2], s2 && i2 in ue[s2] && (delete ue[s2][i2], this.override && delete re[i2]);
|
|
}
|
|
}
|
|
class tn {
|
|
constructor() {
|
|
this.controllers = new Qs(Ns, "datasets", true), this.elements = new Qs(Hs, "elements"), this.plugins = new Qs(Object, "plugins"), this.scales = new Qs(Js, "scales"), this._typedRegistries = [this.controllers, this.scales, this.elements];
|
|
}
|
|
add(...t2) {
|
|
this._each("register", t2);
|
|
}
|
|
remove(...t2) {
|
|
this._each("unregister", t2);
|
|
}
|
|
addControllers(...t2) {
|
|
this._each("register", t2, this.controllers);
|
|
}
|
|
addElements(...t2) {
|
|
this._each("register", t2, this.elements);
|
|
}
|
|
addPlugins(...t2) {
|
|
this._each("register", t2, this.plugins);
|
|
}
|
|
addScales(...t2) {
|
|
this._each("register", t2, this.scales);
|
|
}
|
|
getController(t2) {
|
|
return this._get(t2, this.controllers, "controller");
|
|
}
|
|
getElement(t2) {
|
|
return this._get(t2, this.elements, "element");
|
|
}
|
|
getPlugin(t2) {
|
|
return this._get(t2, this.plugins, "plugin");
|
|
}
|
|
getScale(t2) {
|
|
return this._get(t2, this.scales, "scale");
|
|
}
|
|
removeControllers(...t2) {
|
|
this._each("unregister", t2, this.controllers);
|
|
}
|
|
removeElements(...t2) {
|
|
this._each("unregister", t2, this.elements);
|
|
}
|
|
removePlugins(...t2) {
|
|
this._each("unregister", t2, this.plugins);
|
|
}
|
|
removeScales(...t2) {
|
|
this._each("unregister", t2, this.scales);
|
|
}
|
|
_each(t2, e2, i2) {
|
|
[...e2].forEach((e3) => {
|
|
const s2 = i2 || this._getRegistryForType(e3);
|
|
i2 || s2.isForType(e3) || s2 === this.plugins && e3.id ? this._exec(t2, s2, e3) : u(e3, (e4) => {
|
|
const s3 = i2 || this._getRegistryForType(e4);
|
|
this._exec(t2, s3, e4);
|
|
});
|
|
});
|
|
}
|
|
_exec(t2, e2, i2) {
|
|
const s2 = w(t2);
|
|
d(i2["before" + s2], [], i2), e2[t2](i2), d(i2["after" + s2], [], i2);
|
|
}
|
|
_getRegistryForType(t2) {
|
|
for (let e2 = 0; e2 < this._typedRegistries.length; e2++) {
|
|
const i2 = this._typedRegistries[e2];
|
|
if (i2.isForType(t2)) return i2;
|
|
}
|
|
return this.plugins;
|
|
}
|
|
_get(t2, e2, i2) {
|
|
const s2 = e2.get(t2);
|
|
if (void 0 === s2) throw new Error('"' + t2 + '" is not a registered ' + i2 + ".");
|
|
return s2;
|
|
}
|
|
}
|
|
var en = new tn();
|
|
class sn {
|
|
constructor() {
|
|
this._init = [];
|
|
}
|
|
notify(t2, e2, i2, s2) {
|
|
"beforeInit" === e2 && (this._init = this._createDescriptors(t2, true), this._notify(this._init, t2, "install"));
|
|
const n2 = s2 ? this._descriptors(t2).filter(s2) : this._descriptors(t2), o2 = this._notify(n2, t2, e2, i2);
|
|
return "afterDestroy" === e2 && (this._notify(n2, t2, "stop"), this._notify(this._init, t2, "uninstall")), o2;
|
|
}
|
|
_notify(t2, e2, i2, s2) {
|
|
s2 = s2 || {};
|
|
for (const n2 of t2) {
|
|
const t3 = n2.plugin;
|
|
if (false === d(t3[i2], [e2, s2, n2.options], t3) && s2.cancelable) return false;
|
|
}
|
|
return true;
|
|
}
|
|
invalidate() {
|
|
s(this._cache) || (this._oldCache = this._cache, this._cache = void 0);
|
|
}
|
|
_descriptors(t2) {
|
|
if (this._cache) return this._cache;
|
|
const e2 = this._cache = this._createDescriptors(t2);
|
|
return this._notifyStateChanges(t2), e2;
|
|
}
|
|
_createDescriptors(t2, e2) {
|
|
const i2 = t2 && t2.config, s2 = l(i2.options && i2.options.plugins, {}), n2 = function(t3) {
|
|
const e3 = {}, i3 = [], s3 = Object.keys(en.plugins.items);
|
|
for (let t4 = 0; t4 < s3.length; t4++) i3.push(en.getPlugin(s3[t4]));
|
|
const n3 = t3.plugins || [];
|
|
for (let t4 = 0; t4 < n3.length; t4++) {
|
|
const s4 = n3[t4];
|
|
-1 === i3.indexOf(s4) && (i3.push(s4), e3[s4.id] = true);
|
|
}
|
|
return { plugins: i3, localIds: e3 };
|
|
}(i2);
|
|
return false !== s2 || e2 ? function(t3, { plugins: e3, localIds: i3 }, s3, n3) {
|
|
const o2 = [], a2 = t3.getContext();
|
|
for (const r2 of e3) {
|
|
const e4 = r2.id, l2 = nn(s3[e4], n3);
|
|
null !== l2 && o2.push({ plugin: r2, options: on(t3.config, { plugin: r2, local: i3[e4] }, l2, a2) });
|
|
}
|
|
return o2;
|
|
}(t2, n2, s2, e2) : [];
|
|
}
|
|
_notifyStateChanges(t2) {
|
|
const e2 = this._oldCache || [], i2 = this._cache, s2 = (t3, e3) => t3.filter((t4) => !e3.some((e4) => t4.plugin.id === e4.plugin.id));
|
|
this._notify(s2(e2, i2), t2, "stop"), this._notify(s2(i2, e2), t2, "start");
|
|
}
|
|
}
|
|
function nn(t2, e2) {
|
|
return e2 || false !== t2 ? true === t2 ? {} : t2 : null;
|
|
}
|
|
function on(t2, { plugin: e2, local: i2 }, s2, n2) {
|
|
const o2 = t2.pluginScopeKeys(e2), a2 = t2.getOptionScopes(s2, o2);
|
|
return i2 && e2.defaults && a2.push(e2.defaults), t2.createResolver(a2, n2, [""], { scriptable: false, indexable: false, allKeys: true });
|
|
}
|
|
function an(t2, e2) {
|
|
const i2 = ue.datasets[t2] || {};
|
|
return ((e2.datasets || {})[t2] || {}).indexAxis || e2.indexAxis || i2.indexAxis || "x";
|
|
}
|
|
function rn(t2) {
|
|
if ("x" === t2 || "y" === t2 || "r" === t2) return t2;
|
|
}
|
|
function ln(t2, ...e2) {
|
|
if (rn(t2)) return t2;
|
|
for (const s2 of e2) {
|
|
const e3 = s2.axis || ("top" === (i2 = s2.position) || "bottom" === i2 ? "x" : "left" === i2 || "right" === i2 ? "y" : void 0) || t2.length > 1 && rn(t2[0].toLowerCase());
|
|
if (e3) return e3;
|
|
}
|
|
var i2;
|
|
throw new Error(`Cannot determine type of '${t2}' axis. Please provide 'axis' or 'position' option.`);
|
|
}
|
|
function hn(t2, e2, i2) {
|
|
if (i2[e2 + "AxisID"] === t2) return { axis: e2 };
|
|
}
|
|
function cn(t2, e2) {
|
|
const i2 = re[t2.type] || { scales: {} }, s2 = e2.scales || {}, n2 = an(t2.type, e2), a2 = /* @__PURE__ */ Object.create(null);
|
|
return Object.keys(s2).forEach((e3) => {
|
|
const r2 = s2[e3];
|
|
if (!o(r2)) return console.error(`Invalid scale configuration for scale: ${e3}`);
|
|
if (r2._proxy) return console.warn(`Ignoring resolver passed as options for scale: ${e3}`);
|
|
const l2 = ln(e3, r2, function(t3, e4) {
|
|
if (e4.data && e4.data.datasets) {
|
|
const i3 = e4.data.datasets.filter((e5) => e5.xAxisID === t3 || e5.yAxisID === t3);
|
|
if (i3.length) return hn(t3, "x", i3[0]) || hn(t3, "y", i3[0]);
|
|
}
|
|
return {};
|
|
}(e3, t2), ue.scales[r2.type]), h2 = /* @__PURE__ */ function(t3, e4) {
|
|
return t3 === e4 ? "_index_" : "_value_";
|
|
}(l2, n2), c2 = i2.scales || {};
|
|
a2[e3] = x(/* @__PURE__ */ Object.create(null), [{ axis: l2 }, r2, c2[l2], c2[h2]]);
|
|
}), t2.data.datasets.forEach((i3) => {
|
|
const n3 = i3.type || t2.type, o2 = i3.indexAxis || an(n3, e2), r2 = (re[n3] || {}).scales || {};
|
|
Object.keys(r2).forEach((t3) => {
|
|
const e3 = function(t4, e4) {
|
|
let i4 = t4;
|
|
return "_index_" === t4 ? i4 = e4 : "_value_" === t4 && (i4 = "x" === e4 ? "y" : "x"), i4;
|
|
}(t3, o2), n4 = i3[e3 + "AxisID"] || e3;
|
|
a2[n4] = a2[n4] || /* @__PURE__ */ Object.create(null), x(a2[n4], [{ axis: e3 }, s2[n4], r2[t3]]);
|
|
});
|
|
}), Object.keys(a2).forEach((t3) => {
|
|
const e3 = a2[t3];
|
|
x(e3, [ue.scales[e3.type], ue.scale]);
|
|
}), a2;
|
|
}
|
|
function dn(t2) {
|
|
const e2 = t2.options || (t2.options = {});
|
|
e2.plugins = l(e2.plugins, {}), e2.scales = cn(t2, e2);
|
|
}
|
|
function un(t2) {
|
|
return (t2 = t2 || {}).datasets = t2.datasets || [], t2.labels = t2.labels || [], t2;
|
|
}
|
|
const fn = /* @__PURE__ */ new Map(), gn = /* @__PURE__ */ new Set();
|
|
function pn(t2, e2) {
|
|
let i2 = fn.get(t2);
|
|
return i2 || (i2 = e2(), fn.set(t2, i2), gn.add(i2)), i2;
|
|
}
|
|
const mn = (t2, e2, i2) => {
|
|
const s2 = M(e2, i2);
|
|
void 0 !== s2 && t2.add(s2);
|
|
};
|
|
class bn {
|
|
constructor(t2) {
|
|
this._config = function(t3) {
|
|
return (t3 = t3 || {}).data = un(t3.data), dn(t3), t3;
|
|
}(t2), this._scopeCache = /* @__PURE__ */ new Map(), this._resolverCache = /* @__PURE__ */ new Map();
|
|
}
|
|
get platform() {
|
|
return this._config.platform;
|
|
}
|
|
get type() {
|
|
return this._config.type;
|
|
}
|
|
set type(t2) {
|
|
this._config.type = t2;
|
|
}
|
|
get data() {
|
|
return this._config.data;
|
|
}
|
|
set data(t2) {
|
|
this._config.data = un(t2);
|
|
}
|
|
get options() {
|
|
return this._config.options;
|
|
}
|
|
set options(t2) {
|
|
this._config.options = t2;
|
|
}
|
|
get plugins() {
|
|
return this._config.plugins;
|
|
}
|
|
update() {
|
|
const t2 = this._config;
|
|
this.clearCache(), dn(t2);
|
|
}
|
|
clearCache() {
|
|
this._scopeCache.clear(), this._resolverCache.clear();
|
|
}
|
|
datasetScopeKeys(t2) {
|
|
return pn(t2, () => [[`datasets.${t2}`, ""]]);
|
|
}
|
|
datasetAnimationScopeKeys(t2, e2) {
|
|
return pn(`${t2}.transition.${e2}`, () => [[`datasets.${t2}.transitions.${e2}`, `transitions.${e2}`], [`datasets.${t2}`, ""]]);
|
|
}
|
|
datasetElementScopeKeys(t2, e2) {
|
|
return pn(`${t2}-${e2}`, () => [[`datasets.${t2}.elements.${e2}`, `datasets.${t2}`, `elements.${e2}`, ""]]);
|
|
}
|
|
pluginScopeKeys(t2) {
|
|
const e2 = t2.id;
|
|
return pn(`${this.type}-plugin-${e2}`, () => [[`plugins.${e2}`, ...t2.additionalOptionScopes || []]]);
|
|
}
|
|
_cachedScopes(t2, e2) {
|
|
const i2 = this._scopeCache;
|
|
let s2 = i2.get(t2);
|
|
return s2 && !e2 || (s2 = /* @__PURE__ */ new Map(), i2.set(t2, s2)), s2;
|
|
}
|
|
getOptionScopes(t2, e2, i2) {
|
|
const { options: s2, type: n2 } = this, o2 = this._cachedScopes(t2, i2), a2 = o2.get(e2);
|
|
if (a2) return a2;
|
|
const r2 = /* @__PURE__ */ new Set();
|
|
e2.forEach((e3) => {
|
|
t2 && (r2.add(t2), e3.forEach((e4) => mn(r2, t2, e4))), e3.forEach((t3) => mn(r2, s2, t3)), e3.forEach((t3) => mn(r2, re[n2] || {}, t3)), e3.forEach((t3) => mn(r2, ue, t3)), e3.forEach((t3) => mn(r2, le, t3));
|
|
});
|
|
const l2 = Array.from(r2);
|
|
return 0 === l2.length && l2.push(/* @__PURE__ */ Object.create(null)), gn.has(e2) && o2.set(e2, l2), l2;
|
|
}
|
|
chartOptionScopes() {
|
|
const { options: t2, type: e2 } = this;
|
|
return [t2, re[e2] || {}, ue.datasets[e2] || {}, { type: e2 }, ue, le];
|
|
}
|
|
resolveNamedOptions(t2, e2, i2, s2 = [""]) {
|
|
const o2 = { $shared: true }, { resolver: a2, subPrefixes: r2 } = xn(this._resolverCache, t2, s2);
|
|
let l2 = a2;
|
|
if (function(t3, e3) {
|
|
const { isScriptable: i3, isIndexable: s3 } = Ye(t3);
|
|
for (const o3 of e3) {
|
|
const e4 = i3(o3), a3 = s3(o3), r3 = (a3 || e4) && t3[o3];
|
|
if (e4 && (S(r3) || _n(r3)) || a3 && n(r3)) return true;
|
|
}
|
|
return false;
|
|
}(a2, e2)) {
|
|
o2.$shared = false;
|
|
l2 = $e(a2, i2 = S(i2) ? i2() : i2, this.createResolver(t2, i2, r2));
|
|
}
|
|
for (const t3 of e2) o2[t3] = l2[t3];
|
|
return o2;
|
|
}
|
|
createResolver(t2, e2, i2 = [""], s2) {
|
|
const { resolver: n2 } = xn(this._resolverCache, t2, i2);
|
|
return o(e2) ? $e(n2, e2, void 0, s2) : n2;
|
|
}
|
|
}
|
|
function xn(t2, e2, i2) {
|
|
let s2 = t2.get(e2);
|
|
s2 || (s2 = /* @__PURE__ */ new Map(), t2.set(e2, s2));
|
|
const n2 = i2.join();
|
|
let o2 = s2.get(n2);
|
|
if (!o2) {
|
|
o2 = { resolver: je(e2, i2), subPrefixes: i2.filter((t3) => !t3.toLowerCase().includes("hover")) }, s2.set(n2, o2);
|
|
}
|
|
return o2;
|
|
}
|
|
const _n = (t2) => o(t2) && Object.getOwnPropertyNames(t2).some((e2) => S(t2[e2]));
|
|
const yn = ["top", "bottom", "left", "right", "chartArea"];
|
|
function vn(t2, e2) {
|
|
return "top" === t2 || "bottom" === t2 || -1 === yn.indexOf(t2) && "x" === e2;
|
|
}
|
|
function Mn(t2, e2) {
|
|
return function(i2, s2) {
|
|
return i2[t2] === s2[t2] ? i2[e2] - s2[e2] : i2[t2] - s2[t2];
|
|
};
|
|
}
|
|
function wn(t2) {
|
|
const e2 = t2.chart, i2 = e2.options.animation;
|
|
e2.notifyPlugins("afterRender"), d(i2 && i2.onComplete, [t2], e2);
|
|
}
|
|
function kn(t2) {
|
|
const e2 = t2.chart, i2 = e2.options.animation;
|
|
d(i2 && i2.onProgress, [t2], e2);
|
|
}
|
|
function Sn(t2) {
|
|
return fe() && "string" == typeof t2 ? t2 = document.getElementById(t2) : t2 && t2.length && (t2 = t2[0]), t2 && t2.canvas && (t2 = t2.canvas), t2;
|
|
}
|
|
const Pn = {}, Dn = (t2) => {
|
|
const e2 = Sn(t2);
|
|
return Object.values(Pn).filter((t3) => t3.canvas === e2).pop();
|
|
};
|
|
function Cn(t2, e2, i2) {
|
|
const s2 = Object.keys(t2);
|
|
for (const n2 of s2) {
|
|
const s3 = +n2;
|
|
if (s3 >= e2) {
|
|
const o2 = t2[n2];
|
|
delete t2[n2], (i2 > 0 || s3 > e2) && (t2[s3 + i2] = o2);
|
|
}
|
|
}
|
|
}
|
|
function On(t2, e2, i2) {
|
|
return t2.options.clip ? t2[i2] : e2[i2];
|
|
}
|
|
class An {
|
|
static register(...t2) {
|
|
en.add(...t2), Tn();
|
|
}
|
|
static unregister(...t2) {
|
|
en.remove(...t2), Tn();
|
|
}
|
|
constructor(t2, e2) {
|
|
const s2 = this.config = new bn(e2), n2 = Sn(t2), o2 = Dn(n2);
|
|
if (o2) throw new Error("Canvas is already in use. Chart with ID '" + o2.id + "' must be destroyed before the canvas with ID '" + o2.canvas.id + "' can be reused.");
|
|
const a2 = s2.createResolver(s2.chartOptionScopes(), this.getContext());
|
|
this.platform = new (s2.platform || ks(n2))(), this.platform.updateConfig(s2);
|
|
const r2 = this.platform.acquireContext(n2, a2.aspectRatio), l2 = r2 && r2.canvas, h2 = l2 && l2.height, c2 = l2 && l2.width;
|
|
this.id = i(), this.ctx = r2, this.canvas = l2, this.width = c2, this.height = h2, this._options = a2, this._aspectRatio = this.aspectRatio, this._layers = [], this._metasets = [], this._stacks = void 0, this.boxes = [], this.currentDevicePixelRatio = void 0, this.chartArea = void 0, this._active = [], this._lastEvent = void 0, this._listeners = {}, this._responsiveListeners = void 0, this._sortedMetasets = [], this.scales = {}, this._plugins = new sn(), this.$proxies = {}, this._hiddenIndices = {}, this.attached = false, this._animationsDisabled = void 0, this.$context = void 0, this._doResize = dt((t3) => this.update(t3), a2.resizeDelay || 0), this._dataChanges = [], Pn[this.id] = this, r2 && l2 ? (xt.listen(this, "complete", wn), xt.listen(this, "progress", kn), this._initialize(), this.attached && this.update()) : console.error("Failed to create chart: can't acquire context from the given item");
|
|
}
|
|
get aspectRatio() {
|
|
const { options: { aspectRatio: t2, maintainAspectRatio: e2 }, width: i2, height: n2, _aspectRatio: o2 } = this;
|
|
return s(t2) ? e2 && o2 ? o2 : n2 ? i2 / n2 : null : t2;
|
|
}
|
|
get data() {
|
|
return this.config.data;
|
|
}
|
|
set data(t2) {
|
|
this.config.data = t2;
|
|
}
|
|
get options() {
|
|
return this._options;
|
|
}
|
|
set options(t2) {
|
|
this.config.options = t2;
|
|
}
|
|
get registry() {
|
|
return en;
|
|
}
|
|
_initialize() {
|
|
return this.notifyPlugins("beforeInit"), this.options.responsive ? this.resize() : ke(this, this.options.devicePixelRatio), this.bindEvents(), this.notifyPlugins("afterInit"), this;
|
|
}
|
|
clear() {
|
|
return Te(this.canvas, this.ctx), this;
|
|
}
|
|
stop() {
|
|
return xt.stop(this), this;
|
|
}
|
|
resize(t2, e2) {
|
|
xt.running(this) ? this._resizeBeforeDraw = { width: t2, height: e2 } : this._resize(t2, e2);
|
|
}
|
|
_resize(t2, e2) {
|
|
const i2 = this.options, s2 = this.canvas, n2 = i2.maintainAspectRatio && this.aspectRatio, o2 = this.platform.getMaximumSize(s2, t2, e2, n2), a2 = i2.devicePixelRatio || this.platform.getDevicePixelRatio(), r2 = this.width ? "resize" : "attach";
|
|
this.width = o2.width, this.height = o2.height, this._aspectRatio = this.aspectRatio, ke(this, a2, true) && (this.notifyPlugins("resize", { size: o2 }), d(i2.onResize, [this, o2], this), this.attached && this._doResize(r2) && this.render());
|
|
}
|
|
ensureScalesHaveIDs() {
|
|
u(this.options.scales || {}, (t2, e2) => {
|
|
t2.id = e2;
|
|
});
|
|
}
|
|
buildOrUpdateScales() {
|
|
const t2 = this.options, e2 = t2.scales, i2 = this.scales, s2 = Object.keys(i2).reduce((t3, e3) => (t3[e3] = false, t3), {});
|
|
let n2 = [];
|
|
e2 && (n2 = n2.concat(Object.keys(e2).map((t3) => {
|
|
const i3 = e2[t3], s3 = ln(t3, i3), n3 = "r" === s3, o2 = "x" === s3;
|
|
return { options: i3, dposition: n3 ? "chartArea" : o2 ? "bottom" : "left", dtype: n3 ? "radialLinear" : o2 ? "category" : "linear" };
|
|
}))), u(n2, (e3) => {
|
|
const n3 = e3.options, o2 = n3.id, a2 = ln(o2, n3), r2 = l(n3.type, e3.dtype);
|
|
void 0 !== n3.position && vn(n3.position, a2) === vn(e3.dposition) || (n3.position = e3.dposition), s2[o2] = true;
|
|
let h2 = null;
|
|
if (o2 in i2 && i2[o2].type === r2) h2 = i2[o2];
|
|
else {
|
|
h2 = new (en.getScale(r2))({ id: o2, type: r2, ctx: this.ctx, chart: this }), i2[h2.id] = h2;
|
|
}
|
|
h2.init(n3, t2);
|
|
}), u(s2, (t3, e3) => {
|
|
t3 || delete i2[e3];
|
|
}), u(i2, (t3) => {
|
|
as.configure(this, t3, t3.options), as.addBox(this, t3);
|
|
});
|
|
}
|
|
_updateMetasets() {
|
|
const t2 = this._metasets, e2 = this.data.datasets.length, i2 = t2.length;
|
|
if (t2.sort((t3, e3) => t3.index - e3.index), i2 > e2) {
|
|
for (let t3 = e2; t3 < i2; ++t3) this._destroyDatasetMeta(t3);
|
|
t2.splice(e2, i2 - e2);
|
|
}
|
|
this._sortedMetasets = t2.slice(0).sort(Mn("order", "index"));
|
|
}
|
|
_removeUnreferencedMetasets() {
|
|
const { _metasets: t2, data: { datasets: e2 } } = this;
|
|
t2.length > e2.length && delete this._stacks, t2.forEach((t3, i2) => {
|
|
0 === e2.filter((e3) => e3 === t3._dataset).length && this._destroyDatasetMeta(i2);
|
|
});
|
|
}
|
|
buildOrUpdateControllers() {
|
|
const t2 = [], e2 = this.data.datasets;
|
|
let i2, s2;
|
|
for (this._removeUnreferencedMetasets(), i2 = 0, s2 = e2.length; i2 < s2; i2++) {
|
|
const s3 = e2[i2];
|
|
let n2 = this.getDatasetMeta(i2);
|
|
const o2 = s3.type || this.config.type;
|
|
if (n2.type && n2.type !== o2 && (this._destroyDatasetMeta(i2), n2 = this.getDatasetMeta(i2)), n2.type = o2, n2.indexAxis = s3.indexAxis || an(o2, this.options), n2.order = s3.order || 0, n2.index = i2, n2.label = "" + s3.label, n2.visible = this.isDatasetVisible(i2), n2.controller) n2.controller.updateIndex(i2), n2.controller.linkScales();
|
|
else {
|
|
const e3 = en.getController(o2), { datasetElementType: s4, dataElementType: a2 } = ue.datasets[o2];
|
|
Object.assign(e3, { dataElementType: en.getElement(a2), datasetElementType: s4 && en.getElement(s4) }), n2.controller = new e3(this, i2), t2.push(n2.controller);
|
|
}
|
|
}
|
|
return this._updateMetasets(), t2;
|
|
}
|
|
_resetElements() {
|
|
u(this.data.datasets, (t2, e2) => {
|
|
this.getDatasetMeta(e2).controller.reset();
|
|
}, this);
|
|
}
|
|
reset() {
|
|
this._resetElements(), this.notifyPlugins("reset");
|
|
}
|
|
update(t2) {
|
|
const e2 = this.config;
|
|
e2.update();
|
|
const i2 = this._options = e2.createResolver(e2.chartOptionScopes(), this.getContext()), s2 = this._animationsDisabled = !i2.animation;
|
|
if (this._updateScales(), this._checkEventBindings(), this._updateHiddenIndices(), this._plugins.invalidate(), false === this.notifyPlugins("beforeUpdate", { mode: t2, cancelable: true })) return;
|
|
const n2 = this.buildOrUpdateControllers();
|
|
this.notifyPlugins("beforeElementsUpdate");
|
|
let o2 = 0;
|
|
for (let t3 = 0, e3 = this.data.datasets.length; t3 < e3; t3++) {
|
|
const { controller: e4 } = this.getDatasetMeta(t3), i3 = !s2 && -1 === n2.indexOf(e4);
|
|
e4.buildOrUpdateElements(i3), o2 = Math.max(+e4.getMaxOverflow(), o2);
|
|
}
|
|
o2 = this._minPadding = i2.layout.autoPadding ? o2 : 0, this._updateLayout(o2), s2 || u(n2, (t3) => {
|
|
t3.reset();
|
|
}), this._updateDatasets(t2), this.notifyPlugins("afterUpdate", { mode: t2 }), this._layers.sort(Mn("z", "_idx"));
|
|
const { _active: a2, _lastEvent: r2 } = this;
|
|
r2 ? this._eventHandler(r2, true) : a2.length && this._updateHoverStyles(a2, a2, true), this.render();
|
|
}
|
|
_updateScales() {
|
|
u(this.scales, (t2) => {
|
|
as.removeBox(this, t2);
|
|
}), this.ensureScalesHaveIDs(), this.buildOrUpdateScales();
|
|
}
|
|
_checkEventBindings() {
|
|
const t2 = this.options, e2 = new Set(Object.keys(this._listeners)), i2 = new Set(t2.events);
|
|
P(e2, i2) && !!this._responsiveListeners === t2.responsive || (this.unbindEvents(), this.bindEvents());
|
|
}
|
|
_updateHiddenIndices() {
|
|
const { _hiddenIndices: t2 } = this, e2 = this._getUniformDataChanges() || [];
|
|
for (const { method: i2, start: s2, count: n2 } of e2) {
|
|
Cn(t2, s2, "_removeElements" === i2 ? -n2 : n2);
|
|
}
|
|
}
|
|
_getUniformDataChanges() {
|
|
const t2 = this._dataChanges;
|
|
if (!t2 || !t2.length) return;
|
|
this._dataChanges = [];
|
|
const e2 = this.data.datasets.length, i2 = (e3) => new Set(t2.filter((t3) => t3[0] === e3).map((t3, e4) => e4 + "," + t3.splice(1).join(","))), s2 = i2(0);
|
|
for (let t3 = 1; t3 < e2; t3++) if (!P(s2, i2(t3))) return;
|
|
return Array.from(s2).map((t3) => t3.split(",")).map((t3) => ({ method: t3[1], start: +t3[2], count: +t3[3] }));
|
|
}
|
|
_updateLayout(t2) {
|
|
if (false === this.notifyPlugins("beforeLayout", { cancelable: true })) return;
|
|
as.update(this, this.width, this.height, t2);
|
|
const e2 = this.chartArea, i2 = e2.width <= 0 || e2.height <= 0;
|
|
this._layers = [], u(this.boxes, (t3) => {
|
|
i2 && "chartArea" === t3.position || (t3.configure && t3.configure(), this._layers.push(...t3._layers()));
|
|
}, this), this._layers.forEach((t3, e3) => {
|
|
t3._idx = e3;
|
|
}), this.notifyPlugins("afterLayout");
|
|
}
|
|
_updateDatasets(t2) {
|
|
if (false !== this.notifyPlugins("beforeDatasetsUpdate", { mode: t2, cancelable: true })) {
|
|
for (let t3 = 0, e2 = this.data.datasets.length; t3 < e2; ++t3) this.getDatasetMeta(t3).controller.configure();
|
|
for (let e2 = 0, i2 = this.data.datasets.length; e2 < i2; ++e2) this._updateDataset(e2, S(t2) ? t2({ datasetIndex: e2 }) : t2);
|
|
this.notifyPlugins("afterDatasetsUpdate", { mode: t2 });
|
|
}
|
|
}
|
|
_updateDataset(t2, e2) {
|
|
const i2 = this.getDatasetMeta(t2), s2 = { meta: i2, index: t2, mode: e2, cancelable: true };
|
|
false !== this.notifyPlugins("beforeDatasetUpdate", s2) && (i2.controller._update(e2), s2.cancelable = false, this.notifyPlugins("afterDatasetUpdate", s2));
|
|
}
|
|
render() {
|
|
false !== this.notifyPlugins("beforeRender", { cancelable: true }) && (xt.has(this) ? this.attached && !xt.running(this) && xt.start(this) : (this.draw(), wn({ chart: this })));
|
|
}
|
|
draw() {
|
|
let t2;
|
|
if (this._resizeBeforeDraw) {
|
|
const { width: t3, height: e3 } = this._resizeBeforeDraw;
|
|
this._resize(t3, e3), this._resizeBeforeDraw = null;
|
|
}
|
|
if (this.clear(), this.width <= 0 || this.height <= 0) return;
|
|
if (false === this.notifyPlugins("beforeDraw", { cancelable: true })) return;
|
|
const e2 = this._layers;
|
|
for (t2 = 0; t2 < e2.length && e2[t2].z <= 0; ++t2) e2[t2].draw(this.chartArea);
|
|
for (this._drawDatasets(); t2 < e2.length; ++t2) e2[t2].draw(this.chartArea);
|
|
this.notifyPlugins("afterDraw");
|
|
}
|
|
_getSortedDatasetMetas(t2) {
|
|
const e2 = this._sortedMetasets, i2 = [];
|
|
let s2, n2;
|
|
for (s2 = 0, n2 = e2.length; s2 < n2; ++s2) {
|
|
const n3 = e2[s2];
|
|
t2 && !n3.visible || i2.push(n3);
|
|
}
|
|
return i2;
|
|
}
|
|
getSortedVisibleDatasetMetas() {
|
|
return this._getSortedDatasetMetas(true);
|
|
}
|
|
_drawDatasets() {
|
|
if (false === this.notifyPlugins("beforeDatasetsDraw", { cancelable: true })) return;
|
|
const t2 = this.getSortedVisibleDatasetMetas();
|
|
for (let e2 = t2.length - 1; e2 >= 0; --e2) this._drawDataset(t2[e2]);
|
|
this.notifyPlugins("afterDatasetsDraw");
|
|
}
|
|
_drawDataset(t2) {
|
|
const e2 = this.ctx, i2 = t2._clip, s2 = !i2.disabled, n2 = function(t3, e3) {
|
|
const { xScale: i3, yScale: s3 } = t3;
|
|
return i3 && s3 ? { left: On(i3, e3, "left"), right: On(i3, e3, "right"), top: On(s3, e3, "top"), bottom: On(s3, e3, "bottom") } : e3;
|
|
}(t2, this.chartArea), o2 = { meta: t2, index: t2.index, cancelable: true };
|
|
false !== this.notifyPlugins("beforeDatasetDraw", o2) && (s2 && Ie(e2, { left: false === i2.left ? 0 : n2.left - i2.left, right: false === i2.right ? this.width : n2.right + i2.right, top: false === i2.top ? 0 : n2.top - i2.top, bottom: false === i2.bottom ? this.height : n2.bottom + i2.bottom }), t2.controller.draw(), s2 && ze(e2), o2.cancelable = false, this.notifyPlugins("afterDatasetDraw", o2));
|
|
}
|
|
isPointInArea(t2) {
|
|
return Re(t2, this.chartArea, this._minPadding);
|
|
}
|
|
getElementsAtEventForMode(t2, e2, i2, s2) {
|
|
const n2 = Xi.modes[e2];
|
|
return "function" == typeof n2 ? n2(this, t2, i2, s2) : [];
|
|
}
|
|
getDatasetMeta(t2) {
|
|
const e2 = this.data.datasets[t2], i2 = this._metasets;
|
|
let s2 = i2.filter((t3) => t3 && t3._dataset === e2).pop();
|
|
return s2 || (s2 = { type: null, data: [], dataset: null, controller: null, hidden: null, xAxisID: null, yAxisID: null, order: e2 && e2.order || 0, index: t2, _dataset: e2, _parsed: [], _sorted: false }, i2.push(s2)), s2;
|
|
}
|
|
getContext() {
|
|
return this.$context || (this.$context = Ci(null, { chart: this, type: "chart" }));
|
|
}
|
|
getVisibleDatasetCount() {
|
|
return this.getSortedVisibleDatasetMetas().length;
|
|
}
|
|
isDatasetVisible(t2) {
|
|
const e2 = this.data.datasets[t2];
|
|
if (!e2) return false;
|
|
const i2 = this.getDatasetMeta(t2);
|
|
return "boolean" == typeof i2.hidden ? !i2.hidden : !e2.hidden;
|
|
}
|
|
setDatasetVisibility(t2, e2) {
|
|
this.getDatasetMeta(t2).hidden = !e2;
|
|
}
|
|
toggleDataVisibility(t2) {
|
|
this._hiddenIndices[t2] = !this._hiddenIndices[t2];
|
|
}
|
|
getDataVisibility(t2) {
|
|
return !this._hiddenIndices[t2];
|
|
}
|
|
_updateVisibility(t2, e2, i2) {
|
|
const s2 = i2 ? "show" : "hide", n2 = this.getDatasetMeta(t2), o2 = n2.controller._resolveAnimations(void 0, s2);
|
|
k(e2) ? (n2.data[e2].hidden = !i2, this.update()) : (this.setDatasetVisibility(t2, i2), o2.update(n2, { visible: i2 }), this.update((e3) => e3.datasetIndex === t2 ? s2 : void 0));
|
|
}
|
|
hide(t2, e2) {
|
|
this._updateVisibility(t2, e2, false);
|
|
}
|
|
show(t2, e2) {
|
|
this._updateVisibility(t2, e2, true);
|
|
}
|
|
_destroyDatasetMeta(t2) {
|
|
const e2 = this._metasets[t2];
|
|
e2 && e2.controller && e2.controller._destroy(), delete this._metasets[t2];
|
|
}
|
|
_stop() {
|
|
let t2, e2;
|
|
for (this.stop(), xt.remove(this), t2 = 0, e2 = this.data.datasets.length; t2 < e2; ++t2) this._destroyDatasetMeta(t2);
|
|
}
|
|
destroy() {
|
|
this.notifyPlugins("beforeDestroy");
|
|
const { canvas: t2, ctx: e2 } = this;
|
|
this._stop(), this.config.clearCache(), t2 && (this.unbindEvents(), Te(t2, e2), this.platform.releaseContext(e2), this.canvas = null, this.ctx = null), delete Pn[this.id], this.notifyPlugins("afterDestroy");
|
|
}
|
|
toBase64Image(...t2) {
|
|
return this.canvas.toDataURL(...t2);
|
|
}
|
|
bindEvents() {
|
|
this.bindUserEvents(), this.options.responsive ? this.bindResponsiveEvents() : this.attached = true;
|
|
}
|
|
bindUserEvents() {
|
|
const t2 = this._listeners, e2 = this.platform, i2 = (i3, s3) => {
|
|
e2.addEventListener(this, i3, s3), t2[i3] = s3;
|
|
}, s2 = (t3, e3, i3) => {
|
|
t3.offsetX = e3, t3.offsetY = i3, this._eventHandler(t3);
|
|
};
|
|
u(this.options.events, (t3) => i2(t3, s2));
|
|
}
|
|
bindResponsiveEvents() {
|
|
this._responsiveListeners || (this._responsiveListeners = {});
|
|
const t2 = this._responsiveListeners, e2 = this.platform, i2 = (i3, s3) => {
|
|
e2.addEventListener(this, i3, s3), t2[i3] = s3;
|
|
}, s2 = (i3, s3) => {
|
|
t2[i3] && (e2.removeEventListener(this, i3, s3), delete t2[i3]);
|
|
}, n2 = (t3, e3) => {
|
|
this.canvas && this.resize(t3, e3);
|
|
};
|
|
let o2;
|
|
const a2 = () => {
|
|
s2("attach", a2), this.attached = true, this.resize(), i2("resize", n2), i2("detach", o2);
|
|
};
|
|
o2 = () => {
|
|
this.attached = false, s2("resize", n2), this._stop(), this._resize(0, 0), i2("attach", a2);
|
|
}, e2.isAttached(this.canvas) ? a2() : o2();
|
|
}
|
|
unbindEvents() {
|
|
u(this._listeners, (t2, e2) => {
|
|
this.platform.removeEventListener(this, e2, t2);
|
|
}), this._listeners = {}, u(this._responsiveListeners, (t2, e2) => {
|
|
this.platform.removeEventListener(this, e2, t2);
|
|
}), this._responsiveListeners = void 0;
|
|
}
|
|
updateHoverStyle(t2, e2, i2) {
|
|
const s2 = i2 ? "set" : "remove";
|
|
let n2, o2, a2, r2;
|
|
for ("dataset" === e2 && (n2 = this.getDatasetMeta(t2[0].datasetIndex), n2.controller["_" + s2 + "DatasetHoverStyle"]()), a2 = 0, r2 = t2.length; a2 < r2; ++a2) {
|
|
o2 = t2[a2];
|
|
const e3 = o2 && this.getDatasetMeta(o2.datasetIndex).controller;
|
|
e3 && e3[s2 + "HoverStyle"](o2.element, o2.datasetIndex, o2.index);
|
|
}
|
|
}
|
|
getActiveElements() {
|
|
return this._active || [];
|
|
}
|
|
setActiveElements(t2) {
|
|
const e2 = this._active || [], i2 = t2.map(({ datasetIndex: t3, index: e3 }) => {
|
|
const i3 = this.getDatasetMeta(t3);
|
|
if (!i3) throw new Error("No dataset found at index " + t3);
|
|
return { datasetIndex: t3, element: i3.data[e3], index: e3 };
|
|
});
|
|
!f(i2, e2) && (this._active = i2, this._lastEvent = null, this._updateHoverStyles(i2, e2));
|
|
}
|
|
notifyPlugins(t2, e2, i2) {
|
|
return this._plugins.notify(this, t2, e2, i2);
|
|
}
|
|
isPluginEnabled(t2) {
|
|
return 1 === this._plugins._cache.filter((e2) => e2.plugin.id === t2).length;
|
|
}
|
|
_updateHoverStyles(t2, e2, i2) {
|
|
const s2 = this.options.hover, n2 = (t3, e3) => t3.filter((t4) => !e3.some((e4) => t4.datasetIndex === e4.datasetIndex && t4.index === e4.index)), o2 = n2(e2, t2), a2 = i2 ? t2 : n2(t2, e2);
|
|
o2.length && this.updateHoverStyle(o2, s2.mode, false), a2.length && s2.mode && this.updateHoverStyle(a2, s2.mode, true);
|
|
}
|
|
_eventHandler(t2, e2) {
|
|
const i2 = { event: t2, replay: e2, cancelable: true, inChartArea: this.isPointInArea(t2) }, s2 = (e3) => (e3.options.events || this.options.events).includes(t2.native.type);
|
|
if (false === this.notifyPlugins("beforeEvent", i2, s2)) return;
|
|
const n2 = this._handleEvent(t2, e2, i2.inChartArea);
|
|
return i2.cancelable = false, this.notifyPlugins("afterEvent", i2, s2), (n2 || i2.changed) && this.render(), this;
|
|
}
|
|
_handleEvent(t2, e2, i2) {
|
|
const { _active: s2 = [], options: n2 } = this, o2 = e2, a2 = this._getActiveElements(t2, s2, i2, o2), r2 = D(t2), l2 = function(t3, e3, i3, s3) {
|
|
return i3 && "mouseout" !== t3.type ? s3 ? e3 : t3 : null;
|
|
}(t2, this._lastEvent, i2, r2);
|
|
i2 && (this._lastEvent = null, d(n2.onHover, [t2, a2, this], this), r2 && d(n2.onClick, [t2, a2, this], this));
|
|
const h2 = !f(a2, s2);
|
|
return (h2 || e2) && (this._active = a2, this._updateHoverStyles(a2, s2, e2)), this._lastEvent = l2, h2;
|
|
}
|
|
_getActiveElements(t2, e2, i2, s2) {
|
|
if ("mouseout" === t2.type) return [];
|
|
if (!i2) return e2;
|
|
const n2 = this.options.hover;
|
|
return this.getElementsAtEventForMode(t2, n2.mode, n2, s2);
|
|
}
|
|
}
|
|
__publicField(An, "defaults", ue);
|
|
__publicField(An, "instances", Pn);
|
|
__publicField(An, "overrides", re);
|
|
__publicField(An, "registry", en);
|
|
__publicField(An, "version", "4.4.1");
|
|
__publicField(An, "getChart", Dn);
|
|
function Tn() {
|
|
return u(An.instances, (t2) => t2._plugins.invalidate());
|
|
}
|
|
function Ln() {
|
|
throw new Error("This method is not implemented: Check that a complete date adapter is provided.");
|
|
}
|
|
class En {
|
|
constructor(t2) {
|
|
__publicField(this, "options");
|
|
this.options = t2 || {};
|
|
}
|
|
static override(t2) {
|
|
Object.assign(En.prototype, t2);
|
|
}
|
|
init() {
|
|
}
|
|
formats() {
|
|
return Ln();
|
|
}
|
|
parse() {
|
|
return Ln();
|
|
}
|
|
format() {
|
|
return Ln();
|
|
}
|
|
add() {
|
|
return Ln();
|
|
}
|
|
diff() {
|
|
return Ln();
|
|
}
|
|
startOf() {
|
|
return Ln();
|
|
}
|
|
endOf() {
|
|
return Ln();
|
|
}
|
|
}
|
|
var Rn = { _date: En };
|
|
function In(t2) {
|
|
const e2 = t2.iScale, i2 = function(t3, e3) {
|
|
if (!t3._cache.$bar) {
|
|
const i3 = t3.getMatchingVisibleMetas(e3);
|
|
let s3 = [];
|
|
for (let e4 = 0, n3 = i3.length; e4 < n3; e4++) s3 = s3.concat(i3[e4].controller.getAllParsedValues(t3));
|
|
t3._cache.$bar = lt(s3.sort((t4, e4) => t4 - e4));
|
|
}
|
|
return t3._cache.$bar;
|
|
}(e2, t2.type);
|
|
let s2, n2, o2, a2, r2 = e2._length;
|
|
const l2 = () => {
|
|
32767 !== o2 && -32768 !== o2 && (k(a2) && (r2 = Math.min(r2, Math.abs(o2 - a2) || r2)), a2 = o2);
|
|
};
|
|
for (s2 = 0, n2 = i2.length; s2 < n2; ++s2) o2 = e2.getPixelForValue(i2[s2]), l2();
|
|
for (a2 = void 0, s2 = 0, n2 = e2.ticks.length; s2 < n2; ++s2) o2 = e2.getPixelForTick(s2), l2();
|
|
return r2;
|
|
}
|
|
function zn(t2, e2, i2, s2) {
|
|
return n(t2) ? function(t3, e3, i3, s3) {
|
|
const n2 = i3.parse(t3[0], s3), o2 = i3.parse(t3[1], s3), a2 = Math.min(n2, o2), r2 = Math.max(n2, o2);
|
|
let l2 = a2, h2 = r2;
|
|
Math.abs(a2) > Math.abs(r2) && (l2 = r2, h2 = a2), e3[i3.axis] = h2, e3._custom = { barStart: l2, barEnd: h2, start: n2, end: o2, min: a2, max: r2 };
|
|
}(t2, e2, i2, s2) : e2[i2.axis] = i2.parse(t2, s2), e2;
|
|
}
|
|
function Fn(t2, e2, i2, s2) {
|
|
const n2 = t2.iScale, o2 = t2.vScale, a2 = n2.getLabels(), r2 = n2 === o2, l2 = [];
|
|
let h2, c2, d2, u2;
|
|
for (h2 = i2, c2 = i2 + s2; h2 < c2; ++h2) u2 = e2[h2], d2 = {}, d2[n2.axis] = r2 || n2.parse(a2[h2], h2), l2.push(zn(u2, d2, o2, h2));
|
|
return l2;
|
|
}
|
|
function Vn(t2) {
|
|
return t2 && void 0 !== t2.barStart && void 0 !== t2.barEnd;
|
|
}
|
|
function Bn(t2, e2, i2, s2) {
|
|
let n2 = e2.borderSkipped;
|
|
const o2 = {};
|
|
if (!n2) return void (t2.borderSkipped = o2);
|
|
if (true === n2) return void (t2.borderSkipped = { top: true, right: true, bottom: true, left: true });
|
|
const { start: a2, end: r2, reverse: l2, top: h2, bottom: c2 } = function(t3) {
|
|
let e3, i3, s3, n3, o3;
|
|
return t3.horizontal ? (e3 = t3.base > t3.x, i3 = "left", s3 = "right") : (e3 = t3.base < t3.y, i3 = "bottom", s3 = "top"), e3 ? (n3 = "end", o3 = "start") : (n3 = "start", o3 = "end"), { start: i3, end: s3, reverse: e3, top: n3, bottom: o3 };
|
|
}(t2);
|
|
"middle" === n2 && i2 && (t2.enableBorderRadius = true, (i2._top || 0) === s2 ? n2 = h2 : (i2._bottom || 0) === s2 ? n2 = c2 : (o2[Wn(c2, a2, r2, l2)] = true, n2 = h2)), o2[Wn(n2, a2, r2, l2)] = true, t2.borderSkipped = o2;
|
|
}
|
|
function Wn(t2, e2, i2, s2) {
|
|
var n2, o2, a2;
|
|
return s2 ? (a2 = i2, t2 = Nn(t2 = (n2 = t2) === (o2 = e2) ? a2 : n2 === a2 ? o2 : n2, i2, e2)) : t2 = Nn(t2, e2, i2), t2;
|
|
}
|
|
function Nn(t2, e2, i2) {
|
|
return "start" === t2 ? e2 : "end" === t2 ? i2 : t2;
|
|
}
|
|
function Hn(t2, { inflateAmount: e2 }, i2) {
|
|
t2.inflateAmount = "auto" === e2 ? 1 === i2 ? 0.33 : 0 : e2;
|
|
}
|
|
class jn extends Ns {
|
|
constructor(t2, e2) {
|
|
super(t2, e2), this.enableOptionSharing = true, this.innerRadius = void 0, this.outerRadius = void 0, this.offsetX = void 0, this.offsetY = void 0;
|
|
}
|
|
linkScales() {
|
|
}
|
|
parse(t2, e2) {
|
|
const i2 = this.getDataset().data, s2 = this._cachedMeta;
|
|
if (false === this._parsing) s2._parsed = i2;
|
|
else {
|
|
let n2, a2, r2 = (t3) => +i2[t3];
|
|
if (o(i2[t2])) {
|
|
const { key: t3 = "value" } = this._parsing;
|
|
r2 = (e3) => +M(i2[e3], t3);
|
|
}
|
|
for (n2 = t2, a2 = t2 + e2; n2 < a2; ++n2) s2._parsed[n2] = r2(n2);
|
|
}
|
|
}
|
|
_getRotation() {
|
|
return $(this.options.rotation - 90);
|
|
}
|
|
_getCircumference() {
|
|
return $(this.options.circumference);
|
|
}
|
|
_getRotationExtents() {
|
|
let t2 = O, e2 = -O;
|
|
for (let i2 = 0; i2 < this.chart.data.datasets.length; ++i2) if (this.chart.isDatasetVisible(i2) && this.chart.getDatasetMeta(i2).type === this._type) {
|
|
const s2 = this.chart.getDatasetMeta(i2).controller, n2 = s2._getRotation(), o2 = s2._getCircumference();
|
|
t2 = Math.min(t2, n2), e2 = Math.max(e2, n2 + o2);
|
|
}
|
|
return { rotation: t2, circumference: e2 - t2 };
|
|
}
|
|
update(t2) {
|
|
const e2 = this.chart, { chartArea: i2 } = e2, s2 = this._cachedMeta, n2 = s2.data, o2 = this.getMaxBorderWidth() + this.getMaxOffset(n2) + this.options.spacing, a2 = Math.max((Math.min(i2.width, i2.height) - o2) / 2, 0), r2 = Math.min(h(this.options.cutout, a2), 1), l2 = this._getRingWeight(this.index), { circumference: d2, rotation: u2 } = this._getRotationExtents(), { ratioX: f2, ratioY: g2, offsetX: p2, offsetY: m2 } = function(t3, e3, i3) {
|
|
let s3 = 1, n3 = 1, o3 = 0, a3 = 0;
|
|
if (e3 < O) {
|
|
const r3 = t3, l3 = r3 + e3, h2 = Math.cos(r3), c2 = Math.sin(r3), d3 = Math.cos(l3), u3 = Math.sin(l3), f3 = (t4, e4, s4) => Z(t4, r3, l3, true) ? 1 : Math.max(e4, e4 * i3, s4, s4 * i3), g3 = (t4, e4, s4) => Z(t4, r3, l3, true) ? -1 : Math.min(e4, e4 * i3, s4, s4 * i3), p3 = f3(0, h2, d3), m3 = f3(E, c2, u3), b3 = g3(C, h2, d3), x3 = g3(C + E, c2, u3);
|
|
s3 = (p3 - b3) / 2, n3 = (m3 - x3) / 2, o3 = -(p3 + b3) / 2, a3 = -(m3 + x3) / 2;
|
|
}
|
|
return { ratioX: s3, ratioY: n3, offsetX: o3, offsetY: a3 };
|
|
}(u2, d2, r2), b2 = (i2.width - o2) / f2, x2 = (i2.height - o2) / g2, _2 = Math.max(Math.min(b2, x2) / 2, 0), y2 = c(this.options.radius, _2), v2 = (y2 - Math.max(y2 * r2, 0)) / this._getVisibleDatasetWeightTotal();
|
|
this.offsetX = p2 * y2, this.offsetY = m2 * y2, s2.total = this.calculateTotal(), this.outerRadius = y2 - v2 * this._getRingWeightOffset(this.index), this.innerRadius = Math.max(this.outerRadius - v2 * l2, 0), this.updateElements(n2, 0, n2.length, t2);
|
|
}
|
|
_circumference(t2, e2) {
|
|
const i2 = this.options, s2 = this._cachedMeta, n2 = this._getCircumference();
|
|
return e2 && i2.animation.animateRotate || !this.chart.getDataVisibility(t2) || null === s2._parsed[t2] || s2.data[t2].hidden ? 0 : this.calculateCircumference(s2._parsed[t2] * n2 / O);
|
|
}
|
|
updateElements(t2, e2, i2, s2) {
|
|
const n2 = "reset" === s2, o2 = this.chart, a2 = o2.chartArea, r2 = o2.options.animation, l2 = (a2.left + a2.right) / 2, h2 = (a2.top + a2.bottom) / 2, c2 = n2 && r2.animateScale, d2 = c2 ? 0 : this.innerRadius, u2 = c2 ? 0 : this.outerRadius, { sharedOptions: f2, includeOptions: g2 } = this._getSharedOptions(e2, s2);
|
|
let p2, m2 = this._getRotation();
|
|
for (p2 = 0; p2 < e2; ++p2) m2 += this._circumference(p2, n2);
|
|
for (p2 = e2; p2 < e2 + i2; ++p2) {
|
|
const e3 = this._circumference(p2, n2), i3 = t2[p2], o3 = { x: l2 + this.offsetX, y: h2 + this.offsetY, startAngle: m2, endAngle: m2 + e3, circumference: e3, outerRadius: u2, innerRadius: d2 };
|
|
g2 && (o3.options = f2 || this.resolveDataElementOptions(p2, i3.active ? "active" : s2)), m2 += e3, this.updateElement(i3, p2, o3, s2);
|
|
}
|
|
}
|
|
calculateTotal() {
|
|
const t2 = this._cachedMeta, e2 = t2.data;
|
|
let i2, s2 = 0;
|
|
for (i2 = 0; i2 < e2.length; i2++) {
|
|
const n2 = t2._parsed[i2];
|
|
null === n2 || isNaN(n2) || !this.chart.getDataVisibility(i2) || e2[i2].hidden || (s2 += Math.abs(n2));
|
|
}
|
|
return s2;
|
|
}
|
|
calculateCircumference(t2) {
|
|
const e2 = this._cachedMeta.total;
|
|
return e2 > 0 && !isNaN(t2) ? O * (Math.abs(t2) / e2) : 0;
|
|
}
|
|
getLabelAndValue(t2) {
|
|
const e2 = this._cachedMeta, i2 = this.chart, s2 = i2.data.labels || [], n2 = ne(e2._parsed[t2], i2.options.locale);
|
|
return { label: s2[t2] || "", value: n2 };
|
|
}
|
|
getMaxBorderWidth(t2) {
|
|
let e2 = 0;
|
|
const i2 = this.chart;
|
|
let s2, n2, o2, a2, r2;
|
|
if (!t2) {
|
|
for (s2 = 0, n2 = i2.data.datasets.length; s2 < n2; ++s2) if (i2.isDatasetVisible(s2)) {
|
|
o2 = i2.getDatasetMeta(s2), t2 = o2.data, a2 = o2.controller;
|
|
break;
|
|
}
|
|
}
|
|
if (!t2) return 0;
|
|
for (s2 = 0, n2 = t2.length; s2 < n2; ++s2) r2 = a2.resolveDataElementOptions(s2), "inner" !== r2.borderAlign && (e2 = Math.max(e2, r2.borderWidth || 0, r2.hoverBorderWidth || 0));
|
|
return e2;
|
|
}
|
|
getMaxOffset(t2) {
|
|
let e2 = 0;
|
|
for (let i2 = 0, s2 = t2.length; i2 < s2; ++i2) {
|
|
const t3 = this.resolveDataElementOptions(i2);
|
|
e2 = Math.max(e2, t3.offset || 0, t3.hoverOffset || 0);
|
|
}
|
|
return e2;
|
|
}
|
|
_getRingWeightOffset(t2) {
|
|
let e2 = 0;
|
|
for (let i2 = 0; i2 < t2; ++i2) this.chart.isDatasetVisible(i2) && (e2 += this._getRingWeight(i2));
|
|
return e2;
|
|
}
|
|
_getRingWeight(t2) {
|
|
return Math.max(l(this.chart.data.datasets[t2].weight, 1), 0);
|
|
}
|
|
_getVisibleDatasetWeightTotal() {
|
|
return this._getRingWeightOffset(this.chart.data.datasets.length) || 1;
|
|
}
|
|
}
|
|
__publicField(jn, "id", "doughnut");
|
|
__publicField(jn, "defaults", { datasetElementType: false, dataElementType: "arc", animation: { animateRotate: true, animateScale: false }, animations: { numbers: { type: "number", properties: ["circumference", "endAngle", "innerRadius", "outerRadius", "startAngle", "x", "y", "offset", "borderWidth", "spacing"] } }, cutout: "50%", rotation: 0, circumference: 360, radius: "100%", spacing: 0, indexAxis: "r" });
|
|
__publicField(jn, "descriptors", { _scriptable: (t2) => "spacing" !== t2, _indexable: (t2) => "spacing" !== t2 && !t2.startsWith("borderDash") && !t2.startsWith("hoverBorderDash") });
|
|
__publicField(jn, "overrides", { aspectRatio: 1, plugins: { legend: { labels: { generateLabels(t2) {
|
|
const e2 = t2.data;
|
|
if (e2.labels.length && e2.datasets.length) {
|
|
const { labels: { pointStyle: i2, color: s2 } } = t2.legend.options;
|
|
return e2.labels.map((e3, n2) => {
|
|
const o2 = t2.getDatasetMeta(0).controller.getStyle(n2);
|
|
return { text: e3, fillStyle: o2.backgroundColor, strokeStyle: o2.borderColor, fontColor: s2, lineWidth: o2.borderWidth, pointStyle: i2, hidden: !t2.getDataVisibility(n2), index: n2 };
|
|
});
|
|
}
|
|
return [];
|
|
} }, onClick(t2, e2, i2) {
|
|
i2.chart.toggleDataVisibility(e2.index), i2.chart.update();
|
|
} } } });
|
|
class $n extends Ns {
|
|
constructor(t2, e2) {
|
|
super(t2, e2), this.innerRadius = void 0, this.outerRadius = void 0;
|
|
}
|
|
getLabelAndValue(t2) {
|
|
const e2 = this._cachedMeta, i2 = this.chart, s2 = i2.data.labels || [], n2 = ne(e2._parsed[t2].r, i2.options.locale);
|
|
return { label: s2[t2] || "", value: n2 };
|
|
}
|
|
parseObjectData(t2, e2, i2, s2) {
|
|
return ii.bind(this)(t2, e2, i2, s2);
|
|
}
|
|
update(t2) {
|
|
const e2 = this._cachedMeta.data;
|
|
this._updateRadius(), this.updateElements(e2, 0, e2.length, t2);
|
|
}
|
|
getMinMax() {
|
|
const t2 = this._cachedMeta, e2 = { min: Number.POSITIVE_INFINITY, max: Number.NEGATIVE_INFINITY };
|
|
return t2.data.forEach((t3, i2) => {
|
|
const s2 = this.getParsed(i2).r;
|
|
!isNaN(s2) && this.chart.getDataVisibility(i2) && (s2 < e2.min && (e2.min = s2), s2 > e2.max && (e2.max = s2));
|
|
}), e2;
|
|
}
|
|
_updateRadius() {
|
|
const t2 = this.chart, e2 = t2.chartArea, i2 = t2.options, s2 = Math.min(e2.right - e2.left, e2.bottom - e2.top), n2 = Math.max(s2 / 2, 0), o2 = (n2 - Math.max(i2.cutoutPercentage ? n2 / 100 * i2.cutoutPercentage : 1, 0)) / t2.getVisibleDatasetCount();
|
|
this.outerRadius = n2 - o2 * this.index, this.innerRadius = this.outerRadius - o2;
|
|
}
|
|
updateElements(t2, e2, i2, s2) {
|
|
const n2 = "reset" === s2, o2 = this.chart, a2 = o2.options.animation, r2 = this._cachedMeta.rScale, l2 = r2.xCenter, h2 = r2.yCenter, c2 = r2.getIndexAngle(0) - 0.5 * C;
|
|
let d2, u2 = c2;
|
|
const f2 = 360 / this.countVisibleElements();
|
|
for (d2 = 0; d2 < e2; ++d2) u2 += this._computeAngle(d2, s2, f2);
|
|
for (d2 = e2; d2 < e2 + i2; d2++) {
|
|
const e3 = t2[d2];
|
|
let i3 = u2, g2 = u2 + this._computeAngle(d2, s2, f2), p2 = o2.getDataVisibility(d2) ? r2.getDistanceFromCenterForValue(this.getParsed(d2).r) : 0;
|
|
u2 = g2, n2 && (a2.animateScale && (p2 = 0), a2.animateRotate && (i3 = g2 = c2));
|
|
const m2 = { x: l2, y: h2, innerRadius: 0, outerRadius: p2, startAngle: i3, endAngle: g2, options: this.resolveDataElementOptions(d2, e3.active ? "active" : s2) };
|
|
this.updateElement(e3, d2, m2, s2);
|
|
}
|
|
}
|
|
countVisibleElements() {
|
|
const t2 = this._cachedMeta;
|
|
let e2 = 0;
|
|
return t2.data.forEach((t3, i2) => {
|
|
!isNaN(this.getParsed(i2).r) && this.chart.getDataVisibility(i2) && e2++;
|
|
}), e2;
|
|
}
|
|
_computeAngle(t2, e2, i2) {
|
|
return this.chart.getDataVisibility(t2) ? $(this.resolveDataElementOptions(t2, e2).angle || i2) : 0;
|
|
}
|
|
}
|
|
__publicField($n, "id", "polarArea");
|
|
__publicField($n, "defaults", { dataElementType: "arc", animation: { animateRotate: true, animateScale: true }, animations: { numbers: { type: "number", properties: ["x", "y", "startAngle", "endAngle", "innerRadius", "outerRadius"] } }, indexAxis: "r", startAngle: 0 });
|
|
__publicField($n, "overrides", { aspectRatio: 1, plugins: { legend: { labels: { generateLabels(t2) {
|
|
const e2 = t2.data;
|
|
if (e2.labels.length && e2.datasets.length) {
|
|
const { labels: { pointStyle: i2, color: s2 } } = t2.legend.options;
|
|
return e2.labels.map((e3, n2) => {
|
|
const o2 = t2.getDatasetMeta(0).controller.getStyle(n2);
|
|
return { text: e3, fillStyle: o2.backgroundColor, strokeStyle: o2.borderColor, fontColor: s2, lineWidth: o2.borderWidth, pointStyle: i2, hidden: !t2.getDataVisibility(n2), index: n2 };
|
|
});
|
|
}
|
|
return [];
|
|
} }, onClick(t2, e2, i2) {
|
|
i2.chart.toggleDataVisibility(e2.index), i2.chart.update();
|
|
} } }, scales: { r: { type: "radialLinear", angleLines: { display: false }, beginAtZero: true, grid: { circular: true }, pointLabels: { display: false }, startAngle: 0 } } });
|
|
var Yn = Object.freeze({ __proto__: null, BarController: (_a3 = class extends Ns {
|
|
parsePrimitiveData(t2, e2, i2, s2) {
|
|
return Fn(t2, e2, i2, s2);
|
|
}
|
|
parseArrayData(t2, e2, i2, s2) {
|
|
return Fn(t2, e2, i2, s2);
|
|
}
|
|
parseObjectData(t2, e2, i2, s2) {
|
|
const { iScale: n2, vScale: o2 } = t2, { xAxisKey: a2 = "x", yAxisKey: r2 = "y" } = this._parsing, l2 = "x" === n2.axis ? a2 : r2, h2 = "x" === o2.axis ? a2 : r2, c2 = [];
|
|
let d2, u2, f2, g2;
|
|
for (d2 = i2, u2 = i2 + s2; d2 < u2; ++d2) g2 = e2[d2], f2 = {}, f2[n2.axis] = n2.parse(M(g2, l2), d2), c2.push(zn(M(g2, h2), f2, o2, d2));
|
|
return c2;
|
|
}
|
|
updateRangeFromParsed(t2, e2, i2, s2) {
|
|
super.updateRangeFromParsed(t2, e2, i2, s2);
|
|
const n2 = i2._custom;
|
|
n2 && e2 === this._cachedMeta.vScale && (t2.min = Math.min(t2.min, n2.min), t2.max = Math.max(t2.max, n2.max));
|
|
}
|
|
getMaxOverflow() {
|
|
return 0;
|
|
}
|
|
getLabelAndValue(t2) {
|
|
const e2 = this._cachedMeta, { iScale: i2, vScale: s2 } = e2, n2 = this.getParsed(t2), o2 = n2._custom, a2 = Vn(o2) ? "[" + o2.start + ", " + o2.end + "]" : "" + s2.getLabelForValue(n2[s2.axis]);
|
|
return { label: "" + i2.getLabelForValue(n2[i2.axis]), value: a2 };
|
|
}
|
|
initialize() {
|
|
this.enableOptionSharing = true, super.initialize();
|
|
this._cachedMeta.stack = this.getDataset().stack;
|
|
}
|
|
update(t2) {
|
|
const e2 = this._cachedMeta;
|
|
this.updateElements(e2.data, 0, e2.data.length, t2);
|
|
}
|
|
updateElements(t2, e2, i2, n2) {
|
|
const o2 = "reset" === n2, { index: a2, _cachedMeta: { vScale: r2 } } = this, l2 = r2.getBasePixel(), h2 = r2.isHorizontal(), c2 = this._getRuler(), { sharedOptions: d2, includeOptions: u2 } = this._getSharedOptions(e2, n2);
|
|
for (let f2 = e2; f2 < e2 + i2; f2++) {
|
|
const e3 = this.getParsed(f2), i3 = o2 || s(e3[r2.axis]) ? { base: l2, head: l2 } : this._calculateBarValuePixels(f2), g2 = this._calculateBarIndexPixels(f2, c2), p2 = (e3._stacks || {})[r2.axis], m2 = { horizontal: h2, base: i3.base, enableBorderRadius: !p2 || Vn(e3._custom) || a2 === p2._top || a2 === p2._bottom, x: h2 ? i3.head : g2.center, y: h2 ? g2.center : i3.head, height: h2 ? g2.size : Math.abs(i3.size), width: h2 ? Math.abs(i3.size) : g2.size };
|
|
u2 && (m2.options = d2 || this.resolveDataElementOptions(f2, t2[f2].active ? "active" : n2));
|
|
const b2 = m2.options || t2[f2].options;
|
|
Bn(m2, b2, p2, a2), Hn(m2, b2, c2.ratio), this.updateElement(t2[f2], f2, m2, n2);
|
|
}
|
|
}
|
|
_getStacks(t2, e2) {
|
|
const { iScale: i2 } = this._cachedMeta, n2 = i2.getMatchingVisibleMetas(this._type).filter((t3) => t3.controller.options.grouped), o2 = i2.options.stacked, a2 = [], r2 = (t3) => {
|
|
const i3 = t3.controller.getParsed(e2), n3 = i3 && i3[t3.vScale.axis];
|
|
if (s(n3) || isNaN(n3)) return true;
|
|
};
|
|
for (const i3 of n2) if ((void 0 === e2 || !r2(i3)) && ((false === o2 || -1 === a2.indexOf(i3.stack) || void 0 === o2 && void 0 === i3.stack) && a2.push(i3.stack), i3.index === t2)) break;
|
|
return a2.length || a2.push(void 0), a2;
|
|
}
|
|
_getStackCount(t2) {
|
|
return this._getStacks(void 0, t2).length;
|
|
}
|
|
_getStackIndex(t2, e2, i2) {
|
|
const s2 = this._getStacks(t2, i2), n2 = void 0 !== e2 ? s2.indexOf(e2) : -1;
|
|
return -1 === n2 ? s2.length - 1 : n2;
|
|
}
|
|
_getRuler() {
|
|
const t2 = this.options, e2 = this._cachedMeta, i2 = e2.iScale, s2 = [];
|
|
let n2, o2;
|
|
for (n2 = 0, o2 = e2.data.length; n2 < o2; ++n2) s2.push(i2.getPixelForValue(this.getParsed(n2)[i2.axis], n2));
|
|
const a2 = t2.barThickness;
|
|
return { min: a2 || In(e2), pixels: s2, start: i2._startPixel, end: i2._endPixel, stackCount: this._getStackCount(), scale: i2, grouped: t2.grouped, ratio: a2 ? 1 : t2.categoryPercentage * t2.barPercentage };
|
|
}
|
|
_calculateBarValuePixels(t2) {
|
|
const { _cachedMeta: { vScale: e2, _stacked: i2, index: n2 }, options: { base: o2, minBarLength: a2 } } = this, r2 = o2 || 0, l2 = this.getParsed(t2), h2 = l2._custom, c2 = Vn(h2);
|
|
let d2, u2, f2 = l2[e2.axis], g2 = 0, p2 = i2 ? this.applyStack(e2, l2, i2) : f2;
|
|
p2 !== f2 && (g2 = p2 - f2, p2 = f2), c2 && (f2 = h2.barStart, p2 = h2.barEnd - h2.barStart, 0 !== f2 && F(f2) !== F(h2.barEnd) && (g2 = 0), g2 += f2);
|
|
const m2 = s(o2) || c2 ? g2 : o2;
|
|
let b2 = e2.getPixelForValue(m2);
|
|
if (d2 = this.chart.getDataVisibility(t2) ? e2.getPixelForValue(g2 + p2) : b2, u2 = d2 - b2, Math.abs(u2) < a2) {
|
|
u2 = function(t4, e3, i3) {
|
|
return 0 !== t4 ? F(t4) : (e3.isHorizontal() ? 1 : -1) * (e3.min >= i3 ? 1 : -1);
|
|
}(u2, e2, r2) * a2, f2 === r2 && (b2 -= u2 / 2);
|
|
const t3 = e2.getPixelForDecimal(0), s2 = e2.getPixelForDecimal(1), o3 = Math.min(t3, s2), h3 = Math.max(t3, s2);
|
|
b2 = Math.max(Math.min(b2, h3), o3), d2 = b2 + u2, i2 && !c2 && (l2._stacks[e2.axis]._visualValues[n2] = e2.getValueForPixel(d2) - e2.getValueForPixel(b2));
|
|
}
|
|
if (b2 === e2.getPixelForValue(r2)) {
|
|
const t3 = F(u2) * e2.getLineWidthForValue(r2) / 2;
|
|
b2 += t3, u2 -= t3;
|
|
}
|
|
return { size: u2, base: b2, head: d2, center: d2 + u2 / 2 };
|
|
}
|
|
_calculateBarIndexPixels(t2, e2) {
|
|
const i2 = e2.scale, n2 = this.options, o2 = n2.skipNull, a2 = l(n2.maxBarThickness, 1 / 0);
|
|
let r2, h2;
|
|
if (e2.grouped) {
|
|
const i3 = o2 ? this._getStackCount(t2) : e2.stackCount, l2 = "flex" === n2.barThickness ? function(t3, e3, i4, s2) {
|
|
const n3 = e3.pixels, o3 = n3[t3];
|
|
let a3 = t3 > 0 ? n3[t3 - 1] : null, r3 = t3 < n3.length - 1 ? n3[t3 + 1] : null;
|
|
const l3 = i4.categoryPercentage;
|
|
null === a3 && (a3 = o3 - (null === r3 ? e3.end - e3.start : r3 - o3)), null === r3 && (r3 = o3 + o3 - a3);
|
|
const h3 = o3 - (o3 - Math.min(a3, r3)) / 2 * l3;
|
|
return { chunk: Math.abs(r3 - a3) / 2 * l3 / s2, ratio: i4.barPercentage, start: h3 };
|
|
}(t2, e2, n2, i3) : function(t3, e3, i4, n3) {
|
|
const o3 = i4.barThickness;
|
|
let a3, r3;
|
|
return s(o3) ? (a3 = e3.min * i4.categoryPercentage, r3 = i4.barPercentage) : (a3 = o3 * n3, r3 = 1), { chunk: a3 / n3, ratio: r3, start: e3.pixels[t3] - a3 / 2 };
|
|
}(t2, e2, n2, i3), c2 = this._getStackIndex(this.index, this._cachedMeta.stack, o2 ? t2 : void 0);
|
|
r2 = l2.start + l2.chunk * c2 + l2.chunk / 2, h2 = Math.min(a2, l2.chunk * l2.ratio);
|
|
} else r2 = i2.getPixelForValue(this.getParsed(t2)[i2.axis], t2), h2 = Math.min(a2, e2.min * e2.ratio);
|
|
return { base: r2 - h2 / 2, head: r2 + h2 / 2, center: r2, size: h2 };
|
|
}
|
|
draw() {
|
|
const t2 = this._cachedMeta, e2 = t2.vScale, i2 = t2.data, s2 = i2.length;
|
|
let n2 = 0;
|
|
for (; n2 < s2; ++n2) null !== this.getParsed(n2)[e2.axis] && i2[n2].draw(this._ctx);
|
|
}
|
|
}, __publicField(_a3, "id", "bar"), __publicField(_a3, "defaults", { datasetElementType: false, dataElementType: "bar", categoryPercentage: 0.8, barPercentage: 0.9, grouped: true, animations: { numbers: { type: "number", properties: ["x", "y", "base", "width", "height"] } } }), __publicField(_a3, "overrides", { scales: { _index_: { type: "category", offset: true, grid: { offset: true } }, _value_: { type: "linear", beginAtZero: true } } }), _a3), BubbleController: (_b = class extends Ns {
|
|
initialize() {
|
|
this.enableOptionSharing = true, super.initialize();
|
|
}
|
|
parsePrimitiveData(t2, e2, i2, s2) {
|
|
const n2 = super.parsePrimitiveData(t2, e2, i2, s2);
|
|
for (let t3 = 0; t3 < n2.length; t3++) n2[t3]._custom = this.resolveDataElementOptions(t3 + i2).radius;
|
|
return n2;
|
|
}
|
|
parseArrayData(t2, e2, i2, s2) {
|
|
const n2 = super.parseArrayData(t2, e2, i2, s2);
|
|
for (let t3 = 0; t3 < n2.length; t3++) {
|
|
const s3 = e2[i2 + t3];
|
|
n2[t3]._custom = l(s3[2], this.resolveDataElementOptions(t3 + i2).radius);
|
|
}
|
|
return n2;
|
|
}
|
|
parseObjectData(t2, e2, i2, s2) {
|
|
const n2 = super.parseObjectData(t2, e2, i2, s2);
|
|
for (let t3 = 0; t3 < n2.length; t3++) {
|
|
const s3 = e2[i2 + t3];
|
|
n2[t3]._custom = l(s3 && s3.r && +s3.r, this.resolveDataElementOptions(t3 + i2).radius);
|
|
}
|
|
return n2;
|
|
}
|
|
getMaxOverflow() {
|
|
const t2 = this._cachedMeta.data;
|
|
let e2 = 0;
|
|
for (let i2 = t2.length - 1; i2 >= 0; --i2) e2 = Math.max(e2, t2[i2].size(this.resolveDataElementOptions(i2)) / 2);
|
|
return e2 > 0 && e2;
|
|
}
|
|
getLabelAndValue(t2) {
|
|
const e2 = this._cachedMeta, i2 = this.chart.data.labels || [], { xScale: s2, yScale: n2 } = e2, o2 = this.getParsed(t2), a2 = s2.getLabelForValue(o2.x), r2 = n2.getLabelForValue(o2.y), l2 = o2._custom;
|
|
return { label: i2[t2] || "", value: "(" + a2 + ", " + r2 + (l2 ? ", " + l2 : "") + ")" };
|
|
}
|
|
update(t2) {
|
|
const e2 = this._cachedMeta.data;
|
|
this.updateElements(e2, 0, e2.length, t2);
|
|
}
|
|
updateElements(t2, e2, i2, s2) {
|
|
const n2 = "reset" === s2, { iScale: o2, vScale: a2 } = this._cachedMeta, { sharedOptions: r2, includeOptions: l2 } = this._getSharedOptions(e2, s2), h2 = o2.axis, c2 = a2.axis;
|
|
for (let d2 = e2; d2 < e2 + i2; d2++) {
|
|
const e3 = t2[d2], i3 = !n2 && this.getParsed(d2), u2 = {}, f2 = u2[h2] = n2 ? o2.getPixelForDecimal(0.5) : o2.getPixelForValue(i3[h2]), g2 = u2[c2] = n2 ? a2.getBasePixel() : a2.getPixelForValue(i3[c2]);
|
|
u2.skip = isNaN(f2) || isNaN(g2), l2 && (u2.options = r2 || this.resolveDataElementOptions(d2, e3.active ? "active" : s2), n2 && (u2.options.radius = 0)), this.updateElement(e3, d2, u2, s2);
|
|
}
|
|
}
|
|
resolveDataElementOptions(t2, e2) {
|
|
const i2 = this.getParsed(t2);
|
|
let s2 = super.resolveDataElementOptions(t2, e2);
|
|
s2.$shared && (s2 = Object.assign({}, s2, { $shared: false }));
|
|
const n2 = s2.radius;
|
|
return "active" !== e2 && (s2.radius = 0), s2.radius += l(i2 && i2._custom, n2), s2;
|
|
}
|
|
}, __publicField(_b, "id", "bubble"), __publicField(_b, "defaults", { datasetElementType: false, dataElementType: "point", animations: { numbers: { type: "number", properties: ["x", "y", "borderWidth", "radius"] } } }), __publicField(_b, "overrides", { scales: { x: { type: "linear" }, y: { type: "linear" } } }), _b), DoughnutController: jn, LineController: (_c = class extends Ns {
|
|
initialize() {
|
|
this.enableOptionSharing = true, this.supportsDecimation = true, super.initialize();
|
|
}
|
|
update(t2) {
|
|
const e2 = this._cachedMeta, { dataset: i2, data: s2 = [], _dataset: n2 } = e2, o2 = this.chart._animationsDisabled;
|
|
let { start: a2, count: r2 } = pt(e2, s2, o2);
|
|
this._drawStart = a2, this._drawCount = r2, mt(e2) && (a2 = 0, r2 = s2.length), i2._chart = this.chart, i2._datasetIndex = this.index, i2._decimated = !!n2._decimated, i2.points = s2;
|
|
const l2 = this.resolveDatasetElementOptions(t2);
|
|
this.options.showLine || (l2.borderWidth = 0), l2.segment = this.options.segment, this.updateElement(i2, void 0, { animated: !o2, options: l2 }, t2), this.updateElements(s2, a2, r2, t2);
|
|
}
|
|
updateElements(t2, e2, i2, n2) {
|
|
const o2 = "reset" === n2, { iScale: a2, vScale: r2, _stacked: l2, _dataset: h2 } = this._cachedMeta, { sharedOptions: c2, includeOptions: d2 } = this._getSharedOptions(e2, n2), u2 = a2.axis, f2 = r2.axis, { spanGaps: g2, segment: p2 } = this.options, m2 = N(g2) ? g2 : Number.POSITIVE_INFINITY, b2 = this.chart._animationsDisabled || o2 || "none" === n2, x2 = e2 + i2, _2 = t2.length;
|
|
let y2 = e2 > 0 && this.getParsed(e2 - 1);
|
|
for (let i3 = 0; i3 < _2; ++i3) {
|
|
const g3 = t2[i3], _3 = b2 ? g3 : {};
|
|
if (i3 < e2 || i3 >= x2) {
|
|
_3.skip = true;
|
|
continue;
|
|
}
|
|
const v2 = this.getParsed(i3), M2 = s(v2[f2]), w2 = _3[u2] = a2.getPixelForValue(v2[u2], i3), k2 = _3[f2] = o2 || M2 ? r2.getBasePixel() : r2.getPixelForValue(l2 ? this.applyStack(r2, v2, l2) : v2[f2], i3);
|
|
_3.skip = isNaN(w2) || isNaN(k2) || M2, _3.stop = i3 > 0 && Math.abs(v2[u2] - y2[u2]) > m2, p2 && (_3.parsed = v2, _3.raw = h2.data[i3]), d2 && (_3.options = c2 || this.resolveDataElementOptions(i3, g3.active ? "active" : n2)), b2 || this.updateElement(g3, i3, _3, n2), y2 = v2;
|
|
}
|
|
}
|
|
getMaxOverflow() {
|
|
const t2 = this._cachedMeta, e2 = t2.dataset, i2 = e2.options && e2.options.borderWidth || 0, s2 = t2.data || [];
|
|
if (!s2.length) return i2;
|
|
const n2 = s2[0].size(this.resolveDataElementOptions(0)), o2 = s2[s2.length - 1].size(this.resolveDataElementOptions(s2.length - 1));
|
|
return Math.max(i2, n2, o2) / 2;
|
|
}
|
|
draw() {
|
|
const t2 = this._cachedMeta;
|
|
t2.dataset.updateControlPoints(this.chart.chartArea, t2.iScale.axis), super.draw();
|
|
}
|
|
}, __publicField(_c, "id", "line"), __publicField(_c, "defaults", { datasetElementType: "line", dataElementType: "point", showLine: true, spanGaps: false }), __publicField(_c, "overrides", { scales: { _index_: { type: "category" }, _value_: { type: "linear" } } }), _c), PieController: (_d = class extends jn {
|
|
}, __publicField(_d, "id", "pie"), __publicField(_d, "defaults", { cutout: 0, rotation: 0, circumference: 360, radius: "100%" }), _d), PolarAreaController: $n, RadarController: (_e2 = class extends Ns {
|
|
getLabelAndValue(t2) {
|
|
const e2 = this._cachedMeta.vScale, i2 = this.getParsed(t2);
|
|
return { label: e2.getLabels()[t2], value: "" + e2.getLabelForValue(i2[e2.axis]) };
|
|
}
|
|
parseObjectData(t2, e2, i2, s2) {
|
|
return ii.bind(this)(t2, e2, i2, s2);
|
|
}
|
|
update(t2) {
|
|
const e2 = this._cachedMeta, i2 = e2.dataset, s2 = e2.data || [], n2 = e2.iScale.getLabels();
|
|
if (i2.points = s2, "resize" !== t2) {
|
|
const e3 = this.resolveDatasetElementOptions(t2);
|
|
this.options.showLine || (e3.borderWidth = 0);
|
|
const o2 = { _loop: true, _fullLoop: n2.length === s2.length, options: e3 };
|
|
this.updateElement(i2, void 0, o2, t2);
|
|
}
|
|
this.updateElements(s2, 0, s2.length, t2);
|
|
}
|
|
updateElements(t2, e2, i2, s2) {
|
|
const n2 = this._cachedMeta.rScale, o2 = "reset" === s2;
|
|
for (let a2 = e2; a2 < e2 + i2; a2++) {
|
|
const e3 = t2[a2], i3 = this.resolveDataElementOptions(a2, e3.active ? "active" : s2), r2 = n2.getPointPositionForValue(a2, this.getParsed(a2).r), l2 = o2 ? n2.xCenter : r2.x, h2 = o2 ? n2.yCenter : r2.y, c2 = { x: l2, y: h2, angle: r2.angle, skip: isNaN(l2) || isNaN(h2), options: i3 };
|
|
this.updateElement(e3, a2, c2, s2);
|
|
}
|
|
}
|
|
}, __publicField(_e2, "id", "radar"), __publicField(_e2, "defaults", { datasetElementType: "line", dataElementType: "point", indexAxis: "r", showLine: true, elements: { line: { fill: "start" } } }), __publicField(_e2, "overrides", { aspectRatio: 1, scales: { r: { type: "radialLinear" } } }), _e2), ScatterController: (_f = class extends Ns {
|
|
getLabelAndValue(t2) {
|
|
const e2 = this._cachedMeta, i2 = this.chart.data.labels || [], { xScale: s2, yScale: n2 } = e2, o2 = this.getParsed(t2), a2 = s2.getLabelForValue(o2.x), r2 = n2.getLabelForValue(o2.y);
|
|
return { label: i2[t2] || "", value: "(" + a2 + ", " + r2 + ")" };
|
|
}
|
|
update(t2) {
|
|
const e2 = this._cachedMeta, { data: i2 = [] } = e2, s2 = this.chart._animationsDisabled;
|
|
let { start: n2, count: o2 } = pt(e2, i2, s2);
|
|
if (this._drawStart = n2, this._drawCount = o2, mt(e2) && (n2 = 0, o2 = i2.length), this.options.showLine) {
|
|
this.datasetElementType || this.addElements();
|
|
const { dataset: n3, _dataset: o3 } = e2;
|
|
n3._chart = this.chart, n3._datasetIndex = this.index, n3._decimated = !!o3._decimated, n3.points = i2;
|
|
const a2 = this.resolveDatasetElementOptions(t2);
|
|
a2.segment = this.options.segment, this.updateElement(n3, void 0, { animated: !s2, options: a2 }, t2);
|
|
} else this.datasetElementType && (delete e2.dataset, this.datasetElementType = false);
|
|
this.updateElements(i2, n2, o2, t2);
|
|
}
|
|
addElements() {
|
|
const { showLine: t2 } = this.options;
|
|
!this.datasetElementType && t2 && (this.datasetElementType = this.chart.registry.getElement("line")), super.addElements();
|
|
}
|
|
updateElements(t2, e2, i2, n2) {
|
|
const o2 = "reset" === n2, { iScale: a2, vScale: r2, _stacked: l2, _dataset: h2 } = this._cachedMeta, c2 = this.resolveDataElementOptions(e2, n2), d2 = this.getSharedOptions(c2), u2 = this.includeOptions(n2, d2), f2 = a2.axis, g2 = r2.axis, { spanGaps: p2, segment: m2 } = this.options, b2 = N(p2) ? p2 : Number.POSITIVE_INFINITY, x2 = this.chart._animationsDisabled || o2 || "none" === n2;
|
|
let _2 = e2 > 0 && this.getParsed(e2 - 1);
|
|
for (let c3 = e2; c3 < e2 + i2; ++c3) {
|
|
const e3 = t2[c3], i3 = this.getParsed(c3), p3 = x2 ? e3 : {}, y2 = s(i3[g2]), v2 = p3[f2] = a2.getPixelForValue(i3[f2], c3), M2 = p3[g2] = o2 || y2 ? r2.getBasePixel() : r2.getPixelForValue(l2 ? this.applyStack(r2, i3, l2) : i3[g2], c3);
|
|
p3.skip = isNaN(v2) || isNaN(M2) || y2, p3.stop = c3 > 0 && Math.abs(i3[f2] - _2[f2]) > b2, m2 && (p3.parsed = i3, p3.raw = h2.data[c3]), u2 && (p3.options = d2 || this.resolveDataElementOptions(c3, e3.active ? "active" : n2)), x2 || this.updateElement(e3, c3, p3, n2), _2 = i3;
|
|
}
|
|
this.updateSharedOptions(d2, n2, c2);
|
|
}
|
|
getMaxOverflow() {
|
|
const t2 = this._cachedMeta, e2 = t2.data || [];
|
|
if (!this.options.showLine) {
|
|
let t3 = 0;
|
|
for (let i3 = e2.length - 1; i3 >= 0; --i3) t3 = Math.max(t3, e2[i3].size(this.resolveDataElementOptions(i3)) / 2);
|
|
return t3 > 0 && t3;
|
|
}
|
|
const i2 = t2.dataset, s2 = i2.options && i2.options.borderWidth || 0;
|
|
if (!e2.length) return s2;
|
|
const n2 = e2[0].size(this.resolveDataElementOptions(0)), o2 = e2[e2.length - 1].size(this.resolveDataElementOptions(e2.length - 1));
|
|
return Math.max(s2, n2, o2) / 2;
|
|
}
|
|
}, __publicField(_f, "id", "scatter"), __publicField(_f, "defaults", { datasetElementType: false, dataElementType: "point", showLine: false, fill: false }), __publicField(_f, "overrides", { interaction: { mode: "point" }, scales: { x: { type: "linear" }, y: { type: "linear" } } }), _f) });
|
|
function Un(t2, e2, i2, s2) {
|
|
const n2 = vi(t2.options.borderRadius, ["outerStart", "outerEnd", "innerStart", "innerEnd"]);
|
|
const o2 = (i2 - e2) / 2, a2 = Math.min(o2, s2 * e2 / 2), r2 = (t3) => {
|
|
const e3 = (i2 - Math.min(o2, t3)) * s2 / 2;
|
|
return J(t3, 0, Math.min(o2, e3));
|
|
};
|
|
return { outerStart: r2(n2.outerStart), outerEnd: r2(n2.outerEnd), innerStart: J(n2.innerStart, 0, a2), innerEnd: J(n2.innerEnd, 0, a2) };
|
|
}
|
|
function Xn(t2, e2, i2, s2) {
|
|
return { x: i2 + t2 * Math.cos(e2), y: s2 + t2 * Math.sin(e2) };
|
|
}
|
|
function qn(t2, e2, i2, s2, n2, o2) {
|
|
const { x: a2, y: r2, startAngle: l2, pixelMargin: h2, innerRadius: c2 } = e2, d2 = Math.max(e2.outerRadius + s2 + i2 - h2, 0), u2 = c2 > 0 ? c2 + s2 + i2 + h2 : 0;
|
|
let f2 = 0;
|
|
const g2 = n2 - l2;
|
|
if (s2) {
|
|
const t3 = ((c2 > 0 ? c2 - s2 : 0) + (d2 > 0 ? d2 - s2 : 0)) / 2;
|
|
f2 = (g2 - (0 !== t3 ? g2 * t3 / (t3 + s2) : g2)) / 2;
|
|
}
|
|
const p2 = (g2 - Math.max(1e-3, g2 * d2 - i2 / C) / d2) / 2, m2 = l2 + p2 + f2, b2 = n2 - p2 - f2, { outerStart: x2, outerEnd: _2, innerStart: y2, innerEnd: v2 } = Un(e2, u2, d2, b2 - m2), M2 = d2 - x2, w2 = d2 - _2, k2 = m2 + x2 / M2, S2 = b2 - _2 / w2, P2 = u2 + y2, D2 = u2 + v2, O2 = m2 + y2 / P2, A2 = b2 - v2 / D2;
|
|
if (t2.beginPath(), o2) {
|
|
const e3 = (k2 + S2) / 2;
|
|
if (t2.arc(a2, r2, d2, k2, e3), t2.arc(a2, r2, d2, e3, S2), _2 > 0) {
|
|
const e4 = Xn(w2, S2, a2, r2);
|
|
t2.arc(e4.x, e4.y, _2, S2, b2 + E);
|
|
}
|
|
const i3 = Xn(D2, b2, a2, r2);
|
|
if (t2.lineTo(i3.x, i3.y), v2 > 0) {
|
|
const e4 = Xn(D2, A2, a2, r2);
|
|
t2.arc(e4.x, e4.y, v2, b2 + E, A2 + Math.PI);
|
|
}
|
|
const s3 = (b2 - v2 / u2 + (m2 + y2 / u2)) / 2;
|
|
if (t2.arc(a2, r2, u2, b2 - v2 / u2, s3, true), t2.arc(a2, r2, u2, s3, m2 + y2 / u2, true), y2 > 0) {
|
|
const e4 = Xn(P2, O2, a2, r2);
|
|
t2.arc(e4.x, e4.y, y2, O2 + Math.PI, m2 - E);
|
|
}
|
|
const n3 = Xn(M2, m2, a2, r2);
|
|
if (t2.lineTo(n3.x, n3.y), x2 > 0) {
|
|
const e4 = Xn(M2, k2, a2, r2);
|
|
t2.arc(e4.x, e4.y, x2, m2 - E, k2);
|
|
}
|
|
} else {
|
|
t2.moveTo(a2, r2);
|
|
const e3 = Math.cos(k2) * d2 + a2, i3 = Math.sin(k2) * d2 + r2;
|
|
t2.lineTo(e3, i3);
|
|
const s3 = Math.cos(S2) * d2 + a2, n3 = Math.sin(S2) * d2 + r2;
|
|
t2.lineTo(s3, n3);
|
|
}
|
|
t2.closePath();
|
|
}
|
|
function Kn(t2, e2, i2, s2, n2) {
|
|
const { fullCircles: o2, startAngle: a2, circumference: r2, options: l2 } = e2, { borderWidth: h2, borderJoinStyle: c2, borderDash: d2, borderDashOffset: u2 } = l2, f2 = "inner" === l2.borderAlign;
|
|
if (!h2) return;
|
|
t2.setLineDash(d2 || []), t2.lineDashOffset = u2, f2 ? (t2.lineWidth = 2 * h2, t2.lineJoin = c2 || "round") : (t2.lineWidth = h2, t2.lineJoin = c2 || "bevel");
|
|
let g2 = e2.endAngle;
|
|
if (o2) {
|
|
qn(t2, e2, i2, s2, g2, n2);
|
|
for (let e3 = 0; e3 < o2; ++e3) t2.stroke();
|
|
isNaN(r2) || (g2 = a2 + (r2 % O || O));
|
|
}
|
|
f2 && function(t3, e3, i3) {
|
|
const { startAngle: s3, pixelMargin: n3, x: o3, y: a3, outerRadius: r3, innerRadius: l3 } = e3;
|
|
let h3 = n3 / r3;
|
|
t3.beginPath(), t3.arc(o3, a3, r3, s3 - h3, i3 + h3), l3 > n3 ? (h3 = n3 / l3, t3.arc(o3, a3, l3, i3 + h3, s3 - h3, true)) : t3.arc(o3, a3, n3, i3 + E, s3 - E), t3.closePath(), t3.clip();
|
|
}(t2, e2, g2), o2 || (qn(t2, e2, i2, s2, g2, n2), t2.stroke());
|
|
}
|
|
function Gn(t2, e2, i2 = e2) {
|
|
t2.lineCap = l(i2.borderCapStyle, e2.borderCapStyle), t2.setLineDash(l(i2.borderDash, e2.borderDash)), t2.lineDashOffset = l(i2.borderDashOffset, e2.borderDashOffset), t2.lineJoin = l(i2.borderJoinStyle, e2.borderJoinStyle), t2.lineWidth = l(i2.borderWidth, e2.borderWidth), t2.strokeStyle = l(i2.borderColor, e2.borderColor);
|
|
}
|
|
function Zn(t2, e2, i2) {
|
|
t2.lineTo(i2.x, i2.y);
|
|
}
|
|
function Jn(t2, e2, i2 = {}) {
|
|
const s2 = t2.length, { start: n2 = 0, end: o2 = s2 - 1 } = i2, { start: a2, end: r2 } = e2, l2 = Math.max(n2, a2), h2 = Math.min(o2, r2), c2 = n2 < a2 && o2 < a2 || n2 > r2 && o2 > r2;
|
|
return { count: s2, start: l2, loop: e2.loop, ilen: h2 < l2 && !c2 ? s2 + h2 - l2 : h2 - l2 };
|
|
}
|
|
function Qn(t2, e2, i2, s2) {
|
|
const { points: n2, options: o2 } = e2, { count: a2, start: r2, loop: l2, ilen: h2 } = Jn(n2, i2, s2), c2 = function(t3) {
|
|
return t3.stepped ? Fe : t3.tension || "monotone" === t3.cubicInterpolationMode ? Ve : Zn;
|
|
}(o2);
|
|
let d2, u2, f2, { move: g2 = true, reverse: p2 } = s2 || {};
|
|
for (d2 = 0; d2 <= h2; ++d2) u2 = n2[(r2 + (p2 ? h2 - d2 : d2)) % a2], u2.skip || (g2 ? (t2.moveTo(u2.x, u2.y), g2 = false) : c2(t2, f2, u2, p2, o2.stepped), f2 = u2);
|
|
return l2 && (u2 = n2[(r2 + (p2 ? h2 : 0)) % a2], c2(t2, f2, u2, p2, o2.stepped)), !!l2;
|
|
}
|
|
function to(t2, e2, i2, s2) {
|
|
const n2 = e2.points, { count: o2, start: a2, ilen: r2 } = Jn(n2, i2, s2), { move: l2 = true, reverse: h2 } = s2 || {};
|
|
let c2, d2, u2, f2, g2, p2, m2 = 0, b2 = 0;
|
|
const x2 = (t3) => (a2 + (h2 ? r2 - t3 : t3)) % o2, _2 = () => {
|
|
f2 !== g2 && (t2.lineTo(m2, g2), t2.lineTo(m2, f2), t2.lineTo(m2, p2));
|
|
};
|
|
for (l2 && (d2 = n2[x2(0)], t2.moveTo(d2.x, d2.y)), c2 = 0; c2 <= r2; ++c2) {
|
|
if (d2 = n2[x2(c2)], d2.skip) continue;
|
|
const e3 = d2.x, i3 = d2.y, s3 = 0 | e3;
|
|
s3 === u2 ? (i3 < f2 ? f2 = i3 : i3 > g2 && (g2 = i3), m2 = (b2 * m2 + e3) / ++b2) : (_2(), t2.lineTo(e3, i3), u2 = s3, b2 = 0, f2 = g2 = i3), p2 = i3;
|
|
}
|
|
_2();
|
|
}
|
|
function eo(t2) {
|
|
const e2 = t2.options, i2 = e2.borderDash && e2.borderDash.length;
|
|
return !(t2._decimated || t2._loop || e2.tension || "monotone" === e2.cubicInterpolationMode || e2.stepped || i2) ? to : Qn;
|
|
}
|
|
const io = "function" == typeof Path2D;
|
|
function so(t2, e2, i2, s2) {
|
|
io && !e2.options.segment ? function(t3, e3, i3, s3) {
|
|
let n2 = e3._path;
|
|
n2 || (n2 = e3._path = new Path2D(), e3.path(n2, i3, s3) && n2.closePath()), Gn(t3, e3.options), t3.stroke(n2);
|
|
}(t2, e2, i2, s2) : function(t3, e3, i3, s3) {
|
|
const { segments: n2, options: o2 } = e3, a2 = eo(e3);
|
|
for (const r2 of n2) Gn(t3, o2, r2.style), t3.beginPath(), a2(t3, e3, r2, { start: i3, end: i3 + s3 - 1 }) && t3.closePath(), t3.stroke();
|
|
}(t2, e2, i2, s2);
|
|
}
|
|
class no extends Hs {
|
|
constructor(t2) {
|
|
super(), this.animated = true, this.options = void 0, this._chart = void 0, this._loop = void 0, this._fullLoop = void 0, this._path = void 0, this._points = void 0, this._segments = void 0, this._decimated = false, this._pointsUpdated = false, this._datasetIndex = void 0, t2 && Object.assign(this, t2);
|
|
}
|
|
updateControlPoints(t2, e2) {
|
|
const i2 = this.options;
|
|
if ((i2.tension || "monotone" === i2.cubicInterpolationMode) && !i2.stepped && !this._pointsUpdated) {
|
|
const s2 = i2.spanGaps ? this._loop : this._fullLoop;
|
|
hi(this._points, i2, t2, s2, e2), this._pointsUpdated = true;
|
|
}
|
|
}
|
|
set points(t2) {
|
|
this._points = t2, delete this._segments, delete this._path, this._pointsUpdated = false;
|
|
}
|
|
get points() {
|
|
return this._points;
|
|
}
|
|
get segments() {
|
|
return this._segments || (this._segments = zi(this, this.options.segment));
|
|
}
|
|
first() {
|
|
const t2 = this.segments, e2 = this.points;
|
|
return t2.length && e2[t2[0].start];
|
|
}
|
|
last() {
|
|
const t2 = this.segments, e2 = this.points, i2 = t2.length;
|
|
return i2 && e2[t2[i2 - 1].end];
|
|
}
|
|
interpolate(t2, e2) {
|
|
const i2 = this.options, s2 = t2[e2], n2 = this.points, o2 = Ii(this, { property: e2, start: s2, end: s2 });
|
|
if (!o2.length) return;
|
|
const a2 = [], r2 = function(t3) {
|
|
return t3.stepped ? pi : t3.tension || "monotone" === t3.cubicInterpolationMode ? mi : gi;
|
|
}(i2);
|
|
let l2, h2;
|
|
for (l2 = 0, h2 = o2.length; l2 < h2; ++l2) {
|
|
const { start: h3, end: c2 } = o2[l2], d2 = n2[h3], u2 = n2[c2];
|
|
if (d2 === u2) {
|
|
a2.push(d2);
|
|
continue;
|
|
}
|
|
const f2 = r2(d2, u2, Math.abs((s2 - d2[e2]) / (u2[e2] - d2[e2])), i2.stepped);
|
|
f2[e2] = t2[e2], a2.push(f2);
|
|
}
|
|
return 1 === a2.length ? a2[0] : a2;
|
|
}
|
|
pathSegment(t2, e2, i2) {
|
|
return eo(this)(t2, this, e2, i2);
|
|
}
|
|
path(t2, e2, i2) {
|
|
const s2 = this.segments, n2 = eo(this);
|
|
let o2 = this._loop;
|
|
e2 = e2 || 0, i2 = i2 || this.points.length - e2;
|
|
for (const a2 of s2) o2 &= n2(t2, this, a2, { start: e2, end: e2 + i2 - 1 });
|
|
return !!o2;
|
|
}
|
|
draw(t2, e2, i2, s2) {
|
|
const n2 = this.options || {};
|
|
(this.points || []).length && n2.borderWidth && (t2.save(), so(t2, this, i2, s2), t2.restore()), this.animated && (this._pointsUpdated = false, this._path = void 0);
|
|
}
|
|
}
|
|
__publicField(no, "id", "line");
|
|
__publicField(no, "defaults", { borderCapStyle: "butt", borderDash: [], borderDashOffset: 0, borderJoinStyle: "miter", borderWidth: 3, capBezierPoints: true, cubicInterpolationMode: "default", fill: false, spanGaps: false, stepped: false, tension: 0 });
|
|
__publicField(no, "defaultRoutes", { backgroundColor: "backgroundColor", borderColor: "borderColor" });
|
|
__publicField(no, "descriptors", { _scriptable: true, _indexable: (t2) => "borderDash" !== t2 && "fill" !== t2 });
|
|
function oo(t2, e2, i2, s2) {
|
|
const n2 = t2.options, { [i2]: o2 } = t2.getProps([i2], s2);
|
|
return Math.abs(e2 - o2) < n2.radius + n2.hitRadius;
|
|
}
|
|
function ao(t2, e2) {
|
|
const { x: i2, y: s2, base: n2, width: o2, height: a2 } = t2.getProps(["x", "y", "base", "width", "height"], e2);
|
|
let r2, l2, h2, c2, d2;
|
|
return t2.horizontal ? (d2 = a2 / 2, r2 = Math.min(i2, n2), l2 = Math.max(i2, n2), h2 = s2 - d2, c2 = s2 + d2) : (d2 = o2 / 2, r2 = i2 - d2, l2 = i2 + d2, h2 = Math.min(s2, n2), c2 = Math.max(s2, n2)), { left: r2, top: h2, right: l2, bottom: c2 };
|
|
}
|
|
function ro(t2, e2, i2, s2) {
|
|
return t2 ? 0 : J(e2, i2, s2);
|
|
}
|
|
function lo(t2) {
|
|
const e2 = ao(t2), i2 = e2.right - e2.left, s2 = e2.bottom - e2.top, n2 = function(t3, e3, i3) {
|
|
const s3 = t3.options.borderWidth, n3 = t3.borderSkipped, o2 = Mi(s3);
|
|
return { t: ro(n3.top, o2.top, 0, i3), r: ro(n3.right, o2.right, 0, e3), b: ro(n3.bottom, o2.bottom, 0, i3), l: ro(n3.left, o2.left, 0, e3) };
|
|
}(t2, i2 / 2, s2 / 2), a2 = function(t3, e3, i3) {
|
|
const { enableBorderRadius: s3 } = t3.getProps(["enableBorderRadius"]), n3 = t3.options.borderRadius, a3 = wi(n3), r2 = Math.min(e3, i3), l2 = t3.borderSkipped, h2 = s3 || o(n3);
|
|
return { topLeft: ro(!h2 || l2.top || l2.left, a3.topLeft, 0, r2), topRight: ro(!h2 || l2.top || l2.right, a3.topRight, 0, r2), bottomLeft: ro(!h2 || l2.bottom || l2.left, a3.bottomLeft, 0, r2), bottomRight: ro(!h2 || l2.bottom || l2.right, a3.bottomRight, 0, r2) };
|
|
}(t2, i2 / 2, s2 / 2);
|
|
return { outer: { x: e2.left, y: e2.top, w: i2, h: s2, radius: a2 }, inner: { x: e2.left + n2.l, y: e2.top + n2.t, w: i2 - n2.l - n2.r, h: s2 - n2.t - n2.b, radius: { topLeft: Math.max(0, a2.topLeft - Math.max(n2.t, n2.l)), topRight: Math.max(0, a2.topRight - Math.max(n2.t, n2.r)), bottomLeft: Math.max(0, a2.bottomLeft - Math.max(n2.b, n2.l)), bottomRight: Math.max(0, a2.bottomRight - Math.max(n2.b, n2.r)) } } };
|
|
}
|
|
function ho(t2, e2, i2, s2) {
|
|
const n2 = null === e2, o2 = null === i2, a2 = t2 && !(n2 && o2) && ao(t2, s2);
|
|
return a2 && (n2 || tt(e2, a2.left, a2.right)) && (o2 || tt(i2, a2.top, a2.bottom));
|
|
}
|
|
function co(t2, e2) {
|
|
t2.rect(e2.x, e2.y, e2.w, e2.h);
|
|
}
|
|
function uo(t2, e2, i2 = {}) {
|
|
const s2 = t2.x !== i2.x ? -e2 : 0, n2 = t2.y !== i2.y ? -e2 : 0, o2 = (t2.x + t2.w !== i2.x + i2.w ? e2 : 0) - s2, a2 = (t2.y + t2.h !== i2.y + i2.h ? e2 : 0) - n2;
|
|
return { x: t2.x + s2, y: t2.y + n2, w: t2.w + o2, h: t2.h + a2, radius: t2.radius };
|
|
}
|
|
var fo = Object.freeze({ __proto__: null, ArcElement: (_g = class extends Hs {
|
|
constructor(t2) {
|
|
super();
|
|
__publicField(this, "circumference");
|
|
__publicField(this, "endAngle");
|
|
__publicField(this, "fullCircles");
|
|
__publicField(this, "innerRadius");
|
|
__publicField(this, "outerRadius");
|
|
__publicField(this, "pixelMargin");
|
|
__publicField(this, "startAngle");
|
|
this.options = void 0, this.circumference = void 0, this.startAngle = void 0, this.endAngle = void 0, this.innerRadius = void 0, this.outerRadius = void 0, this.pixelMargin = 0, this.fullCircles = 0, t2 && Object.assign(this, t2);
|
|
}
|
|
inRange(t2, e2, i2) {
|
|
const s2 = this.getProps(["x", "y"], i2), { angle: n2, distance: o2 } = X(s2, { x: t2, y: e2 }), { startAngle: a2, endAngle: r2, innerRadius: h2, outerRadius: c2, circumference: d2 } = this.getProps(["startAngle", "endAngle", "innerRadius", "outerRadius", "circumference"], i2), u2 = (this.options.spacing + this.options.borderWidth) / 2, f2 = l(d2, r2 - a2) >= O || Z(n2, a2, r2), g2 = tt(o2, h2 + u2, c2 + u2);
|
|
return f2 && g2;
|
|
}
|
|
getCenterPoint(t2) {
|
|
const { x: e2, y: i2, startAngle: s2, endAngle: n2, innerRadius: o2, outerRadius: a2 } = this.getProps(["x", "y", "startAngle", "endAngle", "innerRadius", "outerRadius"], t2), { offset: r2, spacing: l2 } = this.options, h2 = (s2 + n2) / 2, c2 = (o2 + a2 + l2 + r2) / 2;
|
|
return { x: e2 + Math.cos(h2) * c2, y: i2 + Math.sin(h2) * c2 };
|
|
}
|
|
tooltipPosition(t2) {
|
|
return this.getCenterPoint(t2);
|
|
}
|
|
draw(t2) {
|
|
const { options: e2, circumference: i2 } = this, s2 = (e2.offset || 0) / 4, n2 = (e2.spacing || 0) / 2, o2 = e2.circular;
|
|
if (this.pixelMargin = "inner" === e2.borderAlign ? 0.33 : 0, this.fullCircles = i2 > O ? Math.floor(i2 / O) : 0, 0 === i2 || this.innerRadius < 0 || this.outerRadius < 0) return;
|
|
t2.save();
|
|
const a2 = (this.startAngle + this.endAngle) / 2;
|
|
t2.translate(Math.cos(a2) * s2, Math.sin(a2) * s2);
|
|
const r2 = s2 * (1 - Math.sin(Math.min(C, i2 || 0)));
|
|
t2.fillStyle = e2.backgroundColor, t2.strokeStyle = e2.borderColor, function(t3, e3, i3, s3, n3) {
|
|
const { fullCircles: o3, startAngle: a3, circumference: r3 } = e3;
|
|
let l2 = e3.endAngle;
|
|
if (o3) {
|
|
qn(t3, e3, i3, s3, l2, n3);
|
|
for (let e4 = 0; e4 < o3; ++e4) t3.fill();
|
|
isNaN(r3) || (l2 = a3 + (r3 % O || O));
|
|
}
|
|
qn(t3, e3, i3, s3, l2, n3), t3.fill();
|
|
}(t2, this, r2, n2, o2), Kn(t2, this, r2, n2, o2), t2.restore();
|
|
}
|
|
}, __publicField(_g, "id", "arc"), __publicField(_g, "defaults", { borderAlign: "center", borderColor: "#fff", borderDash: [], borderDashOffset: 0, borderJoinStyle: void 0, borderRadius: 0, borderWidth: 2, offset: 0, spacing: 0, angle: void 0, circular: true }), __publicField(_g, "defaultRoutes", { backgroundColor: "backgroundColor" }), __publicField(_g, "descriptors", { _scriptable: true, _indexable: (t2) => "borderDash" !== t2 }), _g), BarElement: (_h = class extends Hs {
|
|
constructor(t2) {
|
|
super(), this.options = void 0, this.horizontal = void 0, this.base = void 0, this.width = void 0, this.height = void 0, this.inflateAmount = void 0, t2 && Object.assign(this, t2);
|
|
}
|
|
draw(t2) {
|
|
const { inflateAmount: e2, options: { borderColor: i2, backgroundColor: s2 } } = this, { inner: n2, outer: o2 } = lo(this), a2 = (r2 = o2.radius).topLeft || r2.topRight || r2.bottomLeft || r2.bottomRight ? He : co;
|
|
var r2;
|
|
t2.save(), o2.w === n2.w && o2.h === n2.h || (t2.beginPath(), a2(t2, uo(o2, e2, n2)), t2.clip(), a2(t2, uo(n2, -e2, o2)), t2.fillStyle = i2, t2.fill("evenodd")), t2.beginPath(), a2(t2, uo(n2, e2)), t2.fillStyle = s2, t2.fill(), t2.restore();
|
|
}
|
|
inRange(t2, e2, i2) {
|
|
return ho(this, t2, e2, i2);
|
|
}
|
|
inXRange(t2, e2) {
|
|
return ho(this, t2, null, e2);
|
|
}
|
|
inYRange(t2, e2) {
|
|
return ho(this, null, t2, e2);
|
|
}
|
|
getCenterPoint(t2) {
|
|
const { x: e2, y: i2, base: s2, horizontal: n2 } = this.getProps(["x", "y", "base", "horizontal"], t2);
|
|
return { x: n2 ? (e2 + s2) / 2 : e2, y: n2 ? i2 : (i2 + s2) / 2 };
|
|
}
|
|
getRange(t2) {
|
|
return "x" === t2 ? this.width / 2 : this.height / 2;
|
|
}
|
|
}, __publicField(_h, "id", "bar"), __publicField(_h, "defaults", { borderSkipped: "start", borderWidth: 0, borderRadius: 0, inflateAmount: "auto", pointStyle: void 0 }), __publicField(_h, "defaultRoutes", { backgroundColor: "backgroundColor", borderColor: "borderColor" }), _h), LineElement: no, PointElement: (_i2 = class extends Hs {
|
|
constructor(t2) {
|
|
super();
|
|
__publicField(this, "parsed");
|
|
__publicField(this, "skip");
|
|
__publicField(this, "stop");
|
|
this.options = void 0, this.parsed = void 0, this.skip = void 0, this.stop = void 0, t2 && Object.assign(this, t2);
|
|
}
|
|
inRange(t2, e2, i2) {
|
|
const s2 = this.options, { x: n2, y: o2 } = this.getProps(["x", "y"], i2);
|
|
return Math.pow(t2 - n2, 2) + Math.pow(e2 - o2, 2) < Math.pow(s2.hitRadius + s2.radius, 2);
|
|
}
|
|
inXRange(t2, e2) {
|
|
return oo(this, t2, "x", e2);
|
|
}
|
|
inYRange(t2, e2) {
|
|
return oo(this, t2, "y", e2);
|
|
}
|
|
getCenterPoint(t2) {
|
|
const { x: e2, y: i2 } = this.getProps(["x", "y"], t2);
|
|
return { x: e2, y: i2 };
|
|
}
|
|
size(t2) {
|
|
let e2 = (t2 = t2 || this.options || {}).radius || 0;
|
|
e2 = Math.max(e2, e2 && t2.hoverRadius || 0);
|
|
return 2 * (e2 + (e2 && t2.borderWidth || 0));
|
|
}
|
|
draw(t2, e2) {
|
|
const i2 = this.options;
|
|
this.skip || i2.radius < 0.1 || !Re(this, e2, this.size(i2) / 2) || (t2.strokeStyle = i2.borderColor, t2.lineWidth = i2.borderWidth, t2.fillStyle = i2.backgroundColor, Le(t2, i2, this.x, this.y));
|
|
}
|
|
getRange() {
|
|
const t2 = this.options || {};
|
|
return t2.radius + t2.hitRadius;
|
|
}
|
|
}, __publicField(_i2, "id", "point"), __publicField(_i2, "defaults", { borderWidth: 1, hitRadius: 1, hoverBorderWidth: 1, hoverRadius: 4, pointStyle: "circle", radius: 3, rotation: 0 }), __publicField(_i2, "defaultRoutes", { backgroundColor: "backgroundColor", borderColor: "borderColor" }), _i2) });
|
|
function go(t2, e2, i2, s2) {
|
|
const n2 = t2.indexOf(e2);
|
|
if (-1 === n2) return ((t3, e3, i3, s3) => ("string" == typeof e3 ? (i3 = t3.push(e3) - 1, s3.unshift({ index: i3, label: e3 })) : isNaN(e3) && (i3 = null), i3))(t2, e2, i2, s2);
|
|
return n2 !== t2.lastIndexOf(e2) ? i2 : n2;
|
|
}
|
|
function po(t2) {
|
|
const e2 = this.getLabels();
|
|
return t2 >= 0 && t2 < e2.length ? e2[t2] : t2;
|
|
}
|
|
function mo(t2, e2, { horizontal: i2, minRotation: s2 }) {
|
|
const n2 = $(s2), o2 = (i2 ? Math.sin(n2) : Math.cos(n2)) || 1e-3, a2 = 0.75 * e2 * ("" + t2).length;
|
|
return Math.min(e2 / o2, a2);
|
|
}
|
|
class bo extends Js {
|
|
constructor(t2) {
|
|
super(t2), this.start = void 0, this.end = void 0, this._startValue = void 0, this._endValue = void 0, this._valueRange = 0;
|
|
}
|
|
parse(t2, e2) {
|
|
return s(t2) || ("number" == typeof t2 || t2 instanceof Number) && !isFinite(+t2) ? null : +t2;
|
|
}
|
|
handleTickRangeOptions() {
|
|
const { beginAtZero: t2 } = this.options, { minDefined: e2, maxDefined: i2 } = this.getUserBounds();
|
|
let { min: s2, max: n2 } = this;
|
|
const o2 = (t3) => s2 = e2 ? s2 : t3, a2 = (t3) => n2 = i2 ? n2 : t3;
|
|
if (t2) {
|
|
const t3 = F(s2), e3 = F(n2);
|
|
t3 < 0 && e3 < 0 ? a2(0) : t3 > 0 && e3 > 0 && o2(0);
|
|
}
|
|
if (s2 === n2) {
|
|
let e3 = 0 === n2 ? 1 : Math.abs(0.05 * n2);
|
|
a2(n2 + e3), t2 || o2(s2 - e3);
|
|
}
|
|
this.min = s2, this.max = n2;
|
|
}
|
|
getTickLimit() {
|
|
const t2 = this.options.ticks;
|
|
let e2, { maxTicksLimit: i2, stepSize: s2 } = t2;
|
|
return s2 ? (e2 = Math.ceil(this.max / s2) - Math.floor(this.min / s2) + 1, e2 > 1e3 && (console.warn(`scales.${this.id}.ticks.stepSize: ${s2} would result generating up to ${e2} ticks. Limiting to 1000.`), e2 = 1e3)) : (e2 = this.computeTickLimit(), i2 = i2 || 11), i2 && (e2 = Math.min(i2, e2)), e2;
|
|
}
|
|
computeTickLimit() {
|
|
return Number.POSITIVE_INFINITY;
|
|
}
|
|
buildTicks() {
|
|
const t2 = this.options, e2 = t2.ticks;
|
|
let i2 = this.getTickLimit();
|
|
i2 = Math.max(2, i2);
|
|
const n2 = function(t3, e3) {
|
|
const i3 = [], { bounds: n3, step: o2, min: a2, max: r2, precision: l2, count: h2, maxTicks: c2, maxDigits: d2, includeBounds: u2 } = t3, f2 = o2 || 1, g2 = c2 - 1, { min: p2, max: m2 } = e3, b2 = !s(a2), x2 = !s(r2), _2 = !s(h2), y2 = (m2 - p2) / (d2 + 1);
|
|
let v2, M2, w2, k2, S2 = B((m2 - p2) / g2 / f2) * f2;
|
|
if (S2 < 1e-14 && !b2 && !x2) return [{ value: p2 }, { value: m2 }];
|
|
k2 = Math.ceil(m2 / S2) - Math.floor(p2 / S2), k2 > g2 && (S2 = B(k2 * S2 / g2 / f2) * f2), s(l2) || (v2 = Math.pow(10, l2), S2 = Math.ceil(S2 * v2) / v2), "ticks" === n3 ? (M2 = Math.floor(p2 / S2) * S2, w2 = Math.ceil(m2 / S2) * S2) : (M2 = p2, w2 = m2), b2 && x2 && o2 && H((r2 - a2) / o2, S2 / 1e3) ? (k2 = Math.round(Math.min((r2 - a2) / S2, c2)), S2 = (r2 - a2) / k2, M2 = a2, w2 = r2) : _2 ? (M2 = b2 ? a2 : M2, w2 = x2 ? r2 : w2, k2 = h2 - 1, S2 = (w2 - M2) / k2) : (k2 = (w2 - M2) / S2, k2 = V(k2, Math.round(k2), S2 / 1e3) ? Math.round(k2) : Math.ceil(k2));
|
|
const P2 = Math.max(U(S2), U(M2));
|
|
v2 = Math.pow(10, s(l2) ? P2 : l2), M2 = Math.round(M2 * v2) / v2, w2 = Math.round(w2 * v2) / v2;
|
|
let D2 = 0;
|
|
for (b2 && (u2 && M2 !== a2 ? (i3.push({ value: a2 }), M2 < a2 && D2++, V(Math.round((M2 + D2 * S2) * v2) / v2, a2, mo(a2, y2, t3)) && D2++) : M2 < a2 && D2++); D2 < k2; ++D2) {
|
|
const t4 = Math.round((M2 + D2 * S2) * v2) / v2;
|
|
if (x2 && t4 > r2) break;
|
|
i3.push({ value: t4 });
|
|
}
|
|
return x2 && u2 && w2 !== r2 ? i3.length && V(i3[i3.length - 1].value, r2, mo(r2, y2, t3)) ? i3[i3.length - 1].value = r2 : i3.push({ value: r2 }) : x2 && w2 !== r2 || i3.push({ value: w2 }), i3;
|
|
}({ maxTicks: i2, bounds: t2.bounds, min: t2.min, max: t2.max, precision: e2.precision, step: e2.stepSize, count: e2.count, maxDigits: this._maxDigits(), horizontal: this.isHorizontal(), minRotation: e2.minRotation || 0, includeBounds: false !== e2.includeBounds }, this._range || this);
|
|
return "ticks" === t2.bounds && j(n2, this, "value"), t2.reverse ? (n2.reverse(), this.start = this.max, this.end = this.min) : (this.start = this.min, this.end = this.max), n2;
|
|
}
|
|
configure() {
|
|
const t2 = this.ticks;
|
|
let e2 = this.min, i2 = this.max;
|
|
if (super.configure(), this.options.offset && t2.length) {
|
|
const s2 = (i2 - e2) / Math.max(t2.length - 1, 1) / 2;
|
|
e2 -= s2, i2 += s2;
|
|
}
|
|
this._startValue = e2, this._endValue = i2, this._valueRange = i2 - e2;
|
|
}
|
|
getLabelForValue(t2) {
|
|
return ne(t2, this.chart.options.locale, this.options.ticks.format);
|
|
}
|
|
}
|
|
class xo extends bo {
|
|
determineDataLimits() {
|
|
const { min: t2, max: e2 } = this.getMinMax(true);
|
|
this.min = a(t2) ? t2 : 0, this.max = a(e2) ? e2 : 1, this.handleTickRangeOptions();
|
|
}
|
|
computeTickLimit() {
|
|
const t2 = this.isHorizontal(), e2 = t2 ? this.width : this.height, i2 = $(this.options.ticks.minRotation), s2 = (t2 ? Math.sin(i2) : Math.cos(i2)) || 1e-3, n2 = this._resolveTickFontOptions(0);
|
|
return Math.ceil(e2 / Math.min(40, n2.lineHeight / s2));
|
|
}
|
|
getPixelForValue(t2) {
|
|
return null === t2 ? NaN : this.getPixelForDecimal((t2 - this._startValue) / this._valueRange);
|
|
}
|
|
getValueForPixel(t2) {
|
|
return this._startValue + this.getDecimalForPixel(t2) * this._valueRange;
|
|
}
|
|
}
|
|
__publicField(xo, "id", "linear");
|
|
__publicField(xo, "defaults", { ticks: { callback: ae.formatters.numeric } });
|
|
const _o = (t2) => Math.floor(z(t2)), yo = (t2, e2) => Math.pow(10, _o(t2) + e2);
|
|
function vo(t2) {
|
|
return 1 === t2 / Math.pow(10, _o(t2));
|
|
}
|
|
function Mo(t2, e2, i2) {
|
|
const s2 = Math.pow(10, i2), n2 = Math.floor(t2 / s2);
|
|
return Math.ceil(e2 / s2) - n2;
|
|
}
|
|
function wo(t2, { min: e2, max: i2 }) {
|
|
e2 = r(t2.min, e2);
|
|
const s2 = [], n2 = _o(e2);
|
|
let o2 = function(t3, e3) {
|
|
let i3 = _o(e3 - t3);
|
|
for (; Mo(t3, e3, i3) > 10; ) i3++;
|
|
for (; Mo(t3, e3, i3) < 10; ) i3--;
|
|
return Math.min(i3, _o(t3));
|
|
}(e2, i2), a2 = o2 < 0 ? Math.pow(10, Math.abs(o2)) : 1;
|
|
const l2 = Math.pow(10, o2), h2 = n2 > o2 ? Math.pow(10, n2) : 0, c2 = Math.round((e2 - h2) * a2) / a2, d2 = Math.floor((e2 - h2) / l2 / 10) * l2 * 10;
|
|
let u2 = Math.floor((c2 - d2) / Math.pow(10, o2)), f2 = r(t2.min, Math.round((h2 + d2 + u2 * Math.pow(10, o2)) * a2) / a2);
|
|
for (; f2 < i2; ) s2.push({ value: f2, major: vo(f2), significand: u2 }), u2 >= 10 ? u2 = u2 < 15 ? 15 : 20 : u2++, u2 >= 20 && (o2++, u2 = 2, a2 = o2 >= 0 ? 1 : a2), f2 = Math.round((h2 + d2 + u2 * Math.pow(10, o2)) * a2) / a2;
|
|
const g2 = r(t2.max, f2);
|
|
return s2.push({ value: g2, major: vo(g2), significand: u2 }), s2;
|
|
}
|
|
class ko extends Js {
|
|
constructor(t2) {
|
|
super(t2), this.start = void 0, this.end = void 0, this._startValue = void 0, this._valueRange = 0;
|
|
}
|
|
parse(t2, e2) {
|
|
const i2 = bo.prototype.parse.apply(this, [t2, e2]);
|
|
if (0 !== i2) return a(i2) && i2 > 0 ? i2 : null;
|
|
this._zero = true;
|
|
}
|
|
determineDataLimits() {
|
|
const { min: t2, max: e2 } = this.getMinMax(true);
|
|
this.min = a(t2) ? Math.max(0, t2) : null, this.max = a(e2) ? Math.max(0, e2) : null, this.options.beginAtZero && (this._zero = true), this._zero && this.min !== this._suggestedMin && !a(this._userMin) && (this.min = t2 === yo(this.min, 0) ? yo(this.min, -1) : yo(this.min, 0)), this.handleTickRangeOptions();
|
|
}
|
|
handleTickRangeOptions() {
|
|
const { minDefined: t2, maxDefined: e2 } = this.getUserBounds();
|
|
let i2 = this.min, s2 = this.max;
|
|
const n2 = (e3) => i2 = t2 ? i2 : e3, o2 = (t3) => s2 = e2 ? s2 : t3;
|
|
i2 === s2 && (i2 <= 0 ? (n2(1), o2(10)) : (n2(yo(i2, -1)), o2(yo(s2, 1)))), i2 <= 0 && n2(yo(s2, -1)), s2 <= 0 && o2(yo(i2, 1)), this.min = i2, this.max = s2;
|
|
}
|
|
buildTicks() {
|
|
const t2 = this.options, e2 = wo({ min: this._userMin, max: this._userMax }, this);
|
|
return "ticks" === t2.bounds && j(e2, this, "value"), t2.reverse ? (e2.reverse(), this.start = this.max, this.end = this.min) : (this.start = this.min, this.end = this.max), e2;
|
|
}
|
|
getLabelForValue(t2) {
|
|
return void 0 === t2 ? "0" : ne(t2, this.chart.options.locale, this.options.ticks.format);
|
|
}
|
|
configure() {
|
|
const t2 = this.min;
|
|
super.configure(), this._startValue = z(t2), this._valueRange = z(this.max) - z(t2);
|
|
}
|
|
getPixelForValue(t2) {
|
|
return void 0 !== t2 && 0 !== t2 || (t2 = this.min), null === t2 || isNaN(t2) ? NaN : this.getPixelForDecimal(t2 === this.min ? 0 : (z(t2) - this._startValue) / this._valueRange);
|
|
}
|
|
getValueForPixel(t2) {
|
|
const e2 = this.getDecimalForPixel(t2);
|
|
return Math.pow(10, this._startValue + e2 * this._valueRange);
|
|
}
|
|
}
|
|
__publicField(ko, "id", "logarithmic");
|
|
__publicField(ko, "defaults", { ticks: { callback: ae.formatters.logarithmic, major: { enabled: true } } });
|
|
function So(t2) {
|
|
const e2 = t2.ticks;
|
|
if (e2.display && t2.display) {
|
|
const t3 = ki(e2.backdropPadding);
|
|
return l(e2.font && e2.font.size, ue.font.size) + t3.height;
|
|
}
|
|
return 0;
|
|
}
|
|
function Po(t2, e2, i2, s2, n2) {
|
|
return t2 === s2 || t2 === n2 ? { start: e2 - i2 / 2, end: e2 + i2 / 2 } : t2 < s2 || t2 > n2 ? { start: e2 - i2, end: e2 } : { start: e2, end: e2 + i2 };
|
|
}
|
|
function Do(t2) {
|
|
const e2 = { l: t2.left + t2._padding.left, r: t2.right - t2._padding.right, t: t2.top + t2._padding.top, b: t2.bottom - t2._padding.bottom }, i2 = Object.assign({}, e2), s2 = [], o2 = [], a2 = t2._pointLabels.length, r2 = t2.options.pointLabels, l2 = r2.centerPointLabels ? C / a2 : 0;
|
|
for (let u2 = 0; u2 < a2; u2++) {
|
|
const a3 = r2.setContext(t2.getPointLabelContext(u2));
|
|
o2[u2] = a3.padding;
|
|
const f2 = t2.getPointPosition(u2, t2.drawingArea + o2[u2], l2), g2 = Si(a3.font), p2 = (h2 = t2.ctx, c2 = g2, d2 = n(d2 = t2._pointLabels[u2]) ? d2 : [d2], { w: Oe(h2, c2.string, d2), h: d2.length * c2.lineHeight });
|
|
s2[u2] = p2;
|
|
const m2 = G(t2.getIndexAngle(u2) + l2), b2 = Math.round(Y(m2));
|
|
Co(i2, e2, m2, Po(b2, f2.x, p2.w, 0, 180), Po(b2, f2.y, p2.h, 90, 270));
|
|
}
|
|
var h2, c2, d2;
|
|
t2.setCenterPoint(e2.l - i2.l, i2.r - e2.r, e2.t - i2.t, i2.b - e2.b), t2._pointLabelItems = function(t3, e3, i3) {
|
|
const s3 = [], n2 = t3._pointLabels.length, o3 = t3.options, { centerPointLabels: a3, display: r3 } = o3.pointLabels, l3 = { extra: So(o3) / 2, additionalAngle: a3 ? C / n2 : 0 };
|
|
let h3;
|
|
for (let o4 = 0; o4 < n2; o4++) {
|
|
l3.padding = i3[o4], l3.size = e3[o4];
|
|
const n3 = Oo(t3, o4, l3);
|
|
s3.push(n3), "auto" === r3 && (n3.visible = Ao(n3, h3), n3.visible && (h3 = n3));
|
|
}
|
|
return s3;
|
|
}(t2, s2, o2);
|
|
}
|
|
function Co(t2, e2, i2, s2, n2) {
|
|
const o2 = Math.abs(Math.sin(i2)), a2 = Math.abs(Math.cos(i2));
|
|
let r2 = 0, l2 = 0;
|
|
s2.start < e2.l ? (r2 = (e2.l - s2.start) / o2, t2.l = Math.min(t2.l, e2.l - r2)) : s2.end > e2.r && (r2 = (s2.end - e2.r) / o2, t2.r = Math.max(t2.r, e2.r + r2)), n2.start < e2.t ? (l2 = (e2.t - n2.start) / a2, t2.t = Math.min(t2.t, e2.t - l2)) : n2.end > e2.b && (l2 = (n2.end - e2.b) / a2, t2.b = Math.max(t2.b, e2.b + l2));
|
|
}
|
|
function Oo(t2, e2, i2) {
|
|
const s2 = t2.drawingArea, { extra: n2, additionalAngle: o2, padding: a2, size: r2 } = i2, l2 = t2.getPointPosition(e2, s2 + n2 + a2, o2), h2 = Math.round(Y(G(l2.angle + E))), c2 = function(t3, e3, i3) {
|
|
90 === i3 || 270 === i3 ? t3 -= e3 / 2 : (i3 > 270 || i3 < 90) && (t3 -= e3);
|
|
return t3;
|
|
}(l2.y, r2.h, h2), d2 = function(t3) {
|
|
if (0 === t3 || 180 === t3) return "center";
|
|
if (t3 < 180) return "left";
|
|
return "right";
|
|
}(h2), u2 = function(t3, e3, i3) {
|
|
"right" === i3 ? t3 -= e3 : "center" === i3 && (t3 -= e3 / 2);
|
|
return t3;
|
|
}(l2.x, r2.w, d2);
|
|
return { visible: true, x: l2.x, y: c2, textAlign: d2, left: u2, top: c2, right: u2 + r2.w, bottom: c2 + r2.h };
|
|
}
|
|
function Ao(t2, e2) {
|
|
if (!e2) return true;
|
|
const { left: i2, top: s2, right: n2, bottom: o2 } = t2;
|
|
return !(Re({ x: i2, y: s2 }, e2) || Re({ x: i2, y: o2 }, e2) || Re({ x: n2, y: s2 }, e2) || Re({ x: n2, y: o2 }, e2));
|
|
}
|
|
function To(t2, e2, i2) {
|
|
const { left: n2, top: o2, right: a2, bottom: r2 } = i2, { backdropColor: l2 } = e2;
|
|
if (!s(l2)) {
|
|
const i3 = wi(e2.borderRadius), s2 = ki(e2.backdropPadding);
|
|
t2.fillStyle = l2;
|
|
const h2 = n2 - s2.left, c2 = o2 - s2.top, d2 = a2 - n2 + s2.width, u2 = r2 - o2 + s2.height;
|
|
Object.values(i3).some((t3) => 0 !== t3) ? (t2.beginPath(), He(t2, { x: h2, y: c2, w: d2, h: u2, radius: i3 }), t2.fill()) : t2.fillRect(h2, c2, d2, u2);
|
|
}
|
|
}
|
|
function Lo(t2, e2, i2, s2) {
|
|
const { ctx: n2 } = t2;
|
|
if (i2) n2.arc(t2.xCenter, t2.yCenter, e2, 0, O);
|
|
else {
|
|
let i3 = t2.getPointPosition(0, e2);
|
|
n2.moveTo(i3.x, i3.y);
|
|
for (let o2 = 1; o2 < s2; o2++) i3 = t2.getPointPosition(o2, e2), n2.lineTo(i3.x, i3.y);
|
|
}
|
|
}
|
|
class Eo extends bo {
|
|
constructor(t2) {
|
|
super(t2), this.xCenter = void 0, this.yCenter = void 0, this.drawingArea = void 0, this._pointLabels = [], this._pointLabelItems = [];
|
|
}
|
|
setDimensions() {
|
|
const t2 = this._padding = ki(So(this.options) / 2), e2 = this.width = this.maxWidth - t2.width, i2 = this.height = this.maxHeight - t2.height;
|
|
this.xCenter = Math.floor(this.left + e2 / 2 + t2.left), this.yCenter = Math.floor(this.top + i2 / 2 + t2.top), this.drawingArea = Math.floor(Math.min(e2, i2) / 2);
|
|
}
|
|
determineDataLimits() {
|
|
const { min: t2, max: e2 } = this.getMinMax(false);
|
|
this.min = a(t2) && !isNaN(t2) ? t2 : 0, this.max = a(e2) && !isNaN(e2) ? e2 : 0, this.handleTickRangeOptions();
|
|
}
|
|
computeTickLimit() {
|
|
return Math.ceil(this.drawingArea / So(this.options));
|
|
}
|
|
generateTickLabels(t2) {
|
|
bo.prototype.generateTickLabels.call(this, t2), this._pointLabels = this.getLabels().map((t3, e2) => {
|
|
const i2 = d(this.options.pointLabels.callback, [t3, e2], this);
|
|
return i2 || 0 === i2 ? i2 : "";
|
|
}).filter((t3, e2) => this.chart.getDataVisibility(e2));
|
|
}
|
|
fit() {
|
|
const t2 = this.options;
|
|
t2.display && t2.pointLabels.display ? Do(this) : this.setCenterPoint(0, 0, 0, 0);
|
|
}
|
|
setCenterPoint(t2, e2, i2, s2) {
|
|
this.xCenter += Math.floor((t2 - e2) / 2), this.yCenter += Math.floor((i2 - s2) / 2), this.drawingArea -= Math.min(this.drawingArea / 2, Math.max(t2, e2, i2, s2));
|
|
}
|
|
getIndexAngle(t2) {
|
|
return G(t2 * (O / (this._pointLabels.length || 1)) + $(this.options.startAngle || 0));
|
|
}
|
|
getDistanceFromCenterForValue(t2) {
|
|
if (s(t2)) return NaN;
|
|
const e2 = this.drawingArea / (this.max - this.min);
|
|
return this.options.reverse ? (this.max - t2) * e2 : (t2 - this.min) * e2;
|
|
}
|
|
getValueForDistanceFromCenter(t2) {
|
|
if (s(t2)) return NaN;
|
|
const e2 = t2 / (this.drawingArea / (this.max - this.min));
|
|
return this.options.reverse ? this.max - e2 : this.min + e2;
|
|
}
|
|
getPointLabelContext(t2) {
|
|
const e2 = this._pointLabels || [];
|
|
if (t2 >= 0 && t2 < e2.length) {
|
|
const i2 = e2[t2];
|
|
return function(t3, e3, i3) {
|
|
return Ci(t3, { label: i3, index: e3, type: "pointLabel" });
|
|
}(this.getContext(), t2, i2);
|
|
}
|
|
}
|
|
getPointPosition(t2, e2, i2 = 0) {
|
|
const s2 = this.getIndexAngle(t2) - E + i2;
|
|
return { x: Math.cos(s2) * e2 + this.xCenter, y: Math.sin(s2) * e2 + this.yCenter, angle: s2 };
|
|
}
|
|
getPointPositionForValue(t2, e2) {
|
|
return this.getPointPosition(t2, this.getDistanceFromCenterForValue(e2));
|
|
}
|
|
getBasePosition(t2) {
|
|
return this.getPointPositionForValue(t2 || 0, this.getBaseValue());
|
|
}
|
|
getPointLabelPosition(t2) {
|
|
const { left: e2, top: i2, right: s2, bottom: n2 } = this._pointLabelItems[t2];
|
|
return { left: e2, top: i2, right: s2, bottom: n2 };
|
|
}
|
|
drawBackground() {
|
|
const { backgroundColor: t2, grid: { circular: e2 } } = this.options;
|
|
if (t2) {
|
|
const i2 = this.ctx;
|
|
i2.save(), i2.beginPath(), Lo(this, this.getDistanceFromCenterForValue(this._endValue), e2, this._pointLabels.length), i2.closePath(), i2.fillStyle = t2, i2.fill(), i2.restore();
|
|
}
|
|
}
|
|
drawGrid() {
|
|
const t2 = this.ctx, e2 = this.options, { angleLines: i2, grid: s2, border: n2 } = e2, o2 = this._pointLabels.length;
|
|
let a2, r2, l2;
|
|
if (e2.pointLabels.display && function(t3, e3) {
|
|
const { ctx: i3, options: { pointLabels: s3 } } = t3;
|
|
for (let n3 = e3 - 1; n3 >= 0; n3--) {
|
|
const e4 = t3._pointLabelItems[n3];
|
|
if (!e4.visible) continue;
|
|
const o3 = s3.setContext(t3.getPointLabelContext(n3));
|
|
To(i3, o3, e4);
|
|
const a3 = Si(o3.font), { x: r3, y: l3, textAlign: h2 } = e4;
|
|
Ne(i3, t3._pointLabels[n3], r3, l3 + a3.lineHeight / 2, a3, { color: o3.color, textAlign: h2, textBaseline: "middle" });
|
|
}
|
|
}(this, o2), s2.display && this.ticks.forEach((t3, e3) => {
|
|
if (0 !== e3) {
|
|
r2 = this.getDistanceFromCenterForValue(t3.value);
|
|
const i3 = this.getContext(e3), a3 = s2.setContext(i3), l3 = n2.setContext(i3);
|
|
!function(t4, e4, i4, s3, n3) {
|
|
const o3 = t4.ctx, a4 = e4.circular, { color: r3, lineWidth: l4 } = e4;
|
|
!a4 && !s3 || !r3 || !l4 || i4 < 0 || (o3.save(), o3.strokeStyle = r3, o3.lineWidth = l4, o3.setLineDash(n3.dash), o3.lineDashOffset = n3.dashOffset, o3.beginPath(), Lo(t4, i4, a4, s3), o3.closePath(), o3.stroke(), o3.restore());
|
|
}(this, a3, r2, o2, l3);
|
|
}
|
|
}), i2.display) {
|
|
for (t2.save(), a2 = o2 - 1; a2 >= 0; a2--) {
|
|
const s3 = i2.setContext(this.getPointLabelContext(a2)), { color: n3, lineWidth: o3 } = s3;
|
|
o3 && n3 && (t2.lineWidth = o3, t2.strokeStyle = n3, t2.setLineDash(s3.borderDash), t2.lineDashOffset = s3.borderDashOffset, r2 = this.getDistanceFromCenterForValue(e2.ticks.reverse ? this.min : this.max), l2 = this.getPointPosition(a2, r2), t2.beginPath(), t2.moveTo(this.xCenter, this.yCenter), t2.lineTo(l2.x, l2.y), t2.stroke());
|
|
}
|
|
t2.restore();
|
|
}
|
|
}
|
|
drawBorder() {
|
|
}
|
|
drawLabels() {
|
|
const t2 = this.ctx, e2 = this.options, i2 = e2.ticks;
|
|
if (!i2.display) return;
|
|
const s2 = this.getIndexAngle(0);
|
|
let n2, o2;
|
|
t2.save(), t2.translate(this.xCenter, this.yCenter), t2.rotate(s2), t2.textAlign = "center", t2.textBaseline = "middle", this.ticks.forEach((s3, a2) => {
|
|
if (0 === a2 && !e2.reverse) return;
|
|
const r2 = i2.setContext(this.getContext(a2)), l2 = Si(r2.font);
|
|
if (n2 = this.getDistanceFromCenterForValue(this.ticks[a2].value), r2.showLabelBackdrop) {
|
|
t2.font = l2.string, o2 = t2.measureText(s3.label).width, t2.fillStyle = r2.backdropColor;
|
|
const e3 = ki(r2.backdropPadding);
|
|
t2.fillRect(-o2 / 2 - e3.left, -n2 - l2.size / 2 - e3.top, o2 + e3.width, l2.size + e3.height);
|
|
}
|
|
Ne(t2, s3.label, 0, -n2, l2, { color: r2.color, strokeColor: r2.textStrokeColor, strokeWidth: r2.textStrokeWidth });
|
|
}), t2.restore();
|
|
}
|
|
drawTitle() {
|
|
}
|
|
}
|
|
__publicField(Eo, "id", "radialLinear");
|
|
__publicField(Eo, "defaults", { display: true, animate: true, position: "chartArea", angleLines: { display: true, lineWidth: 1, borderDash: [], borderDashOffset: 0 }, grid: { circular: false }, startAngle: 0, ticks: { showLabelBackdrop: true, callback: ae.formatters.numeric }, pointLabels: { backdropColor: void 0, backdropPadding: 2, display: true, font: { size: 10 }, callback: (t2) => t2, padding: 5, centerPointLabels: false } });
|
|
__publicField(Eo, "defaultRoutes", { "angleLines.color": "borderColor", "pointLabels.color": "color", "ticks.color": "color" });
|
|
__publicField(Eo, "descriptors", { angleLines: { _fallback: "grid" } });
|
|
const Ro = { millisecond: { common: true, size: 1, steps: 1e3 }, second: { common: true, size: 1e3, steps: 60 }, minute: { common: true, size: 6e4, steps: 60 }, hour: { common: true, size: 36e5, steps: 24 }, day: { common: true, size: 864e5, steps: 30 }, week: { common: false, size: 6048e5, steps: 4 }, month: { common: true, size: 2628e6, steps: 12 }, quarter: { common: false, size: 7884e6, steps: 4 }, year: { common: true, size: 3154e7 } }, Io = Object.keys(Ro);
|
|
function zo(t2, e2) {
|
|
return t2 - e2;
|
|
}
|
|
function Fo(t2, e2) {
|
|
if (s(e2)) return null;
|
|
const i2 = t2._adapter, { parser: n2, round: o2, isoWeekday: r2 } = t2._parseOpts;
|
|
let l2 = e2;
|
|
return "function" == typeof n2 && (l2 = n2(l2)), a(l2) || (l2 = "string" == typeof n2 ? i2.parse(l2, n2) : i2.parse(l2)), null === l2 ? null : (o2 && (l2 = "week" !== o2 || !N(r2) && true !== r2 ? i2.startOf(l2, o2) : i2.startOf(l2, "isoWeek", r2)), +l2);
|
|
}
|
|
function Vo(t2, e2, i2, s2) {
|
|
const n2 = Io.length;
|
|
for (let o2 = Io.indexOf(t2); o2 < n2 - 1; ++o2) {
|
|
const t3 = Ro[Io[o2]], n3 = t3.steps ? t3.steps : Number.MAX_SAFE_INTEGER;
|
|
if (t3.common && Math.ceil((i2 - e2) / (n3 * t3.size)) <= s2) return Io[o2];
|
|
}
|
|
return Io[n2 - 1];
|
|
}
|
|
function Bo(t2, e2, i2) {
|
|
if (i2) {
|
|
if (i2.length) {
|
|
const { lo: s2, hi: n2 } = et(i2, e2);
|
|
t2[i2[s2] >= e2 ? i2[s2] : i2[n2]] = true;
|
|
}
|
|
} else t2[e2] = true;
|
|
}
|
|
function Wo(t2, e2, i2) {
|
|
const s2 = [], n2 = {}, o2 = e2.length;
|
|
let a2, r2;
|
|
for (a2 = 0; a2 < o2; ++a2) r2 = e2[a2], n2[r2] = a2, s2.push({ value: r2, major: false });
|
|
return 0 !== o2 && i2 ? function(t3, e3, i3, s3) {
|
|
const n3 = t3._adapter, o3 = +n3.startOf(e3[0].value, s3), a3 = e3[e3.length - 1].value;
|
|
let r3, l2;
|
|
for (r3 = o3; r3 <= a3; r3 = +n3.add(r3, 1, s3)) l2 = i3[r3], l2 >= 0 && (e3[l2].major = true);
|
|
return e3;
|
|
}(t2, s2, n2, i2) : s2;
|
|
}
|
|
class No extends Js {
|
|
constructor(t2) {
|
|
super(t2), this._cache = { data: [], labels: [], all: [] }, this._unit = "day", this._majorUnit = void 0, this._offsets = {}, this._normalized = false, this._parseOpts = void 0;
|
|
}
|
|
init(t2, e2 = {}) {
|
|
const i2 = t2.time || (t2.time = {}), s2 = this._adapter = new Rn._date(t2.adapters.date);
|
|
s2.init(e2), x(i2.displayFormats, s2.formats()), this._parseOpts = { parser: i2.parser, round: i2.round, isoWeekday: i2.isoWeekday }, super.init(t2), this._normalized = e2.normalized;
|
|
}
|
|
parse(t2, e2) {
|
|
return void 0 === t2 ? null : Fo(this, t2);
|
|
}
|
|
beforeLayout() {
|
|
super.beforeLayout(), this._cache = { data: [], labels: [], all: [] };
|
|
}
|
|
determineDataLimits() {
|
|
const t2 = this.options, e2 = this._adapter, i2 = t2.time.unit || "day";
|
|
let { min: s2, max: n2, minDefined: o2, maxDefined: r2 } = this.getUserBounds();
|
|
function l2(t3) {
|
|
o2 || isNaN(t3.min) || (s2 = Math.min(s2, t3.min)), r2 || isNaN(t3.max) || (n2 = Math.max(n2, t3.max));
|
|
}
|
|
o2 && r2 || (l2(this._getLabelBounds()), "ticks" === t2.bounds && "labels" === t2.ticks.source || l2(this.getMinMax(false))), s2 = a(s2) && !isNaN(s2) ? s2 : +e2.startOf(Date.now(), i2), n2 = a(n2) && !isNaN(n2) ? n2 : +e2.endOf(Date.now(), i2) + 1, this.min = Math.min(s2, n2 - 1), this.max = Math.max(s2 + 1, n2);
|
|
}
|
|
_getLabelBounds() {
|
|
const t2 = this.getLabelTimestamps();
|
|
let e2 = Number.POSITIVE_INFINITY, i2 = Number.NEGATIVE_INFINITY;
|
|
return t2.length && (e2 = t2[0], i2 = t2[t2.length - 1]), { min: e2, max: i2 };
|
|
}
|
|
buildTicks() {
|
|
const t2 = this.options, e2 = t2.time, i2 = t2.ticks, s2 = "labels" === i2.source ? this.getLabelTimestamps() : this._generate();
|
|
"ticks" === t2.bounds && s2.length && (this.min = this._userMin || s2[0], this.max = this._userMax || s2[s2.length - 1]);
|
|
const n2 = this.min, o2 = nt(s2, n2, this.max);
|
|
return this._unit = e2.unit || (i2.autoSkip ? Vo(e2.minUnit, this.min, this.max, this._getLabelCapacity(n2)) : function(t3, e3, i3, s3, n3) {
|
|
for (let o3 = Io.length - 1; o3 >= Io.indexOf(i3); o3--) {
|
|
const i4 = Io[o3];
|
|
if (Ro[i4].common && t3._adapter.diff(n3, s3, i4) >= e3 - 1) return i4;
|
|
}
|
|
return Io[i3 ? Io.indexOf(i3) : 0];
|
|
}(this, o2.length, e2.minUnit, this.min, this.max)), this._majorUnit = i2.major.enabled && "year" !== this._unit ? function(t3) {
|
|
for (let e3 = Io.indexOf(t3) + 1, i3 = Io.length; e3 < i3; ++e3) if (Ro[Io[e3]].common) return Io[e3];
|
|
}(this._unit) : void 0, this.initOffsets(s2), t2.reverse && o2.reverse(), Wo(this, o2, this._majorUnit);
|
|
}
|
|
afterAutoSkip() {
|
|
this.options.offsetAfterAutoskip && this.initOffsets(this.ticks.map((t2) => +t2.value));
|
|
}
|
|
initOffsets(t2 = []) {
|
|
let e2, i2, s2 = 0, n2 = 0;
|
|
this.options.offset && t2.length && (e2 = this.getDecimalForValue(t2[0]), s2 = 1 === t2.length ? 1 - e2 : (this.getDecimalForValue(t2[1]) - e2) / 2, i2 = this.getDecimalForValue(t2[t2.length - 1]), n2 = 1 === t2.length ? i2 : (i2 - this.getDecimalForValue(t2[t2.length - 2])) / 2);
|
|
const o2 = t2.length < 3 ? 0.5 : 0.25;
|
|
s2 = J(s2, 0, o2), n2 = J(n2, 0, o2), this._offsets = { start: s2, end: n2, factor: 1 / (s2 + 1 + n2) };
|
|
}
|
|
_generate() {
|
|
const t2 = this._adapter, e2 = this.min, i2 = this.max, s2 = this.options, n2 = s2.time, o2 = n2.unit || Vo(n2.minUnit, e2, i2, this._getLabelCapacity(e2)), a2 = l(s2.ticks.stepSize, 1), r2 = "week" === o2 && n2.isoWeekday, h2 = N(r2) || true === r2, c2 = {};
|
|
let d2, u2, f2 = e2;
|
|
if (h2 && (f2 = +t2.startOf(f2, "isoWeek", r2)), f2 = +t2.startOf(f2, h2 ? "day" : o2), t2.diff(i2, e2, o2) > 1e5 * a2) throw new Error(e2 + " and " + i2 + " are too far apart with stepSize of " + a2 + " " + o2);
|
|
const g2 = "data" === s2.ticks.source && this.getDataTimestamps();
|
|
for (d2 = f2, u2 = 0; d2 < i2; d2 = +t2.add(d2, a2, o2), u2++) Bo(c2, d2, g2);
|
|
return d2 !== i2 && "ticks" !== s2.bounds && 1 !== u2 || Bo(c2, d2, g2), Object.keys(c2).sort(zo).map((t3) => +t3);
|
|
}
|
|
getLabelForValue(t2) {
|
|
const e2 = this._adapter, i2 = this.options.time;
|
|
return i2.tooltipFormat ? e2.format(t2, i2.tooltipFormat) : e2.format(t2, i2.displayFormats.datetime);
|
|
}
|
|
format(t2, e2) {
|
|
const i2 = this.options.time.displayFormats, s2 = this._unit, n2 = e2 || i2[s2];
|
|
return this._adapter.format(t2, n2);
|
|
}
|
|
_tickFormatFunction(t2, e2, i2, s2) {
|
|
const n2 = this.options, o2 = n2.ticks.callback;
|
|
if (o2) return d(o2, [t2, e2, i2], this);
|
|
const a2 = n2.time.displayFormats, r2 = this._unit, l2 = this._majorUnit, h2 = r2 && a2[r2], c2 = l2 && a2[l2], u2 = i2[e2], f2 = l2 && c2 && u2 && u2.major;
|
|
return this._adapter.format(t2, s2 || (f2 ? c2 : h2));
|
|
}
|
|
generateTickLabels(t2) {
|
|
let e2, i2, s2;
|
|
for (e2 = 0, i2 = t2.length; e2 < i2; ++e2) s2 = t2[e2], s2.label = this._tickFormatFunction(s2.value, e2, t2);
|
|
}
|
|
getDecimalForValue(t2) {
|
|
return null === t2 ? NaN : (t2 - this.min) / (this.max - this.min);
|
|
}
|
|
getPixelForValue(t2) {
|
|
const e2 = this._offsets, i2 = this.getDecimalForValue(t2);
|
|
return this.getPixelForDecimal((e2.start + i2) * e2.factor);
|
|
}
|
|
getValueForPixel(t2) {
|
|
const e2 = this._offsets, i2 = this.getDecimalForPixel(t2) / e2.factor - e2.end;
|
|
return this.min + i2 * (this.max - this.min);
|
|
}
|
|
_getLabelSize(t2) {
|
|
const e2 = this.options.ticks, i2 = this.ctx.measureText(t2).width, s2 = $(this.isHorizontal() ? e2.maxRotation : e2.minRotation), n2 = Math.cos(s2), o2 = Math.sin(s2), a2 = this._resolveTickFontOptions(0).size;
|
|
return { w: i2 * n2 + a2 * o2, h: i2 * o2 + a2 * n2 };
|
|
}
|
|
_getLabelCapacity(t2) {
|
|
const e2 = this.options.time, i2 = e2.displayFormats, s2 = i2[e2.unit] || i2.millisecond, n2 = this._tickFormatFunction(t2, 0, Wo(this, [t2], this._majorUnit), s2), o2 = this._getLabelSize(n2), a2 = Math.floor(this.isHorizontal() ? this.width / o2.w : this.height / o2.h) - 1;
|
|
return a2 > 0 ? a2 : 1;
|
|
}
|
|
getDataTimestamps() {
|
|
let t2, e2, i2 = this._cache.data || [];
|
|
if (i2.length) return i2;
|
|
const s2 = this.getMatchingVisibleMetas();
|
|
if (this._normalized && s2.length) return this._cache.data = s2[0].controller.getAllParsedValues(this);
|
|
for (t2 = 0, e2 = s2.length; t2 < e2; ++t2) i2 = i2.concat(s2[t2].controller.getAllParsedValues(this));
|
|
return this._cache.data = this.normalize(i2);
|
|
}
|
|
getLabelTimestamps() {
|
|
const t2 = this._cache.labels || [];
|
|
let e2, i2;
|
|
if (t2.length) return t2;
|
|
const s2 = this.getLabels();
|
|
for (e2 = 0, i2 = s2.length; e2 < i2; ++e2) t2.push(Fo(this, s2[e2]));
|
|
return this._cache.labels = this._normalized ? t2 : this.normalize(t2);
|
|
}
|
|
normalize(t2) {
|
|
return lt(t2.sort(zo));
|
|
}
|
|
}
|
|
__publicField(No, "id", "time");
|
|
__publicField(No, "defaults", { bounds: "data", adapters: {}, time: { parser: false, unit: false, round: false, isoWeekday: false, minUnit: "millisecond", displayFormats: {} }, ticks: { source: "auto", callback: false, major: { enabled: false } } });
|
|
function Ho(t2, e2, i2) {
|
|
let s2, n2, o2, a2, r2 = 0, l2 = t2.length - 1;
|
|
i2 ? (e2 >= t2[r2].pos && e2 <= t2[l2].pos && ({ lo: r2, hi: l2 } = it(t2, "pos", e2)), { pos: s2, time: o2 } = t2[r2], { pos: n2, time: a2 } = t2[l2]) : (e2 >= t2[r2].time && e2 <= t2[l2].time && ({ lo: r2, hi: l2 } = it(t2, "time", e2)), { time: s2, pos: o2 } = t2[r2], { time: n2, pos: a2 } = t2[l2]);
|
|
const h2 = n2 - s2;
|
|
return h2 ? o2 + (a2 - o2) * (e2 - s2) / h2 : o2;
|
|
}
|
|
var jo = Object.freeze({ __proto__: null, CategoryScale: (_j = class extends Js {
|
|
constructor(t2) {
|
|
super(t2), this._startValue = void 0, this._valueRange = 0, this._addedLabels = [];
|
|
}
|
|
init(t2) {
|
|
const e2 = this._addedLabels;
|
|
if (e2.length) {
|
|
const t3 = this.getLabels();
|
|
for (const { index: i2, label: s2 } of e2) t3[i2] === s2 && t3.splice(i2, 1);
|
|
this._addedLabels = [];
|
|
}
|
|
super.init(t2);
|
|
}
|
|
parse(t2, e2) {
|
|
if (s(t2)) return null;
|
|
const i2 = this.getLabels();
|
|
return ((t3, e3) => null === t3 ? null : J(Math.round(t3), 0, e3))(e2 = isFinite(e2) && i2[e2] === t2 ? e2 : go(i2, t2, l(e2, t2), this._addedLabels), i2.length - 1);
|
|
}
|
|
determineDataLimits() {
|
|
const { minDefined: t2, maxDefined: e2 } = this.getUserBounds();
|
|
let { min: i2, max: s2 } = this.getMinMax(true);
|
|
"ticks" === this.options.bounds && (t2 || (i2 = 0), e2 || (s2 = this.getLabels().length - 1)), this.min = i2, this.max = s2;
|
|
}
|
|
buildTicks() {
|
|
const t2 = this.min, e2 = this.max, i2 = this.options.offset, s2 = [];
|
|
let n2 = this.getLabels();
|
|
n2 = 0 === t2 && e2 === n2.length - 1 ? n2 : n2.slice(t2, e2 + 1), this._valueRange = Math.max(n2.length - (i2 ? 0 : 1), 1), this._startValue = this.min - (i2 ? 0.5 : 0);
|
|
for (let i3 = t2; i3 <= e2; i3++) s2.push({ value: i3 });
|
|
return s2;
|
|
}
|
|
getLabelForValue(t2) {
|
|
return po.call(this, t2);
|
|
}
|
|
configure() {
|
|
super.configure(), this.isHorizontal() || (this._reversePixels = !this._reversePixels);
|
|
}
|
|
getPixelForValue(t2) {
|
|
return "number" != typeof t2 && (t2 = this.parse(t2)), null === t2 ? NaN : this.getPixelForDecimal((t2 - this._startValue) / this._valueRange);
|
|
}
|
|
getPixelForTick(t2) {
|
|
const e2 = this.ticks;
|
|
return t2 < 0 || t2 > e2.length - 1 ? null : this.getPixelForValue(e2[t2].value);
|
|
}
|
|
getValueForPixel(t2) {
|
|
return Math.round(this._startValue + this.getDecimalForPixel(t2) * this._valueRange);
|
|
}
|
|
getBasePixel() {
|
|
return this.bottom;
|
|
}
|
|
}, __publicField(_j, "id", "category"), __publicField(_j, "defaults", { ticks: { callback: po } }), _j), LinearScale: xo, LogarithmicScale: ko, RadialLinearScale: Eo, TimeScale: No, TimeSeriesScale: (_k = class extends No {
|
|
constructor(t2) {
|
|
super(t2), this._table = [], this._minPos = void 0, this._tableRange = void 0;
|
|
}
|
|
initOffsets() {
|
|
const t2 = this._getTimestampsForTable(), e2 = this._table = this.buildLookupTable(t2);
|
|
this._minPos = Ho(e2, this.min), this._tableRange = Ho(e2, this.max) - this._minPos, super.initOffsets(t2);
|
|
}
|
|
buildLookupTable(t2) {
|
|
const { min: e2, max: i2 } = this, s2 = [], n2 = [];
|
|
let o2, a2, r2, l2, h2;
|
|
for (o2 = 0, a2 = t2.length; o2 < a2; ++o2) l2 = t2[o2], l2 >= e2 && l2 <= i2 && s2.push(l2);
|
|
if (s2.length < 2) return [{ time: e2, pos: 0 }, { time: i2, pos: 1 }];
|
|
for (o2 = 0, a2 = s2.length; o2 < a2; ++o2) h2 = s2[o2 + 1], r2 = s2[o2 - 1], l2 = s2[o2], Math.round((h2 + r2) / 2) !== l2 && n2.push({ time: l2, pos: o2 / (a2 - 1) });
|
|
return n2;
|
|
}
|
|
_generate() {
|
|
const t2 = this.min, e2 = this.max;
|
|
let i2 = super.getDataTimestamps();
|
|
return i2.includes(t2) && i2.length || i2.splice(0, 0, t2), i2.includes(e2) && 1 !== i2.length || i2.push(e2), i2.sort((t3, e3) => t3 - e3);
|
|
}
|
|
_getTimestampsForTable() {
|
|
let t2 = this._cache.all || [];
|
|
if (t2.length) return t2;
|
|
const e2 = this.getDataTimestamps(), i2 = this.getLabelTimestamps();
|
|
return t2 = e2.length && i2.length ? this.normalize(e2.concat(i2)) : e2.length ? e2 : i2, t2 = this._cache.all = t2, t2;
|
|
}
|
|
getDecimalForValue(t2) {
|
|
return (Ho(this._table, t2) - this._minPos) / this._tableRange;
|
|
}
|
|
getValueForPixel(t2) {
|
|
const e2 = this._offsets, i2 = this.getDecimalForPixel(t2) / e2.factor - e2.end;
|
|
return Ho(this._table, i2 * this._tableRange + this._minPos, true);
|
|
}
|
|
}, __publicField(_k, "id", "timeseries"), __publicField(_k, "defaults", No.defaults), _k) });
|
|
const $o = ["rgb(54, 162, 235)", "rgb(255, 99, 132)", "rgb(255, 159, 64)", "rgb(255, 205, 86)", "rgb(75, 192, 192)", "rgb(153, 102, 255)", "rgb(201, 203, 207)"], Yo = $o.map((t2) => t2.replace("rgb(", "rgba(").replace(")", ", 0.5)"));
|
|
function Uo(t2) {
|
|
return $o[t2 % $o.length];
|
|
}
|
|
function Xo(t2) {
|
|
return Yo[t2 % Yo.length];
|
|
}
|
|
function qo(t2) {
|
|
let e2 = 0;
|
|
return (i2, s2) => {
|
|
const n2 = t2.getDatasetMeta(s2).controller;
|
|
n2 instanceof jn ? e2 = function(t3, e3) {
|
|
return t3.backgroundColor = t3.data.map(() => Uo(e3++)), e3;
|
|
}(i2, e2) : n2 instanceof $n ? e2 = function(t3, e3) {
|
|
return t3.backgroundColor = t3.data.map(() => Xo(e3++)), e3;
|
|
}(i2, e2) : n2 && (e2 = function(t3, e3) {
|
|
return t3.borderColor = Uo(e3), t3.backgroundColor = Xo(e3), ++e3;
|
|
}(i2, e2));
|
|
};
|
|
}
|
|
function Ko(t2) {
|
|
let e2;
|
|
for (e2 in t2) if (t2[e2].borderColor || t2[e2].backgroundColor) return true;
|
|
return false;
|
|
}
|
|
var Go = { id: "colors", defaults: { enabled: true, forceOverride: false }, beforeLayout(t2, e2, i2) {
|
|
if (!i2.enabled) return;
|
|
const { data: { datasets: s2 }, options: n2 } = t2.config, { elements: o2 } = n2;
|
|
if (!i2.forceOverride && (Ko(s2) || (a2 = n2) && (a2.borderColor || a2.backgroundColor) || o2 && Ko(o2))) return;
|
|
var a2;
|
|
const r2 = qo(t2);
|
|
s2.forEach(r2);
|
|
} };
|
|
function Zo(t2) {
|
|
if (t2._decimated) {
|
|
const e2 = t2._data;
|
|
delete t2._decimated, delete t2._data, Object.defineProperty(t2, "data", { configurable: true, enumerable: true, writable: true, value: e2 });
|
|
}
|
|
}
|
|
function Jo(t2) {
|
|
t2.data.datasets.forEach((t3) => {
|
|
Zo(t3);
|
|
});
|
|
}
|
|
var Qo = { id: "decimation", defaults: { algorithm: "min-max", enabled: false }, beforeElementsUpdate: (t2, e2, i2) => {
|
|
if (!i2.enabled) return void Jo(t2);
|
|
const n2 = t2.width;
|
|
t2.data.datasets.forEach((e3, o2) => {
|
|
const { _data: a2, indexAxis: r2 } = e3, l2 = t2.getDatasetMeta(o2), h2 = a2 || e3.data;
|
|
if ("y" === Pi([r2, t2.options.indexAxis])) return;
|
|
if (!l2.controller.supportsDecimation) return;
|
|
const c2 = t2.scales[l2.xAxisID];
|
|
if ("linear" !== c2.type && "time" !== c2.type) return;
|
|
if (t2.options.parsing) return;
|
|
let { start: d2, count: u2 } = function(t3, e4) {
|
|
const i3 = e4.length;
|
|
let s2, n3 = 0;
|
|
const { iScale: o3 } = t3, { min: a3, max: r3, minDefined: l3, maxDefined: h3 } = o3.getUserBounds();
|
|
return l3 && (n3 = J(it(e4, o3.axis, a3).lo, 0, i3 - 1)), s2 = h3 ? J(it(e4, o3.axis, r3).hi + 1, n3, i3) - n3 : i3 - n3, { start: n3, count: s2 };
|
|
}(l2, h2);
|
|
if (u2 <= (i2.threshold || 4 * n2)) return void Zo(e3);
|
|
let f2;
|
|
switch (s(a2) && (e3._data = h2, delete e3.data, Object.defineProperty(e3, "data", { configurable: true, enumerable: true, get: function() {
|
|
return this._decimated;
|
|
}, set: function(t3) {
|
|
this._data = t3;
|
|
} })), i2.algorithm) {
|
|
case "lttb":
|
|
f2 = function(t3, e4, i3, s2, n3) {
|
|
const o3 = n3.samples || s2;
|
|
if (o3 >= i3) return t3.slice(e4, e4 + i3);
|
|
const a3 = [], r3 = (i3 - 2) / (o3 - 2);
|
|
let l3 = 0;
|
|
const h3 = e4 + i3 - 1;
|
|
let c3, d3, u3, f3, g2, p2 = e4;
|
|
for (a3[l3++] = t3[p2], c3 = 0; c3 < o3 - 2; c3++) {
|
|
let s3, n4 = 0, o4 = 0;
|
|
const h4 = Math.floor((c3 + 1) * r3) + 1 + e4, m2 = Math.min(Math.floor((c3 + 2) * r3) + 1, i3) + e4, b2 = m2 - h4;
|
|
for (s3 = h4; s3 < m2; s3++) n4 += t3[s3].x, o4 += t3[s3].y;
|
|
n4 /= b2, o4 /= b2;
|
|
const x2 = Math.floor(c3 * r3) + 1 + e4, _2 = Math.min(Math.floor((c3 + 1) * r3) + 1, i3) + e4, { x: y2, y: v2 } = t3[p2];
|
|
for (u3 = f3 = -1, s3 = x2; s3 < _2; s3++) f3 = 0.5 * Math.abs((y2 - n4) * (t3[s3].y - v2) - (y2 - t3[s3].x) * (o4 - v2)), f3 > u3 && (u3 = f3, d3 = t3[s3], g2 = s3);
|
|
a3[l3++] = d3, p2 = g2;
|
|
}
|
|
return a3[l3++] = t3[h3], a3;
|
|
}(h2, d2, u2, n2, i2);
|
|
break;
|
|
case "min-max":
|
|
f2 = function(t3, e4, i3, n3) {
|
|
let o3, a3, r3, l3, h3, c3, d3, u3, f3, g2, p2 = 0, m2 = 0;
|
|
const b2 = [], x2 = e4 + i3 - 1, _2 = t3[e4].x, y2 = t3[x2].x - _2;
|
|
for (o3 = e4; o3 < e4 + i3; ++o3) {
|
|
a3 = t3[o3], r3 = (a3.x - _2) / y2 * n3, l3 = a3.y;
|
|
const e5 = 0 | r3;
|
|
if (e5 === h3) l3 < f3 ? (f3 = l3, c3 = o3) : l3 > g2 && (g2 = l3, d3 = o3), p2 = (m2 * p2 + a3.x) / ++m2;
|
|
else {
|
|
const i4 = o3 - 1;
|
|
if (!s(c3) && !s(d3)) {
|
|
const e6 = Math.min(c3, d3), s2 = Math.max(c3, d3);
|
|
e6 !== u3 && e6 !== i4 && b2.push(__spreadProps(__spreadValues({}, t3[e6]), { x: p2 })), s2 !== u3 && s2 !== i4 && b2.push(__spreadProps(__spreadValues({}, t3[s2]), { x: p2 }));
|
|
}
|
|
o3 > 0 && i4 !== u3 && b2.push(t3[i4]), b2.push(a3), h3 = e5, m2 = 0, f3 = g2 = l3, c3 = d3 = u3 = o3;
|
|
}
|
|
}
|
|
return b2;
|
|
}(h2, d2, u2, n2);
|
|
break;
|
|
default:
|
|
throw new Error(`Unsupported decimation algorithm '${i2.algorithm}'`);
|
|
}
|
|
e3._decimated = f2;
|
|
});
|
|
}, destroy(t2) {
|
|
Jo(t2);
|
|
} };
|
|
function ta(t2, e2, i2, s2) {
|
|
if (s2) return;
|
|
let n2 = e2[t2], o2 = i2[t2];
|
|
return "angle" === t2 && (n2 = G(n2), o2 = G(o2)), { property: t2, start: n2, end: o2 };
|
|
}
|
|
function ea(t2, e2, i2) {
|
|
for (; e2 > t2; e2--) {
|
|
const t3 = i2[e2];
|
|
if (!isNaN(t3.x) && !isNaN(t3.y)) break;
|
|
}
|
|
return e2;
|
|
}
|
|
function ia(t2, e2, i2, s2) {
|
|
return t2 && e2 ? s2(t2[i2], e2[i2]) : t2 ? t2[i2] : e2 ? e2[i2] : 0;
|
|
}
|
|
function sa(t2, e2) {
|
|
let i2 = [], s2 = false;
|
|
return n(t2) ? (s2 = true, i2 = t2) : i2 = function(t3, e3) {
|
|
const { x: i3 = null, y: s3 = null } = t3 || {}, n2 = e3.points, o2 = [];
|
|
return e3.segments.forEach(({ start: t4, end: e4 }) => {
|
|
e4 = ea(t4, e4, n2);
|
|
const a2 = n2[t4], r2 = n2[e4];
|
|
null !== s3 ? (o2.push({ x: a2.x, y: s3 }), o2.push({ x: r2.x, y: s3 })) : null !== i3 && (o2.push({ x: i3, y: a2.y }), o2.push({ x: i3, y: r2.y }));
|
|
}), o2;
|
|
}(t2, e2), i2.length ? new no({ points: i2, options: { tension: 0 }, _loop: s2, _fullLoop: s2 }) : null;
|
|
}
|
|
function na(t2) {
|
|
return t2 && false !== t2.fill;
|
|
}
|
|
function oa(t2, e2, i2) {
|
|
let s2 = t2[e2].fill;
|
|
const n2 = [e2];
|
|
let o2;
|
|
if (!i2) return s2;
|
|
for (; false !== s2 && -1 === n2.indexOf(s2); ) {
|
|
if (!a(s2)) return s2;
|
|
if (o2 = t2[s2], !o2) return false;
|
|
if (o2.visible) return s2;
|
|
n2.push(s2), s2 = o2.fill;
|
|
}
|
|
return false;
|
|
}
|
|
function aa(t2, e2, i2) {
|
|
const s2 = function(t3) {
|
|
const e3 = t3.options, i3 = e3.fill;
|
|
let s3 = l(i3 && i3.target, i3);
|
|
void 0 === s3 && (s3 = !!e3.backgroundColor);
|
|
if (false === s3 || null === s3) return false;
|
|
if (true === s3) return "origin";
|
|
return s3;
|
|
}(t2);
|
|
if (o(s2)) return !isNaN(s2.value) && s2;
|
|
let n2 = parseFloat(s2);
|
|
return a(n2) && Math.floor(n2) === n2 ? function(t3, e3, i3, s3) {
|
|
"-" !== t3 && "+" !== t3 || (i3 = e3 + i3);
|
|
if (i3 === e3 || i3 < 0 || i3 >= s3) return false;
|
|
return i3;
|
|
}(s2[0], e2, n2, i2) : ["origin", "start", "end", "stack", "shape"].indexOf(s2) >= 0 && s2;
|
|
}
|
|
function ra(t2, e2, i2) {
|
|
const s2 = [];
|
|
for (let n2 = 0; n2 < i2.length; n2++) {
|
|
const o2 = i2[n2], { first: a2, last: r2, point: l2 } = la(o2, e2, "x");
|
|
if (!(!l2 || a2 && r2)) {
|
|
if (a2) s2.unshift(l2);
|
|
else if (t2.push(l2), !r2) break;
|
|
}
|
|
}
|
|
t2.push(...s2);
|
|
}
|
|
function la(t2, e2, i2) {
|
|
const s2 = t2.interpolate(e2, i2);
|
|
if (!s2) return {};
|
|
const n2 = s2[i2], o2 = t2.segments, a2 = t2.points;
|
|
let r2 = false, l2 = false;
|
|
for (let t3 = 0; t3 < o2.length; t3++) {
|
|
const e3 = o2[t3], s3 = a2[e3.start][i2], h2 = a2[e3.end][i2];
|
|
if (tt(n2, s3, h2)) {
|
|
r2 = n2 === s3, l2 = n2 === h2;
|
|
break;
|
|
}
|
|
}
|
|
return { first: r2, last: l2, point: s2 };
|
|
}
|
|
class ha {
|
|
constructor(t2) {
|
|
this.x = t2.x, this.y = t2.y, this.radius = t2.radius;
|
|
}
|
|
pathSegment(t2, e2, i2) {
|
|
const { x: s2, y: n2, radius: o2 } = this;
|
|
return e2 = e2 || { start: 0, end: O }, t2.arc(s2, n2, o2, e2.end, e2.start, true), !i2.bounds;
|
|
}
|
|
interpolate(t2) {
|
|
const { x: e2, y: i2, radius: s2 } = this, n2 = t2.angle;
|
|
return { x: e2 + Math.cos(n2) * s2, y: i2 + Math.sin(n2) * s2, angle: n2 };
|
|
}
|
|
}
|
|
function ca(t2) {
|
|
const { chart: e2, fill: i2, line: s2 } = t2;
|
|
if (a(i2)) return function(t3, e3) {
|
|
const i3 = t3.getDatasetMeta(e3), s3 = i3 && t3.isDatasetVisible(e3);
|
|
return s3 ? i3.dataset : null;
|
|
}(e2, i2);
|
|
if ("stack" === i2) return function(t3) {
|
|
const { scale: e3, index: i3, line: s3 } = t3, n3 = [], o2 = s3.segments, a2 = s3.points, r2 = function(t4, e4) {
|
|
const i4 = [], s4 = t4.getMatchingVisibleMetas("line");
|
|
for (let t5 = 0; t5 < s4.length; t5++) {
|
|
const n4 = s4[t5];
|
|
if (n4.index === e4) break;
|
|
n4.hidden || i4.unshift(n4.dataset);
|
|
}
|
|
return i4;
|
|
}(e3, i3);
|
|
r2.push(sa({ x: null, y: e3.bottom }, s3));
|
|
for (let t4 = 0; t4 < o2.length; t4++) {
|
|
const e4 = o2[t4];
|
|
for (let t5 = e4.start; t5 <= e4.end; t5++) ra(n3, a2[t5], r2);
|
|
}
|
|
return new no({ points: n3, options: {} });
|
|
}(t2);
|
|
if ("shape" === i2) return true;
|
|
const n2 = function(t3) {
|
|
const e3 = t3.scale || {};
|
|
if (e3.getPointPositionForValue) return function(t4) {
|
|
const { scale: e4, fill: i3 } = t4, s3 = e4.options, n3 = e4.getLabels().length, a2 = s3.reverse ? e4.max : e4.min, r2 = function(t5, e5, i4) {
|
|
let s4;
|
|
return s4 = "start" === t5 ? i4 : "end" === t5 ? e5.options.reverse ? e5.min : e5.max : o(t5) ? t5.value : e5.getBaseValue(), s4;
|
|
}(i3, e4, a2), l2 = [];
|
|
if (s3.grid.circular) {
|
|
const t5 = e4.getPointPositionForValue(0, a2);
|
|
return new ha({ x: t5.x, y: t5.y, radius: e4.getDistanceFromCenterForValue(r2) });
|
|
}
|
|
for (let t5 = 0; t5 < n3; ++t5) l2.push(e4.getPointPositionForValue(t5, r2));
|
|
return l2;
|
|
}(t3);
|
|
return function(t4) {
|
|
const { scale: e4 = {}, fill: i3 } = t4, s3 = function(t5, e5) {
|
|
let i4 = null;
|
|
return "start" === t5 ? i4 = e5.bottom : "end" === t5 ? i4 = e5.top : o(t5) ? i4 = e5.getPixelForValue(t5.value) : e5.getBasePixel && (i4 = e5.getBasePixel()), i4;
|
|
}(i3, e4);
|
|
if (a(s3)) {
|
|
const t5 = e4.isHorizontal();
|
|
return { x: t5 ? s3 : null, y: t5 ? null : s3 };
|
|
}
|
|
return null;
|
|
}(t3);
|
|
}(t2);
|
|
return n2 instanceof ha ? n2 : sa(n2, s2);
|
|
}
|
|
function da(t2, e2, i2) {
|
|
const s2 = ca(e2), { line: n2, scale: o2, axis: a2 } = e2, r2 = n2.options, l2 = r2.fill, h2 = r2.backgroundColor, { above: c2 = h2, below: d2 = h2 } = l2 || {};
|
|
s2 && n2.points.length && (Ie(t2, i2), function(t3, e3) {
|
|
const { line: i3, target: s3, above: n3, below: o3, area: a3, scale: r3 } = e3, l3 = i3._loop ? "angle" : e3.axis;
|
|
t3.save(), "x" === l3 && o3 !== n3 && (ua(t3, s3, a3.top), fa(t3, { line: i3, target: s3, color: n3, scale: r3, property: l3 }), t3.restore(), t3.save(), ua(t3, s3, a3.bottom));
|
|
fa(t3, { line: i3, target: s3, color: o3, scale: r3, property: l3 }), t3.restore();
|
|
}(t2, { line: n2, target: s2, above: c2, below: d2, area: i2, scale: o2, axis: a2 }), ze(t2));
|
|
}
|
|
function ua(t2, e2, i2) {
|
|
const { segments: s2, points: n2 } = e2;
|
|
let o2 = true, a2 = false;
|
|
t2.beginPath();
|
|
for (const r2 of s2) {
|
|
const { start: s3, end: l2 } = r2, h2 = n2[s3], c2 = n2[ea(s3, l2, n2)];
|
|
o2 ? (t2.moveTo(h2.x, h2.y), o2 = false) : (t2.lineTo(h2.x, i2), t2.lineTo(h2.x, h2.y)), a2 = !!e2.pathSegment(t2, r2, { move: a2 }), a2 ? t2.closePath() : t2.lineTo(c2.x, i2);
|
|
}
|
|
t2.lineTo(e2.first().x, i2), t2.closePath(), t2.clip();
|
|
}
|
|
function fa(t2, e2) {
|
|
const { line: i2, target: s2, property: n2, color: o2, scale: a2 } = e2, r2 = function(t3, e3, i3) {
|
|
const s3 = t3.segments, n3 = t3.points, o3 = e3.points, a3 = [];
|
|
for (const t4 of s3) {
|
|
let { start: s4, end: r3 } = t4;
|
|
r3 = ea(s4, r3, n3);
|
|
const l2 = ta(i3, n3[s4], n3[r3], t4.loop);
|
|
if (!e3.segments) {
|
|
a3.push({ source: t4, target: l2, start: n3[s4], end: n3[r3] });
|
|
continue;
|
|
}
|
|
const h2 = Ii(e3, l2);
|
|
for (const e4 of h2) {
|
|
const s5 = ta(i3, o3[e4.start], o3[e4.end], e4.loop), r4 = Ri(t4, n3, s5);
|
|
for (const t5 of r4) a3.push({ source: t5, target: e4, start: { [i3]: ia(l2, s5, "start", Math.max) }, end: { [i3]: ia(l2, s5, "end", Math.min) } });
|
|
}
|
|
}
|
|
return a3;
|
|
}(i2, s2, n2);
|
|
for (const { source: e3, target: l2, start: h2, end: c2 } of r2) {
|
|
const { style: { backgroundColor: r3 = o2 } = {} } = e3, d2 = true !== s2;
|
|
t2.save(), t2.fillStyle = r3, ga(t2, a2, d2 && ta(n2, h2, c2)), t2.beginPath();
|
|
const u2 = !!i2.pathSegment(t2, e3);
|
|
let f2;
|
|
if (d2) {
|
|
u2 ? t2.closePath() : pa(t2, s2, c2, n2);
|
|
const e4 = !!s2.pathSegment(t2, l2, { move: u2, reverse: true });
|
|
f2 = u2 && e4, f2 || pa(t2, s2, h2, n2);
|
|
}
|
|
t2.closePath(), t2.fill(f2 ? "evenodd" : "nonzero"), t2.restore();
|
|
}
|
|
}
|
|
function ga(t2, e2, i2) {
|
|
const { top: s2, bottom: n2 } = e2.chart.chartArea, { property: o2, start: a2, end: r2 } = i2 || {};
|
|
"x" === o2 && (t2.beginPath(), t2.rect(a2, s2, r2 - a2, n2 - s2), t2.clip());
|
|
}
|
|
function pa(t2, e2, i2, s2) {
|
|
const n2 = e2.interpolate(i2, s2);
|
|
n2 && t2.lineTo(n2.x, n2.y);
|
|
}
|
|
var ma = { id: "filler", afterDatasetsUpdate(t2, e2, i2) {
|
|
const s2 = (t2.data.datasets || []).length, n2 = [];
|
|
let o2, a2, r2, l2;
|
|
for (a2 = 0; a2 < s2; ++a2) o2 = t2.getDatasetMeta(a2), r2 = o2.dataset, l2 = null, r2 && r2.options && r2 instanceof no && (l2 = { visible: t2.isDatasetVisible(a2), index: a2, fill: aa(r2, a2, s2), chart: t2, axis: o2.controller.options.indexAxis, scale: o2.vScale, line: r2 }), o2.$filler = l2, n2.push(l2);
|
|
for (a2 = 0; a2 < s2; ++a2) l2 = n2[a2], l2 && false !== l2.fill && (l2.fill = oa(n2, a2, i2.propagate));
|
|
}, beforeDraw(t2, e2, i2) {
|
|
const s2 = "beforeDraw" === i2.drawTime, n2 = t2.getSortedVisibleDatasetMetas(), o2 = t2.chartArea;
|
|
for (let e3 = n2.length - 1; e3 >= 0; --e3) {
|
|
const i3 = n2[e3].$filler;
|
|
i3 && (i3.line.updateControlPoints(o2, i3.axis), s2 && i3.fill && da(t2.ctx, i3, o2));
|
|
}
|
|
}, beforeDatasetsDraw(t2, e2, i2) {
|
|
if ("beforeDatasetsDraw" !== i2.drawTime) return;
|
|
const s2 = t2.getSortedVisibleDatasetMetas();
|
|
for (let e3 = s2.length - 1; e3 >= 0; --e3) {
|
|
const i3 = s2[e3].$filler;
|
|
na(i3) && da(t2.ctx, i3, t2.chartArea);
|
|
}
|
|
}, beforeDatasetDraw(t2, e2, i2) {
|
|
const s2 = e2.meta.$filler;
|
|
na(s2) && "beforeDatasetDraw" === i2.drawTime && da(t2.ctx, s2, t2.chartArea);
|
|
}, defaults: { propagate: true, drawTime: "beforeDatasetDraw" } };
|
|
const ba = (t2, e2) => {
|
|
let { boxHeight: i2 = e2, boxWidth: s2 = e2 } = t2;
|
|
return t2.usePointStyle && (i2 = Math.min(i2, e2), s2 = t2.pointStyleWidth || Math.min(s2, e2)), { boxWidth: s2, boxHeight: i2, itemHeight: Math.max(e2, i2) };
|
|
};
|
|
class xa extends Hs {
|
|
constructor(t2) {
|
|
super(), this._added = false, this.legendHitBoxes = [], this._hoveredItem = null, this.doughnutMode = false, this.chart = t2.chart, this.options = t2.options, this.ctx = t2.ctx, this.legendItems = void 0, this.columnSizes = void 0, this.lineWidths = void 0, this.maxHeight = void 0, this.maxWidth = void 0, this.top = void 0, this.bottom = void 0, this.left = void 0, this.right = void 0, this.height = void 0, this.width = void 0, this._margins = void 0, this.position = void 0, this.weight = void 0, this.fullSize = void 0;
|
|
}
|
|
update(t2, e2, i2) {
|
|
this.maxWidth = t2, this.maxHeight = e2, this._margins = i2, this.setDimensions(), this.buildLabels(), this.fit();
|
|
}
|
|
setDimensions() {
|
|
this.isHorizontal() ? (this.width = this.maxWidth, this.left = this._margins.left, this.right = this.width) : (this.height = this.maxHeight, this.top = this._margins.top, this.bottom = this.height);
|
|
}
|
|
buildLabels() {
|
|
const t2 = this.options.labels || {};
|
|
let e2 = d(t2.generateLabels, [this.chart], this) || [];
|
|
t2.filter && (e2 = e2.filter((e3) => t2.filter(e3, this.chart.data))), t2.sort && (e2 = e2.sort((e3, i2) => t2.sort(e3, i2, this.chart.data))), this.options.reverse && e2.reverse(), this.legendItems = e2;
|
|
}
|
|
fit() {
|
|
const { options: t2, ctx: e2 } = this;
|
|
if (!t2.display) return void (this.width = this.height = 0);
|
|
const i2 = t2.labels, s2 = Si(i2.font), n2 = s2.size, o2 = this._computeTitleHeight(), { boxWidth: a2, itemHeight: r2 } = ba(i2, n2);
|
|
let l2, h2;
|
|
e2.font = s2.string, this.isHorizontal() ? (l2 = this.maxWidth, h2 = this._fitRows(o2, n2, a2, r2) + 10) : (h2 = this.maxHeight, l2 = this._fitCols(o2, s2, a2, r2) + 10), this.width = Math.min(l2, t2.maxWidth || this.maxWidth), this.height = Math.min(h2, t2.maxHeight || this.maxHeight);
|
|
}
|
|
_fitRows(t2, e2, i2, s2) {
|
|
const { ctx: n2, maxWidth: o2, options: { labels: { padding: a2 } } } = this, r2 = this.legendHitBoxes = [], l2 = this.lineWidths = [0], h2 = s2 + a2;
|
|
let c2 = t2;
|
|
n2.textAlign = "left", n2.textBaseline = "middle";
|
|
let d2 = -1, u2 = -h2;
|
|
return this.legendItems.forEach((t3, f2) => {
|
|
const g2 = i2 + e2 / 2 + n2.measureText(t3.text).width;
|
|
(0 === f2 || l2[l2.length - 1] + g2 + 2 * a2 > o2) && (c2 += h2, l2[l2.length - (f2 > 0 ? 0 : 1)] = 0, u2 += h2, d2++), r2[f2] = { left: 0, top: u2, row: d2, width: g2, height: s2 }, l2[l2.length - 1] += g2 + a2;
|
|
}), c2;
|
|
}
|
|
_fitCols(t2, e2, i2, s2) {
|
|
const { ctx: n2, maxHeight: o2, options: { labels: { padding: a2 } } } = this, r2 = this.legendHitBoxes = [], l2 = this.columnSizes = [], h2 = o2 - t2;
|
|
let c2 = a2, d2 = 0, u2 = 0, f2 = 0, g2 = 0;
|
|
return this.legendItems.forEach((t3, o3) => {
|
|
const { itemWidth: p2, itemHeight: m2 } = function(t4, e3, i3, s3, n3) {
|
|
const o4 = function(t5, e4, i4, s4) {
|
|
let n4 = t5.text;
|
|
n4 && "string" != typeof n4 && (n4 = n4.reduce((t6, e5) => t6.length > e5.length ? t6 : e5));
|
|
return e4 + i4.size / 2 + s4.measureText(n4).width;
|
|
}(s3, t4, e3, i3), a3 = function(t5, e4, i4) {
|
|
let s4 = t5;
|
|
"string" != typeof e4.text && (s4 = _a2(e4, i4));
|
|
return s4;
|
|
}(n3, s3, e3.lineHeight);
|
|
return { itemWidth: o4, itemHeight: a3 };
|
|
}(i2, e2, n2, t3, s2);
|
|
o3 > 0 && u2 + m2 + 2 * a2 > h2 && (c2 += d2 + a2, l2.push({ width: d2, height: u2 }), f2 += d2 + a2, g2++, d2 = u2 = 0), r2[o3] = { left: f2, top: u2, col: g2, width: p2, height: m2 }, d2 = Math.max(d2, p2), u2 += m2 + a2;
|
|
}), c2 += d2, l2.push({ width: d2, height: u2 }), c2;
|
|
}
|
|
adjustHitBoxes() {
|
|
if (!this.options.display) return;
|
|
const t2 = this._computeTitleHeight(), { legendHitBoxes: e2, options: { align: i2, labels: { padding: s2 }, rtl: n2 } } = this, o2 = Oi(n2, this.left, this.width);
|
|
if (this.isHorizontal()) {
|
|
let n3 = 0, a2 = ft(i2, this.left + s2, this.right - this.lineWidths[n3]);
|
|
for (const r2 of e2) n3 !== r2.row && (n3 = r2.row, a2 = ft(i2, this.left + s2, this.right - this.lineWidths[n3])), r2.top += this.top + t2 + s2, r2.left = o2.leftForLtr(o2.x(a2), r2.width), a2 += r2.width + s2;
|
|
} else {
|
|
let n3 = 0, a2 = ft(i2, this.top + t2 + s2, this.bottom - this.columnSizes[n3].height);
|
|
for (const r2 of e2) r2.col !== n3 && (n3 = r2.col, a2 = ft(i2, this.top + t2 + s2, this.bottom - this.columnSizes[n3].height)), r2.top = a2, r2.left += this.left + s2, r2.left = o2.leftForLtr(o2.x(r2.left), r2.width), a2 += r2.height + s2;
|
|
}
|
|
}
|
|
isHorizontal() {
|
|
return "top" === this.options.position || "bottom" === this.options.position;
|
|
}
|
|
draw() {
|
|
if (this.options.display) {
|
|
const t2 = this.ctx;
|
|
Ie(t2, this), this._draw(), ze(t2);
|
|
}
|
|
}
|
|
_draw() {
|
|
const { options: t2, columnSizes: e2, lineWidths: i2, ctx: s2 } = this, { align: n2, labels: o2 } = t2, a2 = ue.color, r2 = Oi(t2.rtl, this.left, this.width), h2 = Si(o2.font), { padding: c2 } = o2, d2 = h2.size, u2 = d2 / 2;
|
|
let f2;
|
|
this.drawTitle(), s2.textAlign = r2.textAlign("left"), s2.textBaseline = "middle", s2.lineWidth = 0.5, s2.font = h2.string;
|
|
const { boxWidth: g2, boxHeight: p2, itemHeight: m2 } = ba(o2, d2), b2 = this.isHorizontal(), x2 = this._computeTitleHeight();
|
|
f2 = b2 ? { x: ft(n2, this.left + c2, this.right - i2[0]), y: this.top + c2 + x2, line: 0 } : { x: this.left + c2, y: ft(n2, this.top + x2 + c2, this.bottom - e2[0].height), line: 0 }, Ai(this.ctx, t2.textDirection);
|
|
const _2 = m2 + c2;
|
|
this.legendItems.forEach((y2, v2) => {
|
|
s2.strokeStyle = y2.fontColor, s2.fillStyle = y2.fontColor;
|
|
const M2 = s2.measureText(y2.text).width, w2 = r2.textAlign(y2.textAlign || (y2.textAlign = o2.textAlign)), k2 = g2 + u2 + M2;
|
|
let S2 = f2.x, P2 = f2.y;
|
|
r2.setWidth(this.width), b2 ? v2 > 0 && S2 + k2 + c2 > this.right && (P2 = f2.y += _2, f2.line++, S2 = f2.x = ft(n2, this.left + c2, this.right - i2[f2.line])) : v2 > 0 && P2 + _2 > this.bottom && (S2 = f2.x = S2 + e2[f2.line].width + c2, f2.line++, P2 = f2.y = ft(n2, this.top + x2 + c2, this.bottom - e2[f2.line].height));
|
|
if (function(t3, e3, i3) {
|
|
if (isNaN(g2) || g2 <= 0 || isNaN(p2) || p2 < 0) return;
|
|
s2.save();
|
|
const n3 = l(i3.lineWidth, 1);
|
|
if (s2.fillStyle = l(i3.fillStyle, a2), s2.lineCap = l(i3.lineCap, "butt"), s2.lineDashOffset = l(i3.lineDashOffset, 0), s2.lineJoin = l(i3.lineJoin, "miter"), s2.lineWidth = n3, s2.strokeStyle = l(i3.strokeStyle, a2), s2.setLineDash(l(i3.lineDash, [])), o2.usePointStyle) {
|
|
const a3 = { radius: p2 * Math.SQRT2 / 2, pointStyle: i3.pointStyle, rotation: i3.rotation, borderWidth: n3 }, l2 = r2.xPlus(t3, g2 / 2);
|
|
Ee(s2, a3, l2, e3 + u2, o2.pointStyleWidth && g2);
|
|
} else {
|
|
const o3 = e3 + Math.max((d2 - p2) / 2, 0), a3 = r2.leftForLtr(t3, g2), l2 = wi(i3.borderRadius);
|
|
s2.beginPath(), Object.values(l2).some((t4) => 0 !== t4) ? He(s2, { x: a3, y: o3, w: g2, h: p2, radius: l2 }) : s2.rect(a3, o3, g2, p2), s2.fill(), 0 !== n3 && s2.stroke();
|
|
}
|
|
s2.restore();
|
|
}(r2.x(S2), P2, y2), S2 = gt(w2, S2 + g2 + u2, b2 ? S2 + k2 : this.right, t2.rtl), function(t3, e3, i3) {
|
|
Ne(s2, i3.text, t3, e3 + m2 / 2, h2, { strikethrough: i3.hidden, textAlign: r2.textAlign(i3.textAlign) });
|
|
}(r2.x(S2), P2, y2), b2) f2.x += k2 + c2;
|
|
else if ("string" != typeof y2.text) {
|
|
const t3 = h2.lineHeight;
|
|
f2.y += _a2(y2, t3) + c2;
|
|
} else f2.y += _2;
|
|
}), Ti(this.ctx, t2.textDirection);
|
|
}
|
|
drawTitle() {
|
|
const t2 = this.options, e2 = t2.title, i2 = Si(e2.font), s2 = ki(e2.padding);
|
|
if (!e2.display) return;
|
|
const n2 = Oi(t2.rtl, this.left, this.width), o2 = this.ctx, a2 = e2.position, r2 = i2.size / 2, l2 = s2.top + r2;
|
|
let h2, c2 = this.left, d2 = this.width;
|
|
if (this.isHorizontal()) d2 = Math.max(...this.lineWidths), h2 = this.top + l2, c2 = ft(t2.align, c2, this.right - d2);
|
|
else {
|
|
const e3 = this.columnSizes.reduce((t3, e4) => Math.max(t3, e4.height), 0);
|
|
h2 = l2 + ft(t2.align, this.top, this.bottom - e3 - t2.labels.padding - this._computeTitleHeight());
|
|
}
|
|
const u2 = ft(a2, c2, c2 + d2);
|
|
o2.textAlign = n2.textAlign(ut(a2)), o2.textBaseline = "middle", o2.strokeStyle = e2.color, o2.fillStyle = e2.color, o2.font = i2.string, Ne(o2, e2.text, u2, h2, i2);
|
|
}
|
|
_computeTitleHeight() {
|
|
const t2 = this.options.title, e2 = Si(t2.font), i2 = ki(t2.padding);
|
|
return t2.display ? e2.lineHeight + i2.height : 0;
|
|
}
|
|
_getLegendItemAt(t2, e2) {
|
|
let i2, s2, n2;
|
|
if (tt(t2, this.left, this.right) && tt(e2, this.top, this.bottom)) {
|
|
for (n2 = this.legendHitBoxes, i2 = 0; i2 < n2.length; ++i2) if (s2 = n2[i2], tt(t2, s2.left, s2.left + s2.width) && tt(e2, s2.top, s2.top + s2.height)) return this.legendItems[i2];
|
|
}
|
|
return null;
|
|
}
|
|
handleEvent(t2) {
|
|
const e2 = this.options;
|
|
if (!function(t3, e3) {
|
|
if (("mousemove" === t3 || "mouseout" === t3) && (e3.onHover || e3.onLeave)) return true;
|
|
if (e3.onClick && ("click" === t3 || "mouseup" === t3)) return true;
|
|
return false;
|
|
}(t2.type, e2)) return;
|
|
const i2 = this._getLegendItemAt(t2.x, t2.y);
|
|
if ("mousemove" === t2.type || "mouseout" === t2.type) {
|
|
const o2 = this._hoveredItem, a2 = (n2 = i2, null !== (s2 = o2) && null !== n2 && s2.datasetIndex === n2.datasetIndex && s2.index === n2.index);
|
|
o2 && !a2 && d(e2.onLeave, [t2, o2, this], this), this._hoveredItem = i2, i2 && !a2 && d(e2.onHover, [t2, i2, this], this);
|
|
} else i2 && d(e2.onClick, [t2, i2, this], this);
|
|
var s2, n2;
|
|
}
|
|
}
|
|
function _a2(t2, e2) {
|
|
return e2 * (t2.text ? t2.text.length : 0);
|
|
}
|
|
var ya = { id: "legend", _element: xa, start(t2, e2, i2) {
|
|
const s2 = t2.legend = new xa({ ctx: t2.ctx, options: i2, chart: t2 });
|
|
as.configure(t2, s2, i2), as.addBox(t2, s2);
|
|
}, stop(t2) {
|
|
as.removeBox(t2, t2.legend), delete t2.legend;
|
|
}, beforeUpdate(t2, e2, i2) {
|
|
const s2 = t2.legend;
|
|
as.configure(t2, s2, i2), s2.options = i2;
|
|
}, afterUpdate(t2) {
|
|
const e2 = t2.legend;
|
|
e2.buildLabels(), e2.adjustHitBoxes();
|
|
}, afterEvent(t2, e2) {
|
|
e2.replay || t2.legend.handleEvent(e2.event);
|
|
}, defaults: { display: true, position: "top", align: "center", fullSize: true, reverse: false, weight: 1e3, onClick(t2, e2, i2) {
|
|
const s2 = e2.datasetIndex, n2 = i2.chart;
|
|
n2.isDatasetVisible(s2) ? (n2.hide(s2), e2.hidden = true) : (n2.show(s2), e2.hidden = false);
|
|
}, onHover: null, onLeave: null, labels: { color: (t2) => t2.chart.options.color, boxWidth: 40, padding: 10, generateLabels(t2) {
|
|
const e2 = t2.data.datasets, { labels: { usePointStyle: i2, pointStyle: s2, textAlign: n2, color: o2, useBorderRadius: a2, borderRadius: r2 } } = t2.legend.options;
|
|
return t2._getSortedDatasetMetas().map((t3) => {
|
|
const l2 = t3.controller.getStyle(i2 ? 0 : void 0), h2 = ki(l2.borderWidth);
|
|
return { text: e2[t3.index].label, fillStyle: l2.backgroundColor, fontColor: o2, hidden: !t3.visible, lineCap: l2.borderCapStyle, lineDash: l2.borderDash, lineDashOffset: l2.borderDashOffset, lineJoin: l2.borderJoinStyle, lineWidth: (h2.width + h2.height) / 4, strokeStyle: l2.borderColor, pointStyle: s2 || l2.pointStyle, rotation: l2.rotation, textAlign: n2 || l2.textAlign, borderRadius: a2 && (r2 || l2.borderRadius), datasetIndex: t3.index };
|
|
}, this);
|
|
} }, title: { color: (t2) => t2.chart.options.color, display: false, position: "center", text: "" } }, descriptors: { _scriptable: (t2) => !t2.startsWith("on"), labels: { _scriptable: (t2) => !["generateLabels", "filter", "sort"].includes(t2) } } };
|
|
class va extends Hs {
|
|
constructor(t2) {
|
|
super(), this.chart = t2.chart, this.options = t2.options, this.ctx = t2.ctx, this._padding = void 0, this.top = void 0, this.bottom = void 0, this.left = void 0, this.right = void 0, this.width = void 0, this.height = void 0, this.position = void 0, this.weight = void 0, this.fullSize = void 0;
|
|
}
|
|
update(t2, e2) {
|
|
const i2 = this.options;
|
|
if (this.left = 0, this.top = 0, !i2.display) return void (this.width = this.height = this.right = this.bottom = 0);
|
|
this.width = this.right = t2, this.height = this.bottom = e2;
|
|
const s2 = n(i2.text) ? i2.text.length : 1;
|
|
this._padding = ki(i2.padding);
|
|
const o2 = s2 * Si(i2.font).lineHeight + this._padding.height;
|
|
this.isHorizontal() ? this.height = o2 : this.width = o2;
|
|
}
|
|
isHorizontal() {
|
|
const t2 = this.options.position;
|
|
return "top" === t2 || "bottom" === t2;
|
|
}
|
|
_drawArgs(t2) {
|
|
const { top: e2, left: i2, bottom: s2, right: n2, options: o2 } = this, a2 = o2.align;
|
|
let r2, l2, h2, c2 = 0;
|
|
return this.isHorizontal() ? (l2 = ft(a2, i2, n2), h2 = e2 + t2, r2 = n2 - i2) : ("left" === o2.position ? (l2 = i2 + t2, h2 = ft(a2, s2, e2), c2 = -0.5 * C) : (l2 = n2 - t2, h2 = ft(a2, e2, s2), c2 = 0.5 * C), r2 = s2 - e2), { titleX: l2, titleY: h2, maxWidth: r2, rotation: c2 };
|
|
}
|
|
draw() {
|
|
const t2 = this.ctx, e2 = this.options;
|
|
if (!e2.display) return;
|
|
const i2 = Si(e2.font), s2 = i2.lineHeight / 2 + this._padding.top, { titleX: n2, titleY: o2, maxWidth: a2, rotation: r2 } = this._drawArgs(s2);
|
|
Ne(t2, e2.text, 0, 0, i2, { color: e2.color, maxWidth: a2, rotation: r2, textAlign: ut(e2.align), textBaseline: "middle", translation: [n2, o2] });
|
|
}
|
|
}
|
|
var Ma = { id: "title", _element: va, start(t2, e2, i2) {
|
|
!function(t3, e3) {
|
|
const i3 = new va({ ctx: t3.ctx, options: e3, chart: t3 });
|
|
as.configure(t3, i3, e3), as.addBox(t3, i3), t3.titleBlock = i3;
|
|
}(t2, i2);
|
|
}, stop(t2) {
|
|
const e2 = t2.titleBlock;
|
|
as.removeBox(t2, e2), delete t2.titleBlock;
|
|
}, beforeUpdate(t2, e2, i2) {
|
|
const s2 = t2.titleBlock;
|
|
as.configure(t2, s2, i2), s2.options = i2;
|
|
}, defaults: { align: "center", display: false, font: { weight: "bold" }, fullSize: true, padding: 10, position: "top", text: "", weight: 2e3 }, defaultRoutes: { color: "color" }, descriptors: { _scriptable: true, _indexable: false } };
|
|
const wa = /* @__PURE__ */ new WeakMap();
|
|
var ka = { id: "subtitle", start(t2, e2, i2) {
|
|
const s2 = new va({ ctx: t2.ctx, options: i2, chart: t2 });
|
|
as.configure(t2, s2, i2), as.addBox(t2, s2), wa.set(t2, s2);
|
|
}, stop(t2) {
|
|
as.removeBox(t2, wa.get(t2)), wa.delete(t2);
|
|
}, beforeUpdate(t2, e2, i2) {
|
|
const s2 = wa.get(t2);
|
|
as.configure(t2, s2, i2), s2.options = i2;
|
|
}, defaults: { align: "center", display: false, font: { weight: "normal" }, fullSize: true, padding: 0, position: "top", text: "", weight: 1500 }, defaultRoutes: { color: "color" }, descriptors: { _scriptable: true, _indexable: false } };
|
|
const Sa = { average(t2) {
|
|
if (!t2.length) return false;
|
|
let e2, i2, s2 = 0, n2 = 0, o2 = 0;
|
|
for (e2 = 0, i2 = t2.length; e2 < i2; ++e2) {
|
|
const i3 = t2[e2].element;
|
|
if (i3 && i3.hasValue()) {
|
|
const t3 = i3.tooltipPosition();
|
|
s2 += t3.x, n2 += t3.y, ++o2;
|
|
}
|
|
}
|
|
return { x: s2 / o2, y: n2 / o2 };
|
|
}, nearest(t2, e2) {
|
|
if (!t2.length) return false;
|
|
let i2, s2, n2, o2 = e2.x, a2 = e2.y, r2 = Number.POSITIVE_INFINITY;
|
|
for (i2 = 0, s2 = t2.length; i2 < s2; ++i2) {
|
|
const s3 = t2[i2].element;
|
|
if (s3 && s3.hasValue()) {
|
|
const t3 = q(e2, s3.getCenterPoint());
|
|
t3 < r2 && (r2 = t3, n2 = s3);
|
|
}
|
|
}
|
|
if (n2) {
|
|
const t3 = n2.tooltipPosition();
|
|
o2 = t3.x, a2 = t3.y;
|
|
}
|
|
return { x: o2, y: a2 };
|
|
} };
|
|
function Pa(t2, e2) {
|
|
return e2 && (n(e2) ? Array.prototype.push.apply(t2, e2) : t2.push(e2)), t2;
|
|
}
|
|
function Da(t2) {
|
|
return ("string" == typeof t2 || t2 instanceof String) && t2.indexOf("\n") > -1 ? t2.split("\n") : t2;
|
|
}
|
|
function Ca(t2, e2) {
|
|
const { element: i2, datasetIndex: s2, index: n2 } = e2, o2 = t2.getDatasetMeta(s2).controller, { label: a2, value: r2 } = o2.getLabelAndValue(n2);
|
|
return { chart: t2, label: a2, parsed: o2.getParsed(n2), raw: t2.data.datasets[s2].data[n2], formattedValue: r2, dataset: o2.getDataset(), dataIndex: n2, datasetIndex: s2, element: i2 };
|
|
}
|
|
function Oa(t2, e2) {
|
|
const i2 = t2.chart.ctx, { body: s2, footer: n2, title: o2 } = t2, { boxWidth: a2, boxHeight: r2 } = e2, l2 = Si(e2.bodyFont), h2 = Si(e2.titleFont), c2 = Si(e2.footerFont), d2 = o2.length, f2 = n2.length, g2 = s2.length, p2 = ki(e2.padding);
|
|
let m2 = p2.height, b2 = 0, x2 = s2.reduce((t3, e3) => t3 + e3.before.length + e3.lines.length + e3.after.length, 0);
|
|
if (x2 += t2.beforeBody.length + t2.afterBody.length, d2 && (m2 += d2 * h2.lineHeight + (d2 - 1) * e2.titleSpacing + e2.titleMarginBottom), x2) {
|
|
m2 += g2 * (e2.displayColors ? Math.max(r2, l2.lineHeight) : l2.lineHeight) + (x2 - g2) * l2.lineHeight + (x2 - 1) * e2.bodySpacing;
|
|
}
|
|
f2 && (m2 += e2.footerMarginTop + f2 * c2.lineHeight + (f2 - 1) * e2.footerSpacing);
|
|
let _2 = 0;
|
|
const y2 = function(t3) {
|
|
b2 = Math.max(b2, i2.measureText(t3).width + _2);
|
|
};
|
|
return i2.save(), i2.font = h2.string, u(t2.title, y2), i2.font = l2.string, u(t2.beforeBody.concat(t2.afterBody), y2), _2 = e2.displayColors ? a2 + 2 + e2.boxPadding : 0, u(s2, (t3) => {
|
|
u(t3.before, y2), u(t3.lines, y2), u(t3.after, y2);
|
|
}), _2 = 0, i2.font = c2.string, u(t2.footer, y2), i2.restore(), b2 += p2.width, { width: b2, height: m2 };
|
|
}
|
|
function Aa(t2, e2, i2, s2) {
|
|
const { x: n2, width: o2 } = i2, { width: a2, chartArea: { left: r2, right: l2 } } = t2;
|
|
let h2 = "center";
|
|
return "center" === s2 ? h2 = n2 <= (r2 + l2) / 2 ? "left" : "right" : n2 <= o2 / 2 ? h2 = "left" : n2 >= a2 - o2 / 2 && (h2 = "right"), function(t3, e3, i3, s3) {
|
|
const { x: n3, width: o3 } = s3, a3 = i3.caretSize + i3.caretPadding;
|
|
return "left" === t3 && n3 + o3 + a3 > e3.width || "right" === t3 && n3 - o3 - a3 < 0 || void 0;
|
|
}(h2, t2, e2, i2) && (h2 = "center"), h2;
|
|
}
|
|
function Ta(t2, e2, i2) {
|
|
const s2 = i2.yAlign || e2.yAlign || function(t3, e3) {
|
|
const { y: i3, height: s3 } = e3;
|
|
return i3 < s3 / 2 ? "top" : i3 > t3.height - s3 / 2 ? "bottom" : "center";
|
|
}(t2, i2);
|
|
return { xAlign: i2.xAlign || e2.xAlign || Aa(t2, e2, i2, s2), yAlign: s2 };
|
|
}
|
|
function La(t2, e2, i2, s2) {
|
|
const { caretSize: n2, caretPadding: o2, cornerRadius: a2 } = t2, { xAlign: r2, yAlign: l2 } = i2, h2 = n2 + o2, { topLeft: c2, topRight: d2, bottomLeft: u2, bottomRight: f2 } = wi(a2);
|
|
let g2 = function(t3, e3) {
|
|
let { x: i3, width: s3 } = t3;
|
|
return "right" === e3 ? i3 -= s3 : "center" === e3 && (i3 -= s3 / 2), i3;
|
|
}(e2, r2);
|
|
const p2 = function(t3, e3, i3) {
|
|
let { y: s3, height: n3 } = t3;
|
|
return "top" === e3 ? s3 += i3 : s3 -= "bottom" === e3 ? n3 + i3 : n3 / 2, s3;
|
|
}(e2, l2, h2);
|
|
return "center" === l2 ? "left" === r2 ? g2 += h2 : "right" === r2 && (g2 -= h2) : "left" === r2 ? g2 -= Math.max(c2, u2) + n2 : "right" === r2 && (g2 += Math.max(d2, f2) + n2), { x: J(g2, 0, s2.width - e2.width), y: J(p2, 0, s2.height - e2.height) };
|
|
}
|
|
function Ea(t2, e2, i2) {
|
|
const s2 = ki(i2.padding);
|
|
return "center" === e2 ? t2.x + t2.width / 2 : "right" === e2 ? t2.x + t2.width - s2.right : t2.x + s2.left;
|
|
}
|
|
function Ra(t2) {
|
|
return Pa([], Da(t2));
|
|
}
|
|
function Ia(t2, e2) {
|
|
const i2 = e2 && e2.dataset && e2.dataset.tooltip && e2.dataset.tooltip.callbacks;
|
|
return i2 ? t2.override(i2) : t2;
|
|
}
|
|
const za = { beforeTitle: e, title(t2) {
|
|
if (t2.length > 0) {
|
|
const e2 = t2[0], i2 = e2.chart.data.labels, s2 = i2 ? i2.length : 0;
|
|
if (this && this.options && "dataset" === this.options.mode) return e2.dataset.label || "";
|
|
if (e2.label) return e2.label;
|
|
if (s2 > 0 && e2.dataIndex < s2) return i2[e2.dataIndex];
|
|
}
|
|
return "";
|
|
}, afterTitle: e, beforeBody: e, beforeLabel: e, label(t2) {
|
|
if (this && this.options && "dataset" === this.options.mode) return t2.label + ": " + t2.formattedValue || t2.formattedValue;
|
|
let e2 = t2.dataset.label || "";
|
|
e2 && (e2 += ": ");
|
|
const i2 = t2.formattedValue;
|
|
return s(i2) || (e2 += i2), e2;
|
|
}, labelColor(t2) {
|
|
const e2 = t2.chart.getDatasetMeta(t2.datasetIndex).controller.getStyle(t2.dataIndex);
|
|
return { borderColor: e2.borderColor, backgroundColor: e2.backgroundColor, borderWidth: e2.borderWidth, borderDash: e2.borderDash, borderDashOffset: e2.borderDashOffset, borderRadius: 0 };
|
|
}, labelTextColor() {
|
|
return this.options.bodyColor;
|
|
}, labelPointStyle(t2) {
|
|
const e2 = t2.chart.getDatasetMeta(t2.datasetIndex).controller.getStyle(t2.dataIndex);
|
|
return { pointStyle: e2.pointStyle, rotation: e2.rotation };
|
|
}, afterLabel: e, afterBody: e, beforeFooter: e, footer: e, afterFooter: e };
|
|
function Fa(t2, e2, i2, s2) {
|
|
const n2 = t2[e2].call(i2, s2);
|
|
return void 0 === n2 ? za[e2].call(i2, s2) : n2;
|
|
}
|
|
class Va extends Hs {
|
|
constructor(t2) {
|
|
super(), this.opacity = 0, this._active = [], this._eventPosition = void 0, this._size = void 0, this._cachedAnimations = void 0, this._tooltipItems = [], this.$animations = void 0, this.$context = void 0, this.chart = t2.chart, this.options = t2.options, this.dataPoints = void 0, this.title = void 0, this.beforeBody = void 0, this.body = void 0, this.afterBody = void 0, this.footer = void 0, this.xAlign = void 0, this.yAlign = void 0, this.x = void 0, this.y = void 0, this.height = void 0, this.width = void 0, this.caretX = void 0, this.caretY = void 0, this.labelColors = void 0, this.labelPointStyles = void 0, this.labelTextColors = void 0;
|
|
}
|
|
initialize(t2) {
|
|
this.options = t2, this._cachedAnimations = void 0, this.$context = void 0;
|
|
}
|
|
_resolveAnimations() {
|
|
const t2 = this._cachedAnimations;
|
|
if (t2) return t2;
|
|
const e2 = this.chart, i2 = this.options.setContext(this.getContext()), s2 = i2.enabled && e2.options.animation && i2.animations, n2 = new Os(this.chart, s2);
|
|
return s2._cacheable && (this._cachedAnimations = Object.freeze(n2)), n2;
|
|
}
|
|
getContext() {
|
|
return this.$context || (this.$context = (t2 = this.chart.getContext(), e2 = this, i2 = this._tooltipItems, Ci(t2, { tooltip: e2, tooltipItems: i2, type: "tooltip" })));
|
|
var t2, e2, i2;
|
|
}
|
|
getTitle(t2, e2) {
|
|
const { callbacks: i2 } = e2, s2 = Fa(i2, "beforeTitle", this, t2), n2 = Fa(i2, "title", this, t2), o2 = Fa(i2, "afterTitle", this, t2);
|
|
let a2 = [];
|
|
return a2 = Pa(a2, Da(s2)), a2 = Pa(a2, Da(n2)), a2 = Pa(a2, Da(o2)), a2;
|
|
}
|
|
getBeforeBody(t2, e2) {
|
|
return Ra(Fa(e2.callbacks, "beforeBody", this, t2));
|
|
}
|
|
getBody(t2, e2) {
|
|
const { callbacks: i2 } = e2, s2 = [];
|
|
return u(t2, (t3) => {
|
|
const e3 = { before: [], lines: [], after: [] }, n2 = Ia(i2, t3);
|
|
Pa(e3.before, Da(Fa(n2, "beforeLabel", this, t3))), Pa(e3.lines, Fa(n2, "label", this, t3)), Pa(e3.after, Da(Fa(n2, "afterLabel", this, t3))), s2.push(e3);
|
|
}), s2;
|
|
}
|
|
getAfterBody(t2, e2) {
|
|
return Ra(Fa(e2.callbacks, "afterBody", this, t2));
|
|
}
|
|
getFooter(t2, e2) {
|
|
const { callbacks: i2 } = e2, s2 = Fa(i2, "beforeFooter", this, t2), n2 = Fa(i2, "footer", this, t2), o2 = Fa(i2, "afterFooter", this, t2);
|
|
let a2 = [];
|
|
return a2 = Pa(a2, Da(s2)), a2 = Pa(a2, Da(n2)), a2 = Pa(a2, Da(o2)), a2;
|
|
}
|
|
_createItems(t2) {
|
|
const e2 = this._active, i2 = this.chart.data, s2 = [], n2 = [], o2 = [];
|
|
let a2, r2, l2 = [];
|
|
for (a2 = 0, r2 = e2.length; a2 < r2; ++a2) l2.push(Ca(this.chart, e2[a2]));
|
|
return t2.filter && (l2 = l2.filter((e3, s3, n3) => t2.filter(e3, s3, n3, i2))), t2.itemSort && (l2 = l2.sort((e3, s3) => t2.itemSort(e3, s3, i2))), u(l2, (e3) => {
|
|
const i3 = Ia(t2.callbacks, e3);
|
|
s2.push(Fa(i3, "labelColor", this, e3)), n2.push(Fa(i3, "labelPointStyle", this, e3)), o2.push(Fa(i3, "labelTextColor", this, e3));
|
|
}), this.labelColors = s2, this.labelPointStyles = n2, this.labelTextColors = o2, this.dataPoints = l2, l2;
|
|
}
|
|
update(t2, e2) {
|
|
const i2 = this.options.setContext(this.getContext()), s2 = this._active;
|
|
let n2, o2 = [];
|
|
if (s2.length) {
|
|
const t3 = Sa[i2.position].call(this, s2, this._eventPosition);
|
|
o2 = this._createItems(i2), this.title = this.getTitle(o2, i2), this.beforeBody = this.getBeforeBody(o2, i2), this.body = this.getBody(o2, i2), this.afterBody = this.getAfterBody(o2, i2), this.footer = this.getFooter(o2, i2);
|
|
const e3 = this._size = Oa(this, i2), a2 = Object.assign({}, t3, e3), r2 = Ta(this.chart, i2, a2), l2 = La(i2, a2, r2, this.chart);
|
|
this.xAlign = r2.xAlign, this.yAlign = r2.yAlign, n2 = { opacity: 1, x: l2.x, y: l2.y, width: e3.width, height: e3.height, caretX: t3.x, caretY: t3.y };
|
|
} else 0 !== this.opacity && (n2 = { opacity: 0 });
|
|
this._tooltipItems = o2, this.$context = void 0, n2 && this._resolveAnimations().update(this, n2), t2 && i2.external && i2.external.call(this, { chart: this.chart, tooltip: this, replay: e2 });
|
|
}
|
|
drawCaret(t2, e2, i2, s2) {
|
|
const n2 = this.getCaretPosition(t2, i2, s2);
|
|
e2.lineTo(n2.x1, n2.y1), e2.lineTo(n2.x2, n2.y2), e2.lineTo(n2.x3, n2.y3);
|
|
}
|
|
getCaretPosition(t2, e2, i2) {
|
|
const { xAlign: s2, yAlign: n2 } = this, { caretSize: o2, cornerRadius: a2 } = i2, { topLeft: r2, topRight: l2, bottomLeft: h2, bottomRight: c2 } = wi(a2), { x: d2, y: u2 } = t2, { width: f2, height: g2 } = e2;
|
|
let p2, m2, b2, x2, _2, y2;
|
|
return "center" === n2 ? (_2 = u2 + g2 / 2, "left" === s2 ? (p2 = d2, m2 = p2 - o2, x2 = _2 + o2, y2 = _2 - o2) : (p2 = d2 + f2, m2 = p2 + o2, x2 = _2 - o2, y2 = _2 + o2), b2 = p2) : (m2 = "left" === s2 ? d2 + Math.max(r2, h2) + o2 : "right" === s2 ? d2 + f2 - Math.max(l2, c2) - o2 : this.caretX, "top" === n2 ? (x2 = u2, _2 = x2 - o2, p2 = m2 - o2, b2 = m2 + o2) : (x2 = u2 + g2, _2 = x2 + o2, p2 = m2 + o2, b2 = m2 - o2), y2 = x2), { x1: p2, x2: m2, x3: b2, y1: x2, y2: _2, y3: y2 };
|
|
}
|
|
drawTitle(t2, e2, i2) {
|
|
const s2 = this.title, n2 = s2.length;
|
|
let o2, a2, r2;
|
|
if (n2) {
|
|
const l2 = Oi(i2.rtl, this.x, this.width);
|
|
for (t2.x = Ea(this, i2.titleAlign, i2), e2.textAlign = l2.textAlign(i2.titleAlign), e2.textBaseline = "middle", o2 = Si(i2.titleFont), a2 = i2.titleSpacing, e2.fillStyle = i2.titleColor, e2.font = o2.string, r2 = 0; r2 < n2; ++r2) e2.fillText(s2[r2], l2.x(t2.x), t2.y + o2.lineHeight / 2), t2.y += o2.lineHeight + a2, r2 + 1 === n2 && (t2.y += i2.titleMarginBottom - a2);
|
|
}
|
|
}
|
|
_drawColorBox(t2, e2, i2, s2, n2) {
|
|
const a2 = this.labelColors[i2], r2 = this.labelPointStyles[i2], { boxHeight: l2, boxWidth: h2 } = n2, c2 = Si(n2.bodyFont), d2 = Ea(this, "left", n2), u2 = s2.x(d2), f2 = l2 < c2.lineHeight ? (c2.lineHeight - l2) / 2 : 0, g2 = e2.y + f2;
|
|
if (n2.usePointStyle) {
|
|
const e3 = { radius: Math.min(h2, l2) / 2, pointStyle: r2.pointStyle, rotation: r2.rotation, borderWidth: 1 }, i3 = s2.leftForLtr(u2, h2) + h2 / 2, o2 = g2 + l2 / 2;
|
|
t2.strokeStyle = n2.multiKeyBackground, t2.fillStyle = n2.multiKeyBackground, Le(t2, e3, i3, o2), t2.strokeStyle = a2.borderColor, t2.fillStyle = a2.backgroundColor, Le(t2, e3, i3, o2);
|
|
} else {
|
|
t2.lineWidth = o(a2.borderWidth) ? Math.max(...Object.values(a2.borderWidth)) : a2.borderWidth || 1, t2.strokeStyle = a2.borderColor, t2.setLineDash(a2.borderDash || []), t2.lineDashOffset = a2.borderDashOffset || 0;
|
|
const e3 = s2.leftForLtr(u2, h2), i3 = s2.leftForLtr(s2.xPlus(u2, 1), h2 - 2), r3 = wi(a2.borderRadius);
|
|
Object.values(r3).some((t3) => 0 !== t3) ? (t2.beginPath(), t2.fillStyle = n2.multiKeyBackground, He(t2, { x: e3, y: g2, w: h2, h: l2, radius: r3 }), t2.fill(), t2.stroke(), t2.fillStyle = a2.backgroundColor, t2.beginPath(), He(t2, { x: i3, y: g2 + 1, w: h2 - 2, h: l2 - 2, radius: r3 }), t2.fill()) : (t2.fillStyle = n2.multiKeyBackground, t2.fillRect(e3, g2, h2, l2), t2.strokeRect(e3, g2, h2, l2), t2.fillStyle = a2.backgroundColor, t2.fillRect(i3, g2 + 1, h2 - 2, l2 - 2));
|
|
}
|
|
t2.fillStyle = this.labelTextColors[i2];
|
|
}
|
|
drawBody(t2, e2, i2) {
|
|
const { body: s2 } = this, { bodySpacing: n2, bodyAlign: o2, displayColors: a2, boxHeight: r2, boxWidth: l2, boxPadding: h2 } = i2, c2 = Si(i2.bodyFont);
|
|
let d2 = c2.lineHeight, f2 = 0;
|
|
const g2 = Oi(i2.rtl, this.x, this.width), p2 = function(i3) {
|
|
e2.fillText(i3, g2.x(t2.x + f2), t2.y + d2 / 2), t2.y += d2 + n2;
|
|
}, m2 = g2.textAlign(o2);
|
|
let b2, x2, _2, y2, v2, M2, w2;
|
|
for (e2.textAlign = o2, e2.textBaseline = "middle", e2.font = c2.string, t2.x = Ea(this, m2, i2), e2.fillStyle = i2.bodyColor, u(this.beforeBody, p2), f2 = a2 && "right" !== m2 ? "center" === o2 ? l2 / 2 + h2 : l2 + 2 + h2 : 0, y2 = 0, M2 = s2.length; y2 < M2; ++y2) {
|
|
for (b2 = s2[y2], x2 = this.labelTextColors[y2], e2.fillStyle = x2, u(b2.before, p2), _2 = b2.lines, a2 && _2.length && (this._drawColorBox(e2, t2, y2, g2, i2), d2 = Math.max(c2.lineHeight, r2)), v2 = 0, w2 = _2.length; v2 < w2; ++v2) p2(_2[v2]), d2 = c2.lineHeight;
|
|
u(b2.after, p2);
|
|
}
|
|
f2 = 0, d2 = c2.lineHeight, u(this.afterBody, p2), t2.y -= n2;
|
|
}
|
|
drawFooter(t2, e2, i2) {
|
|
const s2 = this.footer, n2 = s2.length;
|
|
let o2, a2;
|
|
if (n2) {
|
|
const r2 = Oi(i2.rtl, this.x, this.width);
|
|
for (t2.x = Ea(this, i2.footerAlign, i2), t2.y += i2.footerMarginTop, e2.textAlign = r2.textAlign(i2.footerAlign), e2.textBaseline = "middle", o2 = Si(i2.footerFont), e2.fillStyle = i2.footerColor, e2.font = o2.string, a2 = 0; a2 < n2; ++a2) e2.fillText(s2[a2], r2.x(t2.x), t2.y + o2.lineHeight / 2), t2.y += o2.lineHeight + i2.footerSpacing;
|
|
}
|
|
}
|
|
drawBackground(t2, e2, i2, s2) {
|
|
const { xAlign: n2, yAlign: o2 } = this, { x: a2, y: r2 } = t2, { width: l2, height: h2 } = i2, { topLeft: c2, topRight: d2, bottomLeft: u2, bottomRight: f2 } = wi(s2.cornerRadius);
|
|
e2.fillStyle = s2.backgroundColor, e2.strokeStyle = s2.borderColor, e2.lineWidth = s2.borderWidth, e2.beginPath(), e2.moveTo(a2 + c2, r2), "top" === o2 && this.drawCaret(t2, e2, i2, s2), e2.lineTo(a2 + l2 - d2, r2), e2.quadraticCurveTo(a2 + l2, r2, a2 + l2, r2 + d2), "center" === o2 && "right" === n2 && this.drawCaret(t2, e2, i2, s2), e2.lineTo(a2 + l2, r2 + h2 - f2), e2.quadraticCurveTo(a2 + l2, r2 + h2, a2 + l2 - f2, r2 + h2), "bottom" === o2 && this.drawCaret(t2, e2, i2, s2), e2.lineTo(a2 + u2, r2 + h2), e2.quadraticCurveTo(a2, r2 + h2, a2, r2 + h2 - u2), "center" === o2 && "left" === n2 && this.drawCaret(t2, e2, i2, s2), e2.lineTo(a2, r2 + c2), e2.quadraticCurveTo(a2, r2, a2 + c2, r2), e2.closePath(), e2.fill(), s2.borderWidth > 0 && e2.stroke();
|
|
}
|
|
_updateAnimationTarget(t2) {
|
|
const e2 = this.chart, i2 = this.$animations, s2 = i2 && i2.x, n2 = i2 && i2.y;
|
|
if (s2 || n2) {
|
|
const i3 = Sa[t2.position].call(this, this._active, this._eventPosition);
|
|
if (!i3) return;
|
|
const o2 = this._size = Oa(this, t2), a2 = Object.assign({}, i3, this._size), r2 = Ta(e2, t2, a2), l2 = La(t2, a2, r2, e2);
|
|
s2._to === l2.x && n2._to === l2.y || (this.xAlign = r2.xAlign, this.yAlign = r2.yAlign, this.width = o2.width, this.height = o2.height, this.caretX = i3.x, this.caretY = i3.y, this._resolveAnimations().update(this, l2));
|
|
}
|
|
}
|
|
_willRender() {
|
|
return !!this.opacity;
|
|
}
|
|
draw(t2) {
|
|
const e2 = this.options.setContext(this.getContext());
|
|
let i2 = this.opacity;
|
|
if (!i2) return;
|
|
this._updateAnimationTarget(e2);
|
|
const s2 = { width: this.width, height: this.height }, n2 = { x: this.x, y: this.y };
|
|
i2 = Math.abs(i2) < 1e-3 ? 0 : i2;
|
|
const o2 = ki(e2.padding), a2 = this.title.length || this.beforeBody.length || this.body.length || this.afterBody.length || this.footer.length;
|
|
e2.enabled && a2 && (t2.save(), t2.globalAlpha = i2, this.drawBackground(n2, t2, s2, e2), Ai(t2, e2.textDirection), n2.y += o2.top, this.drawTitle(n2, t2, e2), this.drawBody(n2, t2, e2), this.drawFooter(n2, t2, e2), Ti(t2, e2.textDirection), t2.restore());
|
|
}
|
|
getActiveElements() {
|
|
return this._active || [];
|
|
}
|
|
setActiveElements(t2, e2) {
|
|
const i2 = this._active, s2 = t2.map(({ datasetIndex: t3, index: e3 }) => {
|
|
const i3 = this.chart.getDatasetMeta(t3);
|
|
if (!i3) throw new Error("Cannot find a dataset at index " + t3);
|
|
return { datasetIndex: t3, element: i3.data[e3], index: e3 };
|
|
}), n2 = !f(i2, s2), o2 = this._positionChanged(s2, e2);
|
|
(n2 || o2) && (this._active = s2, this._eventPosition = e2, this._ignoreReplayEvents = true, this.update(true));
|
|
}
|
|
handleEvent(t2, e2, i2 = true) {
|
|
if (e2 && this._ignoreReplayEvents) return false;
|
|
this._ignoreReplayEvents = false;
|
|
const s2 = this.options, n2 = this._active || [], o2 = this._getActiveElements(t2, n2, e2, i2), a2 = this._positionChanged(o2, t2), r2 = e2 || !f(o2, n2) || a2;
|
|
return r2 && (this._active = o2, (s2.enabled || s2.external) && (this._eventPosition = { x: t2.x, y: t2.y }, this.update(true, e2))), r2;
|
|
}
|
|
_getActiveElements(t2, e2, i2, s2) {
|
|
const n2 = this.options;
|
|
if ("mouseout" === t2.type) return [];
|
|
if (!s2) return e2.filter((t3) => this.chart.data.datasets[t3.datasetIndex] && void 0 !== this.chart.getDatasetMeta(t3.datasetIndex).controller.getParsed(t3.index));
|
|
const o2 = this.chart.getElementsAtEventForMode(t2, n2.mode, n2, i2);
|
|
return n2.reverse && o2.reverse(), o2;
|
|
}
|
|
_positionChanged(t2, e2) {
|
|
const { caretX: i2, caretY: s2, options: n2 } = this, o2 = Sa[n2.position].call(this, t2, e2);
|
|
return false !== o2 && (i2 !== o2.x || s2 !== o2.y);
|
|
}
|
|
}
|
|
__publicField(Va, "positioners", Sa);
|
|
var Ba = { id: "tooltip", _element: Va, positioners: Sa, afterInit(t2, e2, i2) {
|
|
i2 && (t2.tooltip = new Va({ chart: t2, options: i2 }));
|
|
}, beforeUpdate(t2, e2, i2) {
|
|
t2.tooltip && t2.tooltip.initialize(i2);
|
|
}, reset(t2, e2, i2) {
|
|
t2.tooltip && t2.tooltip.initialize(i2);
|
|
}, afterDraw(t2) {
|
|
const e2 = t2.tooltip;
|
|
if (e2 && e2._willRender()) {
|
|
const i2 = { tooltip: e2 };
|
|
if (false === t2.notifyPlugins("beforeTooltipDraw", __spreadProps(__spreadValues({}, i2), { cancelable: true }))) return;
|
|
e2.draw(t2.ctx), t2.notifyPlugins("afterTooltipDraw", i2);
|
|
}
|
|
}, afterEvent(t2, e2) {
|
|
if (t2.tooltip) {
|
|
const i2 = e2.replay;
|
|
t2.tooltip.handleEvent(e2.event, i2, e2.inChartArea) && (e2.changed = true);
|
|
}
|
|
}, defaults: { enabled: true, external: null, position: "average", backgroundColor: "rgba(0,0,0,0.8)", titleColor: "#fff", titleFont: { weight: "bold" }, titleSpacing: 2, titleMarginBottom: 6, titleAlign: "left", bodyColor: "#fff", bodySpacing: 2, bodyFont: {}, bodyAlign: "left", footerColor: "#fff", footerSpacing: 2, footerMarginTop: 6, footerFont: { weight: "bold" }, footerAlign: "left", padding: 6, caretPadding: 2, caretSize: 5, cornerRadius: 6, boxHeight: (t2, e2) => e2.bodyFont.size, boxWidth: (t2, e2) => e2.bodyFont.size, multiKeyBackground: "#fff", displayColors: true, boxPadding: 0, borderColor: "rgba(0,0,0,0)", borderWidth: 0, animation: { duration: 400, easing: "easeOutQuart" }, animations: { numbers: { type: "number", properties: ["x", "y", "width", "height", "caretX", "caretY"] }, opacity: { easing: "linear", duration: 200 } }, callbacks: za }, defaultRoutes: { bodyFont: "font", footerFont: "font", titleFont: "font" }, descriptors: { _scriptable: (t2) => "filter" !== t2 && "itemSort" !== t2 && "external" !== t2, _indexable: false, callbacks: { _scriptable: false, _indexable: false }, animation: { _fallback: false }, animations: { _fallback: "animation" } }, additionalOptionScopes: ["interaction"] };
|
|
return An.register(Yn, jo, fo, t), An.helpers = __spreadValues({}, Wi), An._adapters = Rn, An.Animation = Cs, An.Animations = Os, An.animator = xt, An.controllers = en.controllers.items, An.DatasetController = Ns, An.Element = Hs, An.elements = fo, An.Interaction = Xi, An.layouts = as, An.platforms = Ss, An.Scale = Js, An.Ticks = ae, Object.assign(An, Yn, jo, fo, t, Ss), An.Chart = An, "undefined" != typeof window && (window.Chart = An), An;
|
|
});
|
|
}
|
|
});
|
|
|
|
// vendor/cytoscape.js
|
|
var require_cytoscape = __commonJS({
|
|
"vendor/cytoscape.js"(exports, module) {
|
|
"use strict";
|
|
!function(e, t) {
|
|
"object" == typeof exports && "undefined" != typeof module ? module.exports = t() : "function" == typeof define && define.amd ? define(t) : (e = "undefined" != typeof globalThis ? globalThis : e || self).cytoscape = t();
|
|
}(exports, function() {
|
|
"use strict";
|
|
function e(t2) {
|
|
return (e = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(e2) {
|
|
return typeof e2;
|
|
} : function(e2) {
|
|
return e2 && "function" == typeof Symbol && e2.constructor === Symbol && e2 !== Symbol.prototype ? "symbol" : typeof e2;
|
|
})(t2);
|
|
}
|
|
function t(e2, t2) {
|
|
if (!(e2 instanceof t2)) throw new TypeError("Cannot call a class as a function");
|
|
}
|
|
function n(e2, t2) {
|
|
for (var n2 = 0; n2 < t2.length; n2++) {
|
|
var r2 = t2[n2];
|
|
r2.enumerable = r2.enumerable || false, r2.configurable = true, "value" in r2 && (r2.writable = true), Object.defineProperty(e2, r2.key, r2);
|
|
}
|
|
}
|
|
function r(e2, t2, r2) {
|
|
return t2 && n(e2.prototype, t2), r2 && n(e2, r2), Object.defineProperty(e2, "prototype", { writable: false }), e2;
|
|
}
|
|
function i(e2, t2, n2) {
|
|
return t2 in e2 ? Object.defineProperty(e2, t2, { value: n2, enumerable: true, configurable: true, writable: true }) : e2[t2] = n2, e2;
|
|
}
|
|
function a(e2, t2) {
|
|
return function(e3) {
|
|
if (Array.isArray(e3)) return e3;
|
|
}(e2) || function(e3, t3) {
|
|
var n2 = null == e3 ? null : "undefined" != typeof Symbol && e3[Symbol.iterator] || e3["@@iterator"];
|
|
if (null == n2) return;
|
|
var r2, i2, a2 = [], o2 = true, s2 = false;
|
|
try {
|
|
for (n2 = n2.call(e3); !(o2 = (r2 = n2.next()).done) && (a2.push(r2.value), !t3 || a2.length !== t3); o2 = true) ;
|
|
} catch (e4) {
|
|
s2 = true, i2 = e4;
|
|
} finally {
|
|
try {
|
|
o2 || null == n2.return || n2.return();
|
|
} finally {
|
|
if (s2) throw i2;
|
|
}
|
|
}
|
|
return a2;
|
|
}(e2, t2) || function(e3, t3) {
|
|
if (!e3) return;
|
|
if ("string" == typeof e3) return o(e3, t3);
|
|
var n2 = Object.prototype.toString.call(e3).slice(8, -1);
|
|
"Object" === n2 && e3.constructor && (n2 = e3.constructor.name);
|
|
if ("Map" === n2 || "Set" === n2) return Array.from(e3);
|
|
if ("Arguments" === n2 || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n2)) return o(e3, t3);
|
|
}(e2, t2) || function() {
|
|
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
}();
|
|
}
|
|
function o(e2, t2) {
|
|
(null == t2 || t2 > e2.length) && (t2 = e2.length);
|
|
for (var n2 = 0, r2 = new Array(t2); n2 < t2; n2++) r2[n2] = e2[n2];
|
|
return r2;
|
|
}
|
|
var s = "undefined" == typeof window ? null : window, l = s ? s.navigator : null;
|
|
s && s.document;
|
|
var u = e(""), c = e({}), d = e(function() {
|
|
}), h = "undefined" == typeof HTMLElement ? "undefined" : e(HTMLElement), p = function(e2) {
|
|
return e2 && e2.instanceString && g(e2.instanceString) ? e2.instanceString() : null;
|
|
}, f = function(t2) {
|
|
return null != t2 && e(t2) == u;
|
|
}, g = function(t2) {
|
|
return null != t2 && e(t2) === d;
|
|
}, v = function(e2) {
|
|
return !x(e2) && (Array.isArray ? Array.isArray(e2) : null != e2 && e2 instanceof Array);
|
|
}, y = function(t2) {
|
|
return null != t2 && e(t2) === c && !v(t2) && t2.constructor === Object;
|
|
}, m = function(t2) {
|
|
return null != t2 && e(t2) === e(1) && !isNaN(t2);
|
|
}, b = function(e2) {
|
|
return "undefined" === h ? void 0 : null != e2 && e2 instanceof HTMLElement;
|
|
}, x = function(e2) {
|
|
return w(e2) || E(e2);
|
|
}, w = function(e2) {
|
|
return "collection" === p(e2) && e2._private.single;
|
|
}, E = function(e2) {
|
|
return "collection" === p(e2) && !e2._private.single;
|
|
}, k = function(e2) {
|
|
return "core" === p(e2);
|
|
}, C = function(e2) {
|
|
return "stylesheet" === p(e2);
|
|
}, S = function(e2) {
|
|
return null == e2 || !("" !== e2 && !e2.match(/^\s+$/));
|
|
}, P = function(t2) {
|
|
return function(t3) {
|
|
return null != t3 && e(t3) === c;
|
|
}(t2) && g(t2.then);
|
|
}, D = function(e2, t2) {
|
|
t2 || (t2 = function() {
|
|
if (1 === arguments.length) return arguments[0];
|
|
if (0 === arguments.length) return "undefined";
|
|
for (var e3 = [], t3 = 0; t3 < arguments.length; t3++) e3.push(arguments[t3]);
|
|
return e3.join("$");
|
|
});
|
|
var n2 = function n3() {
|
|
var r2, i2 = this, a2 = arguments, o2 = t2.apply(i2, a2), s2 = n3.cache;
|
|
return (r2 = s2[o2]) || (r2 = s2[o2] = e2.apply(i2, a2)), r2;
|
|
};
|
|
return n2.cache = {}, n2;
|
|
}, T = D(function(e2) {
|
|
return e2.replace(/([A-Z])/g, function(e3) {
|
|
return "-" + e3.toLowerCase();
|
|
});
|
|
}), _ = D(function(e2) {
|
|
return e2.replace(/(-\w)/g, function(e3) {
|
|
return e3[1].toUpperCase();
|
|
});
|
|
}), M = D(function(e2, t2) {
|
|
return e2 + t2[0].toUpperCase() + t2.substring(1);
|
|
}, function(e2, t2) {
|
|
return e2 + "$" + t2;
|
|
}), B = function(e2) {
|
|
return S(e2) ? e2 : e2.charAt(0).toUpperCase() + e2.substring(1);
|
|
}, N = "(?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))", z = function(e2, t2) {
|
|
return e2 < t2 ? -1 : e2 > t2 ? 1 : 0;
|
|
}, I = null != Object.assign ? Object.assign.bind(Object) : function(e2) {
|
|
for (var t2 = arguments, n2 = 1; n2 < t2.length; n2++) {
|
|
var r2 = t2[n2];
|
|
if (null != r2) for (var i2 = Object.keys(r2), a2 = 0; a2 < i2.length; a2++) {
|
|
var o2 = i2[a2];
|
|
e2[o2] = r2[o2];
|
|
}
|
|
}
|
|
return e2;
|
|
}, L2 = function(e2) {
|
|
return (v(e2) ? e2 : null) || function(e3) {
|
|
return A[e3.toLowerCase()];
|
|
}(e2) || function(e3) {
|
|
if ((4 === e3.length || 7 === e3.length) && "#" === e3[0]) {
|
|
var t2, n2, r2;
|
|
return 4 === e3.length ? (t2 = parseInt(e3[1] + e3[1], 16), n2 = parseInt(e3[2] + e3[2], 16), r2 = parseInt(e3[3] + e3[3], 16)) : (t2 = parseInt(e3[1] + e3[2], 16), n2 = parseInt(e3[3] + e3[4], 16), r2 = parseInt(e3[5] + e3[6], 16)), [t2, n2, r2];
|
|
}
|
|
}(e2) || function(e3) {
|
|
var t2, n2 = new RegExp("^rgb[a]?\\(((?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))[%]?)\\s*,\\s*((?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))[%]?)\\s*,\\s*((?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))[%]?)(?:\\s*,\\s*((?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))))?\\)$").exec(e3);
|
|
if (n2) {
|
|
t2 = [];
|
|
for (var r2 = [], i2 = 1; i2 <= 3; i2++) {
|
|
var a2 = n2[i2];
|
|
if ("%" === a2[a2.length - 1] && (r2[i2] = true), a2 = parseFloat(a2), r2[i2] && (a2 = a2 / 100 * 255), a2 < 0 || a2 > 255) return;
|
|
t2.push(Math.floor(a2));
|
|
}
|
|
var o2 = r2[1] || r2[2] || r2[3], s2 = r2[1] && r2[2] && r2[3];
|
|
if (o2 && !s2) return;
|
|
var l2 = n2[4];
|
|
if (void 0 !== l2) {
|
|
if ((l2 = parseFloat(l2)) < 0 || l2 > 1) return;
|
|
t2.push(l2);
|
|
}
|
|
}
|
|
return t2;
|
|
}(e2) || function(e3) {
|
|
var t2, n2, r2, i2, a2, o2, s2, l2;
|
|
function u2(e4, t3, n3) {
|
|
return n3 < 0 && (n3 += 1), n3 > 1 && (n3 -= 1), n3 < 1 / 6 ? e4 + 6 * (t3 - e4) * n3 : n3 < 0.5 ? t3 : n3 < 2 / 3 ? e4 + (t3 - e4) * (2 / 3 - n3) * 6 : e4;
|
|
}
|
|
var c2 = new RegExp("^hsl[a]?\\(((?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?)))\\s*,\\s*((?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))[%])\\s*,\\s*((?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))[%])(?:\\s*,\\s*((?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))))?\\)$").exec(e3);
|
|
if (c2) {
|
|
if ((n2 = parseInt(c2[1])) < 0 ? n2 = (360 - -1 * n2 % 360) % 360 : n2 > 360 && (n2 %= 360), n2 /= 360, (r2 = parseFloat(c2[2])) < 0 || r2 > 100) return;
|
|
if (r2 /= 100, (i2 = parseFloat(c2[3])) < 0 || i2 > 100) return;
|
|
if (i2 /= 100, void 0 !== (a2 = c2[4]) && ((a2 = parseFloat(a2)) < 0 || a2 > 1)) return;
|
|
if (0 === r2) o2 = s2 = l2 = Math.round(255 * i2);
|
|
else {
|
|
var d2 = i2 < 0.5 ? i2 * (1 + r2) : i2 + r2 - i2 * r2, h2 = 2 * i2 - d2;
|
|
o2 = Math.round(255 * u2(h2, d2, n2 + 1 / 3)), s2 = Math.round(255 * u2(h2, d2, n2)), l2 = Math.round(255 * u2(h2, d2, n2 - 1 / 3));
|
|
}
|
|
t2 = [o2, s2, l2, a2];
|
|
}
|
|
return t2;
|
|
}(e2);
|
|
}, A = { transparent: [0, 0, 0, 0], aliceblue: [240, 248, 255], antiquewhite: [250, 235, 215], aqua: [0, 255, 255], aquamarine: [127, 255, 212], azure: [240, 255, 255], beige: [245, 245, 220], bisque: [255, 228, 196], black: [0, 0, 0], blanchedalmond: [255, 235, 205], blue: [0, 0, 255], blueviolet: [138, 43, 226], brown: [165, 42, 42], burlywood: [222, 184, 135], cadetblue: [95, 158, 160], chartreuse: [127, 255, 0], chocolate: [210, 105, 30], coral: [255, 127, 80], cornflowerblue: [100, 149, 237], cornsilk: [255, 248, 220], crimson: [220, 20, 60], cyan: [0, 255, 255], darkblue: [0, 0, 139], darkcyan: [0, 139, 139], darkgoldenrod: [184, 134, 11], darkgray: [169, 169, 169], darkgreen: [0, 100, 0], darkgrey: [169, 169, 169], darkkhaki: [189, 183, 107], darkmagenta: [139, 0, 139], darkolivegreen: [85, 107, 47], darkorange: [255, 140, 0], darkorchid: [153, 50, 204], darkred: [139, 0, 0], darksalmon: [233, 150, 122], darkseagreen: [143, 188, 143], darkslateblue: [72, 61, 139], darkslategray: [47, 79, 79], darkslategrey: [47, 79, 79], darkturquoise: [0, 206, 209], darkviolet: [148, 0, 211], deeppink: [255, 20, 147], deepskyblue: [0, 191, 255], dimgray: [105, 105, 105], dimgrey: [105, 105, 105], dodgerblue: [30, 144, 255], firebrick: [178, 34, 34], floralwhite: [255, 250, 240], forestgreen: [34, 139, 34], fuchsia: [255, 0, 255], gainsboro: [220, 220, 220], ghostwhite: [248, 248, 255], gold: [255, 215, 0], goldenrod: [218, 165, 32], gray: [128, 128, 128], grey: [128, 128, 128], green: [0, 128, 0], greenyellow: [173, 255, 47], honeydew: [240, 255, 240], hotpink: [255, 105, 180], indianred: [205, 92, 92], indigo: [75, 0, 130], ivory: [255, 255, 240], khaki: [240, 230, 140], lavender: [230, 230, 250], lavenderblush: [255, 240, 245], lawngreen: [124, 252, 0], lemonchiffon: [255, 250, 205], lightblue: [173, 216, 230], lightcoral: [240, 128, 128], lightcyan: [224, 255, 255], lightgoldenrodyellow: [250, 250, 210], lightgray: [211, 211, 211], lightgreen: [144, 238, 144], lightgrey: [211, 211, 211], lightpink: [255, 182, 193], lightsalmon: [255, 160, 122], lightseagreen: [32, 178, 170], lightskyblue: [135, 206, 250], lightslategray: [119, 136, 153], lightslategrey: [119, 136, 153], lightsteelblue: [176, 196, 222], lightyellow: [255, 255, 224], lime: [0, 255, 0], limegreen: [50, 205, 50], linen: [250, 240, 230], magenta: [255, 0, 255], maroon: [128, 0, 0], mediumaquamarine: [102, 205, 170], mediumblue: [0, 0, 205], mediumorchid: [186, 85, 211], mediumpurple: [147, 112, 219], mediumseagreen: [60, 179, 113], mediumslateblue: [123, 104, 238], mediumspringgreen: [0, 250, 154], mediumturquoise: [72, 209, 204], mediumvioletred: [199, 21, 133], midnightblue: [25, 25, 112], mintcream: [245, 255, 250], mistyrose: [255, 228, 225], moccasin: [255, 228, 181], navajowhite: [255, 222, 173], navy: [0, 0, 128], oldlace: [253, 245, 230], olive: [128, 128, 0], olivedrab: [107, 142, 35], orange: [255, 165, 0], orangered: [255, 69, 0], orchid: [218, 112, 214], palegoldenrod: [238, 232, 170], palegreen: [152, 251, 152], paleturquoise: [175, 238, 238], palevioletred: [219, 112, 147], papayawhip: [255, 239, 213], peachpuff: [255, 218, 185], peru: [205, 133, 63], pink: [255, 192, 203], plum: [221, 160, 221], powderblue: [176, 224, 230], purple: [128, 0, 128], red: [255, 0, 0], rosybrown: [188, 143, 143], royalblue: [65, 105, 225], saddlebrown: [139, 69, 19], salmon: [250, 128, 114], sandybrown: [244, 164, 96], seagreen: [46, 139, 87], seashell: [255, 245, 238], sienna: [160, 82, 45], silver: [192, 192, 192], skyblue: [135, 206, 235], slateblue: [106, 90, 205], slategray: [112, 128, 144], slategrey: [112, 128, 144], snow: [255, 250, 250], springgreen: [0, 255, 127], steelblue: [70, 130, 180], tan: [210, 180, 140], teal: [0, 128, 128], thistle: [216, 191, 216], tomato: [255, 99, 71], turquoise: [64, 224, 208], violet: [238, 130, 238], wheat: [245, 222, 179], white: [255, 255, 255], whitesmoke: [245, 245, 245], yellow: [255, 255, 0], yellowgreen: [154, 205, 50] }, O = function(e2) {
|
|
for (var t2 = e2.map, n2 = e2.keys, r2 = n2.length, i2 = 0; i2 < r2; i2++) {
|
|
var a2 = n2[i2];
|
|
if (y(a2)) throw Error("Tried to set map with object key");
|
|
i2 < n2.length - 1 ? (null == t2[a2] && (t2[a2] = {}), t2 = t2[a2]) : t2[a2] = e2.value;
|
|
}
|
|
}, R = function(e2) {
|
|
for (var t2 = e2.map, n2 = e2.keys, r2 = n2.length, i2 = 0; i2 < r2; i2++) {
|
|
var a2 = n2[i2];
|
|
if (y(a2)) throw Error("Tried to get map with object key");
|
|
if (null == (t2 = t2[a2])) return t2;
|
|
}
|
|
return t2;
|
|
};
|
|
var V = function(e2) {
|
|
var t2 = typeof e2;
|
|
return null != e2 && ("object" == t2 || "function" == t2);
|
|
}, F = "undefined" != typeof globalThis ? globalThis : "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof self ? self : {};
|
|
var j = "object" == typeof F && F && F.Object === Object && F, q = "object" == typeof self && self && self.Object === Object && self, Y = j || q || Function("return this")(), X = function() {
|
|
return Y.Date.now();
|
|
}, W = /\s/;
|
|
var H = function(e2) {
|
|
for (var t2 = e2.length; t2-- && W.test(e2.charAt(t2)); ) ;
|
|
return t2;
|
|
}, K = /^\s+/;
|
|
var G = function(e2) {
|
|
return e2 ? e2.slice(0, H(e2) + 1).replace(K, "") : e2;
|
|
}, U = Y.Symbol, Z = Object.prototype, $ = Z.hasOwnProperty, Q = Z.toString, J = U ? U.toStringTag : void 0;
|
|
var ee = function(e2) {
|
|
var t2 = $.call(e2, J), n2 = e2[J];
|
|
try {
|
|
e2[J] = void 0;
|
|
var r2 = true;
|
|
} catch (e3) {
|
|
}
|
|
var i2 = Q.call(e2);
|
|
return r2 && (t2 ? e2[J] = n2 : delete e2[J]), i2;
|
|
}, te = Object.prototype.toString;
|
|
var ne = function(e2) {
|
|
return te.call(e2);
|
|
}, re = U ? U.toStringTag : void 0;
|
|
var ie = function(e2) {
|
|
return null == e2 ? void 0 === e2 ? "[object Undefined]" : "[object Null]" : re && re in Object(e2) ? ee(e2) : ne(e2);
|
|
};
|
|
var ae = function(e2) {
|
|
return null != e2 && "object" == typeof e2;
|
|
};
|
|
var oe = function(e2) {
|
|
return "symbol" == typeof e2 || ae(e2) && "[object Symbol]" == ie(e2);
|
|
}, se = /^[-+]0x[0-9a-f]+$/i, le = /^0b[01]+$/i, ue = /^0o[0-7]+$/i, ce = parseInt;
|
|
var de = function(e2) {
|
|
if ("number" == typeof e2) return e2;
|
|
if (oe(e2)) return NaN;
|
|
if (V(e2)) {
|
|
var t2 = "function" == typeof e2.valueOf ? e2.valueOf() : e2;
|
|
e2 = V(t2) ? t2 + "" : t2;
|
|
}
|
|
if ("string" != typeof e2) return 0 === e2 ? e2 : +e2;
|
|
e2 = G(e2);
|
|
var n2 = le.test(e2);
|
|
return n2 || ue.test(e2) ? ce(e2.slice(2), n2 ? 2 : 8) : se.test(e2) ? NaN : +e2;
|
|
}, he = Math.max, pe = Math.min;
|
|
var fe = function(e2, t2, n2) {
|
|
var r2, i2, a2, o2, s2, l2, u2 = 0, c2 = false, d2 = false, h2 = true;
|
|
if ("function" != typeof e2) throw new TypeError("Expected a function");
|
|
function p2(t3) {
|
|
var n3 = r2, a3 = i2;
|
|
return r2 = i2 = void 0, u2 = t3, o2 = e2.apply(a3, n3);
|
|
}
|
|
function f2(e3) {
|
|
return u2 = e3, s2 = setTimeout(v2, t2), c2 ? p2(e3) : o2;
|
|
}
|
|
function g2(e3) {
|
|
var n3 = e3 - l2;
|
|
return void 0 === l2 || n3 >= t2 || n3 < 0 || d2 && e3 - u2 >= a2;
|
|
}
|
|
function v2() {
|
|
var e3 = X();
|
|
if (g2(e3)) return y2(e3);
|
|
s2 = setTimeout(v2, function(e4) {
|
|
var n3 = t2 - (e4 - l2);
|
|
return d2 ? pe(n3, a2 - (e4 - u2)) : n3;
|
|
}(e3));
|
|
}
|
|
function y2(e3) {
|
|
return s2 = void 0, h2 && r2 ? p2(e3) : (r2 = i2 = void 0, o2);
|
|
}
|
|
function m2() {
|
|
var e3 = X(), n3 = g2(e3);
|
|
if (r2 = arguments, i2 = this, l2 = e3, n3) {
|
|
if (void 0 === s2) return f2(l2);
|
|
if (d2) return clearTimeout(s2), s2 = setTimeout(v2, t2), p2(l2);
|
|
}
|
|
return void 0 === s2 && (s2 = setTimeout(v2, t2)), o2;
|
|
}
|
|
return t2 = de(t2) || 0, V(n2) && (c2 = !!n2.leading, a2 = (d2 = "maxWait" in n2) ? he(de(n2.maxWait) || 0, t2) : a2, h2 = "trailing" in n2 ? !!n2.trailing : h2), m2.cancel = function() {
|
|
void 0 !== s2 && clearTimeout(s2), u2 = 0, r2 = l2 = i2 = s2 = void 0;
|
|
}, m2.flush = function() {
|
|
return void 0 === s2 ? o2 : y2(X());
|
|
}, m2;
|
|
}, ge = s ? s.performance : null, ve = ge && ge.now ? function() {
|
|
return ge.now();
|
|
} : function() {
|
|
return Date.now();
|
|
}, ye = function() {
|
|
if (s) {
|
|
if (s.requestAnimationFrame) return function(e2) {
|
|
s.requestAnimationFrame(e2);
|
|
};
|
|
if (s.mozRequestAnimationFrame) return function(e2) {
|
|
s.mozRequestAnimationFrame(e2);
|
|
};
|
|
if (s.webkitRequestAnimationFrame) return function(e2) {
|
|
s.webkitRequestAnimationFrame(e2);
|
|
};
|
|
if (s.msRequestAnimationFrame) return function(e2) {
|
|
s.msRequestAnimationFrame(e2);
|
|
};
|
|
}
|
|
return function(e2) {
|
|
e2 && setTimeout(function() {
|
|
e2(ve());
|
|
}, 1e3 / 60);
|
|
};
|
|
}(), me = function(e2) {
|
|
return ye(e2);
|
|
}, be = ve, xe = 65599, we = function(e2) {
|
|
for (var t2, n2 = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : 9261, r2 = n2; !(t2 = e2.next()).done; ) r2 = r2 * xe + t2.value | 0;
|
|
return r2;
|
|
}, Ee = function(e2) {
|
|
var t2 = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : 9261;
|
|
return t2 * xe + e2 | 0;
|
|
}, ke = function(e2) {
|
|
var t2 = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : 5381;
|
|
return (t2 << 5) + t2 + e2 | 0;
|
|
}, Ce = function(e2) {
|
|
return 2097152 * e2[0] + e2[1];
|
|
}, Se = function(e2, t2) {
|
|
return [Ee(e2[0], t2[0]), ke(e2[1], t2[1])];
|
|
}, Pe = function(e2, t2) {
|
|
var n2 = { value: 0, done: false }, r2 = 0, i2 = e2.length;
|
|
return we({ next: function() {
|
|
return r2 < i2 ? n2.value = e2.charCodeAt(r2++) : n2.done = true, n2;
|
|
} }, t2);
|
|
}, De = function() {
|
|
return Te(arguments);
|
|
}, Te = function(e2) {
|
|
for (var t2, n2 = 0; n2 < e2.length; n2++) {
|
|
var r2 = e2[n2];
|
|
t2 = 0 === n2 ? Pe(r2) : Pe(r2, t2);
|
|
}
|
|
return t2;
|
|
}, _e = true, Me = null != console.warn, Be = null != console.trace, Ne = Number.MAX_SAFE_INTEGER || 9007199254740991, ze = function() {
|
|
return true;
|
|
}, Ie = function() {
|
|
return false;
|
|
}, Le = function() {
|
|
return 0;
|
|
}, Ae = function() {
|
|
}, Oe = function(e2) {
|
|
throw new Error(e2);
|
|
}, Re = function(e2) {
|
|
if (void 0 === e2) return _e;
|
|
_e = !!e2;
|
|
}, Ve = function(e2) {
|
|
Re() && (Me ? console.warn(e2) : (console.log(e2), Be && console.trace()));
|
|
}, Fe = function(e2) {
|
|
return null == e2 ? e2 : v(e2) ? e2.slice() : y(e2) ? function(e3) {
|
|
return I({}, e3);
|
|
}(e2) : e2;
|
|
}, je = function(e2, t2) {
|
|
for (t2 = e2 = ""; e2++ < 36; t2 += 51 * e2 & 52 ? (15 ^ e2 ? 8 ^ Math.random() * (20 ^ e2 ? 16 : 4) : 4).toString(16) : "-") ;
|
|
return t2;
|
|
}, qe = {}, Ye = function() {
|
|
return qe;
|
|
}, Xe = function(e2) {
|
|
var t2 = Object.keys(e2);
|
|
return function(n2) {
|
|
for (var r2 = {}, i2 = 0; i2 < t2.length; i2++) {
|
|
var a2 = t2[i2], o2 = null == n2 ? void 0 : n2[a2];
|
|
r2[a2] = void 0 === o2 ? e2[a2] : o2;
|
|
}
|
|
return r2;
|
|
};
|
|
}, We = function(e2, t2, n2) {
|
|
for (var r2 = e2.length - 1; r2 >= 0 && (e2[r2] !== t2 || (e2.splice(r2, 1), !n2)); r2--) ;
|
|
}, He = function(e2) {
|
|
e2.splice(0, e2.length);
|
|
}, Ke = function(e2, t2, n2) {
|
|
return n2 && (t2 = M(n2, t2)), e2[t2];
|
|
}, Ge = function(e2, t2, n2, r2) {
|
|
n2 && (t2 = M(n2, t2)), e2[t2] = r2;
|
|
}, Ue = "undefined" != typeof Map ? Map : function() {
|
|
function e2() {
|
|
t(this, e2), this._obj = {};
|
|
}
|
|
return r(e2, [{ key: "set", value: function(e3, t2) {
|
|
return this._obj[e3] = t2, this;
|
|
} }, { key: "delete", value: function(e3) {
|
|
return this._obj[e3] = void 0, this;
|
|
} }, { key: "clear", value: function() {
|
|
this._obj = {};
|
|
} }, { key: "has", value: function(e3) {
|
|
return void 0 !== this._obj[e3];
|
|
} }, { key: "get", value: function(e3) {
|
|
return this._obj[e3];
|
|
} }]), e2;
|
|
}(), Ze = function() {
|
|
function e2(n2) {
|
|
if (t(this, e2), this._obj = /* @__PURE__ */ Object.create(null), this.size = 0, null != n2) {
|
|
var r2;
|
|
r2 = null != n2.instanceString && n2.instanceString() === this.instanceString() ? n2.toArray() : n2;
|
|
for (var i2 = 0; i2 < r2.length; i2++) this.add(r2[i2]);
|
|
}
|
|
}
|
|
return r(e2, [{ key: "instanceString", value: function() {
|
|
return "set";
|
|
} }, { key: "add", value: function(e3) {
|
|
var t2 = this._obj;
|
|
1 !== t2[e3] && (t2[e3] = 1, this.size++);
|
|
} }, { key: "delete", value: function(e3) {
|
|
var t2 = this._obj;
|
|
1 === t2[e3] && (t2[e3] = 0, this.size--);
|
|
} }, { key: "clear", value: function() {
|
|
this._obj = /* @__PURE__ */ Object.create(null);
|
|
} }, { key: "has", value: function(e3) {
|
|
return 1 === this._obj[e3];
|
|
} }, { key: "toArray", value: function() {
|
|
var e3 = this;
|
|
return Object.keys(this._obj).filter(function(t2) {
|
|
return e3.has(t2);
|
|
});
|
|
} }, { key: "forEach", value: function(e3, t2) {
|
|
return this.toArray().forEach(e3, t2);
|
|
} }]), e2;
|
|
}(), $e = "undefined" !== ("undefined" == typeof Set ? "undefined" : e(Set)) ? Set : Ze, Qe = function(e2, t2) {
|
|
var n2 = !(arguments.length > 2 && void 0 !== arguments[2]) || arguments[2];
|
|
if (void 0 !== e2 && void 0 !== t2 && k(e2)) {
|
|
var r2 = t2.group;
|
|
if (null == r2 && (r2 = t2.data && null != t2.data.source && null != t2.data.target ? "edges" : "nodes"), "nodes" === r2 || "edges" === r2) {
|
|
this.length = 1, this[0] = this;
|
|
var i2 = this._private = { cy: e2, single: true, data: t2.data || {}, position: t2.position || { x: 0, y: 0 }, autoWidth: void 0, autoHeight: void 0, autoPadding: void 0, compoundBoundsClean: false, listeners: [], group: r2, style: {}, rstyle: {}, styleCxts: [], styleKeys: {}, removed: true, selected: !!t2.selected, selectable: void 0 === t2.selectable || !!t2.selectable, locked: !!t2.locked, grabbed: false, grabbable: void 0 === t2.grabbable || !!t2.grabbable, pannable: void 0 === t2.pannable ? "edges" === r2 : !!t2.pannable, active: false, classes: new $e(), animation: { current: [], queue: [] }, rscratch: {}, scratch: t2.scratch || {}, edges: [], children: [], parent: t2.parent && t2.parent.isNode() ? t2.parent : null, traversalCache: {}, backgrounding: false, bbCache: null, bbCacheShift: { x: 0, y: 0 }, bodyBounds: null, overlayBounds: null, labelBounds: { all: null, source: null, target: null, main: null }, arrowBounds: { source: null, target: null, "mid-source": null, "mid-target": null } };
|
|
if (null == i2.position.x && (i2.position.x = 0), null == i2.position.y && (i2.position.y = 0), t2.renderedPosition) {
|
|
var a2 = t2.renderedPosition, o2 = e2.pan(), s2 = e2.zoom();
|
|
i2.position = { x: (a2.x - o2.x) / s2, y: (a2.y - o2.y) / s2 };
|
|
}
|
|
var l2 = [];
|
|
v(t2.classes) ? l2 = t2.classes : f(t2.classes) && (l2 = t2.classes.split(/\s+/));
|
|
for (var u2 = 0, c2 = l2.length; u2 < c2; u2++) {
|
|
var d2 = l2[u2];
|
|
d2 && "" !== d2 && i2.classes.add(d2);
|
|
}
|
|
this.createEmitter();
|
|
var h2 = t2.style || t2.css;
|
|
h2 && (Ve("Setting a `style` bypass at element creation should be done only when absolutely necessary. Try to use the stylesheet instead."), this.style(h2)), (void 0 === n2 || n2) && this.restore();
|
|
} else Oe("An element must be of type `nodes` or `edges`; you specified `" + r2 + "`");
|
|
} else Oe("An element must have a core reference and parameters set");
|
|
}, Je = function(e2) {
|
|
return e2 = { bfs: e2.bfs || !e2.dfs, dfs: e2.dfs || !e2.bfs }, function(t2, n2, r2) {
|
|
var i2;
|
|
y(t2) && !x(t2) && (t2 = (i2 = t2).roots || i2.root, n2 = i2.visit, r2 = i2.directed), r2 = 2 !== arguments.length || g(n2) ? r2 : n2, n2 = g(n2) ? n2 : function() {
|
|
};
|
|
for (var a2, o2 = this._private.cy, s2 = t2 = f(t2) ? this.filter(t2) : t2, l2 = [], u2 = [], c2 = {}, d2 = {}, h2 = {}, p2 = 0, v2 = this.byGroup(), m2 = v2.nodes, b2 = v2.edges, w2 = 0; w2 < s2.length; w2++) {
|
|
var E2 = s2[w2], k2 = E2.id();
|
|
E2.isNode() && (l2.unshift(E2), e2.bfs && (h2[k2] = true, u2.push(E2)), d2[k2] = 0);
|
|
}
|
|
for (var C2 = function() {
|
|
var t3 = e2.bfs ? l2.shift() : l2.pop(), i3 = t3.id();
|
|
if (e2.dfs) {
|
|
if (h2[i3]) return "continue";
|
|
h2[i3] = true, u2.push(t3);
|
|
}
|
|
var o3, s3 = d2[i3], f2 = c2[i3], g2 = null != f2 ? f2.source() : null, v3 = null != f2 ? f2.target() : null, y2 = null == f2 ? void 0 : t3.same(g2) ? v3[0] : g2[0];
|
|
if (true === (o3 = n2(t3, f2, y2, p2++, s3))) return a2 = t3, "break";
|
|
if (false === o3) return "break";
|
|
for (var x2 = t3.connectedEdges().filter(function(e3) {
|
|
return (!r2 || e3.source().same(t3)) && b2.has(e3);
|
|
}), w3 = 0; w3 < x2.length; w3++) {
|
|
var E3 = x2[w3], k3 = E3.connectedNodes().filter(function(e3) {
|
|
return !e3.same(t3) && m2.has(e3);
|
|
}), C3 = k3.id();
|
|
0 === k3.length || h2[C3] || (k3 = k3[0], l2.push(k3), e2.bfs && (h2[C3] = true, u2.push(k3)), c2[C3] = E3, d2[C3] = d2[i3] + 1);
|
|
}
|
|
}; 0 !== l2.length; ) {
|
|
var S2 = C2();
|
|
if ("continue" !== S2 && "break" === S2) break;
|
|
}
|
|
for (var P2 = o2.collection(), D2 = 0; D2 < u2.length; D2++) {
|
|
var T2 = u2[D2], _2 = c2[T2.id()];
|
|
null != _2 && P2.push(_2), P2.push(T2);
|
|
}
|
|
return { path: o2.collection(P2), found: o2.collection(a2) };
|
|
};
|
|
}, et = { breadthFirstSearch: Je({ bfs: true }), depthFirstSearch: Je({ dfs: true }) };
|
|
et.bfs = et.breadthFirstSearch, et.dfs = et.depthFirstSearch;
|
|
var tt = function(e2, t2) {
|
|
return e2(t2 = { exports: {} }, t2.exports), t2.exports;
|
|
}(function(e2, t2) {
|
|
(function() {
|
|
var t3, n2, r2, i2, a2, o2, s2, l2, u2, c2, d2, h2, p2, f2, g2;
|
|
r2 = Math.floor, c2 = Math.min, n2 = function(e3, t4) {
|
|
return e3 < t4 ? -1 : e3 > t4 ? 1 : 0;
|
|
}, u2 = function(e3, t4, i3, a3, o3) {
|
|
var s3;
|
|
if (null == i3 && (i3 = 0), null == o3 && (o3 = n2), i3 < 0) throw new Error("lo must be non-negative");
|
|
for (null == a3 && (a3 = e3.length); i3 < a3; ) o3(t4, e3[s3 = r2((i3 + a3) / 2)]) < 0 ? a3 = s3 : i3 = s3 + 1;
|
|
return [].splice.apply(e3, [i3, i3 - i3].concat(t4)), t4;
|
|
}, o2 = function(e3, t4, r3) {
|
|
return null == r3 && (r3 = n2), e3.push(t4), f2(e3, 0, e3.length - 1, r3);
|
|
}, a2 = function(e3, t4) {
|
|
var r3, i3;
|
|
return null == t4 && (t4 = n2), r3 = e3.pop(), e3.length ? (i3 = e3[0], e3[0] = r3, g2(e3, 0, t4)) : i3 = r3, i3;
|
|
}, l2 = function(e3, t4, r3) {
|
|
var i3;
|
|
return null == r3 && (r3 = n2), i3 = e3[0], e3[0] = t4, g2(e3, 0, r3), i3;
|
|
}, s2 = function(e3, t4, r3) {
|
|
var i3;
|
|
return null == r3 && (r3 = n2), e3.length && r3(e3[0], t4) < 0 && (t4 = (i3 = [e3[0], t4])[0], e3[0] = i3[1], g2(e3, 0, r3)), t4;
|
|
}, i2 = function(e3, t4) {
|
|
var i3, a3, o3, s3, l3, u3;
|
|
for (null == t4 && (t4 = n2), l3 = [], a3 = 0, o3 = (s3 = function() {
|
|
u3 = [];
|
|
for (var t5 = 0, n3 = r2(e3.length / 2); 0 <= n3 ? t5 < n3 : t5 > n3; 0 <= n3 ? t5++ : t5--) u3.push(t5);
|
|
return u3;
|
|
}.apply(this).reverse()).length; a3 < o3; a3++) i3 = s3[a3], l3.push(g2(e3, i3, t4));
|
|
return l3;
|
|
}, p2 = function(e3, t4, r3) {
|
|
var i3;
|
|
if (null == r3 && (r3 = n2), -1 !== (i3 = e3.indexOf(t4))) return f2(e3, 0, i3, r3), g2(e3, i3, r3);
|
|
}, d2 = function(e3, t4, r3) {
|
|
var a3, o3, l3, u3, c3;
|
|
if (null == r3 && (r3 = n2), !(o3 = e3.slice(0, t4)).length) return o3;
|
|
for (i2(o3, r3), l3 = 0, u3 = (c3 = e3.slice(t4)).length; l3 < u3; l3++) a3 = c3[l3], s2(o3, a3, r3);
|
|
return o3.sort(r3).reverse();
|
|
}, h2 = function(e3, t4, r3) {
|
|
var o3, s3, l3, d3, h3, p3, f3, g3, v2;
|
|
if (null == r3 && (r3 = n2), 10 * t4 <= e3.length) {
|
|
if (!(l3 = e3.slice(0, t4).sort(r3)).length) return l3;
|
|
for (s3 = l3[l3.length - 1], d3 = 0, p3 = (f3 = e3.slice(t4)).length; d3 < p3; d3++) r3(o3 = f3[d3], s3) < 0 && (u2(l3, o3, 0, null, r3), l3.pop(), s3 = l3[l3.length - 1]);
|
|
return l3;
|
|
}
|
|
for (i2(e3, r3), v2 = [], h3 = 0, g3 = c2(t4, e3.length); 0 <= g3 ? h3 < g3 : h3 > g3; 0 <= g3 ? ++h3 : --h3) v2.push(a2(e3, r3));
|
|
return v2;
|
|
}, f2 = function(e3, t4, r3, i3) {
|
|
var a3, o3, s3;
|
|
for (null == i3 && (i3 = n2), a3 = e3[r3]; r3 > t4 && i3(a3, o3 = e3[s3 = r3 - 1 >> 1]) < 0; ) e3[r3] = o3, r3 = s3;
|
|
return e3[r3] = a3;
|
|
}, g2 = function(e3, t4, r3) {
|
|
var i3, a3, o3, s3, l3;
|
|
for (null == r3 && (r3 = n2), a3 = e3.length, l3 = t4, o3 = e3[t4], i3 = 2 * t4 + 1; i3 < a3; ) (s3 = i3 + 1) < a3 && !(r3(e3[i3], e3[s3]) < 0) && (i3 = s3), e3[t4] = e3[i3], i3 = 2 * (t4 = i3) + 1;
|
|
return e3[t4] = o3, f2(e3, l3, t4, r3);
|
|
}, t3 = function() {
|
|
function e3(e4) {
|
|
this.cmp = null != e4 ? e4 : n2, this.nodes = [];
|
|
}
|
|
return e3.push = o2, e3.pop = a2, e3.replace = l2, e3.pushpop = s2, e3.heapify = i2, e3.updateItem = p2, e3.nlargest = d2, e3.nsmallest = h2, e3.prototype.push = function(e4) {
|
|
return o2(this.nodes, e4, this.cmp);
|
|
}, e3.prototype.pop = function() {
|
|
return a2(this.nodes, this.cmp);
|
|
}, e3.prototype.peek = function() {
|
|
return this.nodes[0];
|
|
}, e3.prototype.contains = function(e4) {
|
|
return -1 !== this.nodes.indexOf(e4);
|
|
}, e3.prototype.replace = function(e4) {
|
|
return l2(this.nodes, e4, this.cmp);
|
|
}, e3.prototype.pushpop = function(e4) {
|
|
return s2(this.nodes, e4, this.cmp);
|
|
}, e3.prototype.heapify = function() {
|
|
return i2(this.nodes, this.cmp);
|
|
}, e3.prototype.updateItem = function(e4) {
|
|
return p2(this.nodes, e4, this.cmp);
|
|
}, e3.prototype.clear = function() {
|
|
return this.nodes = [];
|
|
}, e3.prototype.empty = function() {
|
|
return 0 === this.nodes.length;
|
|
}, e3.prototype.size = function() {
|
|
return this.nodes.length;
|
|
}, e3.prototype.clone = function() {
|
|
var t4;
|
|
return (t4 = new e3()).nodes = this.nodes.slice(0), t4;
|
|
}, e3.prototype.toArray = function() {
|
|
return this.nodes.slice(0);
|
|
}, e3.prototype.insert = e3.prototype.push, e3.prototype.top = e3.prototype.peek, e3.prototype.front = e3.prototype.peek, e3.prototype.has = e3.prototype.contains, e3.prototype.copy = e3.prototype.clone, e3;
|
|
}(), e2.exports = t3;
|
|
}).call(F);
|
|
}), nt = Xe({ root: null, weight: function(e2) {
|
|
return 1;
|
|
}, directed: false }), rt = { dijkstra: function(e2) {
|
|
if (!y(e2)) {
|
|
var t2 = arguments;
|
|
e2 = { root: t2[0], weight: t2[1], directed: t2[2] };
|
|
}
|
|
var n2 = nt(e2), r2 = n2.root, i2 = n2.weight, a2 = n2.directed, o2 = this, s2 = i2, l2 = f(r2) ? this.filter(r2)[0] : r2[0], u2 = {}, c2 = {}, d2 = {}, h2 = this.byGroup(), p2 = h2.nodes, g2 = h2.edges;
|
|
g2.unmergeBy(function(e3) {
|
|
return e3.isLoop();
|
|
});
|
|
for (var v2 = function(e3) {
|
|
return u2[e3.id()];
|
|
}, m2 = function(e3, t3) {
|
|
u2[e3.id()] = t3, b2.updateItem(e3);
|
|
}, b2 = new tt(function(e3, t3) {
|
|
return v2(e3) - v2(t3);
|
|
}), x2 = 0; x2 < p2.length; x2++) {
|
|
var w2 = p2[x2];
|
|
u2[w2.id()] = w2.same(l2) ? 0 : 1 / 0, b2.push(w2);
|
|
}
|
|
for (var E2 = function(e3, t3) {
|
|
for (var n3, r3 = (a2 ? e3.edgesTo(t3) : e3.edgesWith(t3)).intersect(g2), i3 = 1 / 0, o3 = 0; o3 < r3.length; o3++) {
|
|
var l3 = r3[o3], u3 = s2(l3);
|
|
(u3 < i3 || !n3) && (i3 = u3, n3 = l3);
|
|
}
|
|
return { edge: n3, dist: i3 };
|
|
}; b2.size() > 0; ) {
|
|
var k2 = b2.pop(), C2 = v2(k2), S2 = k2.id();
|
|
if (d2[S2] = C2, C2 !== 1 / 0) for (var P2 = k2.neighborhood().intersect(p2), D2 = 0; D2 < P2.length; D2++) {
|
|
var T2 = P2[D2], _2 = T2.id(), M2 = E2(k2, T2), B2 = C2 + M2.dist;
|
|
B2 < v2(T2) && (m2(T2, B2), c2[_2] = { node: k2, edge: M2.edge });
|
|
}
|
|
}
|
|
return { distanceTo: function(e3) {
|
|
var t3 = f(e3) ? p2.filter(e3)[0] : e3[0];
|
|
return d2[t3.id()];
|
|
}, pathTo: function(e3) {
|
|
var t3 = f(e3) ? p2.filter(e3)[0] : e3[0], n3 = [], r3 = t3, i3 = r3.id();
|
|
if (t3.length > 0) for (n3.unshift(t3); c2[i3]; ) {
|
|
var a3 = c2[i3];
|
|
n3.unshift(a3.edge), n3.unshift(a3.node), i3 = (r3 = a3.node).id();
|
|
}
|
|
return o2.spawn(n3);
|
|
} };
|
|
} }, it = { kruskal: function(e2) {
|
|
e2 = e2 || function(e3) {
|
|
return 1;
|
|
};
|
|
for (var t2 = this.byGroup(), n2 = t2.nodes, r2 = t2.edges, i2 = n2.length, a2 = new Array(i2), o2 = n2, s2 = function(e3) {
|
|
for (var t3 = 0; t3 < a2.length; t3++) {
|
|
if (a2[t3].has(e3)) return t3;
|
|
}
|
|
}, l2 = 0; l2 < i2; l2++) a2[l2] = this.spawn(n2[l2]);
|
|
for (var u2 = r2.sort(function(t3, n3) {
|
|
return e2(t3) - e2(n3);
|
|
}), c2 = 0; c2 < u2.length; c2++) {
|
|
var d2 = u2[c2], h2 = d2.source()[0], p2 = d2.target()[0], f2 = s2(h2), g2 = s2(p2), v2 = a2[f2], y2 = a2[g2];
|
|
f2 !== g2 && (o2.merge(d2), v2.merge(y2), a2.splice(g2, 1));
|
|
}
|
|
return o2;
|
|
} }, at = Xe({ root: null, goal: null, weight: function(e2) {
|
|
return 1;
|
|
}, heuristic: function(e2) {
|
|
return 0;
|
|
}, directed: false }), ot = { aStar: function(e2) {
|
|
var t2 = this.cy(), n2 = at(e2), r2 = n2.root, i2 = n2.goal, a2 = n2.heuristic, o2 = n2.directed, s2 = n2.weight;
|
|
r2 = t2.collection(r2)[0], i2 = t2.collection(i2)[0];
|
|
var l2, u2, c2 = r2.id(), d2 = i2.id(), h2 = {}, p2 = {}, f2 = {}, g2 = new tt(function(e3, t3) {
|
|
return p2[e3.id()] - p2[t3.id()];
|
|
}), v2 = new $e(), y2 = {}, m2 = {}, b2 = function(e3, t3) {
|
|
g2.push(e3), v2.add(t3);
|
|
};
|
|
b2(r2, c2), h2[c2] = 0, p2[c2] = a2(r2);
|
|
for (var x2, w2 = 0; g2.size() > 0; ) {
|
|
if (l2 = g2.pop(), u2 = l2.id(), v2.delete(u2), w2++, u2 === d2) {
|
|
for (var E2 = [], k2 = i2, C2 = d2, S2 = m2[C2]; E2.unshift(k2), null != S2 && E2.unshift(S2), null != (k2 = y2[C2]); ) S2 = m2[C2 = k2.id()];
|
|
return { found: true, distance: h2[u2], path: this.spawn(E2), steps: w2 };
|
|
}
|
|
f2[u2] = true;
|
|
for (var P2 = l2._private.edges, D2 = 0; D2 < P2.length; D2++) {
|
|
var T2 = P2[D2];
|
|
if (this.hasElementWithId(T2.id()) && (!o2 || T2.data("source") === u2)) {
|
|
var _2 = T2.source(), M2 = T2.target(), B2 = _2.id() !== u2 ? _2 : M2, N2 = B2.id();
|
|
if (this.hasElementWithId(N2) && !f2[N2]) {
|
|
var z2 = h2[u2] + s2(T2);
|
|
x2 = N2, v2.has(x2) ? z2 < h2[N2] && (h2[N2] = z2, p2[N2] = z2 + a2(B2), y2[N2] = l2, m2[N2] = T2) : (h2[N2] = z2, p2[N2] = z2 + a2(B2), b2(B2, N2), y2[N2] = l2, m2[N2] = T2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return { found: false, distance: void 0, path: void 0, steps: w2 };
|
|
} }, st = Xe({ weight: function(e2) {
|
|
return 1;
|
|
}, directed: false }), lt = { floydWarshall: function(e2) {
|
|
for (var t2 = this.cy(), n2 = st(e2), r2 = n2.weight, i2 = n2.directed, a2 = r2, o2 = this.byGroup(), s2 = o2.nodes, l2 = o2.edges, u2 = s2.length, c2 = u2 * u2, d2 = function(e3) {
|
|
return s2.indexOf(e3);
|
|
}, h2 = function(e3) {
|
|
return s2[e3];
|
|
}, p2 = new Array(c2), g2 = 0; g2 < c2; g2++) {
|
|
var v2 = g2 % u2, y2 = (g2 - v2) / u2;
|
|
p2[g2] = y2 === v2 ? 0 : 1 / 0;
|
|
}
|
|
for (var m2 = new Array(c2), b2 = new Array(c2), x2 = 0; x2 < l2.length; x2++) {
|
|
var w2 = l2[x2], E2 = w2.source()[0], k2 = w2.target()[0];
|
|
if (E2 !== k2) {
|
|
var C2 = d2(E2), S2 = d2(k2), P2 = C2 * u2 + S2, D2 = a2(w2);
|
|
if (p2[P2] > D2 && (p2[P2] = D2, m2[P2] = S2, b2[P2] = w2), !i2) {
|
|
var T2 = S2 * u2 + C2;
|
|
!i2 && p2[T2] > D2 && (p2[T2] = D2, m2[T2] = C2, b2[T2] = w2);
|
|
}
|
|
}
|
|
}
|
|
for (var _2 = 0; _2 < u2; _2++) for (var M2 = 0; M2 < u2; M2++) for (var B2 = M2 * u2 + _2, N2 = 0; N2 < u2; N2++) {
|
|
var z2 = M2 * u2 + N2, I2 = _2 * u2 + N2;
|
|
p2[B2] + p2[I2] < p2[z2] && (p2[z2] = p2[B2] + p2[I2], m2[z2] = m2[B2]);
|
|
}
|
|
var L3 = function(e3) {
|
|
return d2(function(e4) {
|
|
return (f(e4) ? t2.filter(e4) : e4)[0];
|
|
}(e3));
|
|
};
|
|
return { distance: function(e3, t3) {
|
|
var n3 = L3(e3), r3 = L3(t3);
|
|
return p2[n3 * u2 + r3];
|
|
}, path: function(e3, n3) {
|
|
var r3 = L3(e3), i3 = L3(n3), a3 = h2(r3);
|
|
if (r3 === i3) return a3.collection();
|
|
if (null == m2[r3 * u2 + i3]) return t2.collection();
|
|
var o3, s3 = t2.collection(), l3 = r3;
|
|
for (s3.merge(a3); r3 !== i3; ) l3 = r3, r3 = m2[r3 * u2 + i3], o3 = b2[l3 * u2 + r3], s3.merge(o3), s3.merge(h2(r3));
|
|
return s3;
|
|
} };
|
|
} }, ut = Xe({ weight: function(e2) {
|
|
return 1;
|
|
}, directed: false, root: null }), ct = { bellmanFord: function(e2) {
|
|
var t2 = this, n2 = ut(e2), r2 = n2.weight, i2 = n2.directed, a2 = n2.root, o2 = r2, s2 = this, l2 = this.cy(), u2 = this.byGroup(), c2 = u2.edges, d2 = u2.nodes, h2 = d2.length, p2 = new Ue(), g2 = false, v2 = [];
|
|
a2 = l2.collection(a2)[0], c2.unmergeBy(function(e3) {
|
|
return e3.isLoop();
|
|
});
|
|
for (var y2 = c2.length, m2 = function(e3) {
|
|
var t3 = p2.get(e3.id());
|
|
return t3 || (t3 = {}, p2.set(e3.id(), t3)), t3;
|
|
}, b2 = function(e3) {
|
|
return (f(e3) ? l2.$(e3) : e3)[0];
|
|
}, x2 = 0; x2 < h2; x2++) {
|
|
var w2 = d2[x2], E2 = m2(w2);
|
|
w2.same(a2) ? E2.dist = 0 : E2.dist = 1 / 0, E2.pred = null, E2.edge = null;
|
|
}
|
|
for (var k2 = false, C2 = function(e3, t3, n3, r3, i3, a3) {
|
|
var o3 = r3.dist + a3;
|
|
o3 < i3.dist && !n3.same(r3.edge) && (i3.dist = o3, i3.pred = e3, i3.edge = n3, k2 = true);
|
|
}, S2 = 1; S2 < h2; S2++) {
|
|
k2 = false;
|
|
for (var P2 = 0; P2 < y2; P2++) {
|
|
var D2 = c2[P2], T2 = D2.source(), _2 = D2.target(), M2 = o2(D2), B2 = m2(T2), N2 = m2(_2);
|
|
C2(T2, 0, D2, B2, N2, M2), i2 || C2(_2, 0, D2, N2, B2, M2);
|
|
}
|
|
if (!k2) break;
|
|
}
|
|
if (k2) for (var z2 = [], I2 = 0; I2 < y2; I2++) {
|
|
var L3 = c2[I2], A2 = L3.source(), O2 = L3.target(), R2 = o2(L3), V2 = m2(A2).dist, F2 = m2(O2).dist;
|
|
if (V2 + R2 < F2 || !i2 && F2 + R2 < V2) {
|
|
if (g2 || (Ve("Graph contains a negative weight cycle for Bellman-Ford"), g2 = true), false === e2.findNegativeWeightCycles) break;
|
|
var j2 = [];
|
|
V2 + R2 < F2 && j2.push(A2), !i2 && F2 + R2 < V2 && j2.push(O2);
|
|
for (var q2 = j2.length, Y2 = 0; Y2 < q2; Y2++) {
|
|
var X2 = j2[Y2], W2 = [X2];
|
|
W2.push(m2(X2).edge);
|
|
for (var H2 = m2(X2).pred; -1 === W2.indexOf(H2); ) W2.push(H2), W2.push(m2(H2).edge), H2 = m2(H2).pred;
|
|
for (var K2 = (W2 = W2.slice(W2.indexOf(H2)))[0].id(), G2 = 0, U2 = 2; U2 < W2.length; U2 += 2) W2[U2].id() < K2 && (K2 = W2[U2].id(), G2 = U2);
|
|
(W2 = W2.slice(G2).concat(W2.slice(0, G2))).push(W2[0]);
|
|
var Z2 = W2.map(function(e3) {
|
|
return e3.id();
|
|
}).join(",");
|
|
-1 === z2.indexOf(Z2) && (v2.push(s2.spawn(W2)), z2.push(Z2));
|
|
}
|
|
}
|
|
}
|
|
return { distanceTo: function(e3) {
|
|
return m2(b2(e3)).dist;
|
|
}, pathTo: function(e3) {
|
|
for (var n3 = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : a2, r3 = b2(e3), i3 = [], o3 = r3; ; ) {
|
|
if (null == o3) return t2.spawn();
|
|
var l3 = m2(o3), u3 = l3.edge, c3 = l3.pred;
|
|
if (i3.unshift(o3[0]), o3.same(n3) && i3.length > 0) break;
|
|
null != u3 && i3.unshift(u3), o3 = c3;
|
|
}
|
|
return s2.spawn(i3);
|
|
}, hasNegativeWeightCycle: g2, negativeWeightCycles: v2 };
|
|
} }, dt = Math.sqrt(2), ht = function(e2, t2, n2) {
|
|
0 === n2.length && Oe("Karger-Stein must be run on a connected (sub)graph");
|
|
for (var r2 = n2[e2], i2 = r2[1], a2 = r2[2], o2 = t2[i2], s2 = t2[a2], l2 = n2, u2 = l2.length - 1; u2 >= 0; u2--) {
|
|
var c2 = l2[u2], d2 = c2[1], h2 = c2[2];
|
|
(t2[d2] === o2 && t2[h2] === s2 || t2[d2] === s2 && t2[h2] === o2) && l2.splice(u2, 1);
|
|
}
|
|
for (var p2 = 0; p2 < l2.length; p2++) {
|
|
var f2 = l2[p2];
|
|
f2[1] === s2 ? (l2[p2] = f2.slice(), l2[p2][1] = o2) : f2[2] === s2 && (l2[p2] = f2.slice(), l2[p2][2] = o2);
|
|
}
|
|
for (var g2 = 0; g2 < t2.length; g2++) t2[g2] === s2 && (t2[g2] = o2);
|
|
return l2;
|
|
}, pt = function(e2, t2, n2, r2) {
|
|
for (; n2 > r2; ) {
|
|
var i2 = Math.floor(Math.random() * t2.length);
|
|
t2 = ht(i2, e2, t2), n2--;
|
|
}
|
|
return t2;
|
|
}, ft = { kargerStein: function() {
|
|
var e2 = this, t2 = this.byGroup(), n2 = t2.nodes, r2 = t2.edges;
|
|
r2.unmergeBy(function(e3) {
|
|
return e3.isLoop();
|
|
});
|
|
var i2 = n2.length, a2 = r2.length, o2 = Math.ceil(Math.pow(Math.log(i2) / Math.LN2, 2)), s2 = Math.floor(i2 / dt);
|
|
if (!(i2 < 2)) {
|
|
for (var l2 = [], u2 = 0; u2 < a2; u2++) {
|
|
var c2 = r2[u2];
|
|
l2.push([u2, n2.indexOf(c2.source()), n2.indexOf(c2.target())]);
|
|
}
|
|
for (var d2 = 1 / 0, h2 = [], p2 = new Array(i2), f2 = new Array(i2), g2 = new Array(i2), v2 = function(e3, t3) {
|
|
for (var n3 = 0; n3 < i2; n3++) t3[n3] = e3[n3];
|
|
}, y2 = 0; y2 <= o2; y2++) {
|
|
for (var m2 = 0; m2 < i2; m2++) f2[m2] = m2;
|
|
var b2 = pt(f2, l2.slice(), i2, s2), x2 = b2.slice();
|
|
v2(f2, g2);
|
|
var w2 = pt(f2, b2, s2, 2), E2 = pt(g2, x2, s2, 2);
|
|
w2.length <= E2.length && w2.length < d2 ? (d2 = w2.length, h2 = w2, v2(f2, p2)) : E2.length <= w2.length && E2.length < d2 && (d2 = E2.length, h2 = E2, v2(g2, p2));
|
|
}
|
|
for (var k2 = this.spawn(h2.map(function(e3) {
|
|
return r2[e3[0]];
|
|
})), C2 = this.spawn(), S2 = this.spawn(), P2 = p2[0], D2 = 0; D2 < p2.length; D2++) {
|
|
var T2 = p2[D2], _2 = n2[D2];
|
|
T2 === P2 ? C2.merge(_2) : S2.merge(_2);
|
|
}
|
|
var M2 = function(t3) {
|
|
var n3 = e2.spawn();
|
|
return t3.forEach(function(t4) {
|
|
n3.merge(t4), t4.connectedEdges().forEach(function(t5) {
|
|
e2.contains(t5) && !k2.contains(t5) && n3.merge(t5);
|
|
});
|
|
}), n3;
|
|
}, B2 = [M2(C2), M2(S2)];
|
|
return { cut: k2, components: B2, partition1: C2, partition2: S2 };
|
|
}
|
|
Oe("At least 2 nodes are required for Karger-Stein algorithm");
|
|
} }, gt = function(e2, t2, n2) {
|
|
return { x: e2.x * t2 + n2.x, y: e2.y * t2 + n2.y };
|
|
}, vt = function(e2, t2, n2) {
|
|
return { x: (e2.x - n2.x) / t2, y: (e2.y - n2.y) / t2 };
|
|
}, yt = function(e2) {
|
|
return { x: e2[0], y: e2[1] };
|
|
}, mt = function(e2, t2) {
|
|
return Math.atan2(t2, e2) - Math.PI / 2;
|
|
}, bt = Math.log2 || function(e2) {
|
|
return Math.log(e2) / Math.log(2);
|
|
}, xt = function(e2) {
|
|
return e2 > 0 ? 1 : e2 < 0 ? -1 : 0;
|
|
}, wt = function(e2, t2) {
|
|
return Math.sqrt(Et(e2, t2));
|
|
}, Et = function(e2, t2) {
|
|
var n2 = t2.x - e2.x, r2 = t2.y - e2.y;
|
|
return n2 * n2 + r2 * r2;
|
|
}, kt = function(e2) {
|
|
for (var t2 = e2.length, n2 = 0, r2 = 0; r2 < t2; r2++) n2 += e2[r2];
|
|
for (var i2 = 0; i2 < t2; i2++) e2[i2] = e2[i2] / n2;
|
|
return e2;
|
|
}, Ct = function(e2, t2, n2, r2) {
|
|
return (1 - r2) * (1 - r2) * e2 + 2 * (1 - r2) * r2 * t2 + r2 * r2 * n2;
|
|
}, St = function(e2, t2, n2, r2) {
|
|
return { x: Ct(e2.x, t2.x, n2.x, r2), y: Ct(e2.y, t2.y, n2.y, r2) };
|
|
}, Pt = function(e2, t2, n2) {
|
|
return Math.max(e2, Math.min(n2, t2));
|
|
}, Dt = function(e2) {
|
|
if (null == e2) return { x1: 1 / 0, y1: 1 / 0, x2: -1 / 0, y2: -1 / 0, w: 0, h: 0 };
|
|
if (null != e2.x1 && null != e2.y1) {
|
|
if (null != e2.x2 && null != e2.y2 && e2.x2 >= e2.x1 && e2.y2 >= e2.y1) return { x1: e2.x1, y1: e2.y1, x2: e2.x2, y2: e2.y2, w: e2.x2 - e2.x1, h: e2.y2 - e2.y1 };
|
|
if (null != e2.w && null != e2.h && e2.w >= 0 && e2.h >= 0) return { x1: e2.x1, y1: e2.y1, x2: e2.x1 + e2.w, y2: e2.y1 + e2.h, w: e2.w, h: e2.h };
|
|
}
|
|
}, Tt = function(e2, t2) {
|
|
e2.x1 = Math.min(e2.x1, t2.x1), e2.x2 = Math.max(e2.x2, t2.x2), e2.w = e2.x2 - e2.x1, e2.y1 = Math.min(e2.y1, t2.y1), e2.y2 = Math.max(e2.y2, t2.y2), e2.h = e2.y2 - e2.y1;
|
|
}, _t = function(e2, t2, n2) {
|
|
e2.x1 = Math.min(e2.x1, t2), e2.x2 = Math.max(e2.x2, t2), e2.w = e2.x2 - e2.x1, e2.y1 = Math.min(e2.y1, n2), e2.y2 = Math.max(e2.y2, n2), e2.h = e2.y2 - e2.y1;
|
|
}, Mt = function(e2) {
|
|
var t2 = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : 0;
|
|
return e2.x1 -= t2, e2.x2 += t2, e2.y1 -= t2, e2.y2 += t2, e2.w = e2.x2 - e2.x1, e2.h = e2.y2 - e2.y1, e2;
|
|
}, Bt = function(e2) {
|
|
var t2, n2, r2, i2, o2 = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : [0];
|
|
if (1 === o2.length) t2 = n2 = r2 = i2 = o2[0];
|
|
else if (2 === o2.length) t2 = r2 = o2[0], i2 = n2 = o2[1];
|
|
else if (4 === o2.length) {
|
|
var s2 = a(o2, 4);
|
|
t2 = s2[0], n2 = s2[1], r2 = s2[2], i2 = s2[3];
|
|
}
|
|
return e2.x1 -= i2, e2.x2 += n2, e2.y1 -= t2, e2.y2 += r2, e2.w = e2.x2 - e2.x1, e2.h = e2.y2 - e2.y1, e2;
|
|
}, Nt = function(e2, t2) {
|
|
e2.x1 = t2.x1, e2.y1 = t2.y1, e2.x2 = t2.x2, e2.y2 = t2.y2, e2.w = e2.x2 - e2.x1, e2.h = e2.y2 - e2.y1;
|
|
}, zt = function(e2, t2) {
|
|
return !(e2.x1 > t2.x2) && (!(t2.x1 > e2.x2) && (!(e2.x2 < t2.x1) && (!(t2.x2 < e2.x1) && (!(e2.y2 < t2.y1) && (!(t2.y2 < e2.y1) && (!(e2.y1 > t2.y2) && !(t2.y1 > e2.y2)))))));
|
|
}, It = function(e2, t2, n2) {
|
|
return e2.x1 <= t2 && t2 <= e2.x2 && e2.y1 <= n2 && n2 <= e2.y2;
|
|
}, Lt = function(e2, t2) {
|
|
return It(e2, t2.x1, t2.y1) && It(e2, t2.x2, t2.y2);
|
|
}, At = function(e2, t2, n2, r2, i2, a2, o2) {
|
|
var s2, l2 = en(i2, a2), u2 = i2 / 2, c2 = a2 / 2, d2 = r2 - c2 - o2;
|
|
if ((s2 = Gt(e2, t2, n2, r2, n2 - u2 + l2 - o2, d2, n2 + u2 - l2 + o2, d2, false)).length > 0) return s2;
|
|
var h2 = n2 + u2 + o2;
|
|
if ((s2 = Gt(e2, t2, n2, r2, h2, r2 - c2 + l2 - o2, h2, r2 + c2 - l2 + o2, false)).length > 0) return s2;
|
|
var p2 = r2 + c2 + o2;
|
|
if ((s2 = Gt(e2, t2, n2, r2, n2 - u2 + l2 - o2, p2, n2 + u2 - l2 + o2, p2, false)).length > 0) return s2;
|
|
var f2, g2 = n2 - u2 - o2;
|
|
if ((s2 = Gt(e2, t2, n2, r2, g2, r2 - c2 + l2 - o2, g2, r2 + c2 - l2 + o2, false)).length > 0) return s2;
|
|
var v2 = n2 - u2 + l2, y2 = r2 - c2 + l2;
|
|
if ((f2 = Ht(e2, t2, n2, r2, v2, y2, l2 + o2)).length > 0 && f2[0] <= v2 && f2[1] <= y2) return [f2[0], f2[1]];
|
|
var m2 = n2 + u2 - l2, b2 = r2 - c2 + l2;
|
|
if ((f2 = Ht(e2, t2, n2, r2, m2, b2, l2 + o2)).length > 0 && f2[0] >= m2 && f2[1] <= b2) return [f2[0], f2[1]];
|
|
var x2 = n2 + u2 - l2, w2 = r2 + c2 - l2;
|
|
if ((f2 = Ht(e2, t2, n2, r2, x2, w2, l2 + o2)).length > 0 && f2[0] >= x2 && f2[1] >= w2) return [f2[0], f2[1]];
|
|
var E2 = n2 - u2 + l2, k2 = r2 + c2 - l2;
|
|
return (f2 = Ht(e2, t2, n2, r2, E2, k2, l2 + o2)).length > 0 && f2[0] <= E2 && f2[1] >= k2 ? [f2[0], f2[1]] : [];
|
|
}, Ot = function(e2, t2, n2, r2, i2, a2, o2) {
|
|
var s2 = o2, l2 = Math.min(n2, i2), u2 = Math.max(n2, i2), c2 = Math.min(r2, a2), d2 = Math.max(r2, a2);
|
|
return l2 - s2 <= e2 && e2 <= u2 + s2 && c2 - s2 <= t2 && t2 <= d2 + s2;
|
|
}, Rt = function(e2, t2, n2, r2, i2, a2, o2, s2, l2) {
|
|
var u2 = Math.min(n2, o2, i2) - l2, c2 = Math.max(n2, o2, i2) + l2, d2 = Math.min(r2, s2, a2) - l2, h2 = Math.max(r2, s2, a2) + l2;
|
|
return !(e2 < u2 || e2 > c2 || t2 < d2 || t2 > h2);
|
|
}, Vt = function(e2, t2, n2, r2, i2, a2, o2, s2) {
|
|
var l2 = [];
|
|
!function(e3, t3, n3, r3, i3) {
|
|
var a3, o3, s3, l3, u3, c3, d3, h3;
|
|
0 === e3 && (e3 = 1e-5), s3 = -27 * (r3 /= e3) + (t3 /= e3) * (9 * (n3 /= e3) - t3 * t3 * 2), a3 = (o3 = (3 * n3 - t3 * t3) / 9) * o3 * o3 + (s3 /= 54) * s3, i3[1] = 0, d3 = t3 / 3, a3 > 0 ? (u3 = (u3 = s3 + Math.sqrt(a3)) < 0 ? -Math.pow(-u3, 1 / 3) : Math.pow(u3, 1 / 3), c3 = (c3 = s3 - Math.sqrt(a3)) < 0 ? -Math.pow(-c3, 1 / 3) : Math.pow(c3, 1 / 3), i3[0] = -d3 + u3 + c3, d3 += (u3 + c3) / 2, i3[4] = i3[2] = -d3, d3 = Math.sqrt(3) * (-c3 + u3) / 2, i3[3] = d3, i3[5] = -d3) : (i3[5] = i3[3] = 0, 0 === a3 ? (h3 = s3 < 0 ? -Math.pow(-s3, 1 / 3) : Math.pow(s3, 1 / 3), i3[0] = 2 * h3 - d3, i3[4] = i3[2] = -(h3 + d3)) : (l3 = (o3 = -o3) * o3 * o3, l3 = Math.acos(s3 / Math.sqrt(l3)), h3 = 2 * Math.sqrt(o3), i3[0] = -d3 + h3 * Math.cos(l3 / 3), i3[2] = -d3 + h3 * Math.cos((l3 + 2 * Math.PI) / 3), i3[4] = -d3 + h3 * Math.cos((l3 + 4 * Math.PI) / 3)));
|
|
}(1 * n2 * n2 - 4 * n2 * i2 + 2 * n2 * o2 + 4 * i2 * i2 - 4 * i2 * o2 + o2 * o2 + r2 * r2 - 4 * r2 * a2 + 2 * r2 * s2 + 4 * a2 * a2 - 4 * a2 * s2 + s2 * s2, 9 * n2 * i2 - 3 * n2 * n2 - 3 * n2 * o2 - 6 * i2 * i2 + 3 * i2 * o2 + 9 * r2 * a2 - 3 * r2 * r2 - 3 * r2 * s2 - 6 * a2 * a2 + 3 * a2 * s2, 3 * n2 * n2 - 6 * n2 * i2 + n2 * o2 - n2 * e2 + 2 * i2 * i2 + 2 * i2 * e2 - o2 * e2 + 3 * r2 * r2 - 6 * r2 * a2 + r2 * s2 - r2 * t2 + 2 * a2 * a2 + 2 * a2 * t2 - s2 * t2, 1 * n2 * i2 - n2 * n2 + n2 * e2 - i2 * e2 + r2 * a2 - r2 * r2 + r2 * t2 - a2 * t2, l2);
|
|
for (var u2 = [], c2 = 0; c2 < 6; c2 += 2) Math.abs(l2[c2 + 1]) < 1e-7 && l2[c2] >= 0 && l2[c2] <= 1 && u2.push(l2[c2]);
|
|
u2.push(1), u2.push(0);
|
|
for (var d2, h2, p2, f2 = -1, g2 = 0; g2 < u2.length; g2++) d2 = Math.pow(1 - u2[g2], 2) * n2 + 2 * (1 - u2[g2]) * u2[g2] * i2 + u2[g2] * u2[g2] * o2, h2 = Math.pow(1 - u2[g2], 2) * r2 + 2 * (1 - u2[g2]) * u2[g2] * a2 + u2[g2] * u2[g2] * s2, p2 = Math.pow(d2 - e2, 2) + Math.pow(h2 - t2, 2), f2 >= 0 ? p2 < f2 && (f2 = p2) : f2 = p2;
|
|
return f2;
|
|
}, Ft = function(e2, t2, n2, r2, i2, a2) {
|
|
var o2 = [e2 - n2, t2 - r2], s2 = [i2 - n2, a2 - r2], l2 = s2[0] * s2[0] + s2[1] * s2[1], u2 = o2[0] * o2[0] + o2[1] * o2[1], c2 = o2[0] * s2[0] + o2[1] * s2[1], d2 = c2 * c2 / l2;
|
|
return c2 < 0 ? u2 : d2 > l2 ? (e2 - i2) * (e2 - i2) + (t2 - a2) * (t2 - a2) : u2 - d2;
|
|
}, jt = function(e2, t2, n2) {
|
|
for (var r2, i2, a2, o2, s2 = 0, l2 = 0; l2 < n2.length / 2; l2++) if (r2 = n2[2 * l2], i2 = n2[2 * l2 + 1], l2 + 1 < n2.length / 2 ? (a2 = n2[2 * (l2 + 1)], o2 = n2[2 * (l2 + 1) + 1]) : (a2 = n2[2 * (l2 + 1 - n2.length / 2)], o2 = n2[2 * (l2 + 1 - n2.length / 2) + 1]), r2 == e2 && a2 == e2) ;
|
|
else {
|
|
if (!(r2 >= e2 && e2 >= a2 || r2 <= e2 && e2 <= a2)) continue;
|
|
(e2 - r2) / (a2 - r2) * (o2 - i2) + i2 > t2 && s2++;
|
|
}
|
|
return s2 % 2 != 0;
|
|
}, qt = function(e2, t2, n2, r2, i2, a2, o2, s2, l2) {
|
|
var u2, c2 = new Array(n2.length);
|
|
null != s2[0] ? (u2 = Math.atan(s2[1] / s2[0]), s2[0] < 0 ? u2 += Math.PI / 2 : u2 = -u2 - Math.PI / 2) : u2 = s2;
|
|
for (var d2, h2 = Math.cos(-u2), p2 = Math.sin(-u2), f2 = 0; f2 < c2.length / 2; f2++) c2[2 * f2] = a2 / 2 * (n2[2 * f2] * h2 - n2[2 * f2 + 1] * p2), c2[2 * f2 + 1] = o2 / 2 * (n2[2 * f2 + 1] * h2 + n2[2 * f2] * p2), c2[2 * f2] += r2, c2[2 * f2 + 1] += i2;
|
|
if (l2 > 0) {
|
|
var g2 = Xt(c2, -l2);
|
|
d2 = Yt(g2);
|
|
} else d2 = c2;
|
|
return jt(e2, t2, d2);
|
|
}, Yt = function(e2) {
|
|
for (var t2, n2, r2, i2, a2, o2, s2, l2, u2 = new Array(e2.length / 2), c2 = 0; c2 < e2.length / 4; c2++) {
|
|
t2 = e2[4 * c2], n2 = e2[4 * c2 + 1], r2 = e2[4 * c2 + 2], i2 = e2[4 * c2 + 3], c2 < e2.length / 4 - 1 ? (a2 = e2[4 * (c2 + 1)], o2 = e2[4 * (c2 + 1) + 1], s2 = e2[4 * (c2 + 1) + 2], l2 = e2[4 * (c2 + 1) + 3]) : (a2 = e2[0], o2 = e2[1], s2 = e2[2], l2 = e2[3]);
|
|
var d2 = Gt(t2, n2, r2, i2, a2, o2, s2, l2, true);
|
|
u2[2 * c2] = d2[0], u2[2 * c2 + 1] = d2[1];
|
|
}
|
|
return u2;
|
|
}, Xt = function(e2, t2) {
|
|
for (var n2, r2, i2, a2, o2 = new Array(2 * e2.length), s2 = 0; s2 < e2.length / 2; s2++) {
|
|
n2 = e2[2 * s2], r2 = e2[2 * s2 + 1], s2 < e2.length / 2 - 1 ? (i2 = e2[2 * (s2 + 1)], a2 = e2[2 * (s2 + 1) + 1]) : (i2 = e2[0], a2 = e2[1]);
|
|
var l2 = a2 - r2, u2 = -(i2 - n2), c2 = Math.sqrt(l2 * l2 + u2 * u2), d2 = l2 / c2, h2 = u2 / c2;
|
|
o2[4 * s2] = n2 + d2 * t2, o2[4 * s2 + 1] = r2 + h2 * t2, o2[4 * s2 + 2] = i2 + d2 * t2, o2[4 * s2 + 3] = a2 + h2 * t2;
|
|
}
|
|
return o2;
|
|
}, Wt = function(e2, t2, n2, r2, i2, a2, o2) {
|
|
return e2 -= i2, t2 -= a2, (e2 /= n2 / 2 + o2) * e2 + (t2 /= r2 / 2 + o2) * t2 <= 1;
|
|
}, Ht = function(e2, t2, n2, r2, i2, a2, o2) {
|
|
var s2 = [n2 - e2, r2 - t2], l2 = [e2 - i2, t2 - a2], u2 = s2[0] * s2[0] + s2[1] * s2[1], c2 = 2 * (l2[0] * s2[0] + l2[1] * s2[1]), d2 = c2 * c2 - 4 * u2 * (l2[0] * l2[0] + l2[1] * l2[1] - o2 * o2);
|
|
if (d2 < 0) return [];
|
|
var h2 = (-c2 + Math.sqrt(d2)) / (2 * u2), p2 = (-c2 - Math.sqrt(d2)) / (2 * u2), f2 = Math.min(h2, p2), g2 = Math.max(h2, p2), v2 = [];
|
|
if (f2 >= 0 && f2 <= 1 && v2.push(f2), g2 >= 0 && g2 <= 1 && v2.push(g2), 0 === v2.length) return [];
|
|
var y2 = v2[0] * s2[0] + e2, m2 = v2[0] * s2[1] + t2;
|
|
return v2.length > 1 ? v2[0] == v2[1] ? [y2, m2] : [y2, m2, v2[1] * s2[0] + e2, v2[1] * s2[1] + t2] : [y2, m2];
|
|
}, Kt = function(e2, t2, n2) {
|
|
return t2 <= e2 && e2 <= n2 || n2 <= e2 && e2 <= t2 ? e2 : e2 <= t2 && t2 <= n2 || n2 <= t2 && t2 <= e2 ? t2 : n2;
|
|
}, Gt = function(e2, t2, n2, r2, i2, a2, o2, s2, l2) {
|
|
var u2 = e2 - i2, c2 = n2 - e2, d2 = o2 - i2, h2 = t2 - a2, p2 = r2 - t2, f2 = s2 - a2, g2 = d2 * h2 - f2 * u2, v2 = c2 * h2 - p2 * u2, y2 = f2 * c2 - d2 * p2;
|
|
if (0 !== y2) {
|
|
var m2 = g2 / y2, b2 = v2 / y2;
|
|
return -1e-3 <= m2 && m2 <= 1.001 && -1e-3 <= b2 && b2 <= 1.001 || l2 ? [e2 + m2 * c2, t2 + m2 * p2] : [];
|
|
}
|
|
return 0 === g2 || 0 === v2 ? Kt(e2, n2, o2) === o2 ? [o2, s2] : Kt(e2, n2, i2) === i2 ? [i2, a2] : Kt(i2, o2, n2) === n2 ? [n2, r2] : [] : [];
|
|
}, Ut = function(e2, t2, n2, r2, i2, a2, o2, s2) {
|
|
var l2, u2, c2, d2, h2, p2, f2 = [], g2 = new Array(n2.length), v2 = true;
|
|
if (null == a2 && (v2 = false), v2) {
|
|
for (var y2 = 0; y2 < g2.length / 2; y2++) g2[2 * y2] = n2[2 * y2] * a2 + r2, g2[2 * y2 + 1] = n2[2 * y2 + 1] * o2 + i2;
|
|
if (s2 > 0) {
|
|
var m2 = Xt(g2, -s2);
|
|
u2 = Yt(m2);
|
|
} else u2 = g2;
|
|
} else u2 = n2;
|
|
for (var b2 = 0; b2 < u2.length / 2; b2++) c2 = u2[2 * b2], d2 = u2[2 * b2 + 1], b2 < u2.length / 2 - 1 ? (h2 = u2[2 * (b2 + 1)], p2 = u2[2 * (b2 + 1) + 1]) : (h2 = u2[0], p2 = u2[1]), 0 !== (l2 = Gt(e2, t2, r2, i2, c2, d2, h2, p2)).length && f2.push(l2[0], l2[1]);
|
|
return f2;
|
|
}, Zt = function(e2, t2, n2) {
|
|
var r2 = [e2[0] - t2[0], e2[1] - t2[1]], i2 = Math.sqrt(r2[0] * r2[0] + r2[1] * r2[1]), a2 = (i2 - n2) / i2;
|
|
return a2 < 0 && (a2 = 1e-5), [t2[0] + a2 * r2[0], t2[1] + a2 * r2[1]];
|
|
}, $t = function(e2, t2) {
|
|
var n2 = Jt(e2, t2);
|
|
return n2 = Qt(n2);
|
|
}, Qt = function(e2) {
|
|
for (var t2, n2, r2 = e2.length / 2, i2 = 1 / 0, a2 = 1 / 0, o2 = -1 / 0, s2 = -1 / 0, l2 = 0; l2 < r2; l2++) t2 = e2[2 * l2], n2 = e2[2 * l2 + 1], i2 = Math.min(i2, t2), o2 = Math.max(o2, t2), a2 = Math.min(a2, n2), s2 = Math.max(s2, n2);
|
|
for (var u2 = 2 / (o2 - i2), c2 = 2 / (s2 - a2), d2 = 0; d2 < r2; d2++) t2 = e2[2 * d2] = e2[2 * d2] * u2, n2 = e2[2 * d2 + 1] = e2[2 * d2 + 1] * c2, i2 = Math.min(i2, t2), o2 = Math.max(o2, t2), a2 = Math.min(a2, n2), s2 = Math.max(s2, n2);
|
|
if (a2 < -1) for (var h2 = 0; h2 < r2; h2++) n2 = e2[2 * h2 + 1] = e2[2 * h2 + 1] + (-1 - a2);
|
|
return e2;
|
|
}, Jt = function(e2, t2) {
|
|
var n2 = 1 / e2 * 2 * Math.PI, r2 = e2 % 2 == 0 ? Math.PI / 2 + n2 / 2 : Math.PI / 2;
|
|
r2 += t2;
|
|
for (var i2, a2 = new Array(2 * e2), o2 = 0; o2 < e2; o2++) i2 = o2 * n2 + r2, a2[2 * o2] = Math.cos(i2), a2[2 * o2 + 1] = Math.sin(-i2);
|
|
return a2;
|
|
}, en = function(e2, t2) {
|
|
return Math.min(e2 / 4, t2 / 4, 8);
|
|
}, tn = function(e2, t2) {
|
|
return Math.min(e2 / 10, t2 / 10, 8);
|
|
}, nn = function(e2, t2) {
|
|
return { heightOffset: Math.min(15, 0.05 * t2), widthOffset: Math.min(100, 0.25 * e2), ctrlPtOffsetPct: 0.05 };
|
|
}, rn = Xe({ dampingFactor: 0.8, precision: 1e-6, iterations: 200, weight: function(e2) {
|
|
return 1;
|
|
} }), an = { pageRank: function(e2) {
|
|
for (var t2 = rn(e2), n2 = t2.dampingFactor, r2 = t2.precision, i2 = t2.iterations, a2 = t2.weight, o2 = this._private.cy, s2 = this.byGroup(), l2 = s2.nodes, u2 = s2.edges, c2 = l2.length, d2 = c2 * c2, h2 = u2.length, p2 = new Array(d2), f2 = new Array(c2), g2 = (1 - n2) / c2, v2 = 0; v2 < c2; v2++) {
|
|
for (var y2 = 0; y2 < c2; y2++) {
|
|
p2[v2 * c2 + y2] = 0;
|
|
}
|
|
f2[v2] = 0;
|
|
}
|
|
for (var m2 = 0; m2 < h2; m2++) {
|
|
var b2 = u2[m2], x2 = b2.data("source"), w2 = b2.data("target");
|
|
if (x2 !== w2) {
|
|
var E2 = l2.indexOfId(x2), k2 = l2.indexOfId(w2), C2 = a2(b2);
|
|
p2[k2 * c2 + E2] += C2, f2[E2] += C2;
|
|
}
|
|
}
|
|
for (var S2 = 1 / c2 + g2, P2 = 0; P2 < c2; P2++) if (0 === f2[P2]) for (var D2 = 0; D2 < c2; D2++) {
|
|
p2[D2 * c2 + P2] = S2;
|
|
}
|
|
else for (var T2 = 0; T2 < c2; T2++) {
|
|
var _2 = T2 * c2 + P2;
|
|
p2[_2] = p2[_2] / f2[P2] + g2;
|
|
}
|
|
for (var M2, B2 = new Array(c2), N2 = new Array(c2), z2 = 0; z2 < c2; z2++) B2[z2] = 1;
|
|
for (var I2 = 0; I2 < i2; I2++) {
|
|
for (var L3 = 0; L3 < c2; L3++) N2[L3] = 0;
|
|
for (var A2 = 0; A2 < c2; A2++) for (var O2 = 0; O2 < c2; O2++) {
|
|
var R2 = A2 * c2 + O2;
|
|
N2[A2] += p2[R2] * B2[O2];
|
|
}
|
|
kt(N2), M2 = B2, B2 = N2, N2 = M2;
|
|
for (var V2 = 0, F2 = 0; F2 < c2; F2++) {
|
|
var j2 = M2[F2] - B2[F2];
|
|
V2 += j2 * j2;
|
|
}
|
|
if (V2 < r2) break;
|
|
}
|
|
return { rank: function(e3) {
|
|
return e3 = o2.collection(e3)[0], B2[l2.indexOf(e3)];
|
|
} };
|
|
} }, on = Xe({ root: null, weight: function(e2) {
|
|
return 1;
|
|
}, directed: false, alpha: 0 }), sn = { degreeCentralityNormalized: function(e2) {
|
|
e2 = on(e2);
|
|
var t2 = this.cy(), n2 = this.nodes(), r2 = n2.length;
|
|
if (e2.directed) {
|
|
for (var i2 = {}, a2 = {}, o2 = 0, s2 = 0, l2 = 0; l2 < r2; l2++) {
|
|
var u2 = n2[l2], c2 = u2.id();
|
|
e2.root = u2;
|
|
var d2 = this.degreeCentrality(e2);
|
|
o2 < d2.indegree && (o2 = d2.indegree), s2 < d2.outdegree && (s2 = d2.outdegree), i2[c2] = d2.indegree, a2[c2] = d2.outdegree;
|
|
}
|
|
return { indegree: function(e3) {
|
|
return 0 == o2 ? 0 : (f(e3) && (e3 = t2.filter(e3)), i2[e3.id()] / o2);
|
|
}, outdegree: function(e3) {
|
|
return 0 === s2 ? 0 : (f(e3) && (e3 = t2.filter(e3)), a2[e3.id()] / s2);
|
|
} };
|
|
}
|
|
for (var h2 = {}, p2 = 0, g2 = 0; g2 < r2; g2++) {
|
|
var v2 = n2[g2];
|
|
e2.root = v2;
|
|
var y2 = this.degreeCentrality(e2);
|
|
p2 < y2.degree && (p2 = y2.degree), h2[v2.id()] = y2.degree;
|
|
}
|
|
return { degree: function(e3) {
|
|
return 0 === p2 ? 0 : (f(e3) && (e3 = t2.filter(e3)), h2[e3.id()] / p2);
|
|
} };
|
|
}, degreeCentrality: function(e2) {
|
|
e2 = on(e2);
|
|
var t2 = this.cy(), n2 = this, r2 = e2, i2 = r2.root, a2 = r2.weight, o2 = r2.directed, s2 = r2.alpha;
|
|
if (i2 = t2.collection(i2)[0], o2) {
|
|
for (var l2 = i2.connectedEdges(), u2 = l2.filter(function(e3) {
|
|
return e3.target().same(i2) && n2.has(e3);
|
|
}), c2 = l2.filter(function(e3) {
|
|
return e3.source().same(i2) && n2.has(e3);
|
|
}), d2 = u2.length, h2 = c2.length, p2 = 0, f2 = 0, g2 = 0; g2 < u2.length; g2++) p2 += a2(u2[g2]);
|
|
for (var v2 = 0; v2 < c2.length; v2++) f2 += a2(c2[v2]);
|
|
return { indegree: Math.pow(d2, 1 - s2) * Math.pow(p2, s2), outdegree: Math.pow(h2, 1 - s2) * Math.pow(f2, s2) };
|
|
}
|
|
for (var y2 = i2.connectedEdges().intersection(n2), m2 = y2.length, b2 = 0, x2 = 0; x2 < y2.length; x2++) b2 += a2(y2[x2]);
|
|
return { degree: Math.pow(m2, 1 - s2) * Math.pow(b2, s2) };
|
|
} };
|
|
sn.dc = sn.degreeCentrality, sn.dcn = sn.degreeCentralityNormalised = sn.degreeCentralityNormalized;
|
|
var ln = Xe({ harmonic: true, weight: function() {
|
|
return 1;
|
|
}, directed: false, root: null }), un = { closenessCentralityNormalized: function(e2) {
|
|
for (var t2 = ln(e2), n2 = t2.harmonic, r2 = t2.weight, i2 = t2.directed, a2 = this.cy(), o2 = {}, s2 = 0, l2 = this.nodes(), u2 = this.floydWarshall({ weight: r2, directed: i2 }), c2 = 0; c2 < l2.length; c2++) {
|
|
for (var d2 = 0, h2 = l2[c2], p2 = 0; p2 < l2.length; p2++) if (c2 !== p2) {
|
|
var g2 = u2.distance(h2, l2[p2]);
|
|
d2 += n2 ? 1 / g2 : g2;
|
|
}
|
|
n2 || (d2 = 1 / d2), s2 < d2 && (s2 = d2), o2[h2.id()] = d2;
|
|
}
|
|
return { closeness: function(e3) {
|
|
return 0 == s2 ? 0 : (e3 = f(e3) ? a2.filter(e3)[0].id() : e3.id(), o2[e3] / s2);
|
|
} };
|
|
}, closenessCentrality: function(e2) {
|
|
var t2 = ln(e2), n2 = t2.root, r2 = t2.weight, i2 = t2.directed, a2 = t2.harmonic;
|
|
n2 = this.filter(n2)[0];
|
|
for (var o2 = this.dijkstra({ root: n2, weight: r2, directed: i2 }), s2 = 0, l2 = this.nodes(), u2 = 0; u2 < l2.length; u2++) {
|
|
var c2 = l2[u2];
|
|
if (!c2.same(n2)) {
|
|
var d2 = o2.distanceTo(c2);
|
|
s2 += a2 ? 1 / d2 : d2;
|
|
}
|
|
}
|
|
return a2 ? s2 : 1 / s2;
|
|
} };
|
|
un.cc = un.closenessCentrality, un.ccn = un.closenessCentralityNormalised = un.closenessCentralityNormalized;
|
|
var cn = Xe({ weight: null, directed: false }), dn = { betweennessCentrality: function(e2) {
|
|
for (var t2 = cn(e2), n2 = t2.directed, r2 = t2.weight, i2 = null != r2, a2 = this.cy(), o2 = this.nodes(), s2 = {}, l2 = {}, u2 = 0, c2 = function(e3, t3) {
|
|
l2[e3] = t3, t3 > u2 && (u2 = t3);
|
|
}, d2 = function(e3) {
|
|
return l2[e3];
|
|
}, h2 = 0; h2 < o2.length; h2++) {
|
|
var p2 = o2[h2], f2 = p2.id();
|
|
s2[f2] = n2 ? p2.outgoers().nodes() : p2.openNeighborhood().nodes(), c2(f2, 0);
|
|
}
|
|
for (var g2 = function(e3) {
|
|
for (var t3 = o2[e3].id(), n3 = [], l3 = {}, u3 = {}, h3 = {}, p3 = new tt(function(e4, t4) {
|
|
return h3[e4] - h3[t4];
|
|
}), f3 = 0; f3 < o2.length; f3++) {
|
|
var g3 = o2[f3].id();
|
|
l3[g3] = [], u3[g3] = 0, h3[g3] = 1 / 0;
|
|
}
|
|
for (u3[t3] = 1, h3[t3] = 0, p3.push(t3); !p3.empty(); ) {
|
|
var v3 = p3.pop();
|
|
if (n3.push(v3), i2) for (var y3 = 0; y3 < s2[v3].length; y3++) {
|
|
var m2 = s2[v3][y3], b2 = a2.getElementById(v3), x2 = void 0;
|
|
x2 = b2.edgesTo(m2).length > 0 ? b2.edgesTo(m2)[0] : m2.edgesTo(b2)[0];
|
|
var w2 = r2(x2);
|
|
m2 = m2.id(), h3[m2] > h3[v3] + w2 && (h3[m2] = h3[v3] + w2, p3.nodes.indexOf(m2) < 0 ? p3.push(m2) : p3.updateItem(m2), u3[m2] = 0, l3[m2] = []), h3[m2] == h3[v3] + w2 && (u3[m2] = u3[m2] + u3[v3], l3[m2].push(v3));
|
|
}
|
|
else for (var E2 = 0; E2 < s2[v3].length; E2++) {
|
|
var k2 = s2[v3][E2].id();
|
|
h3[k2] == 1 / 0 && (p3.push(k2), h3[k2] = h3[v3] + 1), h3[k2] == h3[v3] + 1 && (u3[k2] = u3[k2] + u3[v3], l3[k2].push(v3));
|
|
}
|
|
}
|
|
for (var C2 = {}, S2 = 0; S2 < o2.length; S2++) C2[o2[S2].id()] = 0;
|
|
for (; n3.length > 0; ) {
|
|
for (var P2 = n3.pop(), D2 = 0; D2 < l3[P2].length; D2++) {
|
|
var T2 = l3[P2][D2];
|
|
C2[T2] = C2[T2] + u3[T2] / u3[P2] * (1 + C2[P2]);
|
|
}
|
|
P2 != o2[e3].id() && c2(P2, d2(P2) + C2[P2]);
|
|
}
|
|
}, v2 = 0; v2 < o2.length; v2++) g2(v2);
|
|
var y2 = { betweenness: function(e3) {
|
|
var t3 = a2.collection(e3).id();
|
|
return d2(t3);
|
|
}, betweennessNormalized: function(e3) {
|
|
if (0 == u2) return 0;
|
|
var t3 = a2.collection(e3).id();
|
|
return d2(t3) / u2;
|
|
} };
|
|
return y2.betweennessNormalised = y2.betweennessNormalized, y2;
|
|
} };
|
|
dn.bc = dn.betweennessCentrality;
|
|
var hn = Xe({ expandFactor: 2, inflateFactor: 2, multFactor: 1, maxIterations: 20, attributes: [function(e2) {
|
|
return 1;
|
|
}] }), pn = function(e2, t2) {
|
|
for (var n2 = 0, r2 = 0; r2 < t2.length; r2++) n2 += t2[r2](e2);
|
|
return n2;
|
|
}, fn = function(e2, t2) {
|
|
for (var n2, r2 = 0; r2 < t2; r2++) {
|
|
n2 = 0;
|
|
for (var i2 = 0; i2 < t2; i2++) n2 += e2[i2 * t2 + r2];
|
|
for (var a2 = 0; a2 < t2; a2++) e2[a2 * t2 + r2] = e2[a2 * t2 + r2] / n2;
|
|
}
|
|
}, gn = function(e2, t2, n2) {
|
|
for (var r2 = new Array(n2 * n2), i2 = 0; i2 < n2; i2++) {
|
|
for (var a2 = 0; a2 < n2; a2++) r2[i2 * n2 + a2] = 0;
|
|
for (var o2 = 0; o2 < n2; o2++) for (var s2 = 0; s2 < n2; s2++) r2[i2 * n2 + s2] += e2[i2 * n2 + o2] * t2[o2 * n2 + s2];
|
|
}
|
|
return r2;
|
|
}, vn = function(e2, t2, n2) {
|
|
for (var r2 = e2.slice(0), i2 = 1; i2 < n2; i2++) e2 = gn(e2, r2, t2);
|
|
return e2;
|
|
}, yn = function(e2, t2, n2) {
|
|
for (var r2 = new Array(t2 * t2), i2 = 0; i2 < t2 * t2; i2++) r2[i2] = Math.pow(e2[i2], n2);
|
|
return fn(r2, t2), r2;
|
|
}, mn = function(e2, t2, n2, r2) {
|
|
for (var i2 = 0; i2 < n2; i2++) {
|
|
if (Math.round(e2[i2] * Math.pow(10, r2)) / Math.pow(10, r2) !== Math.round(t2[i2] * Math.pow(10, r2)) / Math.pow(10, r2)) return false;
|
|
}
|
|
return true;
|
|
}, bn = function(e2, t2) {
|
|
for (var n2 = 0; n2 < e2.length; n2++) if (!t2[n2] || e2[n2].id() !== t2[n2].id()) return false;
|
|
return true;
|
|
}, xn = function(e2) {
|
|
for (var t2 = this.nodes(), n2 = this.edges(), r2 = this.cy(), i2 = function(e3) {
|
|
return hn(e3);
|
|
}(e2), a2 = {}, o2 = 0; o2 < t2.length; o2++) a2[t2[o2].id()] = o2;
|
|
for (var s2, l2 = t2.length, u2 = l2 * l2, c2 = new Array(u2), d2 = 0; d2 < u2; d2++) c2[d2] = 0;
|
|
for (var h2 = 0; h2 < n2.length; h2++) {
|
|
var p2 = n2[h2], f2 = a2[p2.source().id()], g2 = a2[p2.target().id()], v2 = pn(p2, i2.attributes);
|
|
c2[f2 * l2 + g2] += v2, c2[g2 * l2 + f2] += v2;
|
|
}
|
|
!function(e3, t3, n3) {
|
|
for (var r3 = 0; r3 < t3; r3++) e3[r3 * t3 + r3] = n3;
|
|
}(c2, l2, i2.multFactor), fn(c2, l2);
|
|
for (var y2 = true, m2 = 0; y2 && m2 < i2.maxIterations; ) y2 = false, s2 = vn(c2, l2, i2.expandFactor), c2 = yn(s2, l2, i2.inflateFactor), mn(c2, s2, u2, 4) || (y2 = true), m2++;
|
|
var b2 = function(e3, t3, n3, r3) {
|
|
for (var i3 = [], a3 = 0; a3 < t3; a3++) {
|
|
for (var o3 = [], s3 = 0; s3 < t3; s3++) Math.round(1e3 * e3[a3 * t3 + s3]) / 1e3 > 0 && o3.push(n3[s3]);
|
|
0 !== o3.length && i3.push(r3.collection(o3));
|
|
}
|
|
return i3;
|
|
}(c2, l2, t2, r2);
|
|
return b2 = function(e3) {
|
|
for (var t3 = 0; t3 < e3.length; t3++) for (var n3 = 0; n3 < e3.length; n3++) t3 != n3 && bn(e3[t3], e3[n3]) && e3.splice(n3, 1);
|
|
return e3;
|
|
}(b2);
|
|
}, wn = { markovClustering: xn, mcl: xn }, En = function(e2) {
|
|
return e2;
|
|
}, kn = function(e2, t2) {
|
|
return Math.abs(t2 - e2);
|
|
}, Cn = function(e2, t2, n2) {
|
|
return e2 + kn(t2, n2);
|
|
}, Sn = function(e2, t2, n2) {
|
|
return e2 + Math.pow(n2 - t2, 2);
|
|
}, Pn = function(e2) {
|
|
return Math.sqrt(e2);
|
|
}, Dn = function(e2, t2, n2) {
|
|
return Math.max(e2, kn(t2, n2));
|
|
}, Tn = function(e2, t2, n2, r2, i2) {
|
|
for (var a2 = arguments.length > 5 && void 0 !== arguments[5] ? arguments[5] : En, o2 = r2, s2 = 0; s2 < e2; s2++) o2 = i2(o2, t2(s2), n2(s2));
|
|
return a2(o2);
|
|
}, _n = { euclidean: function(e2, t2, n2) {
|
|
return e2 >= 2 ? Tn(e2, t2, n2, 0, Sn, Pn) : Tn(e2, t2, n2, 0, Cn);
|
|
}, squaredEuclidean: function(e2, t2, n2) {
|
|
return Tn(e2, t2, n2, 0, Sn);
|
|
}, manhattan: function(e2, t2, n2) {
|
|
return Tn(e2, t2, n2, 0, Cn);
|
|
}, max: function(e2, t2, n2) {
|
|
return Tn(e2, t2, n2, -1 / 0, Dn);
|
|
} };
|
|
function Mn(e2, t2, n2, r2, i2, a2) {
|
|
var o2;
|
|
return o2 = g(e2) ? e2 : _n[e2] || _n.euclidean, 0 === t2 && g(e2) ? o2(i2, a2) : o2(t2, n2, r2, i2, a2);
|
|
}
|
|
_n["squared-euclidean"] = _n.squaredEuclidean, _n.squaredeuclidean = _n.squaredEuclidean;
|
|
var Bn = Xe({ k: 2, m: 2, sensitivityThreshold: 1e-4, distance: "euclidean", maxIterations: 10, attributes: [], testMode: false, testCentroids: null }), Nn = function(e2) {
|
|
return Bn(e2);
|
|
}, zn = function(e2, t2, n2, r2, i2) {
|
|
var a2 = "kMedoids" !== i2 ? function(e3) {
|
|
return n2[e3];
|
|
} : function(e3) {
|
|
return r2[e3](n2);
|
|
}, o2 = n2, s2 = t2;
|
|
return Mn(e2, r2.length, a2, function(e3) {
|
|
return r2[e3](t2);
|
|
}, o2, s2);
|
|
}, In = function(e2, t2, n2) {
|
|
for (var r2 = n2.length, i2 = new Array(r2), a2 = new Array(r2), o2 = new Array(t2), s2 = null, l2 = 0; l2 < r2; l2++) i2[l2] = e2.min(n2[l2]).value, a2[l2] = e2.max(n2[l2]).value;
|
|
for (var u2 = 0; u2 < t2; u2++) {
|
|
s2 = [];
|
|
for (var c2 = 0; c2 < r2; c2++) s2[c2] = Math.random() * (a2[c2] - i2[c2]) + i2[c2];
|
|
o2[u2] = s2;
|
|
}
|
|
return o2;
|
|
}, Ln = function(e2, t2, n2, r2, i2) {
|
|
for (var a2 = 1 / 0, o2 = 0, s2 = 0; s2 < t2.length; s2++) {
|
|
var l2 = zn(n2, e2, t2[s2], r2, i2);
|
|
l2 < a2 && (a2 = l2, o2 = s2);
|
|
}
|
|
return o2;
|
|
}, An = function(e2, t2, n2) {
|
|
for (var r2 = [], i2 = null, a2 = 0; a2 < t2.length; a2++) n2[(i2 = t2[a2]).id()] === e2 && r2.push(i2);
|
|
return r2;
|
|
}, On = function(e2, t2, n2) {
|
|
for (var r2 = 0; r2 < e2.length; r2++) for (var i2 = 0; i2 < e2[r2].length; i2++) {
|
|
if (Math.abs(e2[r2][i2] - t2[r2][i2]) > n2) return false;
|
|
}
|
|
return true;
|
|
}, Rn = function(e2, t2, n2) {
|
|
for (var r2 = 0; r2 < n2; r2++) if (e2 === t2[r2]) return true;
|
|
return false;
|
|
}, Vn = function(e2, t2) {
|
|
var n2 = new Array(t2);
|
|
if (e2.length < 50) for (var r2 = 0; r2 < t2; r2++) {
|
|
for (var i2 = e2[Math.floor(Math.random() * e2.length)]; Rn(i2, n2, r2); ) i2 = e2[Math.floor(Math.random() * e2.length)];
|
|
n2[r2] = i2;
|
|
}
|
|
else for (var a2 = 0; a2 < t2; a2++) n2[a2] = e2[Math.floor(Math.random() * e2.length)];
|
|
return n2;
|
|
}, Fn = function(e2, t2, n2) {
|
|
for (var r2 = 0, i2 = 0; i2 < t2.length; i2++) r2 += zn("manhattan", t2[i2], e2, n2, "kMedoids");
|
|
return r2;
|
|
}, jn = function(e2, t2, n2, r2, i2) {
|
|
for (var a2, o2, s2 = 0; s2 < t2.length; s2++) for (var l2 = 0; l2 < e2.length; l2++) r2[s2][l2] = Math.pow(n2[s2][l2], i2.m);
|
|
for (var u2 = 0; u2 < e2.length; u2++) for (var c2 = 0; c2 < i2.attributes.length; c2++) {
|
|
a2 = 0, o2 = 0;
|
|
for (var d2 = 0; d2 < t2.length; d2++) a2 += r2[d2][u2] * i2.attributes[c2](t2[d2]), o2 += r2[d2][u2];
|
|
e2[u2][c2] = a2 / o2;
|
|
}
|
|
}, qn = function(e2, t2, n2, r2, i2) {
|
|
for (var a2 = 0; a2 < e2.length; a2++) t2[a2] = e2[a2].slice();
|
|
for (var o2, s2, l2, u2 = 2 / (i2.m - 1), c2 = 0; c2 < n2.length; c2++) for (var d2 = 0; d2 < r2.length; d2++) {
|
|
o2 = 0;
|
|
for (var h2 = 0; h2 < n2.length; h2++) s2 = zn(i2.distance, r2[d2], n2[c2], i2.attributes, "cmeans"), l2 = zn(i2.distance, r2[d2], n2[h2], i2.attributes, "cmeans"), o2 += Math.pow(s2 / l2, u2);
|
|
e2[d2][c2] = 1 / o2;
|
|
}
|
|
}, Yn = function(e2) {
|
|
var t2, n2, r2, i2, a2 = this.cy(), o2 = this.nodes(), s2 = Nn(e2);
|
|
r2 = new Array(o2.length);
|
|
for (var l2 = 0; l2 < o2.length; l2++) r2[l2] = new Array(s2.k);
|
|
n2 = new Array(o2.length);
|
|
for (var u2 = 0; u2 < o2.length; u2++) n2[u2] = new Array(s2.k);
|
|
for (var c2 = 0; c2 < o2.length; c2++) {
|
|
for (var d2 = 0, h2 = 0; h2 < s2.k; h2++) n2[c2][h2] = Math.random(), d2 += n2[c2][h2];
|
|
for (var p2 = 0; p2 < s2.k; p2++) n2[c2][p2] = n2[c2][p2] / d2;
|
|
}
|
|
t2 = new Array(s2.k);
|
|
for (var f2 = 0; f2 < s2.k; f2++) t2[f2] = new Array(s2.attributes.length);
|
|
i2 = new Array(o2.length);
|
|
for (var g2 = 0; g2 < o2.length; g2++) i2[g2] = new Array(s2.k);
|
|
for (var v2 = true, y2 = 0; v2 && y2 < s2.maxIterations; ) v2 = false, jn(t2, o2, n2, i2, s2), qn(n2, r2, t2, o2, s2), On(n2, r2, s2.sensitivityThreshold) || (v2 = true), y2++;
|
|
return { clusters: function(e3, t3, n3, r3) {
|
|
for (var i3, a3, o3 = new Array(n3.k), s3 = 0; s3 < o3.length; s3++) o3[s3] = [];
|
|
for (var l3 = 0; l3 < t3.length; l3++) {
|
|
i3 = -1 / 0, a3 = -1;
|
|
for (var u3 = 0; u3 < t3[0].length; u3++) t3[l3][u3] > i3 && (i3 = t3[l3][u3], a3 = u3);
|
|
o3[a3].push(e3[l3]);
|
|
}
|
|
for (var c3 = 0; c3 < o3.length; c3++) o3[c3] = r3.collection(o3[c3]);
|
|
return o3;
|
|
}(o2, n2, s2, a2), degreeOfMembership: n2 };
|
|
}, Xn = { kMeans: function(t2) {
|
|
var n2, r2 = this.cy(), i2 = this.nodes(), a2 = null, o2 = Nn(t2), s2 = new Array(o2.k), l2 = {};
|
|
o2.testMode ? "number" == typeof o2.testCentroids ? (o2.testCentroids, n2 = In(i2, o2.k, o2.attributes)) : n2 = "object" === e(o2.testCentroids) ? o2.testCentroids : In(i2, o2.k, o2.attributes) : n2 = In(i2, o2.k, o2.attributes);
|
|
for (var u2, c2, d2, h2 = true, p2 = 0; h2 && p2 < o2.maxIterations; ) {
|
|
for (var f2 = 0; f2 < i2.length; f2++) l2[(a2 = i2[f2]).id()] = Ln(a2, n2, o2.distance, o2.attributes, "kMeans");
|
|
h2 = false;
|
|
for (var g2 = 0; g2 < o2.k; g2++) {
|
|
var v2 = An(g2, i2, l2);
|
|
if (0 !== v2.length) {
|
|
for (var y2 = o2.attributes.length, m2 = n2[g2], b2 = new Array(y2), x2 = new Array(y2), w2 = 0; w2 < y2; w2++) {
|
|
x2[w2] = 0;
|
|
for (var E2 = 0; E2 < v2.length; E2++) a2 = v2[E2], x2[w2] += o2.attributes[w2](a2);
|
|
b2[w2] = x2[w2] / v2.length, u2 = b2[w2], c2 = m2[w2], d2 = o2.sensitivityThreshold, Math.abs(c2 - u2) <= d2 || (h2 = true);
|
|
}
|
|
n2[g2] = b2, s2[g2] = r2.collection(v2);
|
|
}
|
|
}
|
|
p2++;
|
|
}
|
|
return s2;
|
|
}, kMedoids: function(t2) {
|
|
var n2, r2, i2 = this.cy(), a2 = this.nodes(), o2 = null, s2 = Nn(t2), l2 = new Array(s2.k), u2 = {}, c2 = new Array(s2.k);
|
|
s2.testMode ? "number" == typeof s2.testCentroids || (n2 = "object" === e(s2.testCentroids) ? s2.testCentroids : Vn(a2, s2.k)) : n2 = Vn(a2, s2.k);
|
|
for (var d2 = true, h2 = 0; d2 && h2 < s2.maxIterations; ) {
|
|
for (var p2 = 0; p2 < a2.length; p2++) u2[(o2 = a2[p2]).id()] = Ln(o2, n2, s2.distance, s2.attributes, "kMedoids");
|
|
d2 = false;
|
|
for (var f2 = 0; f2 < n2.length; f2++) {
|
|
var g2 = An(f2, a2, u2);
|
|
if (0 !== g2.length) {
|
|
c2[f2] = Fn(n2[f2], g2, s2.attributes);
|
|
for (var v2 = 0; v2 < g2.length; v2++) (r2 = Fn(g2[v2], g2, s2.attributes)) < c2[f2] && (c2[f2] = r2, n2[f2] = g2[v2], d2 = true);
|
|
l2[f2] = i2.collection(g2);
|
|
}
|
|
}
|
|
h2++;
|
|
}
|
|
return l2;
|
|
}, fuzzyCMeans: Yn, fcm: Yn }, Wn = Xe({ distance: "euclidean", linkage: "min", mode: "threshold", threshold: 1 / 0, addDendrogram: false, dendrogramDepth: 0, attributes: [] }), Hn = { single: "min", complete: "max" }, Kn = function(e2, t2, n2, r2, i2) {
|
|
for (var a2, o2 = 0, s2 = 1 / 0, l2 = i2.attributes, u2 = function(e3, t3) {
|
|
return Mn(i2.distance, l2.length, function(t4) {
|
|
return l2[t4](e3);
|
|
}, function(e4) {
|
|
return l2[e4](t3);
|
|
}, e3, t3);
|
|
}, c2 = 0; c2 < e2.length; c2++) {
|
|
var d2 = e2[c2].key, h2 = n2[d2][r2[d2]];
|
|
h2 < s2 && (o2 = d2, s2 = h2);
|
|
}
|
|
if ("threshold" === i2.mode && s2 >= i2.threshold || "dendrogram" === i2.mode && 1 === e2.length) return false;
|
|
var p2, f2 = t2[o2], g2 = t2[r2[o2]];
|
|
p2 = "dendrogram" === i2.mode ? { left: f2, right: g2, key: f2.key } : { value: f2.value.concat(g2.value), key: f2.key }, e2[f2.index] = p2, e2.splice(g2.index, 1), t2[f2.key] = p2;
|
|
for (var v2 = 0; v2 < e2.length; v2++) {
|
|
var y2 = e2[v2];
|
|
f2.key === y2.key ? a2 = 1 / 0 : "min" === i2.linkage ? (a2 = n2[f2.key][y2.key], n2[f2.key][y2.key] > n2[g2.key][y2.key] && (a2 = n2[g2.key][y2.key])) : "max" === i2.linkage ? (a2 = n2[f2.key][y2.key], n2[f2.key][y2.key] < n2[g2.key][y2.key] && (a2 = n2[g2.key][y2.key])) : a2 = "mean" === i2.linkage ? (n2[f2.key][y2.key] * f2.size + n2[g2.key][y2.key] * g2.size) / (f2.size + g2.size) : "dendrogram" === i2.mode ? u2(y2.value, f2.value) : u2(y2.value[0], f2.value[0]), n2[f2.key][y2.key] = n2[y2.key][f2.key] = a2;
|
|
}
|
|
for (var m2 = 0; m2 < e2.length; m2++) {
|
|
var b2 = e2[m2].key;
|
|
if (r2[b2] === f2.key || r2[b2] === g2.key) {
|
|
for (var x2 = b2, w2 = 0; w2 < e2.length; w2++) {
|
|
var E2 = e2[w2].key;
|
|
n2[b2][E2] < n2[b2][x2] && (x2 = E2);
|
|
}
|
|
r2[b2] = x2;
|
|
}
|
|
e2[m2].index = m2;
|
|
}
|
|
return f2.key = g2.key = f2.index = g2.index = null, true;
|
|
}, Gn = function e2(t2, n2, r2) {
|
|
t2 && (t2.value ? n2.push(t2.value) : (t2.left && e2(t2.left, n2), t2.right && e2(t2.right, n2)));
|
|
}, Un = function(e2) {
|
|
for (var t2 = this.cy(), n2 = this.nodes(), r2 = function(e3) {
|
|
var t3 = Wn(e3), n3 = Hn[t3.linkage];
|
|
return null != n3 && (t3.linkage = n3), t3;
|
|
}(e2), i2 = r2.attributes, a2 = function(e3, t3) {
|
|
return Mn(r2.distance, i2.length, function(t4) {
|
|
return i2[t4](e3);
|
|
}, function(e4) {
|
|
return i2[e4](t3);
|
|
}, e3, t3);
|
|
}, o2 = [], s2 = [], l2 = [], u2 = [], c2 = 0; c2 < n2.length; c2++) {
|
|
var d2 = { value: "dendrogram" === r2.mode ? n2[c2] : [n2[c2]], key: c2, index: c2 };
|
|
o2[c2] = d2, u2[c2] = d2, s2[c2] = [], l2[c2] = 0;
|
|
}
|
|
for (var h2 = 0; h2 < o2.length; h2++) for (var p2 = 0; p2 <= h2; p2++) {
|
|
var f2 = void 0;
|
|
f2 = "dendrogram" === r2.mode ? h2 === p2 ? 1 / 0 : a2(o2[h2].value, o2[p2].value) : h2 === p2 ? 1 / 0 : a2(o2[h2].value[0], o2[p2].value[0]), s2[h2][p2] = f2, s2[p2][h2] = f2, f2 < s2[h2][l2[h2]] && (l2[h2] = p2);
|
|
}
|
|
for (var g2, v2 = Kn(o2, u2, s2, l2, r2); v2; ) v2 = Kn(o2, u2, s2, l2, r2);
|
|
return "dendrogram" === r2.mode ? (g2 = function e3(t3, n3, r3) {
|
|
if (!t3) return [];
|
|
var i3 = [], a3 = [], o3 = [];
|
|
return 0 === n3 ? (t3.left && Gn(t3.left, i3), t3.right && Gn(t3.right, a3), o3 = i3.concat(a3), [r3.collection(o3)]) : 1 === n3 ? t3.value ? [r3.collection(t3.value)] : (t3.left && Gn(t3.left, i3), t3.right && Gn(t3.right, a3), [r3.collection(i3), r3.collection(a3)]) : t3.value ? [r3.collection(t3.value)] : (t3.left && (i3 = e3(t3.left, n3 - 1, r3)), t3.right && (a3 = e3(t3.right, n3 - 1, r3)), i3.concat(a3));
|
|
}(o2[0], r2.dendrogramDepth, t2), r2.addDendrogram && function e3(t3, n3) {
|
|
if (!t3) return "";
|
|
if (t3.left && t3.right) {
|
|
var r3 = e3(t3.left, n3), i3 = e3(t3.right, n3), a3 = n3.add({ group: "nodes", data: { id: r3 + "," + i3 } });
|
|
return n3.add({ group: "edges", data: { source: r3, target: a3.id() } }), n3.add({ group: "edges", data: { source: i3, target: a3.id() } }), a3.id();
|
|
}
|
|
return t3.value ? t3.value.id() : void 0;
|
|
}(o2[0], t2)) : (g2 = new Array(o2.length), o2.forEach(function(e3, n3) {
|
|
e3.key = e3.index = null, g2[n3] = t2.collection(e3.value);
|
|
})), g2;
|
|
}, Zn = { hierarchicalClustering: Un, hca: Un }, $n = Xe({ distance: "euclidean", preference: "median", damping: 0.8, maxIterations: 1e3, minIterations: 100, attributes: [] }), Qn = function(e2, t2, n2, r2) {
|
|
var i2 = function(e3, t3) {
|
|
return r2[t3](e3);
|
|
};
|
|
return -Mn(e2, r2.length, function(e3) {
|
|
return i2(t2, e3);
|
|
}, function(e3) {
|
|
return i2(n2, e3);
|
|
}, t2, n2);
|
|
}, Jn = function(e2, t2) {
|
|
return "median" === t2 ? function(e3) {
|
|
var t3 = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : 0, n2 = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : e3.length, r2 = !(arguments.length > 3 && void 0 !== arguments[3]) || arguments[3], i2 = !(arguments.length > 4 && void 0 !== arguments[4]) || arguments[4], a2 = !(arguments.length > 5 && void 0 !== arguments[5]) || arguments[5];
|
|
r2 ? e3 = e3.slice(t3, n2) : (n2 < e3.length && e3.splice(n2, e3.length - n2), t3 > 0 && e3.splice(0, t3));
|
|
for (var o2 = 0, s2 = e3.length - 1; s2 >= 0; s2--) {
|
|
var l2 = e3[s2];
|
|
a2 ? isFinite(l2) || (e3[s2] = -1 / 0, o2++) : e3.splice(s2, 1);
|
|
}
|
|
i2 && e3.sort(function(e4, t4) {
|
|
return e4 - t4;
|
|
});
|
|
var u2 = e3.length, c2 = Math.floor(u2 / 2);
|
|
return u2 % 2 != 0 ? e3[c2 + 1 + o2] : (e3[c2 - 1 + o2] + e3[c2 + o2]) / 2;
|
|
}(e2) : "mean" === t2 ? function(e3) {
|
|
for (var t3 = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : 0, n2 = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : e3.length, r2 = 0, i2 = 0, a2 = t3; a2 < n2; a2++) {
|
|
var o2 = e3[a2];
|
|
isFinite(o2) && (r2 += o2, i2++);
|
|
}
|
|
return r2 / i2;
|
|
}(e2) : "min" === t2 ? function(e3) {
|
|
for (var t3 = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : 0, n2 = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : e3.length, r2 = 1 / 0, i2 = t3; i2 < n2; i2++) {
|
|
var a2 = e3[i2];
|
|
isFinite(a2) && (r2 = Math.min(a2, r2));
|
|
}
|
|
return r2;
|
|
}(e2) : "max" === t2 ? function(e3) {
|
|
for (var t3 = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : 0, n2 = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : e3.length, r2 = -1 / 0, i2 = t3; i2 < n2; i2++) {
|
|
var a2 = e3[i2];
|
|
isFinite(a2) && (r2 = Math.max(a2, r2));
|
|
}
|
|
return r2;
|
|
}(e2) : t2;
|
|
}, er = function(e2, t2, n2) {
|
|
for (var r2 = [], i2 = 0; i2 < e2; i2++) {
|
|
for (var a2 = -1, o2 = -1 / 0, s2 = 0; s2 < n2.length; s2++) {
|
|
var l2 = n2[s2];
|
|
t2[i2 * e2 + l2] > o2 && (a2 = l2, o2 = t2[i2 * e2 + l2]);
|
|
}
|
|
a2 > 0 && r2.push(a2);
|
|
}
|
|
for (var u2 = 0; u2 < n2.length; u2++) r2[n2[u2]] = n2[u2];
|
|
return r2;
|
|
}, tr = function(e2) {
|
|
for (var t2, n2, r2, i2, a2, o2, s2 = this.cy(), l2 = this.nodes(), u2 = function(e3) {
|
|
var t3 = e3.damping, n3 = e3.preference;
|
|
0.5 <= t3 && t3 < 1 || Oe("Damping must range on [0.5, 1). Got: ".concat(t3));
|
|
var r3 = ["median", "mean", "min", "max"];
|
|
return r3.some(function(e4) {
|
|
return e4 === n3;
|
|
}) || m(n3) || Oe("Preference must be one of [".concat(r3.map(function(e4) {
|
|
return "'".concat(e4, "'");
|
|
}).join(", "), "] or a number. Got: ").concat(n3)), $n(e3);
|
|
}(e2), c2 = {}, d2 = 0; d2 < l2.length; d2++) c2[l2[d2].id()] = d2;
|
|
n2 = (t2 = l2.length) * t2, r2 = new Array(n2);
|
|
for (var h2 = 0; h2 < n2; h2++) r2[h2] = -1 / 0;
|
|
for (var p2 = 0; p2 < t2; p2++) for (var f2 = 0; f2 < t2; f2++) p2 !== f2 && (r2[p2 * t2 + f2] = Qn(u2.distance, l2[p2], l2[f2], u2.attributes));
|
|
i2 = Jn(r2, u2.preference);
|
|
for (var g2 = 0; g2 < t2; g2++) r2[g2 * t2 + g2] = i2;
|
|
a2 = new Array(n2);
|
|
for (var v2 = 0; v2 < n2; v2++) a2[v2] = 0;
|
|
o2 = new Array(n2);
|
|
for (var y2 = 0; y2 < n2; y2++) o2[y2] = 0;
|
|
for (var b2 = new Array(t2), x2 = new Array(t2), w2 = new Array(t2), E2 = 0; E2 < t2; E2++) b2[E2] = 0, x2[E2] = 0, w2[E2] = 0;
|
|
for (var k2, C2 = new Array(t2 * u2.minIterations), S2 = 0; S2 < C2.length; S2++) C2[S2] = 0;
|
|
for (k2 = 0; k2 < u2.maxIterations; k2++) {
|
|
for (var P2 = 0; P2 < t2; P2++) {
|
|
for (var D2 = -1 / 0, T2 = -1 / 0, _2 = -1, M2 = 0, B2 = 0; B2 < t2; B2++) b2[B2] = a2[P2 * t2 + B2], (M2 = o2[P2 * t2 + B2] + r2[P2 * t2 + B2]) >= D2 ? (T2 = D2, D2 = M2, _2 = B2) : M2 > T2 && (T2 = M2);
|
|
for (var N2 = 0; N2 < t2; N2++) a2[P2 * t2 + N2] = (1 - u2.damping) * (r2[P2 * t2 + N2] - D2) + u2.damping * b2[N2];
|
|
a2[P2 * t2 + _2] = (1 - u2.damping) * (r2[P2 * t2 + _2] - T2) + u2.damping * b2[_2];
|
|
}
|
|
for (var z2 = 0; z2 < t2; z2++) {
|
|
for (var I2 = 0, L3 = 0; L3 < t2; L3++) b2[L3] = o2[L3 * t2 + z2], x2[L3] = Math.max(0, a2[L3 * t2 + z2]), I2 += x2[L3];
|
|
I2 -= x2[z2], x2[z2] = a2[z2 * t2 + z2], I2 += x2[z2];
|
|
for (var A2 = 0; A2 < t2; A2++) o2[A2 * t2 + z2] = (1 - u2.damping) * Math.min(0, I2 - x2[A2]) + u2.damping * b2[A2];
|
|
o2[z2 * t2 + z2] = (1 - u2.damping) * (I2 - x2[z2]) + u2.damping * b2[z2];
|
|
}
|
|
for (var O2 = 0, R2 = 0; R2 < t2; R2++) {
|
|
var V2 = o2[R2 * t2 + R2] + a2[R2 * t2 + R2] > 0 ? 1 : 0;
|
|
C2[k2 % u2.minIterations * t2 + R2] = V2, O2 += V2;
|
|
}
|
|
if (O2 > 0 && (k2 >= u2.minIterations - 1 || k2 == u2.maxIterations - 1)) {
|
|
for (var F2 = 0, j2 = 0; j2 < t2; j2++) {
|
|
w2[j2] = 0;
|
|
for (var q2 = 0; q2 < u2.minIterations; q2++) w2[j2] += C2[q2 * t2 + j2];
|
|
0 !== w2[j2] && w2[j2] !== u2.minIterations || F2++;
|
|
}
|
|
if (F2 === t2) break;
|
|
}
|
|
}
|
|
for (var Y2 = function(e3, t3, n3) {
|
|
for (var r3 = [], i3 = 0; i3 < e3; i3++) t3[i3 * e3 + i3] + n3[i3 * e3 + i3] > 0 && r3.push(i3);
|
|
return r3;
|
|
}(t2, a2, o2), X2 = function(e3, t3, n3) {
|
|
for (var r3 = er(e3, t3, n3), i3 = 0; i3 < n3.length; i3++) {
|
|
for (var a3 = [], o3 = 0; o3 < r3.length; o3++) r3[o3] === n3[i3] && a3.push(o3);
|
|
for (var s3 = -1, l3 = -1 / 0, u3 = 0; u3 < a3.length; u3++) {
|
|
for (var c3 = 0, d3 = 0; d3 < a3.length; d3++) c3 += t3[a3[d3] * e3 + a3[u3]];
|
|
c3 > l3 && (s3 = u3, l3 = c3);
|
|
}
|
|
n3[i3] = a3[s3];
|
|
}
|
|
return r3 = er(e3, t3, n3);
|
|
}(t2, r2, Y2), W2 = {}, H2 = 0; H2 < Y2.length; H2++) W2[Y2[H2]] = [];
|
|
for (var K2 = 0; K2 < l2.length; K2++) {
|
|
var G2 = X2[c2[l2[K2].id()]];
|
|
null != G2 && W2[G2].push(l2[K2]);
|
|
}
|
|
for (var U2 = new Array(Y2.length), Z2 = 0; Z2 < Y2.length; Z2++) U2[Z2] = s2.collection(W2[Y2[Z2]]);
|
|
return U2;
|
|
}, nr = { affinityPropagation: tr, ap: tr }, rr = Xe({ root: void 0, directed: false }), ir = function() {
|
|
var e2 = this, t2 = {}, n2 = 0, r2 = 0, i2 = [], a2 = [], o2 = {}, s2 = function s3(l3, u2, c2) {
|
|
l3 === c2 && (r2 += 1), t2[u2] = { id: n2, low: n2++, cutVertex: false };
|
|
var d2, h2, p2, f2, g2 = e2.getElementById(u2).connectedEdges().intersection(e2);
|
|
0 === g2.size() ? i2.push(e2.spawn(e2.getElementById(u2))) : g2.forEach(function(n3) {
|
|
d2 = n3.source().id(), h2 = n3.target().id(), (p2 = d2 === u2 ? h2 : d2) !== c2 && (f2 = n3.id(), o2[f2] || (o2[f2] = true, a2.push({ x: u2, y: p2, edge: n3 })), p2 in t2 ? t2[u2].low = Math.min(t2[u2].low, t2[p2].id) : (s3(l3, p2, u2), t2[u2].low = Math.min(t2[u2].low, t2[p2].low), t2[u2].id <= t2[p2].low && (t2[u2].cutVertex = true, function(n4, r3) {
|
|
for (var o3 = a2.length - 1, s4 = [], l4 = e2.spawn(); a2[o3].x != n4 || a2[o3].y != r3; ) s4.push(a2.pop().edge), o3--;
|
|
s4.push(a2.pop().edge), s4.forEach(function(n5) {
|
|
var r4 = n5.connectedNodes().intersection(e2);
|
|
l4.merge(n5), r4.forEach(function(n6) {
|
|
var r5 = n6.id(), i3 = n6.connectedEdges().intersection(e2);
|
|
l4.merge(n6), t2[r5].cutVertex ? l4.merge(i3.filter(function(e3) {
|
|
return e3.isLoop();
|
|
})) : l4.merge(i3);
|
|
});
|
|
}), i2.push(l4);
|
|
}(u2, p2))));
|
|
});
|
|
};
|
|
e2.forEach(function(e3) {
|
|
if (e3.isNode()) {
|
|
var n3 = e3.id();
|
|
n3 in t2 || (r2 = 0, s2(n3, n3), t2[n3].cutVertex = r2 > 1);
|
|
}
|
|
});
|
|
var l2 = Object.keys(t2).filter(function(e3) {
|
|
return t2[e3].cutVertex;
|
|
}).map(function(t3) {
|
|
return e2.getElementById(t3);
|
|
});
|
|
return { cut: e2.spawn(l2), components: i2 };
|
|
}, ar = function() {
|
|
var e2 = this, t2 = {}, n2 = 0, r2 = [], i2 = [], a2 = e2.spawn(e2);
|
|
return e2.forEach(function(o2) {
|
|
if (o2.isNode()) {
|
|
var s2 = o2.id();
|
|
s2 in t2 || function o3(s3) {
|
|
if (i2.push(s3), t2[s3] = { index: n2, low: n2++, explored: false }, e2.getElementById(s3).connectedEdges().intersection(e2).forEach(function(e3) {
|
|
var n3 = e3.target().id();
|
|
n3 !== s3 && (n3 in t2 || o3(n3), t2[n3].explored || (t2[s3].low = Math.min(t2[s3].low, t2[n3].low)));
|
|
}), t2[s3].index === t2[s3].low) {
|
|
for (var l2 = e2.spawn(); ; ) {
|
|
var u2 = i2.pop();
|
|
if (l2.merge(e2.getElementById(u2)), t2[u2].low = t2[s3].index, t2[u2].explored = true, u2 === s3) break;
|
|
}
|
|
var c2 = l2.edgesWith(l2), d2 = l2.merge(c2);
|
|
r2.push(d2), a2 = a2.difference(d2);
|
|
}
|
|
}(s2);
|
|
}
|
|
}), { cut: a2, components: r2 };
|
|
}, or = {};
|
|
[et, rt, it, ot, lt, ct, ft, an, sn, un, dn, wn, Xn, Zn, nr, { hierholzer: function(e2) {
|
|
if (!y(e2)) {
|
|
var t2 = arguments;
|
|
e2 = { root: t2[0], directed: t2[1] };
|
|
}
|
|
var n2, r2, i2, a2 = rr(e2), o2 = a2.root, s2 = a2.directed, l2 = this, u2 = false;
|
|
o2 && (i2 = f(o2) ? this.filter(o2)[0].id() : o2[0].id());
|
|
var c2 = {}, d2 = {};
|
|
s2 ? l2.forEach(function(e3) {
|
|
var t3 = e3.id();
|
|
if (e3.isNode()) {
|
|
var i3 = e3.indegree(true), a3 = e3.outdegree(true), o3 = i3 - a3, s3 = a3 - i3;
|
|
1 == o3 ? n2 ? u2 = true : n2 = t3 : 1 == s3 ? r2 ? u2 = true : r2 = t3 : (s3 > 1 || o3 > 1) && (u2 = true), c2[t3] = [], e3.outgoers().forEach(function(e4) {
|
|
e4.isEdge() && c2[t3].push(e4.id());
|
|
});
|
|
} else d2[t3] = [void 0, e3.target().id()];
|
|
}) : l2.forEach(function(e3) {
|
|
var t3 = e3.id();
|
|
e3.isNode() ? (e3.degree(true) % 2 && (n2 ? r2 ? u2 = true : r2 = t3 : n2 = t3), c2[t3] = [], e3.connectedEdges().forEach(function(e4) {
|
|
return c2[t3].push(e4.id());
|
|
})) : d2[t3] = [e3.source().id(), e3.target().id()];
|
|
});
|
|
var h2 = { found: false, trail: void 0 };
|
|
if (u2) return h2;
|
|
if (r2 && n2) if (s2) {
|
|
if (i2 && r2 != i2) return h2;
|
|
i2 = r2;
|
|
} else {
|
|
if (i2 && r2 != i2 && n2 != i2) return h2;
|
|
i2 || (i2 = r2);
|
|
}
|
|
else i2 || (i2 = l2[0].id());
|
|
var p2 = function(e3) {
|
|
for (var t3, n3, r3, i3 = e3, a3 = [e3]; c2[i3].length; ) t3 = c2[i3].shift(), n3 = d2[t3][0], i3 != (r3 = d2[t3][1]) ? (c2[r3] = c2[r3].filter(function(e4) {
|
|
return e4 != t3;
|
|
}), i3 = r3) : s2 || i3 == n3 || (c2[n3] = c2[n3].filter(function(e4) {
|
|
return e4 != t3;
|
|
}), i3 = n3), a3.unshift(t3), a3.unshift(i3);
|
|
return a3;
|
|
}, g2 = [], v2 = [];
|
|
for (v2 = p2(i2); 1 != v2.length; ) 0 == c2[v2[0]].length ? (g2.unshift(l2.getElementById(v2.shift())), g2.unshift(l2.getElementById(v2.shift()))) : v2 = p2(v2.shift()).concat(v2);
|
|
for (var m2 in g2.unshift(l2.getElementById(v2.shift())), c2) if (c2[m2].length) return h2;
|
|
return h2.found = true, h2.trail = this.spawn(g2, true), h2;
|
|
} }, { hopcroftTarjanBiconnected: ir, htbc: ir, htb: ir, hopcroftTarjanBiconnectedComponents: ir }, { tarjanStronglyConnected: ar, tsc: ar, tscc: ar, tarjanStronglyConnectedComponents: ar }].forEach(function(e2) {
|
|
I(or, e2);
|
|
});
|
|
var sr = function e2(t2) {
|
|
if (!(this instanceof e2)) return new e2(t2);
|
|
this.id = "Thenable/1.0.7", this.state = 0, this.fulfillValue = void 0, this.rejectReason = void 0, this.onFulfilled = [], this.onRejected = [], this.proxy = { then: this.then.bind(this) }, "function" == typeof t2 && t2.call(this, this.fulfill.bind(this), this.reject.bind(this));
|
|
};
|
|
sr.prototype = { fulfill: function(e2) {
|
|
return lr(this, 1, "fulfillValue", e2);
|
|
}, reject: function(e2) {
|
|
return lr(this, 2, "rejectReason", e2);
|
|
}, then: function(e2, t2) {
|
|
var n2 = new sr();
|
|
return this.onFulfilled.push(dr(e2, n2, "fulfill")), this.onRejected.push(dr(t2, n2, "reject")), ur(this), n2.proxy;
|
|
} };
|
|
var lr = function(e2, t2, n2, r2) {
|
|
return 0 === e2.state && (e2.state = t2, e2[n2] = r2, ur(e2)), e2;
|
|
}, ur = function(e2) {
|
|
1 === e2.state ? cr(e2, "onFulfilled", e2.fulfillValue) : 2 === e2.state && cr(e2, "onRejected", e2.rejectReason);
|
|
}, cr = function(e2, t2, n2) {
|
|
if (0 !== e2[t2].length) {
|
|
var r2 = e2[t2];
|
|
e2[t2] = [];
|
|
var i2 = function() {
|
|
for (var e3 = 0; e3 < r2.length; e3++) r2[e3](n2);
|
|
};
|
|
"function" == typeof setImmediate ? setImmediate(i2) : setTimeout(i2, 0);
|
|
}
|
|
}, dr = function(e2, t2, n2) {
|
|
return function(r2) {
|
|
if ("function" != typeof e2) t2[n2].call(t2, r2);
|
|
else {
|
|
var i2;
|
|
try {
|
|
i2 = e2(r2);
|
|
} catch (e3) {
|
|
return void t2.reject(e3);
|
|
}
|
|
hr(t2, i2);
|
|
}
|
|
};
|
|
}, hr = function t2(n2, r2) {
|
|
if (n2 !== r2 && n2.proxy !== r2) {
|
|
var i2;
|
|
if ("object" === e(r2) && null !== r2 || "function" == typeof r2) try {
|
|
i2 = r2.then;
|
|
} catch (e2) {
|
|
return void n2.reject(e2);
|
|
}
|
|
if ("function" != typeof i2) n2.fulfill(r2);
|
|
else {
|
|
var a2 = false;
|
|
try {
|
|
i2.call(r2, function(e2) {
|
|
a2 || (a2 = true, e2 === r2 ? n2.reject(new TypeError("circular thenable chain")) : t2(n2, e2));
|
|
}, function(e2) {
|
|
a2 || (a2 = true, n2.reject(e2));
|
|
});
|
|
} catch (e2) {
|
|
a2 || n2.reject(e2);
|
|
}
|
|
}
|
|
} else n2.reject(new TypeError("cannot resolve promise with itself"));
|
|
};
|
|
sr.all = function(e2) {
|
|
return new sr(function(t2, n2) {
|
|
for (var r2 = new Array(e2.length), i2 = 0, a2 = function(n3, a3) {
|
|
r2[n3] = a3, ++i2 === e2.length && t2(r2);
|
|
}, o2 = 0; o2 < e2.length; o2++) !function(t3) {
|
|
var r3 = e2[t3];
|
|
null != r3 && null != r3.then ? r3.then(function(e3) {
|
|
a2(t3, e3);
|
|
}, function(e3) {
|
|
n2(e3);
|
|
}) : a2(t3, r3);
|
|
}(o2);
|
|
});
|
|
}, sr.resolve = function(e2) {
|
|
return new sr(function(t2, n2) {
|
|
t2(e2);
|
|
});
|
|
}, sr.reject = function(e2) {
|
|
return new sr(function(t2, n2) {
|
|
n2(e2);
|
|
});
|
|
};
|
|
var pr = "undefined" != typeof Promise ? Promise : sr, fr = function(e2, t2, n2) {
|
|
var r2 = k(e2), i2 = !r2, a2 = this._private = I({ duration: 1e3 }, t2, n2);
|
|
if (a2.target = e2, a2.style = a2.style || a2.css, a2.started = false, a2.playing = false, a2.hooked = false, a2.applying = false, a2.progress = 0, a2.completes = [], a2.frames = [], a2.complete && g(a2.complete) && a2.completes.push(a2.complete), i2) {
|
|
var o2 = e2.position();
|
|
a2.startPosition = a2.startPosition || { x: o2.x, y: o2.y }, a2.startStyle = a2.startStyle || e2.cy().style().getAnimationStartStyle(e2, a2.style);
|
|
}
|
|
if (r2) {
|
|
var s2 = e2.pan();
|
|
a2.startPan = { x: s2.x, y: s2.y }, a2.startZoom = e2.zoom();
|
|
}
|
|
this.length = 1, this[0] = this;
|
|
}, gr = fr.prototype;
|
|
I(gr, { instanceString: function() {
|
|
return "animation";
|
|
}, hook: function() {
|
|
var e2 = this._private;
|
|
if (!e2.hooked) {
|
|
var t2 = e2.target._private.animation;
|
|
(e2.queue ? t2.queue : t2.current).push(this), x(e2.target) && e2.target.cy().addToAnimationPool(e2.target), e2.hooked = true;
|
|
}
|
|
return this;
|
|
}, play: function() {
|
|
var e2 = this._private;
|
|
return 1 === e2.progress && (e2.progress = 0), e2.playing = true, e2.started = false, e2.stopped = false, this.hook(), this;
|
|
}, playing: function() {
|
|
return this._private.playing;
|
|
}, apply: function() {
|
|
var e2 = this._private;
|
|
return e2.applying = true, e2.started = false, e2.stopped = false, this.hook(), this;
|
|
}, applying: function() {
|
|
return this._private.applying;
|
|
}, pause: function() {
|
|
var e2 = this._private;
|
|
return e2.playing = false, e2.started = false, this;
|
|
}, stop: function() {
|
|
var e2 = this._private;
|
|
return e2.playing = false, e2.started = false, e2.stopped = true, this;
|
|
}, rewind: function() {
|
|
return this.progress(0);
|
|
}, fastforward: function() {
|
|
return this.progress(1);
|
|
}, time: function(e2) {
|
|
var t2 = this._private;
|
|
return void 0 === e2 ? t2.progress * t2.duration : this.progress(e2 / t2.duration);
|
|
}, progress: function(e2) {
|
|
var t2 = this._private, n2 = t2.playing;
|
|
return void 0 === e2 ? t2.progress : (n2 && this.pause(), t2.progress = e2, t2.started = false, n2 && this.play(), this);
|
|
}, completed: function() {
|
|
return 1 === this._private.progress;
|
|
}, reverse: function() {
|
|
var e2 = this._private, t2 = e2.playing;
|
|
t2 && this.pause(), e2.progress = 1 - e2.progress, e2.started = false;
|
|
var n2 = function(t3, n3) {
|
|
var r3 = e2[t3];
|
|
null != r3 && (e2[t3] = e2[n3], e2[n3] = r3);
|
|
};
|
|
if (n2("zoom", "startZoom"), n2("pan", "startPan"), n2("position", "startPosition"), e2.style) for (var r2 = 0; r2 < e2.style.length; r2++) {
|
|
var i2 = e2.style[r2], a2 = i2.name, o2 = e2.startStyle[a2];
|
|
e2.startStyle[a2] = i2, e2.style[r2] = o2;
|
|
}
|
|
return t2 && this.play(), this;
|
|
}, promise: function(e2) {
|
|
var t2, n2 = this._private;
|
|
switch (e2) {
|
|
case "frame":
|
|
t2 = n2.frames;
|
|
break;
|
|
default:
|
|
case "complete":
|
|
case "completed":
|
|
t2 = n2.completes;
|
|
}
|
|
return new pr(function(e3, n3) {
|
|
t2.push(function() {
|
|
e3();
|
|
});
|
|
});
|
|
} }), gr.complete = gr.completed, gr.run = gr.play, gr.running = gr.playing;
|
|
var vr = { animated: function() {
|
|
return function() {
|
|
var e2 = void 0 !== this.length ? this : [this];
|
|
if (!(this._private.cy || this).styleEnabled()) return false;
|
|
var t2 = e2[0];
|
|
return t2 ? t2._private.animation.current.length > 0 : void 0;
|
|
};
|
|
}, clearQueue: function() {
|
|
return function() {
|
|
var e2 = void 0 !== this.length ? this : [this];
|
|
if (!(this._private.cy || this).styleEnabled()) return this;
|
|
for (var t2 = 0; t2 < e2.length; t2++) {
|
|
e2[t2]._private.animation.queue = [];
|
|
}
|
|
return this;
|
|
};
|
|
}, delay: function() {
|
|
return function(e2, t2) {
|
|
return (this._private.cy || this).styleEnabled() ? this.animate({ delay: e2, duration: e2, complete: t2 }) : this;
|
|
};
|
|
}, delayAnimation: function() {
|
|
return function(e2, t2) {
|
|
return (this._private.cy || this).styleEnabled() ? this.animation({ delay: e2, duration: e2, complete: t2 }) : this;
|
|
};
|
|
}, animation: function() {
|
|
return function(e2, t2) {
|
|
var n2 = void 0 !== this.length, r2 = n2 ? this : [this], i2 = this._private.cy || this, a2 = !n2, o2 = !a2;
|
|
if (!i2.styleEnabled()) return this;
|
|
var s2 = i2.style();
|
|
if (e2 = I({}, e2, t2), 0 === Object.keys(e2).length) return new fr(r2[0], e2);
|
|
switch (void 0 === e2.duration && (e2.duration = 400), e2.duration) {
|
|
case "slow":
|
|
e2.duration = 600;
|
|
break;
|
|
case "fast":
|
|
e2.duration = 200;
|
|
}
|
|
if (o2 && (e2.style = s2.getPropsList(e2.style || e2.css), e2.css = void 0), o2 && null != e2.renderedPosition) {
|
|
var l2 = e2.renderedPosition, u2 = i2.pan(), c2 = i2.zoom();
|
|
e2.position = vt(l2, c2, u2);
|
|
}
|
|
if (a2 && null != e2.panBy) {
|
|
var d2 = e2.panBy, h2 = i2.pan();
|
|
e2.pan = { x: h2.x + d2.x, y: h2.y + d2.y };
|
|
}
|
|
var p2 = e2.center || e2.centre;
|
|
if (a2 && null != p2) {
|
|
var f2 = i2.getCenterPan(p2.eles, e2.zoom);
|
|
null != f2 && (e2.pan = f2);
|
|
}
|
|
if (a2 && null != e2.fit) {
|
|
var g2 = e2.fit, v2 = i2.getFitViewport(g2.eles || g2.boundingBox, g2.padding);
|
|
null != v2 && (e2.pan = v2.pan, e2.zoom = v2.zoom);
|
|
}
|
|
if (a2 && y(e2.zoom)) {
|
|
var m2 = i2.getZoomedViewport(e2.zoom);
|
|
null != m2 ? (m2.zoomed && (e2.zoom = m2.zoom), m2.panned && (e2.pan = m2.pan)) : e2.zoom = null;
|
|
}
|
|
return new fr(r2[0], e2);
|
|
};
|
|
}, animate: function() {
|
|
return function(e2, t2) {
|
|
var n2 = void 0 !== this.length ? this : [this];
|
|
if (!(this._private.cy || this).styleEnabled()) return this;
|
|
t2 && (e2 = I({}, e2, t2));
|
|
for (var r2 = 0; r2 < n2.length; r2++) {
|
|
var i2 = n2[r2], a2 = i2.animated() && (void 0 === e2.queue || e2.queue);
|
|
i2.animation(e2, a2 ? { queue: true } : void 0).play();
|
|
}
|
|
return this;
|
|
};
|
|
}, stop: function() {
|
|
return function(e2, t2) {
|
|
var n2 = void 0 !== this.length ? this : [this], r2 = this._private.cy || this;
|
|
if (!r2.styleEnabled()) return this;
|
|
for (var i2 = 0; i2 < n2.length; i2++) {
|
|
for (var a2 = n2[i2]._private, o2 = a2.animation.current, s2 = 0; s2 < o2.length; s2++) {
|
|
var l2 = o2[s2]._private;
|
|
t2 && (l2.duration = 0);
|
|
}
|
|
e2 && (a2.animation.queue = []), t2 || (a2.animation.current = []);
|
|
}
|
|
return r2.notify("draw"), this;
|
|
};
|
|
} }, yr = Array.isArray, mr = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, br = /^\w*$/;
|
|
var xr = function(e2, t2) {
|
|
if (yr(e2)) return false;
|
|
var n2 = typeof e2;
|
|
return !("number" != n2 && "symbol" != n2 && "boolean" != n2 && null != e2 && !oe(e2)) || (br.test(e2) || !mr.test(e2) || null != t2 && e2 in Object(t2));
|
|
};
|
|
var wr, Er = function(e2) {
|
|
if (!V(e2)) return false;
|
|
var t2 = ie(e2);
|
|
return "[object Function]" == t2 || "[object GeneratorFunction]" == t2 || "[object AsyncFunction]" == t2 || "[object Proxy]" == t2;
|
|
}, kr = Y["__core-js_shared__"], Cr = (wr = /[^.]+$/.exec(kr && kr.keys && kr.keys.IE_PROTO || "")) ? "Symbol(src)_1." + wr : "";
|
|
var Sr = function(e2) {
|
|
return !!Cr && Cr in e2;
|
|
}, Pr = Function.prototype.toString;
|
|
var Dr = function(e2) {
|
|
if (null != e2) {
|
|
try {
|
|
return Pr.call(e2);
|
|
} catch (e3) {
|
|
}
|
|
try {
|
|
return e2 + "";
|
|
} catch (e3) {
|
|
}
|
|
}
|
|
return "";
|
|
}, Tr = /^\[object .+?Constructor\]$/, _r = Function.prototype, Mr = Object.prototype, Br = _r.toString, Nr = Mr.hasOwnProperty, zr = RegExp("^" + Br.call(Nr).replace(/[\\^$.*+?()[\]{}|]/g, "\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, "$1.*?") + "$");
|
|
var Ir = function(e2) {
|
|
return !(!V(e2) || Sr(e2)) && (Er(e2) ? zr : Tr).test(Dr(e2));
|
|
};
|
|
var Lr = function(e2, t2) {
|
|
return null == e2 ? void 0 : e2[t2];
|
|
};
|
|
var Ar = function(e2, t2) {
|
|
var n2 = Lr(e2, t2);
|
|
return Ir(n2) ? n2 : void 0;
|
|
}, Or = Ar(Object, "create");
|
|
var Rr = function() {
|
|
this.__data__ = Or ? Or(null) : {}, this.size = 0;
|
|
};
|
|
var Vr = function(e2) {
|
|
var t2 = this.has(e2) && delete this.__data__[e2];
|
|
return this.size -= t2 ? 1 : 0, t2;
|
|
}, Fr = Object.prototype.hasOwnProperty;
|
|
var jr = function(e2) {
|
|
var t2 = this.__data__;
|
|
if (Or) {
|
|
var n2 = t2[e2];
|
|
return "__lodash_hash_undefined__" === n2 ? void 0 : n2;
|
|
}
|
|
return Fr.call(t2, e2) ? t2[e2] : void 0;
|
|
}, qr = Object.prototype.hasOwnProperty;
|
|
var Yr = function(e2) {
|
|
var t2 = this.__data__;
|
|
return Or ? void 0 !== t2[e2] : qr.call(t2, e2);
|
|
};
|
|
var Xr = function(e2, t2) {
|
|
var n2 = this.__data__;
|
|
return this.size += this.has(e2) ? 0 : 1, n2[e2] = Or && void 0 === t2 ? "__lodash_hash_undefined__" : t2, this;
|
|
};
|
|
function Wr(e2) {
|
|
var t2 = -1, n2 = null == e2 ? 0 : e2.length;
|
|
for (this.clear(); ++t2 < n2; ) {
|
|
var r2 = e2[t2];
|
|
this.set(r2[0], r2[1]);
|
|
}
|
|
}
|
|
Wr.prototype.clear = Rr, Wr.prototype.delete = Vr, Wr.prototype.get = jr, Wr.prototype.has = Yr, Wr.prototype.set = Xr;
|
|
var Hr = Wr;
|
|
var Kr = function() {
|
|
this.__data__ = [], this.size = 0;
|
|
};
|
|
var Gr = function(e2, t2) {
|
|
return e2 === t2 || e2 != e2 && t2 != t2;
|
|
};
|
|
var Ur = function(e2, t2) {
|
|
for (var n2 = e2.length; n2--; ) if (Gr(e2[n2][0], t2)) return n2;
|
|
return -1;
|
|
}, Zr = Array.prototype.splice;
|
|
var $r = function(e2) {
|
|
var t2 = this.__data__, n2 = Ur(t2, e2);
|
|
return !(n2 < 0) && (n2 == t2.length - 1 ? t2.pop() : Zr.call(t2, n2, 1), --this.size, true);
|
|
};
|
|
var Qr = function(e2) {
|
|
var t2 = this.__data__, n2 = Ur(t2, e2);
|
|
return n2 < 0 ? void 0 : t2[n2][1];
|
|
};
|
|
var Jr = function(e2) {
|
|
return Ur(this.__data__, e2) > -1;
|
|
};
|
|
var ei = function(e2, t2) {
|
|
var n2 = this.__data__, r2 = Ur(n2, e2);
|
|
return r2 < 0 ? (++this.size, n2.push([e2, t2])) : n2[r2][1] = t2, this;
|
|
};
|
|
function ti(e2) {
|
|
var t2 = -1, n2 = null == e2 ? 0 : e2.length;
|
|
for (this.clear(); ++t2 < n2; ) {
|
|
var r2 = e2[t2];
|
|
this.set(r2[0], r2[1]);
|
|
}
|
|
}
|
|
ti.prototype.clear = Kr, ti.prototype.delete = $r, ti.prototype.get = Qr, ti.prototype.has = Jr, ti.prototype.set = ei;
|
|
var ni = ti, ri = Ar(Y, "Map");
|
|
var ii = function() {
|
|
this.size = 0, this.__data__ = { hash: new Hr(), map: new (ri || ni)(), string: new Hr() };
|
|
};
|
|
var ai = function(e2) {
|
|
var t2 = typeof e2;
|
|
return "string" == t2 || "number" == t2 || "symbol" == t2 || "boolean" == t2 ? "__proto__" !== e2 : null === e2;
|
|
};
|
|
var oi = function(e2, t2) {
|
|
var n2 = e2.__data__;
|
|
return ai(t2) ? n2["string" == typeof t2 ? "string" : "hash"] : n2.map;
|
|
};
|
|
var si = function(e2) {
|
|
var t2 = oi(this, e2).delete(e2);
|
|
return this.size -= t2 ? 1 : 0, t2;
|
|
};
|
|
var li = function(e2) {
|
|
return oi(this, e2).get(e2);
|
|
};
|
|
var ui = function(e2) {
|
|
return oi(this, e2).has(e2);
|
|
};
|
|
var ci = function(e2, t2) {
|
|
var n2 = oi(this, e2), r2 = n2.size;
|
|
return n2.set(e2, t2), this.size += n2.size == r2 ? 0 : 1, this;
|
|
};
|
|
function di(e2) {
|
|
var t2 = -1, n2 = null == e2 ? 0 : e2.length;
|
|
for (this.clear(); ++t2 < n2; ) {
|
|
var r2 = e2[t2];
|
|
this.set(r2[0], r2[1]);
|
|
}
|
|
}
|
|
di.prototype.clear = ii, di.prototype.delete = si, di.prototype.get = li, di.prototype.has = ui, di.prototype.set = ci;
|
|
var hi = di;
|
|
function pi(e2, t2) {
|
|
if ("function" != typeof e2 || null != t2 && "function" != typeof t2) throw new TypeError("Expected a function");
|
|
var n2 = function() {
|
|
var r2 = arguments, i2 = t2 ? t2.apply(this, r2) : r2[0], a2 = n2.cache;
|
|
if (a2.has(i2)) return a2.get(i2);
|
|
var o2 = e2.apply(this, r2);
|
|
return n2.cache = a2.set(i2, o2) || a2, o2;
|
|
};
|
|
return n2.cache = new (pi.Cache || hi)(), n2;
|
|
}
|
|
pi.Cache = hi;
|
|
var fi = pi;
|
|
var gi = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g, vi = /\\(\\)?/g, yi = function(e2) {
|
|
var t2 = fi(e2, function(e3) {
|
|
return 500 === n2.size && n2.clear(), e3;
|
|
}), n2 = t2.cache;
|
|
return t2;
|
|
}(function(e2) {
|
|
var t2 = [];
|
|
return 46 === e2.charCodeAt(0) && t2.push(""), e2.replace(gi, function(e3, n2, r2, i2) {
|
|
t2.push(r2 ? i2.replace(vi, "$1") : n2 || e3);
|
|
}), t2;
|
|
});
|
|
var mi = function(e2, t2) {
|
|
for (var n2 = -1, r2 = null == e2 ? 0 : e2.length, i2 = Array(r2); ++n2 < r2; ) i2[n2] = t2(e2[n2], n2, e2);
|
|
return i2;
|
|
}, bi = U ? U.prototype : void 0, xi = bi ? bi.toString : void 0;
|
|
var wi = function e2(t2) {
|
|
if ("string" == typeof t2) return t2;
|
|
if (yr(t2)) return mi(t2, e2) + "";
|
|
if (oe(t2)) return xi ? xi.call(t2) : "";
|
|
var n2 = t2 + "";
|
|
return "0" == n2 && 1 / t2 == -1 / 0 ? "-0" : n2;
|
|
};
|
|
var Ei = function(e2) {
|
|
return null == e2 ? "" : wi(e2);
|
|
};
|
|
var ki = function(e2, t2) {
|
|
return yr(e2) ? e2 : xr(e2, t2) ? [e2] : yi(Ei(e2));
|
|
};
|
|
var Ci = function(e2) {
|
|
if ("string" == typeof e2 || oe(e2)) return e2;
|
|
var t2 = e2 + "";
|
|
return "0" == t2 && 1 / e2 == -1 / 0 ? "-0" : t2;
|
|
};
|
|
var Si = function(e2, t2) {
|
|
for (var n2 = 0, r2 = (t2 = ki(t2, e2)).length; null != e2 && n2 < r2; ) e2 = e2[Ci(t2[n2++])];
|
|
return n2 && n2 == r2 ? e2 : void 0;
|
|
};
|
|
var Pi = function(e2, t2, n2) {
|
|
var r2 = null == e2 ? void 0 : Si(e2, t2);
|
|
return void 0 === r2 ? n2 : r2;
|
|
}, Di = function() {
|
|
try {
|
|
var e2 = Ar(Object, "defineProperty");
|
|
return e2({}, "", {}), e2;
|
|
} catch (e3) {
|
|
}
|
|
}();
|
|
var Ti = function(e2, t2, n2) {
|
|
"__proto__" == t2 && Di ? Di(e2, t2, { configurable: true, enumerable: true, value: n2, writable: true }) : e2[t2] = n2;
|
|
}, _i = Object.prototype.hasOwnProperty;
|
|
var Mi = function(e2, t2, n2) {
|
|
var r2 = e2[t2];
|
|
_i.call(e2, t2) && Gr(r2, n2) && (void 0 !== n2 || t2 in e2) || Ti(e2, t2, n2);
|
|
}, Bi = /^(?:0|[1-9]\d*)$/;
|
|
var Ni = function(e2, t2) {
|
|
var n2 = typeof e2;
|
|
return !!(t2 = null == t2 ? 9007199254740991 : t2) && ("number" == n2 || "symbol" != n2 && Bi.test(e2)) && e2 > -1 && e2 % 1 == 0 && e2 < t2;
|
|
};
|
|
var zi = function(e2, t2, n2, r2) {
|
|
if (!V(e2)) return e2;
|
|
for (var i2 = -1, a2 = (t2 = ki(t2, e2)).length, o2 = a2 - 1, s2 = e2; null != s2 && ++i2 < a2; ) {
|
|
var l2 = Ci(t2[i2]), u2 = n2;
|
|
if ("__proto__" === l2 || "constructor" === l2 || "prototype" === l2) return e2;
|
|
if (i2 != o2) {
|
|
var c2 = s2[l2];
|
|
void 0 === (u2 = r2 ? r2(c2, l2, s2) : void 0) && (u2 = V(c2) ? c2 : Ni(t2[i2 + 1]) ? [] : {});
|
|
}
|
|
Mi(s2, l2, u2), s2 = s2[l2];
|
|
}
|
|
return e2;
|
|
};
|
|
var Ii = function(e2, t2, n2) {
|
|
return null == e2 ? e2 : zi(e2, t2, n2);
|
|
};
|
|
var Li = function(e2, t2) {
|
|
var n2 = -1, r2 = e2.length;
|
|
for (t2 || (t2 = Array(r2)); ++n2 < r2; ) t2[n2] = e2[n2];
|
|
return t2;
|
|
};
|
|
var Ai = function(e2) {
|
|
return yr(e2) ? mi(e2, Ci) : oe(e2) ? [e2] : Li(yi(Ei(e2)));
|
|
}, Oi = {};
|
|
[vr, { data: function(e2) {
|
|
return e2 = I({}, { field: "data", bindingEvent: "data", allowBinding: false, allowSetting: false, allowGetting: false, settingEvent: "data", settingTriggersEvent: false, triggerFnName: "trigger", immutableKeys: {}, updateStyle: false, beforeGet: function(e3) {
|
|
}, beforeSet: function(e3, t2) {
|
|
}, onSet: function(e3) {
|
|
}, canSet: function(e3) {
|
|
return true;
|
|
} }, e2), function(t2, n2) {
|
|
var r2 = e2, a2 = void 0 !== this.length, o2 = a2 ? this : [this], s2 = a2 ? this[0] : this;
|
|
if (f(t2)) {
|
|
var l2, u2 = -1 !== t2.indexOf(".") && Ai(t2);
|
|
if (r2.allowGetting && void 0 === n2) return s2 && (r2.beforeGet(s2), l2 = u2 && void 0 === s2._private[r2.field][t2] ? Pi(s2._private[r2.field], u2) : s2._private[r2.field][t2]), l2;
|
|
if (r2.allowSetting && void 0 !== n2 && !r2.immutableKeys[t2]) {
|
|
var c2 = i({}, t2, n2);
|
|
r2.beforeSet(this, c2);
|
|
for (var d2 = 0, h2 = o2.length; d2 < h2; d2++) {
|
|
var p2 = o2[d2];
|
|
r2.canSet(p2) && (u2 && void 0 === s2._private[r2.field][t2] ? Ii(p2._private[r2.field], u2, n2) : p2._private[r2.field][t2] = n2);
|
|
}
|
|
r2.updateStyle && this.updateStyle(), r2.onSet(this), r2.settingTriggersEvent && this[r2.triggerFnName](r2.settingEvent);
|
|
}
|
|
} else if (r2.allowSetting && y(t2)) {
|
|
var v2, m2, b2 = t2, x2 = Object.keys(b2);
|
|
r2.beforeSet(this, b2);
|
|
for (var w2 = 0; w2 < x2.length; w2++) {
|
|
if (m2 = b2[v2 = x2[w2]], !r2.immutableKeys[v2]) for (var E2 = 0; E2 < o2.length; E2++) {
|
|
var k2 = o2[E2];
|
|
r2.canSet(k2) && (k2._private[r2.field][v2] = m2);
|
|
}
|
|
}
|
|
r2.updateStyle && this.updateStyle(), r2.onSet(this), r2.settingTriggersEvent && this[r2.triggerFnName](r2.settingEvent);
|
|
} else if (r2.allowBinding && g(t2)) {
|
|
var C2 = t2;
|
|
this.on(r2.bindingEvent, C2);
|
|
} else if (r2.allowGetting && void 0 === t2) {
|
|
var S2;
|
|
return s2 && (r2.beforeGet(s2), S2 = s2._private[r2.field]), S2;
|
|
}
|
|
return this;
|
|
};
|
|
}, removeData: function(e2) {
|
|
return e2 = I({}, { field: "data", event: "data", triggerFnName: "trigger", triggerEvent: false, immutableKeys: {} }, e2), function(t2) {
|
|
var n2 = e2, r2 = void 0 !== this.length ? this : [this];
|
|
if (f(t2)) {
|
|
for (var i2 = t2.split(/\s+/), a2 = i2.length, o2 = 0; o2 < a2; o2++) {
|
|
var s2 = i2[o2];
|
|
if (!S(s2)) {
|
|
if (!n2.immutableKeys[s2]) for (var l2 = 0, u2 = r2.length; l2 < u2; l2++) r2[l2]._private[n2.field][s2] = void 0;
|
|
}
|
|
}
|
|
n2.triggerEvent && this[n2.triggerFnName](n2.event);
|
|
} else if (void 0 === t2) {
|
|
for (var c2 = 0, d2 = r2.length; c2 < d2; c2++) for (var h2 = r2[c2]._private[n2.field], p2 = Object.keys(h2), g2 = 0; g2 < p2.length; g2++) {
|
|
var v2 = p2[g2];
|
|
!n2.immutableKeys[v2] && (h2[v2] = void 0);
|
|
}
|
|
n2.triggerEvent && this[n2.triggerFnName](n2.event);
|
|
}
|
|
return this;
|
|
};
|
|
} }, { eventAliasesOn: function(e2) {
|
|
var t2 = e2;
|
|
t2.addListener = t2.listen = t2.bind = t2.on, t2.unlisten = t2.unbind = t2.off = t2.removeListener, t2.trigger = t2.emit, t2.pon = t2.promiseOn = function(e3, t3) {
|
|
var n2 = this, r2 = Array.prototype.slice.call(arguments, 0);
|
|
return new pr(function(e4, t4) {
|
|
var i2 = r2.concat([function(t5) {
|
|
n2.off.apply(n2, a2), e4(t5);
|
|
}]), a2 = i2.concat([]);
|
|
n2.on.apply(n2, i2);
|
|
});
|
|
};
|
|
} }].forEach(function(e2) {
|
|
I(Oi, e2);
|
|
});
|
|
var Ri = { animate: Oi.animate(), animation: Oi.animation(), animated: Oi.animated(), clearQueue: Oi.clearQueue(), delay: Oi.delay(), delayAnimation: Oi.delayAnimation(), stop: Oi.stop() }, Vi = { classes: function(e2) {
|
|
if (void 0 === e2) {
|
|
var t2 = [];
|
|
return this[0]._private.classes.forEach(function(e3) {
|
|
return t2.push(e3);
|
|
}), t2;
|
|
}
|
|
v(e2) || (e2 = (e2 || "").match(/\S+/g) || []);
|
|
for (var n2 = [], r2 = new $e(e2), i2 = 0; i2 < this.length; i2++) {
|
|
for (var a2 = this[i2], o2 = a2._private, s2 = o2.classes, l2 = false, u2 = 0; u2 < e2.length; u2++) {
|
|
var c2 = e2[u2];
|
|
if (!s2.has(c2)) {
|
|
l2 = true;
|
|
break;
|
|
}
|
|
}
|
|
l2 || (l2 = s2.size !== e2.length), l2 && (o2.classes = r2, n2.push(a2));
|
|
}
|
|
return n2.length > 0 && this.spawn(n2).updateStyle().emit("class"), this;
|
|
}, addClass: function(e2) {
|
|
return this.toggleClass(e2, true);
|
|
}, hasClass: function(e2) {
|
|
var t2 = this[0];
|
|
return null != t2 && t2._private.classes.has(e2);
|
|
}, toggleClass: function(e2, t2) {
|
|
v(e2) || (e2 = e2.match(/\S+/g) || []);
|
|
for (var n2 = void 0 === t2, r2 = [], i2 = 0, a2 = this.length; i2 < a2; i2++) for (var o2 = this[i2], s2 = o2._private.classes, l2 = false, u2 = 0; u2 < e2.length; u2++) {
|
|
var c2 = e2[u2], d2 = s2.has(c2), h2 = false;
|
|
t2 || n2 && !d2 ? (s2.add(c2), h2 = true) : (!t2 || n2 && d2) && (s2.delete(c2), h2 = true), !l2 && h2 && (r2.push(o2), l2 = true);
|
|
}
|
|
return r2.length > 0 && this.spawn(r2).updateStyle().emit("class"), this;
|
|
}, removeClass: function(e2) {
|
|
return this.toggleClass(e2, false);
|
|
}, flashClass: function(e2, t2) {
|
|
var n2 = this;
|
|
if (null == t2) t2 = 250;
|
|
else if (0 === t2) return n2;
|
|
return n2.addClass(e2), setTimeout(function() {
|
|
n2.removeClass(e2);
|
|
}, t2), n2;
|
|
} };
|
|
Vi.className = Vi.classNames = Vi.classes;
|
|
var Fi = { metaChar: "[\\!\\\"\\#\\$\\%\\&\\'\\(\\)\\*\\+\\,\\.\\/\\:\\;\\<\\=\\>\\?\\@\\[\\]\\^\\`\\{\\|\\}\\~]", comparatorOp: "=|\\!=|>|>=|<|<=|\\$=|\\^=|\\*=", boolOp: "\\?|\\!|\\^", string: `"(?:\\\\"|[^"])*"|'(?:\\\\'|[^'])*'`, number: N, meta: "degree|indegree|outdegree", separator: "\\s*,\\s*", descendant: "\\s+", child: "\\s+>\\s+", subject: "\\$", group: "node|edge|\\*", directedEdge: "\\s+->\\s+", undirectedEdge: "\\s+<->\\s+" };
|
|
Fi.variable = "(?:[\\w-.]|(?:\\\\" + Fi.metaChar + "))+", Fi.className = "(?:[\\w-]|(?:\\\\" + Fi.metaChar + "))+", Fi.value = Fi.string + "|" + Fi.number, Fi.id = Fi.variable, function() {
|
|
var e2, t2, n2;
|
|
for (e2 = Fi.comparatorOp.split("|"), n2 = 0; n2 < e2.length; n2++) t2 = e2[n2], Fi.comparatorOp += "|@" + t2;
|
|
for (e2 = Fi.comparatorOp.split("|"), n2 = 0; n2 < e2.length; n2++) (t2 = e2[n2]).indexOf("!") >= 0 || "=" !== t2 && (Fi.comparatorOp += "|\\!" + t2);
|
|
}();
|
|
var ji = 0, qi = 1, Yi = 2, Xi = 3, Wi = 4, Hi = 5, Ki = 6, Gi = 7, Ui = 8, Zi = 9, $i = 10, Qi = 11, Ji = 12, ea = 13, ta = 14, na = 15, ra = 16, ia = 17, aa = 18, oa = 19, sa = 20, la = [{ selector: ":selected", matches: function(e2) {
|
|
return e2.selected();
|
|
} }, { selector: ":unselected", matches: function(e2) {
|
|
return !e2.selected();
|
|
} }, { selector: ":selectable", matches: function(e2) {
|
|
return e2.selectable();
|
|
} }, { selector: ":unselectable", matches: function(e2) {
|
|
return !e2.selectable();
|
|
} }, { selector: ":locked", matches: function(e2) {
|
|
return e2.locked();
|
|
} }, { selector: ":unlocked", matches: function(e2) {
|
|
return !e2.locked();
|
|
} }, { selector: ":visible", matches: function(e2) {
|
|
return e2.visible();
|
|
} }, { selector: ":hidden", matches: function(e2) {
|
|
return !e2.visible();
|
|
} }, { selector: ":transparent", matches: function(e2) {
|
|
return e2.transparent();
|
|
} }, { selector: ":grabbed", matches: function(e2) {
|
|
return e2.grabbed();
|
|
} }, { selector: ":free", matches: function(e2) {
|
|
return !e2.grabbed();
|
|
} }, { selector: ":removed", matches: function(e2) {
|
|
return e2.removed();
|
|
} }, { selector: ":inside", matches: function(e2) {
|
|
return !e2.removed();
|
|
} }, { selector: ":grabbable", matches: function(e2) {
|
|
return e2.grabbable();
|
|
} }, { selector: ":ungrabbable", matches: function(e2) {
|
|
return !e2.grabbable();
|
|
} }, { selector: ":animated", matches: function(e2) {
|
|
return e2.animated();
|
|
} }, { selector: ":unanimated", matches: function(e2) {
|
|
return !e2.animated();
|
|
} }, { selector: ":parent", matches: function(e2) {
|
|
return e2.isParent();
|
|
} }, { selector: ":childless", matches: function(e2) {
|
|
return e2.isChildless();
|
|
} }, { selector: ":child", matches: function(e2) {
|
|
return e2.isChild();
|
|
} }, { selector: ":orphan", matches: function(e2) {
|
|
return e2.isOrphan();
|
|
} }, { selector: ":nonorphan", matches: function(e2) {
|
|
return e2.isChild();
|
|
} }, { selector: ":compound", matches: function(e2) {
|
|
return e2.isNode() ? e2.isParent() : e2.source().isParent() || e2.target().isParent();
|
|
} }, { selector: ":loop", matches: function(e2) {
|
|
return e2.isLoop();
|
|
} }, { selector: ":simple", matches: function(e2) {
|
|
return e2.isSimple();
|
|
} }, { selector: ":active", matches: function(e2) {
|
|
return e2.active();
|
|
} }, { selector: ":inactive", matches: function(e2) {
|
|
return !e2.active();
|
|
} }, { selector: ":backgrounding", matches: function(e2) {
|
|
return e2.backgrounding();
|
|
} }, { selector: ":nonbackgrounding", matches: function(e2) {
|
|
return !e2.backgrounding();
|
|
} }].sort(function(e2, t2) {
|
|
return function(e3, t3) {
|
|
return -1 * z(e3, t3);
|
|
}(e2.selector, t2.selector);
|
|
}), ua = function() {
|
|
for (var e2, t2 = {}, n2 = 0; n2 < la.length; n2++) t2[(e2 = la[n2]).selector] = e2.matches;
|
|
return t2;
|
|
}(), ca = "(" + la.map(function(e2) {
|
|
return e2.selector;
|
|
}).join("|") + ")", da = function(e2) {
|
|
return e2.replace(new RegExp("\\\\(" + Fi.metaChar + ")", "g"), function(e3, t2) {
|
|
return t2;
|
|
});
|
|
}, ha = function(e2, t2, n2) {
|
|
e2[e2.length - 1] = n2;
|
|
}, pa = [{ name: "group", query: true, regex: "(" + Fi.group + ")", populate: function(e2, t2, n2) {
|
|
var r2 = a(n2, 1)[0];
|
|
t2.checks.push({ type: ji, value: "*" === r2 ? r2 : r2 + "s" });
|
|
} }, { name: "state", query: true, regex: ca, populate: function(e2, t2, n2) {
|
|
var r2 = a(n2, 1)[0];
|
|
t2.checks.push({ type: Gi, value: r2 });
|
|
} }, { name: "id", query: true, regex: "\\#(" + Fi.id + ")", populate: function(e2, t2, n2) {
|
|
var r2 = a(n2, 1)[0];
|
|
t2.checks.push({ type: Ui, value: da(r2) });
|
|
} }, { name: "className", query: true, regex: "\\.(" + Fi.className + ")", populate: function(e2, t2, n2) {
|
|
var r2 = a(n2, 1)[0];
|
|
t2.checks.push({ type: Zi, value: da(r2) });
|
|
} }, { name: "dataExists", query: true, regex: "\\[\\s*(" + Fi.variable + ")\\s*\\]", populate: function(e2, t2, n2) {
|
|
var r2 = a(n2, 1)[0];
|
|
t2.checks.push({ type: Wi, field: da(r2) });
|
|
} }, { name: "dataCompare", query: true, regex: "\\[\\s*(" + Fi.variable + ")\\s*(" + Fi.comparatorOp + ")\\s*(" + Fi.value + ")\\s*\\]", populate: function(e2, t2, n2) {
|
|
var r2 = a(n2, 3), i2 = r2[0], o2 = r2[1], s2 = r2[2];
|
|
s2 = null != new RegExp("^" + Fi.string + "$").exec(s2) ? s2.substring(1, s2.length - 1) : parseFloat(s2), t2.checks.push({ type: Xi, field: da(i2), operator: o2, value: s2 });
|
|
} }, { name: "dataBool", query: true, regex: "\\[\\s*(" + Fi.boolOp + ")\\s*(" + Fi.variable + ")\\s*\\]", populate: function(e2, t2, n2) {
|
|
var r2 = a(n2, 2), i2 = r2[0], o2 = r2[1];
|
|
t2.checks.push({ type: Hi, field: da(o2), operator: i2 });
|
|
} }, { name: "metaCompare", query: true, regex: "\\[\\[\\s*(" + Fi.meta + ")\\s*(" + Fi.comparatorOp + ")\\s*(" + Fi.number + ")\\s*\\]\\]", populate: function(e2, t2, n2) {
|
|
var r2 = a(n2, 3), i2 = r2[0], o2 = r2[1], s2 = r2[2];
|
|
t2.checks.push({ type: Ki, field: da(i2), operator: o2, value: parseFloat(s2) });
|
|
} }, { name: "nextQuery", separator: true, regex: Fi.separator, populate: function(e2, t2) {
|
|
var n2 = e2.currentSubject, r2 = e2.edgeCount, i2 = e2.compoundCount, a2 = e2[e2.length - 1];
|
|
return null != n2 && (a2.subject = n2, e2.currentSubject = null), a2.edgeCount = r2, a2.compoundCount = i2, e2.edgeCount = 0, e2.compoundCount = 0, e2[e2.length++] = { checks: [] };
|
|
} }, { name: "directedEdge", separator: true, regex: Fi.directedEdge, populate: function(e2, t2) {
|
|
if (null == e2.currentSubject) {
|
|
var n2 = { checks: [] }, r2 = t2, i2 = { checks: [] };
|
|
return n2.checks.push({ type: Qi, source: r2, target: i2 }), ha(e2, 0, n2), e2.edgeCount++, i2;
|
|
}
|
|
var a2 = { checks: [] }, o2 = t2, s2 = { checks: [] };
|
|
return a2.checks.push({ type: Ji, source: o2, target: s2 }), ha(e2, 0, a2), e2.edgeCount++, s2;
|
|
} }, { name: "undirectedEdge", separator: true, regex: Fi.undirectedEdge, populate: function(e2, t2) {
|
|
if (null == e2.currentSubject) {
|
|
var n2 = { checks: [] }, r2 = t2, i2 = { checks: [] };
|
|
return n2.checks.push({ type: $i, nodes: [r2, i2] }), ha(e2, 0, n2), e2.edgeCount++, i2;
|
|
}
|
|
var a2 = { checks: [] }, o2 = t2, s2 = { checks: [] };
|
|
return a2.checks.push({ type: ta, node: o2, neighbor: s2 }), ha(e2, 0, a2), s2;
|
|
} }, { name: "child", separator: true, regex: Fi.child, populate: function(e2, t2) {
|
|
if (null == e2.currentSubject) {
|
|
var n2 = { checks: [] }, r2 = { checks: [] }, i2 = e2[e2.length - 1];
|
|
return n2.checks.push({ type: na, parent: i2, child: r2 }), ha(e2, 0, n2), e2.compoundCount++, r2;
|
|
}
|
|
if (e2.currentSubject === t2) {
|
|
var a2 = { checks: [] }, o2 = e2[e2.length - 1], s2 = { checks: [] }, l2 = { checks: [] }, u2 = { checks: [] }, c2 = { checks: [] };
|
|
return a2.checks.push({ type: oa, left: o2, right: s2, subject: l2 }), l2.checks = t2.checks, t2.checks = [{ type: sa }], c2.checks.push({ type: sa }), s2.checks.push({ type: ia, parent: c2, child: u2 }), ha(e2, 0, a2), e2.currentSubject = l2, e2.compoundCount++, u2;
|
|
}
|
|
var d2 = { checks: [] }, h2 = { checks: [] }, p2 = [{ type: ia, parent: d2, child: h2 }];
|
|
return d2.checks = t2.checks, t2.checks = p2, e2.compoundCount++, h2;
|
|
} }, { name: "descendant", separator: true, regex: Fi.descendant, populate: function(e2, t2) {
|
|
if (null == e2.currentSubject) {
|
|
var n2 = { checks: [] }, r2 = { checks: [] }, i2 = e2[e2.length - 1];
|
|
return n2.checks.push({ type: ra, ancestor: i2, descendant: r2 }), ha(e2, 0, n2), e2.compoundCount++, r2;
|
|
}
|
|
if (e2.currentSubject === t2) {
|
|
var a2 = { checks: [] }, o2 = e2[e2.length - 1], s2 = { checks: [] }, l2 = { checks: [] }, u2 = { checks: [] }, c2 = { checks: [] };
|
|
return a2.checks.push({ type: oa, left: o2, right: s2, subject: l2 }), l2.checks = t2.checks, t2.checks = [{ type: sa }], c2.checks.push({ type: sa }), s2.checks.push({ type: aa, ancestor: c2, descendant: u2 }), ha(e2, 0, a2), e2.currentSubject = l2, e2.compoundCount++, u2;
|
|
}
|
|
var d2 = { checks: [] }, h2 = { checks: [] }, p2 = [{ type: aa, ancestor: d2, descendant: h2 }];
|
|
return d2.checks = t2.checks, t2.checks = p2, e2.compoundCount++, h2;
|
|
} }, { name: "subject", modifier: true, regex: Fi.subject, populate: function(e2, t2) {
|
|
if (null != e2.currentSubject && e2.currentSubject !== t2) return Ve("Redefinition of subject in selector `" + e2.toString() + "`"), false;
|
|
e2.currentSubject = t2;
|
|
var n2 = e2[e2.length - 1].checks[0], r2 = null == n2 ? null : n2.type;
|
|
r2 === Qi ? n2.type = ea : r2 === $i && (n2.type = ta, n2.node = n2.nodes[1], n2.neighbor = n2.nodes[0], n2.nodes = null);
|
|
} }];
|
|
pa.forEach(function(e2) {
|
|
return e2.regexObj = new RegExp("^" + e2.regex);
|
|
});
|
|
var fa = function(e2) {
|
|
for (var t2, n2, r2, i2 = 0; i2 < pa.length; i2++) {
|
|
var a2 = pa[i2], o2 = a2.name, s2 = e2.match(a2.regexObj);
|
|
if (null != s2) {
|
|
n2 = s2, t2 = a2, r2 = o2;
|
|
var l2 = s2[0];
|
|
e2 = e2.substring(l2.length);
|
|
break;
|
|
}
|
|
}
|
|
return { expr: t2, match: n2, name: r2, remaining: e2 };
|
|
}, ga = { parse: function(e2) {
|
|
var t2 = this.inputText = e2, n2 = this[0] = { checks: [] };
|
|
for (this.length = 1, t2 = function(e3) {
|
|
var t3 = e3.match(/^\s+/);
|
|
if (t3) {
|
|
var n3 = t3[0];
|
|
e3 = e3.substring(n3.length);
|
|
}
|
|
return e3;
|
|
}(t2); ; ) {
|
|
var r2 = fa(t2);
|
|
if (null == r2.expr) return Ve("The selector `" + e2 + "`is invalid"), false;
|
|
var i2 = r2.match.slice(1), a2 = r2.expr.populate(this, n2, i2);
|
|
if (false === a2) return false;
|
|
if (null != a2 && (n2 = a2), (t2 = r2.remaining).match(/^\s*$/)) break;
|
|
}
|
|
var o2 = this[this.length - 1];
|
|
null != this.currentSubject && (o2.subject = this.currentSubject), o2.edgeCount = this.edgeCount, o2.compoundCount = this.compoundCount;
|
|
for (var s2 = 0; s2 < this.length; s2++) {
|
|
var l2 = this[s2];
|
|
if (l2.compoundCount > 0 && l2.edgeCount > 0) return Ve("The selector `" + e2 + "` is invalid because it uses both a compound selector and an edge selector"), false;
|
|
if (l2.edgeCount > 1) return Ve("The selector `" + e2 + "` is invalid because it uses multiple edge selectors"), false;
|
|
1 === l2.edgeCount && Ve("The selector `" + e2 + "` is deprecated. Edge selectors do not take effect on changes to source and target nodes after an edge is added, for performance reasons. Use a class or data selector on edges instead, updating the class or data of an edge when your app detects a change in source or target nodes.");
|
|
}
|
|
return true;
|
|
}, toString: function() {
|
|
if (null != this.toStringCache) return this.toStringCache;
|
|
for (var e2 = function(e3) {
|
|
return null == e3 ? "" : e3;
|
|
}, t2 = function(t3) {
|
|
return f(t3) ? '"' + t3 + '"' : e2(t3);
|
|
}, n2 = function(e3) {
|
|
return " " + e3 + " ";
|
|
}, r2 = function(r3, a3) {
|
|
var o3 = r3.type, s3 = r3.value;
|
|
switch (o3) {
|
|
case ji:
|
|
var l2 = e2(s3);
|
|
return l2.substring(0, l2.length - 1);
|
|
case Xi:
|
|
var u2 = r3.field, c2 = r3.operator;
|
|
return "[" + u2 + n2(e2(c2)) + t2(s3) + "]";
|
|
case Hi:
|
|
var d2 = r3.operator, h2 = r3.field;
|
|
return "[" + e2(d2) + h2 + "]";
|
|
case Wi:
|
|
return "[" + r3.field + "]";
|
|
case Ki:
|
|
var p2 = r3.operator;
|
|
return "[[" + r3.field + n2(e2(p2)) + t2(s3) + "]]";
|
|
case Gi:
|
|
return s3;
|
|
case Ui:
|
|
return "#" + s3;
|
|
case Zi:
|
|
return "." + s3;
|
|
case ia:
|
|
case na:
|
|
return i2(r3.parent, a3) + n2(">") + i2(r3.child, a3);
|
|
case aa:
|
|
case ra:
|
|
return i2(r3.ancestor, a3) + " " + i2(r3.descendant, a3);
|
|
case oa:
|
|
var f2 = i2(r3.left, a3), g2 = i2(r3.subject, a3), v2 = i2(r3.right, a3);
|
|
return f2 + (f2.length > 0 ? " " : "") + g2 + v2;
|
|
case sa:
|
|
return "";
|
|
}
|
|
}, i2 = function(e3, t3) {
|
|
return e3.checks.reduce(function(n3, i3, a3) {
|
|
return n3 + (t3 === e3 && 0 === a3 ? "$" : "") + r2(i3, t3);
|
|
}, "");
|
|
}, a2 = "", o2 = 0; o2 < this.length; o2++) {
|
|
var s2 = this[o2];
|
|
a2 += i2(s2, s2.subject), this.length > 1 && o2 < this.length - 1 && (a2 += ", ");
|
|
}
|
|
return this.toStringCache = a2, a2;
|
|
} }, va = function(e2, t2, n2) {
|
|
var r2, i2, a2, o2 = f(e2), s2 = m(e2), l2 = f(n2), u2 = false, c2 = false, d2 = false;
|
|
switch (t2.indexOf("!") >= 0 && (t2 = t2.replace("!", ""), c2 = true), t2.indexOf("@") >= 0 && (t2 = t2.replace("@", ""), u2 = true), (o2 || l2 || u2) && (i2 = o2 || s2 ? "" + e2 : "", a2 = "" + n2), u2 && (e2 = i2 = i2.toLowerCase(), n2 = a2 = a2.toLowerCase()), t2) {
|
|
case "*=":
|
|
r2 = i2.indexOf(a2) >= 0;
|
|
break;
|
|
case "$=":
|
|
r2 = i2.indexOf(a2, i2.length - a2.length) >= 0;
|
|
break;
|
|
case "^=":
|
|
r2 = 0 === i2.indexOf(a2);
|
|
break;
|
|
case "=":
|
|
r2 = e2 === n2;
|
|
break;
|
|
case ">":
|
|
d2 = true, r2 = e2 > n2;
|
|
break;
|
|
case ">=":
|
|
d2 = true, r2 = e2 >= n2;
|
|
break;
|
|
case "<":
|
|
d2 = true, r2 = e2 < n2;
|
|
break;
|
|
case "<=":
|
|
d2 = true, r2 = e2 <= n2;
|
|
break;
|
|
default:
|
|
r2 = false;
|
|
}
|
|
return !c2 || null == e2 && d2 || (r2 = !r2), r2;
|
|
}, ya = function(e2, t2) {
|
|
return e2.data(t2);
|
|
}, ma = [], ba = function(e2, t2) {
|
|
return e2.checks.every(function(e3) {
|
|
return ma[e3.type](e3, t2);
|
|
});
|
|
};
|
|
ma[ji] = function(e2, t2) {
|
|
var n2 = e2.value;
|
|
return "*" === n2 || n2 === t2.group();
|
|
}, ma[Gi] = function(e2, t2) {
|
|
return function(e3, t3) {
|
|
return ua[e3](t3);
|
|
}(e2.value, t2);
|
|
}, ma[Ui] = function(e2, t2) {
|
|
var n2 = e2.value;
|
|
return t2.id() === n2;
|
|
}, ma[Zi] = function(e2, t2) {
|
|
var n2 = e2.value;
|
|
return t2.hasClass(n2);
|
|
}, ma[Ki] = function(e2, t2) {
|
|
var n2 = e2.field, r2 = e2.operator, i2 = e2.value;
|
|
return va(function(e3, t3) {
|
|
return e3[t3]();
|
|
}(t2, n2), r2, i2);
|
|
}, ma[Xi] = function(e2, t2) {
|
|
var n2 = e2.field, r2 = e2.operator, i2 = e2.value;
|
|
return va(ya(t2, n2), r2, i2);
|
|
}, ma[Hi] = function(e2, t2) {
|
|
var n2 = e2.field, r2 = e2.operator;
|
|
return function(e3, t3) {
|
|
switch (t3) {
|
|
case "?":
|
|
return !!e3;
|
|
case "!":
|
|
return !e3;
|
|
case "^":
|
|
return void 0 === e3;
|
|
}
|
|
}(ya(t2, n2), r2);
|
|
}, ma[Wi] = function(e2, t2) {
|
|
var n2 = e2.field;
|
|
return e2.operator, void 0 !== ya(t2, n2);
|
|
}, ma[$i] = function(e2, t2) {
|
|
var n2 = e2.nodes[0], r2 = e2.nodes[1], i2 = t2.source(), a2 = t2.target();
|
|
return ba(n2, i2) && ba(r2, a2) || ba(r2, i2) && ba(n2, a2);
|
|
}, ma[ta] = function(e2, t2) {
|
|
return ba(e2.node, t2) && t2.neighborhood().some(function(t3) {
|
|
return t3.isNode() && ba(e2.neighbor, t3);
|
|
});
|
|
}, ma[Qi] = function(e2, t2) {
|
|
return ba(e2.source, t2.source()) && ba(e2.target, t2.target());
|
|
}, ma[Ji] = function(e2, t2) {
|
|
return ba(e2.source, t2) && t2.outgoers().some(function(t3) {
|
|
return t3.isNode() && ba(e2.target, t3);
|
|
});
|
|
}, ma[ea] = function(e2, t2) {
|
|
return ba(e2.target, t2) && t2.incomers().some(function(t3) {
|
|
return t3.isNode() && ba(e2.source, t3);
|
|
});
|
|
}, ma[na] = function(e2, t2) {
|
|
return ba(e2.child, t2) && ba(e2.parent, t2.parent());
|
|
}, ma[ia] = function(e2, t2) {
|
|
return ba(e2.parent, t2) && t2.children().some(function(t3) {
|
|
return ba(e2.child, t3);
|
|
});
|
|
}, ma[ra] = function(e2, t2) {
|
|
return ba(e2.descendant, t2) && t2.ancestors().some(function(t3) {
|
|
return ba(e2.ancestor, t3);
|
|
});
|
|
}, ma[aa] = function(e2, t2) {
|
|
return ba(e2.ancestor, t2) && t2.descendants().some(function(t3) {
|
|
return ba(e2.descendant, t3);
|
|
});
|
|
}, ma[oa] = function(e2, t2) {
|
|
return ba(e2.subject, t2) && ba(e2.left, t2) && ba(e2.right, t2);
|
|
}, ma[sa] = function() {
|
|
return true;
|
|
}, ma[qi] = function(e2, t2) {
|
|
return e2.value.has(t2);
|
|
}, ma[Yi] = function(e2, t2) {
|
|
return (0, e2.value)(t2);
|
|
};
|
|
var xa = function(e2) {
|
|
this.inputText = e2, this.currentSubject = null, this.compoundCount = 0, this.edgeCount = 0, this.length = 0, null == e2 || f(e2) && e2.match(/^\s*$/) || (x(e2) ? this.addQuery({ checks: [{ type: qi, value: e2.collection() }] }) : g(e2) ? this.addQuery({ checks: [{ type: Yi, value: e2 }] }) : f(e2) ? this.parse(e2) || (this.invalid = true) : Oe("A selector must be created from a string; found "));
|
|
}, wa = xa.prototype;
|
|
[ga, { matches: function(e2) {
|
|
for (var t2 = 0; t2 < this.length; t2++) {
|
|
var n2 = this[t2];
|
|
if (ba(n2, e2)) return true;
|
|
}
|
|
return false;
|
|
}, filter: function(e2) {
|
|
var t2 = this;
|
|
if (1 === t2.length && 1 === t2[0].checks.length && t2[0].checks[0].type === Ui) return e2.getElementById(t2[0].checks[0].value).collection();
|
|
var n2 = function(e3) {
|
|
for (var n3 = 0; n3 < t2.length; n3++) {
|
|
var r2 = t2[n3];
|
|
if (ba(r2, e3)) return true;
|
|
}
|
|
return false;
|
|
};
|
|
return null == t2.text() && (n2 = function() {
|
|
return true;
|
|
}), e2.filter(n2);
|
|
} }].forEach(function(e2) {
|
|
return I(wa, e2);
|
|
}), wa.text = function() {
|
|
return this.inputText;
|
|
}, wa.size = function() {
|
|
return this.length;
|
|
}, wa.eq = function(e2) {
|
|
return this[e2];
|
|
}, wa.sameText = function(e2) {
|
|
return !this.invalid && !e2.invalid && this.text() === e2.text();
|
|
}, wa.addQuery = function(e2) {
|
|
this[this.length++] = e2;
|
|
}, wa.selector = wa.toString;
|
|
var Ea = { allAre: function(e2) {
|
|
var t2 = new xa(e2);
|
|
return this.every(function(e3) {
|
|
return t2.matches(e3);
|
|
});
|
|
}, is: function(e2) {
|
|
var t2 = new xa(e2);
|
|
return this.some(function(e3) {
|
|
return t2.matches(e3);
|
|
});
|
|
}, some: function(e2, t2) {
|
|
for (var n2 = 0; n2 < this.length; n2++) {
|
|
if (t2 ? e2.apply(t2, [this[n2], n2, this]) : e2(this[n2], n2, this)) return true;
|
|
}
|
|
return false;
|
|
}, every: function(e2, t2) {
|
|
for (var n2 = 0; n2 < this.length; n2++) {
|
|
if (!(t2 ? e2.apply(t2, [this[n2], n2, this]) : e2(this[n2], n2, this))) return false;
|
|
}
|
|
return true;
|
|
}, same: function(e2) {
|
|
if (this === e2) return true;
|
|
e2 = this.cy().collection(e2);
|
|
var t2 = this.length;
|
|
return t2 === e2.length && (1 === t2 ? this[0] === e2[0] : this.every(function(t3) {
|
|
return e2.hasElementWithId(t3.id());
|
|
}));
|
|
}, anySame: function(e2) {
|
|
return e2 = this.cy().collection(e2), this.some(function(t2) {
|
|
return e2.hasElementWithId(t2.id());
|
|
});
|
|
}, allAreNeighbors: function(e2) {
|
|
e2 = this.cy().collection(e2);
|
|
var t2 = this.neighborhood();
|
|
return e2.every(function(e3) {
|
|
return t2.hasElementWithId(e3.id());
|
|
});
|
|
}, contains: function(e2) {
|
|
e2 = this.cy().collection(e2);
|
|
var t2 = this;
|
|
return e2.every(function(e3) {
|
|
return t2.hasElementWithId(e3.id());
|
|
});
|
|
} };
|
|
Ea.allAreNeighbours = Ea.allAreNeighbors, Ea.has = Ea.contains, Ea.equal = Ea.equals = Ea.same;
|
|
var ka, Ca, Sa = function(e2, t2) {
|
|
return function(n2, r2, i2, a2) {
|
|
var o2, s2 = n2;
|
|
if (null == s2 ? o2 = "" : x(s2) && 1 === s2.length && (o2 = s2.id()), 1 === this.length && o2) {
|
|
var l2 = this[0]._private, u2 = l2.traversalCache = l2.traversalCache || {}, c2 = u2[t2] = u2[t2] || [], d2 = Pe(o2), h2 = c2[d2];
|
|
return h2 || (c2[d2] = e2.call(this, n2, r2, i2, a2));
|
|
}
|
|
return e2.call(this, n2, r2, i2, a2);
|
|
};
|
|
}, Pa = { parent: function(e2) {
|
|
var t2 = [];
|
|
if (1 === this.length) {
|
|
var n2 = this[0]._private.parent;
|
|
if (n2) return n2;
|
|
}
|
|
for (var r2 = 0; r2 < this.length; r2++) {
|
|
var i2 = this[r2]._private.parent;
|
|
i2 && t2.push(i2);
|
|
}
|
|
return this.spawn(t2, true).filter(e2);
|
|
}, parents: function(e2) {
|
|
for (var t2 = [], n2 = this.parent(); n2.nonempty(); ) {
|
|
for (var r2 = 0; r2 < n2.length; r2++) {
|
|
var i2 = n2[r2];
|
|
t2.push(i2);
|
|
}
|
|
n2 = n2.parent();
|
|
}
|
|
return this.spawn(t2, true).filter(e2);
|
|
}, commonAncestors: function(e2) {
|
|
for (var t2, n2 = 0; n2 < this.length; n2++) {
|
|
var r2 = this[n2].parents();
|
|
t2 = (t2 = t2 || r2).intersect(r2);
|
|
}
|
|
return t2.filter(e2);
|
|
}, orphans: function(e2) {
|
|
return this.stdFilter(function(e3) {
|
|
return e3.isOrphan();
|
|
}).filter(e2);
|
|
}, nonorphans: function(e2) {
|
|
return this.stdFilter(function(e3) {
|
|
return e3.isChild();
|
|
}).filter(e2);
|
|
}, children: Sa(function(e2) {
|
|
for (var t2 = [], n2 = 0; n2 < this.length; n2++) for (var r2 = this[n2]._private.children, i2 = 0; i2 < r2.length; i2++) t2.push(r2[i2]);
|
|
return this.spawn(t2, true).filter(e2);
|
|
}, "children"), siblings: function(e2) {
|
|
return this.parent().children().not(this).filter(e2);
|
|
}, isParent: function() {
|
|
var e2 = this[0];
|
|
if (e2) return e2.isNode() && 0 !== e2._private.children.length;
|
|
}, isChildless: function() {
|
|
var e2 = this[0];
|
|
if (e2) return e2.isNode() && 0 === e2._private.children.length;
|
|
}, isChild: function() {
|
|
var e2 = this[0];
|
|
if (e2) return e2.isNode() && null != e2._private.parent;
|
|
}, isOrphan: function() {
|
|
var e2 = this[0];
|
|
if (e2) return e2.isNode() && null == e2._private.parent;
|
|
}, descendants: function(e2) {
|
|
var t2 = [];
|
|
return function e3(n2) {
|
|
for (var r2 = 0; r2 < n2.length; r2++) {
|
|
var i2 = n2[r2];
|
|
t2.push(i2), i2.children().nonempty() && e3(i2.children());
|
|
}
|
|
}(this.children()), this.spawn(t2, true).filter(e2);
|
|
} };
|
|
function Da(e2, t2, n2, r2) {
|
|
for (var i2 = [], a2 = new $e(), o2 = e2.cy().hasCompoundNodes(), s2 = 0; s2 < e2.length; s2++) {
|
|
var l2 = e2[s2];
|
|
n2 ? i2.push(l2) : o2 && r2(i2, a2, l2);
|
|
}
|
|
for (; i2.length > 0; ) {
|
|
var u2 = i2.shift();
|
|
t2(u2), a2.add(u2.id()), o2 && r2(i2, a2, u2);
|
|
}
|
|
return e2;
|
|
}
|
|
function Ta(e2, t2, n2) {
|
|
if (n2.isParent()) for (var r2 = n2._private.children, i2 = 0; i2 < r2.length; i2++) {
|
|
var a2 = r2[i2];
|
|
t2.has(a2.id()) || e2.push(a2);
|
|
}
|
|
}
|
|
function _a2(e2, t2, n2) {
|
|
if (n2.isChild()) {
|
|
var r2 = n2._private.parent;
|
|
t2.has(r2.id()) || e2.push(r2);
|
|
}
|
|
}
|
|
function Ma(e2, t2, n2) {
|
|
_a2(e2, t2, n2), Ta(e2, t2, n2);
|
|
}
|
|
Pa.forEachDown = function(e2) {
|
|
var t2 = !(arguments.length > 1 && void 0 !== arguments[1]) || arguments[1];
|
|
return Da(this, e2, t2, Ta);
|
|
}, Pa.forEachUp = function(e2) {
|
|
var t2 = !(arguments.length > 1 && void 0 !== arguments[1]) || arguments[1];
|
|
return Da(this, e2, t2, _a2);
|
|
}, Pa.forEachUpAndDown = function(e2) {
|
|
var t2 = !(arguments.length > 1 && void 0 !== arguments[1]) || arguments[1];
|
|
return Da(this, e2, t2, Ma);
|
|
}, Pa.ancestors = Pa.parents, (ka = Ca = { data: Oi.data({ field: "data", bindingEvent: "data", allowBinding: true, allowSetting: true, settingEvent: "data", settingTriggersEvent: true, triggerFnName: "trigger", allowGetting: true, immutableKeys: { id: true, source: true, target: true, parent: true }, updateStyle: true }), removeData: Oi.removeData({ field: "data", event: "data", triggerFnName: "trigger", triggerEvent: true, immutableKeys: { id: true, source: true, target: true, parent: true }, updateStyle: true }), scratch: Oi.data({ field: "scratch", bindingEvent: "scratch", allowBinding: true, allowSetting: true, settingEvent: "scratch", settingTriggersEvent: true, triggerFnName: "trigger", allowGetting: true, updateStyle: true }), removeScratch: Oi.removeData({ field: "scratch", event: "scratch", triggerFnName: "trigger", triggerEvent: true, updateStyle: true }), rscratch: Oi.data({ field: "rscratch", allowBinding: false, allowSetting: true, settingTriggersEvent: false, allowGetting: true }), removeRscratch: Oi.removeData({ field: "rscratch", triggerEvent: false }), id: function() {
|
|
var e2 = this[0];
|
|
if (e2) return e2._private.data.id;
|
|
} }).attr = ka.data, ka.removeAttr = ka.removeData;
|
|
var Ba, Na, za = Ca, Ia = {};
|
|
function La(e2) {
|
|
return function(t2) {
|
|
if (void 0 === t2 && (t2 = true), 0 !== this.length && this.isNode() && !this.removed()) {
|
|
for (var n2 = 0, r2 = this[0], i2 = r2._private.edges, a2 = 0; a2 < i2.length; a2++) {
|
|
var o2 = i2[a2];
|
|
!t2 && o2.isLoop() || (n2 += e2(r2, o2));
|
|
}
|
|
return n2;
|
|
}
|
|
};
|
|
}
|
|
function Aa(e2, t2) {
|
|
return function(n2) {
|
|
for (var r2, i2 = this.nodes(), a2 = 0; a2 < i2.length; a2++) {
|
|
var o2 = i2[a2][e2](n2);
|
|
void 0 === o2 || void 0 !== r2 && !t2(o2, r2) || (r2 = o2);
|
|
}
|
|
return r2;
|
|
};
|
|
}
|
|
I(Ia, { degree: La(function(e2, t2) {
|
|
return t2.source().same(t2.target()) ? 2 : 1;
|
|
}), indegree: La(function(e2, t2) {
|
|
return t2.target().same(e2) ? 1 : 0;
|
|
}), outdegree: La(function(e2, t2) {
|
|
return t2.source().same(e2) ? 1 : 0;
|
|
}) }), I(Ia, { minDegree: Aa("degree", function(e2, t2) {
|
|
return e2 < t2;
|
|
}), maxDegree: Aa("degree", function(e2, t2) {
|
|
return e2 > t2;
|
|
}), minIndegree: Aa("indegree", function(e2, t2) {
|
|
return e2 < t2;
|
|
}), maxIndegree: Aa("indegree", function(e2, t2) {
|
|
return e2 > t2;
|
|
}), minOutdegree: Aa("outdegree", function(e2, t2) {
|
|
return e2 < t2;
|
|
}), maxOutdegree: Aa("outdegree", function(e2, t2) {
|
|
return e2 > t2;
|
|
}) }), I(Ia, { totalDegree: function(e2) {
|
|
for (var t2 = 0, n2 = this.nodes(), r2 = 0; r2 < n2.length; r2++) t2 += n2[r2].degree(e2);
|
|
return t2;
|
|
} });
|
|
var Oa = function(e2, t2, n2) {
|
|
for (var r2 = 0; r2 < e2.length; r2++) {
|
|
var i2 = e2[r2];
|
|
if (!i2.locked()) {
|
|
var a2 = i2._private.position, o2 = { x: null != t2.x ? t2.x - a2.x : 0, y: null != t2.y ? t2.y - a2.y : 0 };
|
|
!i2.isParent() || 0 === o2.x && 0 === o2.y || i2.children().shift(o2, n2), i2.dirtyBoundingBoxCache();
|
|
}
|
|
}
|
|
}, Ra = { field: "position", bindingEvent: "position", allowBinding: true, allowSetting: true, settingEvent: "position", settingTriggersEvent: true, triggerFnName: "emitAndNotify", allowGetting: true, validKeys: ["x", "y"], beforeGet: function(e2) {
|
|
e2.updateCompoundBounds();
|
|
}, beforeSet: function(e2, t2) {
|
|
Oa(e2, t2, false);
|
|
}, onSet: function(e2) {
|
|
e2.dirtyCompoundBoundsCache();
|
|
}, canSet: function(e2) {
|
|
return !e2.locked();
|
|
} };
|
|
(Ba = Na = { position: Oi.data(Ra), silentPosition: Oi.data(I({}, Ra, { allowBinding: false, allowSetting: true, settingTriggersEvent: false, allowGetting: false, beforeSet: function(e2, t2) {
|
|
Oa(e2, t2, true);
|
|
}, onSet: function(e2) {
|
|
e2.dirtyCompoundBoundsCache();
|
|
} })), positions: function(e2, t2) {
|
|
if (y(e2)) t2 ? this.silentPosition(e2) : this.position(e2);
|
|
else if (g(e2)) {
|
|
var n2 = e2, r2 = this.cy();
|
|
r2.startBatch();
|
|
for (var i2 = 0; i2 < this.length; i2++) {
|
|
var a2, o2 = this[i2];
|
|
(a2 = n2(o2, i2)) && (t2 ? o2.silentPosition(a2) : o2.position(a2));
|
|
}
|
|
r2.endBatch();
|
|
}
|
|
return this;
|
|
}, silentPositions: function(e2) {
|
|
return this.positions(e2, true);
|
|
}, shift: function(e2, t2, n2) {
|
|
var r2;
|
|
if (y(e2) ? (r2 = { x: m(e2.x) ? e2.x : 0, y: m(e2.y) ? e2.y : 0 }, n2 = t2) : f(e2) && m(t2) && ((r2 = { x: 0, y: 0 })[e2] = t2), null != r2) {
|
|
var i2 = this.cy();
|
|
i2.startBatch();
|
|
for (var a2 = 0; a2 < this.length; a2++) {
|
|
var o2 = this[a2];
|
|
if (!(i2.hasCompoundNodes() && o2.isChild() && o2.ancestors().anySame(this))) {
|
|
var s2 = o2.position(), l2 = { x: s2.x + r2.x, y: s2.y + r2.y };
|
|
n2 ? o2.silentPosition(l2) : o2.position(l2);
|
|
}
|
|
}
|
|
i2.endBatch();
|
|
}
|
|
return this;
|
|
}, silentShift: function(e2, t2) {
|
|
return y(e2) ? this.shift(e2, true) : f(e2) && m(t2) && this.shift(e2, t2, true), this;
|
|
}, renderedPosition: function(e2, t2) {
|
|
var n2 = this[0], r2 = this.cy(), i2 = r2.zoom(), a2 = r2.pan(), o2 = y(e2) ? e2 : void 0, s2 = void 0 !== o2 || void 0 !== t2 && f(e2);
|
|
if (n2 && n2.isNode()) {
|
|
if (!s2) {
|
|
var l2 = n2.position();
|
|
return o2 = gt(l2, i2, a2), void 0 === e2 ? o2 : o2[e2];
|
|
}
|
|
for (var u2 = 0; u2 < this.length; u2++) {
|
|
var c2 = this[u2];
|
|
void 0 !== t2 ? c2.position(e2, (t2 - a2[e2]) / i2) : void 0 !== o2 && c2.position(vt(o2, i2, a2));
|
|
}
|
|
} else if (!s2) return;
|
|
return this;
|
|
}, relativePosition: function(e2, t2) {
|
|
var n2 = this[0], r2 = this.cy(), i2 = y(e2) ? e2 : void 0, a2 = void 0 !== i2 || void 0 !== t2 && f(e2), o2 = r2.hasCompoundNodes();
|
|
if (n2 && n2.isNode()) {
|
|
if (!a2) {
|
|
var s2 = n2.position(), l2 = o2 ? n2.parent() : null, u2 = l2 && l2.length > 0, c2 = u2;
|
|
u2 && (l2 = l2[0]);
|
|
var d2 = c2 ? l2.position() : { x: 0, y: 0 };
|
|
return i2 = { x: s2.x - d2.x, y: s2.y - d2.y }, void 0 === e2 ? i2 : i2[e2];
|
|
}
|
|
for (var h2 = 0; h2 < this.length; h2++) {
|
|
var p2 = this[h2], g2 = o2 ? p2.parent() : null, v2 = g2 && g2.length > 0, m2 = v2;
|
|
v2 && (g2 = g2[0]);
|
|
var b2 = m2 ? g2.position() : { x: 0, y: 0 };
|
|
void 0 !== t2 ? p2.position(e2, t2 + b2[e2]) : void 0 !== i2 && p2.position({ x: i2.x + b2.x, y: i2.y + b2.y });
|
|
}
|
|
} else if (!a2) return;
|
|
return this;
|
|
} }).modelPosition = Ba.point = Ba.position, Ba.modelPositions = Ba.points = Ba.positions, Ba.renderedPoint = Ba.renderedPosition, Ba.relativePoint = Ba.relativePosition;
|
|
var Va, Fa, ja = Na;
|
|
Va = Fa = {}, Fa.renderedBoundingBox = function(e2) {
|
|
var t2 = this.boundingBox(e2), n2 = this.cy(), r2 = n2.zoom(), i2 = n2.pan(), a2 = t2.x1 * r2 + i2.x, o2 = t2.x2 * r2 + i2.x, s2 = t2.y1 * r2 + i2.y, l2 = t2.y2 * r2 + i2.y;
|
|
return { x1: a2, x2: o2, y1: s2, y2: l2, w: o2 - a2, h: l2 - s2 };
|
|
}, Fa.dirtyCompoundBoundsCache = function() {
|
|
var e2 = arguments.length > 0 && void 0 !== arguments[0] && arguments[0], t2 = this.cy();
|
|
return t2.styleEnabled() && t2.hasCompoundNodes() ? (this.forEachUp(function(t3) {
|
|
if (t3.isParent()) {
|
|
var n2 = t3._private;
|
|
n2.compoundBoundsClean = false, n2.bbCache = null, e2 || t3.emitAndNotify("bounds");
|
|
}
|
|
}), this) : this;
|
|
}, Fa.updateCompoundBounds = function() {
|
|
var e2 = arguments.length > 0 && void 0 !== arguments[0] && arguments[0], t2 = this.cy();
|
|
if (!t2.styleEnabled() || !t2.hasCompoundNodes()) return this;
|
|
if (!e2 && t2.batching()) return this;
|
|
function n2(e3) {
|
|
if (e3.isParent()) {
|
|
var t3 = e3._private, n3 = e3.children(), r3 = "include" === e3.pstyle("compound-sizing-wrt-labels").value, i3 = { width: { val: e3.pstyle("min-width").pfValue, left: e3.pstyle("min-width-bias-left"), right: e3.pstyle("min-width-bias-right") }, height: { val: e3.pstyle("min-height").pfValue, top: e3.pstyle("min-height-bias-top"), bottom: e3.pstyle("min-height-bias-bottom") } }, a3 = n3.boundingBox({ includeLabels: r3, includeOverlays: false, useCache: false }), o2 = t3.position;
|
|
0 !== a3.w && 0 !== a3.h || ((a3 = { w: e3.pstyle("width").pfValue, h: e3.pstyle("height").pfValue }).x1 = o2.x - a3.w / 2, a3.x2 = o2.x + a3.w / 2, a3.y1 = o2.y - a3.h / 2, a3.y2 = o2.y + a3.h / 2);
|
|
var s2 = i3.width.left.value;
|
|
"px" === i3.width.left.units && i3.width.val > 0 && (s2 = 100 * s2 / i3.width.val);
|
|
var l2 = i3.width.right.value;
|
|
"px" === i3.width.right.units && i3.width.val > 0 && (l2 = 100 * l2 / i3.width.val);
|
|
var u2 = i3.height.top.value;
|
|
"px" === i3.height.top.units && i3.height.val > 0 && (u2 = 100 * u2 / i3.height.val);
|
|
var c2 = i3.height.bottom.value;
|
|
"px" === i3.height.bottom.units && i3.height.val > 0 && (c2 = 100 * c2 / i3.height.val);
|
|
var d2 = y2(i3.width.val - a3.w, s2, l2), h2 = d2.biasDiff, p2 = d2.biasComplementDiff, f2 = y2(i3.height.val - a3.h, u2, c2), g2 = f2.biasDiff, v2 = f2.biasComplementDiff;
|
|
t3.autoPadding = function(e4, t4, n4, r4) {
|
|
if ("%" !== n4.units) return "px" === n4.units ? n4.pfValue : 0;
|
|
switch (r4) {
|
|
case "width":
|
|
return e4 > 0 ? n4.pfValue * e4 : 0;
|
|
case "height":
|
|
return t4 > 0 ? n4.pfValue * t4 : 0;
|
|
case "average":
|
|
return e4 > 0 && t4 > 0 ? n4.pfValue * (e4 + t4) / 2 : 0;
|
|
case "min":
|
|
return e4 > 0 && t4 > 0 ? e4 > t4 ? n4.pfValue * t4 : n4.pfValue * e4 : 0;
|
|
case "max":
|
|
return e4 > 0 && t4 > 0 ? e4 > t4 ? n4.pfValue * e4 : n4.pfValue * t4 : 0;
|
|
default:
|
|
return 0;
|
|
}
|
|
}(a3.w, a3.h, e3.pstyle("padding"), e3.pstyle("padding-relative-to").value), t3.autoWidth = Math.max(a3.w, i3.width.val), o2.x = (-h2 + a3.x1 + a3.x2 + p2) / 2, t3.autoHeight = Math.max(a3.h, i3.height.val), o2.y = (-g2 + a3.y1 + a3.y2 + v2) / 2;
|
|
}
|
|
function y2(e4, t4, n4) {
|
|
var r4 = 0, i4 = 0, a4 = t4 + n4;
|
|
return e4 > 0 && a4 > 0 && (r4 = t4 / a4 * e4, i4 = n4 / a4 * e4), { biasDiff: r4, biasComplementDiff: i4 };
|
|
}
|
|
}
|
|
for (var r2 = 0; r2 < this.length; r2++) {
|
|
var i2 = this[r2], a2 = i2._private;
|
|
a2.compoundBoundsClean && !e2 || (n2(i2), t2.batching() || (a2.compoundBoundsClean = true));
|
|
}
|
|
return this;
|
|
};
|
|
var qa = function(e2) {
|
|
return e2 === 1 / 0 || e2 === -1 / 0 ? 0 : e2;
|
|
}, Ya = function(e2, t2, n2, r2, i2) {
|
|
r2 - t2 != 0 && i2 - n2 != 0 && null != t2 && null != n2 && null != r2 && null != i2 && (e2.x1 = t2 < e2.x1 ? t2 : e2.x1, e2.x2 = r2 > e2.x2 ? r2 : e2.x2, e2.y1 = n2 < e2.y1 ? n2 : e2.y1, e2.y2 = i2 > e2.y2 ? i2 : e2.y2, e2.w = e2.x2 - e2.x1, e2.h = e2.y2 - e2.y1);
|
|
}, Xa = function(e2, t2) {
|
|
return null == t2 ? e2 : Ya(e2, t2.x1, t2.y1, t2.x2, t2.y2);
|
|
}, Wa = function(e2, t2, n2) {
|
|
return Ke(e2, t2, n2);
|
|
}, Ha = function(e2, t2, n2) {
|
|
if (!t2.cy().headless()) {
|
|
var r2, i2, a2 = t2._private, o2 = a2.rstyle, s2 = o2.arrowWidth / 2;
|
|
if ("none" !== t2.pstyle(n2 + "-arrow-shape").value) {
|
|
"source" === n2 ? (r2 = o2.srcX, i2 = o2.srcY) : "target" === n2 ? (r2 = o2.tgtX, i2 = o2.tgtY) : (r2 = o2.midX, i2 = o2.midY);
|
|
var l2 = a2.arrowBounds = a2.arrowBounds || {}, u2 = l2[n2] = l2[n2] || {};
|
|
u2.x1 = r2 - s2, u2.y1 = i2 - s2, u2.x2 = r2 + s2, u2.y2 = i2 + s2, u2.w = u2.x2 - u2.x1, u2.h = u2.y2 - u2.y1, Mt(u2, 1), Ya(e2, u2.x1, u2.y1, u2.x2, u2.y2);
|
|
}
|
|
}
|
|
}, Ka = function(e2, t2, n2) {
|
|
if (!t2.cy().headless()) {
|
|
var r2;
|
|
r2 = n2 ? n2 + "-" : "";
|
|
var i2 = t2._private, a2 = i2.rstyle;
|
|
if (t2.pstyle(r2 + "label").strValue) {
|
|
var o2, s2, l2, u2, c2 = t2.pstyle("text-halign"), d2 = t2.pstyle("text-valign"), h2 = Wa(a2, "labelWidth", n2), p2 = Wa(a2, "labelHeight", n2), f2 = Wa(a2, "labelX", n2), g2 = Wa(a2, "labelY", n2), v2 = t2.pstyle(r2 + "text-margin-x").pfValue, y2 = t2.pstyle(r2 + "text-margin-y").pfValue, m2 = t2.isEdge(), b2 = t2.pstyle(r2 + "text-rotation"), x2 = t2.pstyle("text-outline-width").pfValue, w2 = t2.pstyle("text-border-width").pfValue / 2, E2 = t2.pstyle("text-background-padding").pfValue, k2 = p2, C2 = h2, S2 = C2 / 2, P2 = k2 / 2;
|
|
if (m2) o2 = f2 - S2, s2 = f2 + S2, l2 = g2 - P2, u2 = g2 + P2;
|
|
else {
|
|
switch (c2.value) {
|
|
case "left":
|
|
o2 = f2 - C2, s2 = f2;
|
|
break;
|
|
case "center":
|
|
o2 = f2 - S2, s2 = f2 + S2;
|
|
break;
|
|
case "right":
|
|
o2 = f2, s2 = f2 + C2;
|
|
}
|
|
switch (d2.value) {
|
|
case "top":
|
|
l2 = g2 - k2, u2 = g2;
|
|
break;
|
|
case "center":
|
|
l2 = g2 - P2, u2 = g2 + P2;
|
|
break;
|
|
case "bottom":
|
|
l2 = g2, u2 = g2 + k2;
|
|
}
|
|
}
|
|
o2 += v2 - Math.max(x2, w2) - E2 - 2, s2 += v2 + Math.max(x2, w2) + E2 + 2, l2 += y2 - Math.max(x2, w2) - E2 - 2, u2 += y2 + Math.max(x2, w2) + E2 + 2;
|
|
var D2 = n2 || "main", T2 = i2.labelBounds, _2 = T2[D2] = T2[D2] || {};
|
|
_2.x1 = o2, _2.y1 = l2, _2.x2 = s2, _2.y2 = u2, _2.w = s2 - o2, _2.h = u2 - l2;
|
|
var M2 = m2 && "autorotate" === b2.strValue, B2 = null != b2.pfValue && 0 !== b2.pfValue;
|
|
if (M2 || B2) {
|
|
var N2 = M2 ? Wa(i2.rstyle, "labelAngle", n2) : b2.pfValue, z2 = Math.cos(N2), I2 = Math.sin(N2), L3 = (o2 + s2) / 2, A2 = (l2 + u2) / 2;
|
|
if (!m2) {
|
|
switch (c2.value) {
|
|
case "left":
|
|
L3 = s2;
|
|
break;
|
|
case "right":
|
|
L3 = o2;
|
|
}
|
|
switch (d2.value) {
|
|
case "top":
|
|
A2 = u2;
|
|
break;
|
|
case "bottom":
|
|
A2 = l2;
|
|
}
|
|
}
|
|
var O2 = function(e3, t3) {
|
|
return { x: (e3 -= L3) * z2 - (t3 -= A2) * I2 + L3, y: e3 * I2 + t3 * z2 + A2 };
|
|
}, R2 = O2(o2, l2), V2 = O2(o2, u2), F2 = O2(s2, l2), j2 = O2(s2, u2);
|
|
o2 = Math.min(R2.x, V2.x, F2.x, j2.x), s2 = Math.max(R2.x, V2.x, F2.x, j2.x), l2 = Math.min(R2.y, V2.y, F2.y, j2.y), u2 = Math.max(R2.y, V2.y, F2.y, j2.y);
|
|
}
|
|
var q2 = D2 + "Rot", Y2 = T2[q2] = T2[q2] || {};
|
|
Y2.x1 = o2, Y2.y1 = l2, Y2.x2 = s2, Y2.y2 = u2, Y2.w = s2 - o2, Y2.h = u2 - l2, Ya(e2, o2, l2, s2, u2), Ya(i2.labelBounds.all, o2, l2, s2, u2);
|
|
}
|
|
return e2;
|
|
}
|
|
}, Ga = function(e2, t2) {
|
|
var n2, r2, i2, a2, o2, s2, l2, u2 = e2._private.cy, c2 = u2.styleEnabled(), d2 = u2.headless(), h2 = Dt(), p2 = e2._private, f2 = e2.isNode(), g2 = e2.isEdge(), v2 = p2.rstyle, y2 = f2 && c2 ? e2.pstyle("bounds-expansion").pfValue : [0], m2 = function(e3) {
|
|
return "none" !== e3.pstyle("display").value;
|
|
}, b2 = !c2 || m2(e2) && (!g2 || m2(e2.source()) && m2(e2.target()));
|
|
if (b2) {
|
|
var x2 = 0;
|
|
c2 && t2.includeOverlays && 0 !== e2.pstyle("overlay-opacity").value && (x2 = e2.pstyle("overlay-padding").value);
|
|
var w2 = 0;
|
|
c2 && t2.includeUnderlays && 0 !== e2.pstyle("underlay-opacity").value && (w2 = e2.pstyle("underlay-padding").value);
|
|
var E2 = Math.max(x2, w2), k2 = 0;
|
|
if (c2 && (k2 = e2.pstyle("width").pfValue / 2), f2 && t2.includeNodes) {
|
|
var C2 = e2.position();
|
|
o2 = C2.x, s2 = C2.y;
|
|
var S2 = e2.outerWidth() / 2, P2 = e2.outerHeight() / 2;
|
|
Ya(h2, n2 = o2 - S2, i2 = s2 - P2, r2 = o2 + S2, a2 = s2 + P2), c2 && t2.includeOutlines && function(e3, t3) {
|
|
if (!t3.cy().headless()) {
|
|
var n3, r3, i3, a3 = t3.pstyle("outline-opacity").value, o3 = t3.pstyle("outline-width").value;
|
|
if (a3 > 0 && o3 > 0) {
|
|
var s3 = t3.pstyle("outline-offset").value, l3 = t3.pstyle("shape").value, u3 = o3 + s3, c3 = (e3.w + 2 * u3) / e3.w, d3 = (e3.h + 2 * u3) / e3.h, h3 = 0;
|
|
["diamond", "pentagon", "round-triangle"].includes(l3) ? (c3 = (e3.w + 2.4 * u3) / e3.w, h3 = -u3 / 3.6) : ["concave-hexagon", "rhomboid", "right-rhomboid"].includes(l3) ? c3 = (e3.w + 2.4 * u3) / e3.w : "star" === l3 ? (c3 = (e3.w + 2.8 * u3) / e3.w, d3 = (e3.h + 2.6 * u3) / e3.h, h3 = -u3 / 3.8) : "triangle" === l3 ? (c3 = (e3.w + 2.8 * u3) / e3.w, d3 = (e3.h + 2.4 * u3) / e3.h, h3 = -u3 / 1.4) : "vee" === l3 && (c3 = (e3.w + 4.4 * u3) / e3.w, d3 = (e3.h + 3.8 * u3) / e3.h, h3 = 0.5 * -u3);
|
|
var p3 = e3.h * d3 - e3.h, f3 = e3.w * c3 - e3.w;
|
|
if (Bt(e3, [Math.ceil(p3 / 2), Math.ceil(f3 / 2)]), 0 !== h3) {
|
|
var g3 = (r3 = 0, i3 = h3, { x1: (n3 = e3).x1 + r3, x2: n3.x2 + r3, y1: n3.y1 + i3, y2: n3.y2 + i3, w: n3.w, h: n3.h });
|
|
Tt(e3, g3);
|
|
}
|
|
}
|
|
}
|
|
}(h2, e2);
|
|
} else if (g2 && t2.includeEdges) if (c2 && !d2) {
|
|
var D2 = e2.pstyle("curve-style").strValue;
|
|
if (n2 = Math.min(v2.srcX, v2.midX, v2.tgtX), r2 = Math.max(v2.srcX, v2.midX, v2.tgtX), i2 = Math.min(v2.srcY, v2.midY, v2.tgtY), a2 = Math.max(v2.srcY, v2.midY, v2.tgtY), Ya(h2, n2 -= k2, i2 -= k2, r2 += k2, a2 += k2), "haystack" === D2) {
|
|
var T2 = v2.haystackPts;
|
|
if (T2 && 2 === T2.length) {
|
|
if (n2 = T2[0].x, i2 = T2[0].y, n2 > (r2 = T2[1].x)) {
|
|
var _2 = n2;
|
|
n2 = r2, r2 = _2;
|
|
}
|
|
if (i2 > (a2 = T2[1].y)) {
|
|
var M2 = i2;
|
|
i2 = a2, a2 = M2;
|
|
}
|
|
Ya(h2, n2 - k2, i2 - k2, r2 + k2, a2 + k2);
|
|
}
|
|
} else if ("bezier" === D2 || "unbundled-bezier" === D2 || "segments" === D2 || "taxi" === D2) {
|
|
var B2;
|
|
switch (D2) {
|
|
case "bezier":
|
|
case "unbundled-bezier":
|
|
B2 = v2.bezierPts;
|
|
break;
|
|
case "segments":
|
|
case "taxi":
|
|
B2 = v2.linePts;
|
|
}
|
|
if (null != B2) for (var N2 = 0; N2 < B2.length; N2++) {
|
|
var z2 = B2[N2];
|
|
n2 = z2.x - k2, r2 = z2.x + k2, i2 = z2.y - k2, a2 = z2.y + k2, Ya(h2, n2, i2, r2, a2);
|
|
}
|
|
}
|
|
} else {
|
|
var I2 = e2.source().position(), L3 = e2.target().position();
|
|
if ((n2 = I2.x) > (r2 = L3.x)) {
|
|
var A2 = n2;
|
|
n2 = r2, r2 = A2;
|
|
}
|
|
if ((i2 = I2.y) > (a2 = L3.y)) {
|
|
var O2 = i2;
|
|
i2 = a2, a2 = O2;
|
|
}
|
|
Ya(h2, n2 -= k2, i2 -= k2, r2 += k2, a2 += k2);
|
|
}
|
|
if (c2 && t2.includeEdges && g2 && (Ha(h2, e2, "mid-source"), Ha(h2, e2, "mid-target"), Ha(h2, e2, "source"), Ha(h2, e2, "target")), c2) {
|
|
if ("yes" === e2.pstyle("ghost").value) {
|
|
var R2 = e2.pstyle("ghost-offset-x").pfValue, V2 = e2.pstyle("ghost-offset-y").pfValue;
|
|
Ya(h2, h2.x1 + R2, h2.y1 + V2, h2.x2 + R2, h2.y2 + V2);
|
|
}
|
|
}
|
|
var F2 = p2.bodyBounds = p2.bodyBounds || {};
|
|
Nt(F2, h2), Bt(F2, y2), Mt(F2, 1), c2 && (n2 = h2.x1, r2 = h2.x2, i2 = h2.y1, a2 = h2.y2, Ya(h2, n2 - E2, i2 - E2, r2 + E2, a2 + E2));
|
|
var j2 = p2.overlayBounds = p2.overlayBounds || {};
|
|
Nt(j2, h2), Bt(j2, y2), Mt(j2, 1);
|
|
var q2 = p2.labelBounds = p2.labelBounds || {};
|
|
null != q2.all ? ((l2 = q2.all).x1 = 1 / 0, l2.y1 = 1 / 0, l2.x2 = -1 / 0, l2.y2 = -1 / 0, l2.w = 0, l2.h = 0) : q2.all = Dt(), c2 && t2.includeLabels && (t2.includeMainLabels && Ka(h2, e2, null), g2 && (t2.includeSourceLabels && Ka(h2, e2, "source"), t2.includeTargetLabels && Ka(h2, e2, "target")));
|
|
}
|
|
return h2.x1 = qa(h2.x1), h2.y1 = qa(h2.y1), h2.x2 = qa(h2.x2), h2.y2 = qa(h2.y2), h2.w = qa(h2.x2 - h2.x1), h2.h = qa(h2.y2 - h2.y1), h2.w > 0 && h2.h > 0 && b2 && (Bt(h2, y2), Mt(h2, 1)), h2;
|
|
}, Ua = function(e2) {
|
|
var t2 = 0, n2 = function(e3) {
|
|
return (e3 ? 1 : 0) << t2++;
|
|
}, r2 = 0;
|
|
return r2 += n2(e2.incudeNodes), r2 += n2(e2.includeEdges), r2 += n2(e2.includeLabels), r2 += n2(e2.includeMainLabels), r2 += n2(e2.includeSourceLabels), r2 += n2(e2.includeTargetLabels), r2 += n2(e2.includeOverlays), r2 += n2(e2.includeOutlines);
|
|
}, Za = function(e2) {
|
|
if (e2.isEdge()) {
|
|
var t2 = e2.source().position(), n2 = e2.target().position(), r2 = function(e3) {
|
|
return Math.round(e3);
|
|
};
|
|
return function(e3, t3) {
|
|
var n3 = { value: 0, done: false }, r3 = 0, i2 = e3.length;
|
|
return we({ next: function() {
|
|
return r3 < i2 ? n3.value = e3[r3++] : n3.done = true, n3;
|
|
} }, t3);
|
|
}([r2(t2.x), r2(t2.y), r2(n2.x), r2(n2.y)]);
|
|
}
|
|
return 0;
|
|
}, $a = function(e2, t2) {
|
|
var n2, r2 = e2._private, i2 = e2.isEdge(), a2 = (null == t2 ? Ja : Ua(t2)) === Ja, o2 = Za(e2), s2 = r2.bbCachePosKey === o2, l2 = t2.useCache && s2, u2 = function(e3) {
|
|
return null == e3._private.bbCache || e3._private.styleDirty;
|
|
};
|
|
if (!l2 || u2(e2) || i2 && u2(e2.source()) || u2(e2.target()) ? (s2 || e2.recalculateRenderedStyle(l2), n2 = Ga(e2, Qa), r2.bbCache = n2, r2.bbCachePosKey = o2) : n2 = r2.bbCache, !a2) {
|
|
var c2 = e2.isNode();
|
|
n2 = Dt(), (t2.includeNodes && c2 || t2.includeEdges && !c2) && (t2.includeOverlays ? Xa(n2, r2.overlayBounds) : Xa(n2, r2.bodyBounds)), t2.includeLabels && (t2.includeMainLabels && (!i2 || t2.includeSourceLabels && t2.includeTargetLabels) ? Xa(n2, r2.labelBounds.all) : (t2.includeMainLabels && Xa(n2, r2.labelBounds.mainRot), t2.includeSourceLabels && Xa(n2, r2.labelBounds.sourceRot), t2.includeTargetLabels && Xa(n2, r2.labelBounds.targetRot))), n2.w = n2.x2 - n2.x1, n2.h = n2.y2 - n2.y1;
|
|
}
|
|
return n2;
|
|
}, Qa = { includeNodes: true, includeEdges: true, includeLabels: true, includeMainLabels: true, includeSourceLabels: true, includeTargetLabels: true, includeOverlays: true, includeUnderlays: true, includeOutlines: true, useCache: true }, Ja = Ua(Qa), eo = Xe(Qa);
|
|
Fa.boundingBox = function(e2) {
|
|
var t2;
|
|
if (1 !== this.length || null == this[0]._private.bbCache || this[0]._private.styleDirty || void 0 !== e2 && void 0 !== e2.useCache && true !== e2.useCache) {
|
|
t2 = Dt();
|
|
var n2 = eo(e2 = e2 || Qa);
|
|
if (this.cy().styleEnabled()) for (var r2 = 0; r2 < this.length; r2++) {
|
|
var i2 = this[r2], a2 = i2._private, o2 = Za(i2), s2 = a2.bbCachePosKey === o2, l2 = n2.useCache && s2 && !a2.styleDirty;
|
|
i2.recalculateRenderedStyle(l2);
|
|
}
|
|
this.updateCompoundBounds(!e2.useCache);
|
|
for (var u2 = 0; u2 < this.length; u2++) {
|
|
var c2 = this[u2];
|
|
Xa(t2, $a(c2, n2));
|
|
}
|
|
} else e2 = void 0 === e2 ? Qa : eo(e2), t2 = $a(this[0], e2);
|
|
return t2.x1 = qa(t2.x1), t2.y1 = qa(t2.y1), t2.x2 = qa(t2.x2), t2.y2 = qa(t2.y2), t2.w = qa(t2.x2 - t2.x1), t2.h = qa(t2.y2 - t2.y1), t2;
|
|
}, Fa.dirtyBoundingBoxCache = function() {
|
|
for (var e2 = 0; e2 < this.length; e2++) {
|
|
var t2 = this[e2]._private;
|
|
t2.bbCache = null, t2.bbCachePosKey = null, t2.bodyBounds = null, t2.overlayBounds = null, t2.labelBounds.all = null, t2.labelBounds.source = null, t2.labelBounds.target = null, t2.labelBounds.main = null, t2.labelBounds.sourceRot = null, t2.labelBounds.targetRot = null, t2.labelBounds.mainRot = null, t2.arrowBounds.source = null, t2.arrowBounds.target = null, t2.arrowBounds["mid-source"] = null, t2.arrowBounds["mid-target"] = null;
|
|
}
|
|
return this.emitAndNotify("bounds"), this;
|
|
}, Fa.boundingBoxAt = function(e2) {
|
|
var t2 = this.nodes(), n2 = this.cy(), r2 = n2.hasCompoundNodes(), i2 = n2.collection();
|
|
if (r2 && (i2 = t2.filter(function(e3) {
|
|
return e3.isParent();
|
|
}), t2 = t2.not(i2)), y(e2)) {
|
|
var a2 = e2;
|
|
e2 = function() {
|
|
return a2;
|
|
};
|
|
}
|
|
n2.startBatch(), t2.forEach(function(t3, n3) {
|
|
return t3._private.bbAtOldPos = e2(t3, n3);
|
|
}).silentPositions(e2), r2 && (i2.dirtyCompoundBoundsCache(), i2.dirtyBoundingBoxCache(), i2.updateCompoundBounds(true));
|
|
var o2 = function(e3) {
|
|
return { x1: e3.x1, x2: e3.x2, w: e3.w, y1: e3.y1, y2: e3.y2, h: e3.h };
|
|
}(this.boundingBox({ useCache: false }));
|
|
return t2.silentPositions(function(e3) {
|
|
return e3._private.bbAtOldPos;
|
|
}), r2 && (i2.dirtyCompoundBoundsCache(), i2.dirtyBoundingBoxCache(), i2.updateCompoundBounds(true)), n2.endBatch(), o2;
|
|
}, Va.boundingbox = Va.bb = Va.boundingBox, Va.renderedBoundingbox = Va.renderedBoundingBox;
|
|
var to, no, ro = Fa;
|
|
to = no = {};
|
|
var io = function(e2) {
|
|
e2.uppercaseName = B(e2.name), e2.autoName = "auto" + e2.uppercaseName, e2.labelName = "label" + e2.uppercaseName, e2.outerName = "outer" + e2.uppercaseName, e2.uppercaseOuterName = B(e2.outerName), to[e2.name] = function() {
|
|
var t2 = this[0], n2 = t2._private, r2 = n2.cy._private.styleEnabled;
|
|
if (t2) {
|
|
if (!r2) return 1;
|
|
if (t2.isParent()) return t2.updateCompoundBounds(), n2[e2.autoName] || 0;
|
|
var i2 = t2.pstyle(e2.name);
|
|
switch (i2.strValue) {
|
|
case "label":
|
|
return t2.recalculateRenderedStyle(), n2.rstyle[e2.labelName] || 0;
|
|
default:
|
|
return i2.pfValue;
|
|
}
|
|
}
|
|
}, to["outer" + e2.uppercaseName] = function() {
|
|
var t2 = this[0], n2 = t2._private.cy._private.styleEnabled;
|
|
if (t2) return n2 ? t2[e2.name]() + t2.pstyle("border-width").pfValue + 2 * t2.padding() : 1;
|
|
}, to["rendered" + e2.uppercaseName] = function() {
|
|
var t2 = this[0];
|
|
if (t2) return t2[e2.name]() * this.cy().zoom();
|
|
}, to["rendered" + e2.uppercaseOuterName] = function() {
|
|
var t2 = this[0];
|
|
if (t2) return t2[e2.outerName]() * this.cy().zoom();
|
|
};
|
|
};
|
|
io({ name: "width" }), io({ name: "height" }), no.padding = function() {
|
|
var e2 = this[0], t2 = e2._private;
|
|
return e2.isParent() ? (e2.updateCompoundBounds(), void 0 !== t2.autoPadding ? t2.autoPadding : e2.pstyle("padding").pfValue) : e2.pstyle("padding").pfValue;
|
|
}, no.paddedHeight = function() {
|
|
var e2 = this[0];
|
|
return e2.height() + 2 * e2.padding();
|
|
}, no.paddedWidth = function() {
|
|
var e2 = this[0];
|
|
return e2.width() + 2 * e2.padding();
|
|
};
|
|
var ao = no, oo = { controlPoints: { get: function(e2) {
|
|
return e2.renderer().getControlPoints(e2);
|
|
}, mult: true }, segmentPoints: { get: function(e2) {
|
|
return e2.renderer().getSegmentPoints(e2);
|
|
}, mult: true }, sourceEndpoint: { get: function(e2) {
|
|
return e2.renderer().getSourceEndpoint(e2);
|
|
} }, targetEndpoint: { get: function(e2) {
|
|
return e2.renderer().getTargetEndpoint(e2);
|
|
} }, midpoint: { get: function(e2) {
|
|
return e2.renderer().getEdgeMidpoint(e2);
|
|
} } }, so = Object.keys(oo).reduce(function(e2, t2) {
|
|
var n2 = oo[t2], r2 = function(e3) {
|
|
return "rendered" + e3[0].toUpperCase() + e3.substr(1);
|
|
}(t2);
|
|
return e2[t2] = function() {
|
|
return function(e3, t3) {
|
|
if (e3.isEdge()) return t3(e3);
|
|
}(this, n2.get);
|
|
}, n2.mult ? e2[r2] = function() {
|
|
return function(e3, t3) {
|
|
if (e3.isEdge()) {
|
|
var n3 = e3.cy(), r3 = n3.pan(), i2 = n3.zoom();
|
|
return t3(e3).map(function(e4) {
|
|
return gt(e4, i2, r3);
|
|
});
|
|
}
|
|
}(this, n2.get);
|
|
} : e2[r2] = function() {
|
|
return function(e3, t3) {
|
|
if (e3.isEdge()) {
|
|
var n3 = e3.cy();
|
|
return gt(t3(e3), n3.zoom(), n3.pan());
|
|
}
|
|
}(this, n2.get);
|
|
}, e2;
|
|
}, {}), lo = I({}, ja, ro, ao, so), uo = function(e2, t2) {
|
|
this.recycle(e2, t2);
|
|
};
|
|
function co() {
|
|
return false;
|
|
}
|
|
function ho() {
|
|
return true;
|
|
}
|
|
uo.prototype = { instanceString: function() {
|
|
return "event";
|
|
}, recycle: function(e2, t2) {
|
|
if (this.isImmediatePropagationStopped = this.isPropagationStopped = this.isDefaultPrevented = co, null != e2 && e2.preventDefault ? (this.type = e2.type, this.isDefaultPrevented = e2.defaultPrevented ? ho : co) : null != e2 && e2.type ? t2 = e2 : this.type = e2, null != t2 && (this.originalEvent = t2.originalEvent, this.type = null != t2.type ? t2.type : this.type, this.cy = t2.cy, this.target = t2.target, this.position = t2.position, this.renderedPosition = t2.renderedPosition, this.namespace = t2.namespace, this.layout = t2.layout), null != this.cy && null != this.position && null == this.renderedPosition) {
|
|
var n2 = this.position, r2 = this.cy.zoom(), i2 = this.cy.pan();
|
|
this.renderedPosition = { x: n2.x * r2 + i2.x, y: n2.y * r2 + i2.y };
|
|
}
|
|
this.timeStamp = e2 && e2.timeStamp || Date.now();
|
|
}, preventDefault: function() {
|
|
this.isDefaultPrevented = ho;
|
|
var e2 = this.originalEvent;
|
|
e2 && e2.preventDefault && e2.preventDefault();
|
|
}, stopPropagation: function() {
|
|
this.isPropagationStopped = ho;
|
|
var e2 = this.originalEvent;
|
|
e2 && e2.stopPropagation && e2.stopPropagation();
|
|
}, stopImmediatePropagation: function() {
|
|
this.isImmediatePropagationStopped = ho, this.stopPropagation();
|
|
}, isDefaultPrevented: co, isPropagationStopped: co, isImmediatePropagationStopped: co };
|
|
var po = /^([^.]+)(\.(?:[^.]+))?$/, fo = { qualifierCompare: function(e2, t2) {
|
|
return e2 === t2;
|
|
}, eventMatches: function() {
|
|
return true;
|
|
}, addEventFields: function() {
|
|
}, callbackContext: function(e2) {
|
|
return e2;
|
|
}, beforeEmit: function() {
|
|
}, afterEmit: function() {
|
|
}, bubble: function() {
|
|
return false;
|
|
}, parent: function() {
|
|
return null;
|
|
}, context: null }, go = Object.keys(fo), vo = {};
|
|
function yo() {
|
|
for (var e2 = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : vo, t2 = arguments.length > 1 ? arguments[1] : void 0, n2 = 0; n2 < go.length; n2++) {
|
|
var r2 = go[n2];
|
|
this[r2] = e2[r2] || fo[r2];
|
|
}
|
|
this.context = t2 || this.context, this.listeners = [], this.emitting = 0;
|
|
}
|
|
var mo = yo.prototype, bo = function(e2, t2, n2, r2, i2, a2, o2) {
|
|
g(r2) && (i2 = r2, r2 = null), o2 && (a2 = null == a2 ? o2 : I({}, a2, o2));
|
|
for (var s2 = v(n2) ? n2 : n2.split(/\s+/), l2 = 0; l2 < s2.length; l2++) {
|
|
var u2 = s2[l2];
|
|
if (!S(u2)) {
|
|
var c2 = u2.match(po);
|
|
if (c2) {
|
|
if (false === t2(e2, u2, c2[1], c2[2] ? c2[2] : null, r2, i2, a2)) break;
|
|
}
|
|
}
|
|
}
|
|
}, xo = function(e2, t2) {
|
|
return e2.addEventFields(e2.context, t2), new uo(t2.type, t2);
|
|
}, wo = function(e2, t2, n2) {
|
|
if ("event" !== p(n2)) if (y(n2)) t2(e2, xo(e2, n2));
|
|
else for (var r2 = v(n2) ? n2 : n2.split(/\s+/), i2 = 0; i2 < r2.length; i2++) {
|
|
var a2 = r2[i2];
|
|
if (!S(a2)) {
|
|
var o2 = a2.match(po);
|
|
if (o2) {
|
|
var s2 = o2[1], l2 = o2[2] ? o2[2] : null;
|
|
t2(e2, xo(e2, { type: s2, namespace: l2, target: e2.context }));
|
|
}
|
|
}
|
|
}
|
|
else t2(e2, n2);
|
|
};
|
|
mo.on = mo.addListener = function(e2, t2, n2, r2, i2) {
|
|
return bo(this, function(e3, t3, n3, r3, i3, a2, o2) {
|
|
g(a2) && e3.listeners.push({ event: t3, callback: a2, type: n3, namespace: r3, qualifier: i3, conf: o2 });
|
|
}, e2, t2, n2, r2, i2), this;
|
|
}, mo.one = function(e2, t2, n2, r2) {
|
|
return this.on(e2, t2, n2, r2, { one: true });
|
|
}, mo.removeListener = mo.off = function(e2, t2, n2, r2) {
|
|
var i2 = this;
|
|
0 !== this.emitting && (this.listeners = this.listeners.slice());
|
|
for (var a2 = this.listeners, o2 = function(o3) {
|
|
var s3 = a2[o3];
|
|
bo(i2, function(t3, n3, r3, i3, l2, u2) {
|
|
if ((s3.type === r3 || "*" === e2) && (!i3 && ".*" !== s3.namespace || s3.namespace === i3) && (!l2 || t3.qualifierCompare(s3.qualifier, l2)) && (!u2 || s3.callback === u2)) return a2.splice(o3, 1), false;
|
|
}, e2, t2, n2, r2);
|
|
}, s2 = a2.length - 1; s2 >= 0; s2--) o2(s2);
|
|
return this;
|
|
}, mo.removeAllListeners = function() {
|
|
return this.removeListener("*");
|
|
}, mo.emit = mo.trigger = function(e2, t2, n2) {
|
|
var r2 = this.listeners, i2 = r2.length;
|
|
return this.emitting++, v(t2) || (t2 = [t2]), wo(this, function(e3, a2) {
|
|
null != n2 && (r2 = [{ event: a2.event, type: a2.type, namespace: a2.namespace, callback: n2 }], i2 = r2.length);
|
|
for (var o2 = function(n3) {
|
|
var i3 = r2[n3];
|
|
if (i3.type === a2.type && (!i3.namespace || i3.namespace === a2.namespace || ".*" === i3.namespace) && e3.eventMatches(e3.context, i3, a2)) {
|
|
var o3 = [a2];
|
|
null != t2 && function(e4, t3) {
|
|
for (var n4 = 0; n4 < t3.length; n4++) {
|
|
var r3 = t3[n4];
|
|
e4.push(r3);
|
|
}
|
|
}(o3, t2), e3.beforeEmit(e3.context, i3, a2), i3.conf && i3.conf.one && (e3.listeners = e3.listeners.filter(function(e4) {
|
|
return e4 !== i3;
|
|
}));
|
|
var s3 = e3.callbackContext(e3.context, i3, a2), l2 = i3.callback.apply(s3, o3);
|
|
e3.afterEmit(e3.context, i3, a2), false === l2 && (a2.stopPropagation(), a2.preventDefault());
|
|
}
|
|
}, s2 = 0; s2 < i2; s2++) o2(s2);
|
|
e3.bubble(e3.context) && !a2.isPropagationStopped() && e3.parent(e3.context).emit(a2, t2);
|
|
}, e2), this.emitting--, this;
|
|
};
|
|
var Eo = { qualifierCompare: function(e2, t2) {
|
|
return null == e2 || null == t2 ? null == e2 && null == t2 : e2.sameText(t2);
|
|
}, eventMatches: function(e2, t2, n2) {
|
|
var r2 = t2.qualifier;
|
|
return null == r2 || e2 !== n2.target && w(n2.target) && r2.matches(n2.target);
|
|
}, addEventFields: function(e2, t2) {
|
|
t2.cy = e2.cy(), t2.target = e2;
|
|
}, callbackContext: function(e2, t2, n2) {
|
|
return null != t2.qualifier ? n2.target : e2;
|
|
}, beforeEmit: function(e2, t2) {
|
|
t2.conf && t2.conf.once && t2.conf.onceCollection.removeListener(t2.event, t2.qualifier, t2.callback);
|
|
}, bubble: function() {
|
|
return true;
|
|
}, parent: function(e2) {
|
|
return e2.isChild() ? e2.parent() : e2.cy();
|
|
} }, ko = function(e2) {
|
|
return f(e2) ? new xa(e2) : e2;
|
|
}, Co = { createEmitter: function() {
|
|
for (var e2 = 0; e2 < this.length; e2++) {
|
|
var t2 = this[e2], n2 = t2._private;
|
|
n2.emitter || (n2.emitter = new yo(Eo, t2));
|
|
}
|
|
return this;
|
|
}, emitter: function() {
|
|
return this._private.emitter;
|
|
}, on: function(e2, t2, n2) {
|
|
for (var r2 = ko(t2), i2 = 0; i2 < this.length; i2++) {
|
|
this[i2].emitter().on(e2, r2, n2);
|
|
}
|
|
return this;
|
|
}, removeListener: function(e2, t2, n2) {
|
|
for (var r2 = ko(t2), i2 = 0; i2 < this.length; i2++) {
|
|
this[i2].emitter().removeListener(e2, r2, n2);
|
|
}
|
|
return this;
|
|
}, removeAllListeners: function() {
|
|
for (var e2 = 0; e2 < this.length; e2++) {
|
|
this[e2].emitter().removeAllListeners();
|
|
}
|
|
return this;
|
|
}, one: function(e2, t2, n2) {
|
|
for (var r2 = ko(t2), i2 = 0; i2 < this.length; i2++) {
|
|
this[i2].emitter().one(e2, r2, n2);
|
|
}
|
|
return this;
|
|
}, once: function(e2, t2, n2) {
|
|
for (var r2 = ko(t2), i2 = 0; i2 < this.length; i2++) {
|
|
this[i2].emitter().on(e2, r2, n2, { once: true, onceCollection: this });
|
|
}
|
|
}, emit: function(e2, t2) {
|
|
for (var n2 = 0; n2 < this.length; n2++) {
|
|
this[n2].emitter().emit(e2, t2);
|
|
}
|
|
return this;
|
|
}, emitAndNotify: function(e2, t2) {
|
|
if (0 !== this.length) return this.cy().notify(e2, this), this.emit(e2, t2), this;
|
|
} };
|
|
Oi.eventAliasesOn(Co);
|
|
var So = { nodes: function(e2) {
|
|
return this.filter(function(e3) {
|
|
return e3.isNode();
|
|
}).filter(e2);
|
|
}, edges: function(e2) {
|
|
return this.filter(function(e3) {
|
|
return e3.isEdge();
|
|
}).filter(e2);
|
|
}, byGroup: function() {
|
|
for (var e2 = this.spawn(), t2 = this.spawn(), n2 = 0; n2 < this.length; n2++) {
|
|
var r2 = this[n2];
|
|
r2.isNode() ? e2.push(r2) : t2.push(r2);
|
|
}
|
|
return { nodes: e2, edges: t2 };
|
|
}, filter: function(e2, t2) {
|
|
if (void 0 === e2) return this;
|
|
if (f(e2) || x(e2)) return new xa(e2).filter(this);
|
|
if (g(e2)) {
|
|
for (var n2 = this.spawn(), r2 = 0; r2 < this.length; r2++) {
|
|
var i2 = this[r2];
|
|
(t2 ? e2.apply(t2, [i2, r2, this]) : e2(i2, r2, this)) && n2.push(i2);
|
|
}
|
|
return n2;
|
|
}
|
|
return this.spawn();
|
|
}, not: function(e2) {
|
|
if (e2) {
|
|
f(e2) && (e2 = this.filter(e2));
|
|
for (var t2 = this.spawn(), n2 = 0; n2 < this.length; n2++) {
|
|
var r2 = this[n2];
|
|
e2.has(r2) || t2.push(r2);
|
|
}
|
|
return t2;
|
|
}
|
|
return this;
|
|
}, absoluteComplement: function() {
|
|
return this.cy().mutableElements().not(this);
|
|
}, intersect: function(e2) {
|
|
if (f(e2)) {
|
|
var t2 = e2;
|
|
return this.filter(t2);
|
|
}
|
|
for (var n2 = this.spawn(), r2 = e2, i2 = this.length < e2.length, a2 = i2 ? this : r2, o2 = i2 ? r2 : this, s2 = 0; s2 < a2.length; s2++) {
|
|
var l2 = a2[s2];
|
|
o2.has(l2) && n2.push(l2);
|
|
}
|
|
return n2;
|
|
}, xor: function(e2) {
|
|
var t2 = this._private.cy;
|
|
f(e2) && (e2 = t2.$(e2));
|
|
var n2 = this.spawn(), r2 = e2, i2 = function(e3, t3) {
|
|
for (var r3 = 0; r3 < e3.length; r3++) {
|
|
var i3 = e3[r3], a2 = i3._private.data.id;
|
|
t3.hasElementWithId(a2) || n2.push(i3);
|
|
}
|
|
};
|
|
return i2(this, r2), i2(r2, this), n2;
|
|
}, diff: function(e2) {
|
|
var t2 = this._private.cy;
|
|
f(e2) && (e2 = t2.$(e2));
|
|
var n2 = this.spawn(), r2 = this.spawn(), i2 = this.spawn(), a2 = e2, o2 = function(e3, t3, n3) {
|
|
for (var r3 = 0; r3 < e3.length; r3++) {
|
|
var a3 = e3[r3], o3 = a3._private.data.id;
|
|
t3.hasElementWithId(o3) ? i2.merge(a3) : n3.push(a3);
|
|
}
|
|
};
|
|
return o2(this, a2, n2), o2(a2, this, r2), { left: n2, right: r2, both: i2 };
|
|
}, add: function(e2) {
|
|
var t2 = this._private.cy;
|
|
if (!e2) return this;
|
|
if (f(e2)) {
|
|
var n2 = e2;
|
|
e2 = t2.mutableElements().filter(n2);
|
|
}
|
|
for (var r2 = this.spawnSelf(), i2 = 0; i2 < e2.length; i2++) {
|
|
var a2 = e2[i2], o2 = !this.has(a2);
|
|
o2 && r2.push(a2);
|
|
}
|
|
return r2;
|
|
}, merge: function(e2) {
|
|
var t2 = this._private, n2 = t2.cy;
|
|
if (!e2) return this;
|
|
if (e2 && f(e2)) {
|
|
var r2 = e2;
|
|
e2 = n2.mutableElements().filter(r2);
|
|
}
|
|
for (var i2 = t2.map, a2 = 0; a2 < e2.length; a2++) {
|
|
var o2 = e2[a2], s2 = o2._private.data.id;
|
|
if (!i2.has(s2)) {
|
|
var l2 = this.length++;
|
|
this[l2] = o2, i2.set(s2, { ele: o2, index: l2 });
|
|
}
|
|
}
|
|
return this;
|
|
}, unmergeAt: function(e2) {
|
|
var t2 = this[e2].id(), n2 = this._private.map;
|
|
this[e2] = void 0, n2.delete(t2);
|
|
var r2 = e2 === this.length - 1;
|
|
if (this.length > 1 && !r2) {
|
|
var i2 = this.length - 1, a2 = this[i2], o2 = a2._private.data.id;
|
|
this[i2] = void 0, this[e2] = a2, n2.set(o2, { ele: a2, index: e2 });
|
|
}
|
|
return this.length--, this;
|
|
}, unmergeOne: function(e2) {
|
|
e2 = e2[0];
|
|
var t2 = this._private, n2 = e2._private.data.id, r2 = t2.map.get(n2);
|
|
if (!r2) return this;
|
|
var i2 = r2.index;
|
|
return this.unmergeAt(i2), this;
|
|
}, unmerge: function(e2) {
|
|
var t2 = this._private.cy;
|
|
if (!e2) return this;
|
|
if (e2 && f(e2)) {
|
|
var n2 = e2;
|
|
e2 = t2.mutableElements().filter(n2);
|
|
}
|
|
for (var r2 = 0; r2 < e2.length; r2++) this.unmergeOne(e2[r2]);
|
|
return this;
|
|
}, unmergeBy: function(e2) {
|
|
for (var t2 = this.length - 1; t2 >= 0; t2--) {
|
|
e2(this[t2]) && this.unmergeAt(t2);
|
|
}
|
|
return this;
|
|
}, map: function(e2, t2) {
|
|
for (var n2 = [], r2 = 0; r2 < this.length; r2++) {
|
|
var i2 = this[r2], a2 = t2 ? e2.apply(t2, [i2, r2, this]) : e2(i2, r2, this);
|
|
n2.push(a2);
|
|
}
|
|
return n2;
|
|
}, reduce: function(e2, t2) {
|
|
for (var n2 = t2, r2 = 0; r2 < this.length; r2++) n2 = e2(n2, this[r2], r2, this);
|
|
return n2;
|
|
}, max: function(e2, t2) {
|
|
for (var n2, r2 = -1 / 0, i2 = 0; i2 < this.length; i2++) {
|
|
var a2 = this[i2], o2 = t2 ? e2.apply(t2, [a2, i2, this]) : e2(a2, i2, this);
|
|
o2 > r2 && (r2 = o2, n2 = a2);
|
|
}
|
|
return { value: r2, ele: n2 };
|
|
}, min: function(e2, t2) {
|
|
for (var n2, r2 = 1 / 0, i2 = 0; i2 < this.length; i2++) {
|
|
var a2 = this[i2], o2 = t2 ? e2.apply(t2, [a2, i2, this]) : e2(a2, i2, this);
|
|
o2 < r2 && (r2 = o2, n2 = a2);
|
|
}
|
|
return { value: r2, ele: n2 };
|
|
} }, Po = So;
|
|
Po.u = Po["|"] = Po["+"] = Po.union = Po.or = Po.add, Po["\\"] = Po["!"] = Po["-"] = Po.difference = Po.relativeComplement = Po.subtract = Po.not, Po.n = Po["&"] = Po["."] = Po.and = Po.intersection = Po.intersect, Po["^"] = Po["(+)"] = Po["(-)"] = Po.symmetricDifference = Po.symdiff = Po.xor, Po.fnFilter = Po.filterFn = Po.stdFilter = Po.filter, Po.complement = Po.abscomp = Po.absoluteComplement;
|
|
var Do = function(e2, t2) {
|
|
var n2 = e2.cy().hasCompoundNodes();
|
|
function r2(e3) {
|
|
var t3 = e3.pstyle("z-compound-depth");
|
|
return "auto" === t3.value ? n2 ? e3.zDepth() : 0 : "bottom" === t3.value ? -1 : "top" === t3.value ? Ne : 0;
|
|
}
|
|
var i2 = r2(e2) - r2(t2);
|
|
if (0 !== i2) return i2;
|
|
function a2(e3) {
|
|
return "auto" === e3.pstyle("z-index-compare").value && e3.isNode() ? 1 : 0;
|
|
}
|
|
var o2 = a2(e2) - a2(t2);
|
|
if (0 !== o2) return o2;
|
|
var s2 = e2.pstyle("z-index").value - t2.pstyle("z-index").value;
|
|
return 0 !== s2 ? s2 : e2.poolIndex() - t2.poolIndex();
|
|
}, To = { forEach: function(e2, t2) {
|
|
if (g(e2)) for (var n2 = this.length, r2 = 0; r2 < n2; r2++) {
|
|
var i2 = this[r2];
|
|
if (false === (t2 ? e2.apply(t2, [i2, r2, this]) : e2(i2, r2, this))) break;
|
|
}
|
|
return this;
|
|
}, toArray: function() {
|
|
for (var e2 = [], t2 = 0; t2 < this.length; t2++) e2.push(this[t2]);
|
|
return e2;
|
|
}, slice: function(e2, t2) {
|
|
var n2 = [], r2 = this.length;
|
|
null == t2 && (t2 = r2), null == e2 && (e2 = 0), e2 < 0 && (e2 = r2 + e2), t2 < 0 && (t2 = r2 + t2);
|
|
for (var i2 = e2; i2 >= 0 && i2 < t2 && i2 < r2; i2++) n2.push(this[i2]);
|
|
return this.spawn(n2);
|
|
}, size: function() {
|
|
return this.length;
|
|
}, eq: function(e2) {
|
|
return this[e2] || this.spawn();
|
|
}, first: function() {
|
|
return this[0] || this.spawn();
|
|
}, last: function() {
|
|
return this[this.length - 1] || this.spawn();
|
|
}, empty: function() {
|
|
return 0 === this.length;
|
|
}, nonempty: function() {
|
|
return !this.empty();
|
|
}, sort: function(e2) {
|
|
if (!g(e2)) return this;
|
|
var t2 = this.toArray().sort(e2);
|
|
return this.spawn(t2);
|
|
}, sortByZIndex: function() {
|
|
return this.sort(Do);
|
|
}, zDepth: function() {
|
|
var e2 = this[0];
|
|
if (e2) {
|
|
var t2 = e2._private;
|
|
if ("nodes" === t2.group) {
|
|
var n2 = t2.data.parent ? e2.parents().size() : 0;
|
|
return e2.isParent() ? n2 : Ne - 1;
|
|
}
|
|
var r2 = t2.source, i2 = t2.target, a2 = r2.zDepth(), o2 = i2.zDepth();
|
|
return Math.max(a2, o2, 0);
|
|
}
|
|
} };
|
|
To.each = To.forEach;
|
|
"undefined" != ("undefined" == typeof Symbol ? "undefined" : e(Symbol)) && "undefined" != e(Symbol.iterator) && (To[Symbol.iterator] = function() {
|
|
var e2 = this, t2 = { value: void 0, done: false }, n2 = 0, r2 = this.length;
|
|
return i({ next: function() {
|
|
return n2 < r2 ? t2.value = e2[n2++] : (t2.value = void 0, t2.done = true), t2;
|
|
} }, Symbol.iterator, function() {
|
|
return this;
|
|
});
|
|
});
|
|
var _o = Xe({ nodeDimensionsIncludeLabels: false }), Mo = { layoutDimensions: function(e2) {
|
|
var t2;
|
|
if (e2 = _o(e2), this.takesUpSpace()) if (e2.nodeDimensionsIncludeLabels) {
|
|
var n2 = this.boundingBox();
|
|
t2 = { w: n2.w, h: n2.h };
|
|
} else t2 = { w: this.outerWidth(), h: this.outerHeight() };
|
|
else t2 = { w: 0, h: 0 };
|
|
return 0 !== t2.w && 0 !== t2.h || (t2.w = t2.h = 1), t2;
|
|
}, layoutPositions: function(e2, t2, n2) {
|
|
var r2 = this.nodes().filter(function(e3) {
|
|
return !e3.isParent();
|
|
}), i2 = this.cy(), a2 = t2.eles, o2 = function(e3) {
|
|
return e3.id();
|
|
}, s2 = D(n2, o2);
|
|
e2.emit({ type: "layoutstart", layout: e2 }), e2.animations = [];
|
|
var l2 = t2.spacingFactor && 1 !== t2.spacingFactor, u2 = function() {
|
|
if (!l2) return null;
|
|
for (var e3 = Dt(), t3 = 0; t3 < r2.length; t3++) {
|
|
var n3 = r2[t3], i3 = s2(n3, t3);
|
|
_t(e3, i3.x, i3.y);
|
|
}
|
|
return e3;
|
|
}(), c2 = D(function(e3, n3) {
|
|
var r3 = s2(e3, n3);
|
|
l2 && (r3 = function(e4, t3, n4) {
|
|
var r4 = t3.x1 + t3.w / 2, i3 = t3.y1 + t3.h / 2;
|
|
return { x: r4 + (n4.x - r4) * e4, y: i3 + (n4.y - i3) * e4 };
|
|
}(Math.abs(t2.spacingFactor), u2, r3));
|
|
return null != t2.transform && (r3 = t2.transform(e3, r3)), r3;
|
|
}, o2);
|
|
if (t2.animate) {
|
|
for (var d2 = 0; d2 < r2.length; d2++) {
|
|
var h2 = r2[d2], p2 = c2(h2, d2);
|
|
if (null == t2.animateFilter || t2.animateFilter(h2, d2)) {
|
|
var f2 = h2.animation({ position: p2, duration: t2.animationDuration, easing: t2.animationEasing });
|
|
e2.animations.push(f2);
|
|
} else h2.position(p2);
|
|
}
|
|
if (t2.fit) {
|
|
var g2 = i2.animation({ fit: { boundingBox: a2.boundingBoxAt(c2), padding: t2.padding }, duration: t2.animationDuration, easing: t2.animationEasing });
|
|
e2.animations.push(g2);
|
|
} else if (void 0 !== t2.zoom && void 0 !== t2.pan) {
|
|
var v2 = i2.animation({ zoom: t2.zoom, pan: t2.pan, duration: t2.animationDuration, easing: t2.animationEasing });
|
|
e2.animations.push(v2);
|
|
}
|
|
e2.animations.forEach(function(e3) {
|
|
return e3.play();
|
|
}), e2.one("layoutready", t2.ready), e2.emit({ type: "layoutready", layout: e2 }), pr.all(e2.animations.map(function(e3) {
|
|
return e3.promise();
|
|
})).then(function() {
|
|
e2.one("layoutstop", t2.stop), e2.emit({ type: "layoutstop", layout: e2 });
|
|
});
|
|
} else r2.positions(c2), t2.fit && i2.fit(t2.eles, t2.padding), null != t2.zoom && i2.zoom(t2.zoom), t2.pan && i2.pan(t2.pan), e2.one("layoutready", t2.ready), e2.emit({ type: "layoutready", layout: e2 }), e2.one("layoutstop", t2.stop), e2.emit({ type: "layoutstop", layout: e2 });
|
|
return this;
|
|
}, layout: function(e2) {
|
|
return this.cy().makeLayout(I({}, e2, { eles: this }));
|
|
} };
|
|
function Bo(e2, t2, n2) {
|
|
var r2, i2 = n2._private, a2 = i2.styleCache = i2.styleCache || [];
|
|
return null != (r2 = a2[e2]) ? r2 : r2 = a2[e2] = t2(n2);
|
|
}
|
|
function No(e2, t2) {
|
|
return e2 = Pe(e2), function(n2) {
|
|
return Bo(e2, t2, n2);
|
|
};
|
|
}
|
|
function zo(e2, t2) {
|
|
e2 = Pe(e2);
|
|
var n2 = function(e3) {
|
|
return t2.call(e3);
|
|
};
|
|
return function() {
|
|
var t3 = this[0];
|
|
if (t3) return Bo(e2, n2, t3);
|
|
};
|
|
}
|
|
Mo.createLayout = Mo.makeLayout = Mo.layout;
|
|
var Io = { recalculateRenderedStyle: function(e2) {
|
|
var t2 = this.cy(), n2 = t2.renderer(), r2 = t2.styleEnabled();
|
|
return n2 && r2 && n2.recalculateRenderedStyle(this, e2), this;
|
|
}, dirtyStyleCache: function() {
|
|
var e2, t2 = this.cy(), n2 = function(e3) {
|
|
return e3._private.styleCache = null;
|
|
};
|
|
t2.hasCompoundNodes() ? ((e2 = this.spawnSelf().merge(this.descendants()).merge(this.parents())).merge(e2.connectedEdges()), e2.forEach(n2)) : this.forEach(function(e3) {
|
|
n2(e3), e3.connectedEdges().forEach(n2);
|
|
});
|
|
return this;
|
|
}, updateStyle: function(e2) {
|
|
var t2 = this._private.cy;
|
|
if (!t2.styleEnabled()) return this;
|
|
if (t2.batching()) return t2._private.batchStyleEles.merge(this), this;
|
|
var n2 = this;
|
|
e2 = !(!e2 && void 0 !== e2), t2.hasCompoundNodes() && (n2 = this.spawnSelf().merge(this.descendants()).merge(this.parents()));
|
|
var r2 = n2;
|
|
return e2 ? r2.emitAndNotify("style") : r2.emit("style"), n2.forEach(function(e3) {
|
|
return e3._private.styleDirty = true;
|
|
}), this;
|
|
}, cleanStyle: function() {
|
|
var e2 = this.cy();
|
|
if (e2.styleEnabled()) for (var t2 = 0; t2 < this.length; t2++) {
|
|
var n2 = this[t2];
|
|
n2._private.styleDirty && (n2._private.styleDirty = false, e2.style().apply(n2));
|
|
}
|
|
}, parsedStyle: function(e2) {
|
|
var t2 = !(arguments.length > 1 && void 0 !== arguments[1]) || arguments[1], n2 = this[0], r2 = n2.cy();
|
|
if (r2.styleEnabled() && n2) {
|
|
this.cleanStyle();
|
|
var i2 = n2._private.style[e2];
|
|
return null != i2 ? i2 : t2 ? r2.style().getDefaultProperty(e2) : null;
|
|
}
|
|
}, numericStyle: function(e2) {
|
|
var t2 = this[0];
|
|
if (t2.cy().styleEnabled() && t2) {
|
|
var n2 = t2.pstyle(e2);
|
|
return void 0 !== n2.pfValue ? n2.pfValue : n2.value;
|
|
}
|
|
}, numericStyleUnits: function(e2) {
|
|
var t2 = this[0];
|
|
if (t2.cy().styleEnabled()) return t2 ? t2.pstyle(e2).units : void 0;
|
|
}, renderedStyle: function(e2) {
|
|
var t2 = this.cy();
|
|
if (!t2.styleEnabled()) return this;
|
|
var n2 = this[0];
|
|
return n2 ? t2.style().getRenderedStyle(n2, e2) : void 0;
|
|
}, style: function(e2, t2) {
|
|
var n2 = this.cy();
|
|
if (!n2.styleEnabled()) return this;
|
|
var r2 = n2.style();
|
|
if (y(e2)) {
|
|
var i2 = e2;
|
|
r2.applyBypass(this, i2, false), this.emitAndNotify("style");
|
|
} else if (f(e2)) {
|
|
if (void 0 === t2) {
|
|
var a2 = this[0];
|
|
return a2 ? r2.getStylePropertyValue(a2, e2) : void 0;
|
|
}
|
|
r2.applyBypass(this, e2, t2, false), this.emitAndNotify("style");
|
|
} else if (void 0 === e2) {
|
|
var o2 = this[0];
|
|
return o2 ? r2.getRawStyle(o2) : void 0;
|
|
}
|
|
return this;
|
|
}, removeStyle: function(e2) {
|
|
var t2 = this.cy();
|
|
if (!t2.styleEnabled()) return this;
|
|
var n2 = t2.style();
|
|
if (void 0 === e2) for (var r2 = 0; r2 < this.length; r2++) {
|
|
var i2 = this[r2];
|
|
n2.removeAllBypasses(i2, false);
|
|
}
|
|
else {
|
|
e2 = e2.split(/\s+/);
|
|
for (var a2 = 0; a2 < this.length; a2++) {
|
|
var o2 = this[a2];
|
|
n2.removeBypasses(o2, e2, false);
|
|
}
|
|
}
|
|
return this.emitAndNotify("style"), this;
|
|
}, show: function() {
|
|
return this.css("display", "element"), this;
|
|
}, hide: function() {
|
|
return this.css("display", "none"), this;
|
|
}, effectiveOpacity: function() {
|
|
var e2 = this.cy();
|
|
if (!e2.styleEnabled()) return 1;
|
|
var t2 = e2.hasCompoundNodes(), n2 = this[0];
|
|
if (n2) {
|
|
var r2 = n2._private, i2 = n2.pstyle("opacity").value;
|
|
if (!t2) return i2;
|
|
var a2 = r2.data.parent ? n2.parents() : null;
|
|
if (a2) for (var o2 = 0; o2 < a2.length; o2++) {
|
|
i2 *= a2[o2].pstyle("opacity").value;
|
|
}
|
|
return i2;
|
|
}
|
|
}, transparent: function() {
|
|
if (!this.cy().styleEnabled()) return false;
|
|
var e2 = this[0], t2 = e2.cy().hasCompoundNodes();
|
|
return e2 ? t2 ? 0 === e2.effectiveOpacity() : 0 === e2.pstyle("opacity").value : void 0;
|
|
}, backgrounding: function() {
|
|
return !!this.cy().styleEnabled() && !!this[0]._private.backgrounding;
|
|
} };
|
|
function Lo(e2, t2) {
|
|
var n2 = e2._private.data.parent ? e2.parents() : null;
|
|
if (n2) for (var r2 = 0; r2 < n2.length; r2++) {
|
|
if (!t2(n2[r2])) return false;
|
|
}
|
|
return true;
|
|
}
|
|
function Ao(e2) {
|
|
var t2 = e2.ok, n2 = e2.edgeOkViaNode || e2.ok, r2 = e2.parentOk || e2.ok;
|
|
return function() {
|
|
var e3 = this.cy();
|
|
if (!e3.styleEnabled()) return true;
|
|
var i2 = this[0], a2 = e3.hasCompoundNodes();
|
|
if (i2) {
|
|
var o2 = i2._private;
|
|
if (!t2(i2)) return false;
|
|
if (i2.isNode()) return !a2 || Lo(i2, r2);
|
|
var s2 = o2.source, l2 = o2.target;
|
|
return n2(s2) && (!a2 || Lo(s2, n2)) && (s2 === l2 || n2(l2) && (!a2 || Lo(l2, n2)));
|
|
}
|
|
};
|
|
}
|
|
var Oo = No("eleTakesUpSpace", function(e2) {
|
|
return "element" === e2.pstyle("display").value && 0 !== e2.width() && (!e2.isNode() || 0 !== e2.height());
|
|
});
|
|
Io.takesUpSpace = zo("takesUpSpace", Ao({ ok: Oo }));
|
|
var Ro = No("eleInteractive", function(e2) {
|
|
return "yes" === e2.pstyle("events").value && "visible" === e2.pstyle("visibility").value && Oo(e2);
|
|
}), Vo = No("parentInteractive", function(e2) {
|
|
return "visible" === e2.pstyle("visibility").value && Oo(e2);
|
|
});
|
|
Io.interactive = zo("interactive", Ao({ ok: Ro, parentOk: Vo, edgeOkViaNode: Oo })), Io.noninteractive = function() {
|
|
var e2 = this[0];
|
|
if (e2) return !e2.interactive();
|
|
};
|
|
var Fo = No("eleVisible", function(e2) {
|
|
return "visible" === e2.pstyle("visibility").value && 0 !== e2.pstyle("opacity").pfValue && Oo(e2);
|
|
}), jo = Oo;
|
|
Io.visible = zo("visible", Ao({ ok: Fo, edgeOkViaNode: jo })), Io.hidden = function() {
|
|
var e2 = this[0];
|
|
if (e2) return !e2.visible();
|
|
}, Io.isBundledBezier = zo("isBundledBezier", function() {
|
|
return !!this.cy().styleEnabled() && (!this.removed() && "bezier" === this.pstyle("curve-style").value && this.takesUpSpace());
|
|
}), Io.bypass = Io.css = Io.style, Io.renderedCss = Io.renderedStyle, Io.removeBypass = Io.removeCss = Io.removeStyle, Io.pstyle = Io.parsedStyle;
|
|
var qo = {};
|
|
function Yo(e2) {
|
|
return function() {
|
|
var t2 = arguments, n2 = [];
|
|
if (2 === t2.length) {
|
|
var r2 = t2[0], i2 = t2[1];
|
|
this.on(e2.event, r2, i2);
|
|
} else if (1 === t2.length && g(t2[0])) {
|
|
var a2 = t2[0];
|
|
this.on(e2.event, a2);
|
|
} else if (0 === t2.length || 1 === t2.length && v(t2[0])) {
|
|
for (var o2 = 1 === t2.length ? t2[0] : null, s2 = 0; s2 < this.length; s2++) {
|
|
var l2 = this[s2], u2 = !e2.ableField || l2._private[e2.ableField], c2 = l2._private[e2.field] != e2.value;
|
|
if (e2.overrideAble) {
|
|
var d2 = e2.overrideAble(l2);
|
|
if (void 0 !== d2 && (u2 = d2, !d2)) return this;
|
|
}
|
|
u2 && (l2._private[e2.field] = e2.value, c2 && n2.push(l2));
|
|
}
|
|
var h2 = this.spawn(n2);
|
|
h2.updateStyle(), h2.emit(e2.event), o2 && h2.emit(o2);
|
|
}
|
|
return this;
|
|
};
|
|
}
|
|
function Xo(e2) {
|
|
qo[e2.field] = function() {
|
|
var t2 = this[0];
|
|
if (t2) {
|
|
if (e2.overrideField) {
|
|
var n2 = e2.overrideField(t2);
|
|
if (void 0 !== n2) return n2;
|
|
}
|
|
return t2._private[e2.field];
|
|
}
|
|
}, qo[e2.on] = Yo({ event: e2.on, field: e2.field, ableField: e2.ableField, overrideAble: e2.overrideAble, value: true }), qo[e2.off] = Yo({ event: e2.off, field: e2.field, ableField: e2.ableField, overrideAble: e2.overrideAble, value: false });
|
|
}
|
|
Xo({ field: "locked", overrideField: function(e2) {
|
|
return !!e2.cy().autolock() || void 0;
|
|
}, on: "lock", off: "unlock" }), Xo({ field: "grabbable", overrideField: function(e2) {
|
|
return !e2.cy().autoungrabify() && !e2.pannable() && void 0;
|
|
}, on: "grabify", off: "ungrabify" }), Xo({ field: "selected", ableField: "selectable", overrideAble: function(e2) {
|
|
return !e2.cy().autounselectify() && void 0;
|
|
}, on: "select", off: "unselect" }), Xo({ field: "selectable", overrideField: function(e2) {
|
|
return !e2.cy().autounselectify() && void 0;
|
|
}, on: "selectify", off: "unselectify" }), qo.deselect = qo.unselect, qo.grabbed = function() {
|
|
var e2 = this[0];
|
|
if (e2) return e2._private.grabbed;
|
|
}, Xo({ field: "active", on: "activate", off: "unactivate" }), Xo({ field: "pannable", on: "panify", off: "unpanify" }), qo.inactive = function() {
|
|
var e2 = this[0];
|
|
if (e2) return !e2._private.active;
|
|
};
|
|
var Wo = {}, Ho = function(e2) {
|
|
return function(t2) {
|
|
for (var n2 = [], r2 = 0; r2 < this.length; r2++) {
|
|
var i2 = this[r2];
|
|
if (i2.isNode()) {
|
|
for (var a2 = false, o2 = i2.connectedEdges(), s2 = 0; s2 < o2.length; s2++) {
|
|
var l2 = o2[s2], u2 = l2.source(), c2 = l2.target();
|
|
if (e2.noIncomingEdges && c2 === i2 && u2 !== i2 || e2.noOutgoingEdges && u2 === i2 && c2 !== i2) {
|
|
a2 = true;
|
|
break;
|
|
}
|
|
}
|
|
a2 || n2.push(i2);
|
|
}
|
|
}
|
|
return this.spawn(n2, true).filter(t2);
|
|
};
|
|
}, Ko = function(e2) {
|
|
return function(t2) {
|
|
for (var n2 = [], r2 = 0; r2 < this.length; r2++) {
|
|
var i2 = this[r2];
|
|
if (i2.isNode()) for (var a2 = i2.connectedEdges(), o2 = 0; o2 < a2.length; o2++) {
|
|
var s2 = a2[o2], l2 = s2.source(), u2 = s2.target();
|
|
e2.outgoing && l2 === i2 ? (n2.push(s2), n2.push(u2)) : e2.incoming && u2 === i2 && (n2.push(s2), n2.push(l2));
|
|
}
|
|
}
|
|
return this.spawn(n2, true).filter(t2);
|
|
};
|
|
}, Go = function(e2) {
|
|
return function(t2) {
|
|
for (var n2 = this, r2 = [], i2 = {}; ; ) {
|
|
var a2 = e2.outgoing ? n2.outgoers() : n2.incomers();
|
|
if (0 === a2.length) break;
|
|
for (var o2 = false, s2 = 0; s2 < a2.length; s2++) {
|
|
var l2 = a2[s2], u2 = l2.id();
|
|
i2[u2] || (i2[u2] = true, r2.push(l2), o2 = true);
|
|
}
|
|
if (!o2) break;
|
|
n2 = a2;
|
|
}
|
|
return this.spawn(r2, true).filter(t2);
|
|
};
|
|
};
|
|
function Uo(e2) {
|
|
return function(t2) {
|
|
for (var n2 = [], r2 = 0; r2 < this.length; r2++) {
|
|
var i2 = this[r2]._private[e2.attr];
|
|
i2 && n2.push(i2);
|
|
}
|
|
return this.spawn(n2, true).filter(t2);
|
|
};
|
|
}
|
|
function Zo(e2) {
|
|
return function(t2) {
|
|
var n2 = [], r2 = this._private.cy, i2 = e2 || {};
|
|
f(t2) && (t2 = r2.$(t2));
|
|
for (var a2 = 0; a2 < t2.length; a2++) for (var o2 = t2[a2]._private.edges, s2 = 0; s2 < o2.length; s2++) {
|
|
var l2 = o2[s2], u2 = l2._private.data, c2 = this.hasElementWithId(u2.source) && t2.hasElementWithId(u2.target), d2 = t2.hasElementWithId(u2.source) && this.hasElementWithId(u2.target);
|
|
if (c2 || d2) {
|
|
if (i2.thisIsSrc || i2.thisIsTgt) {
|
|
if (i2.thisIsSrc && !c2) continue;
|
|
if (i2.thisIsTgt && !d2) continue;
|
|
}
|
|
n2.push(l2);
|
|
}
|
|
}
|
|
return this.spawn(n2, true);
|
|
};
|
|
}
|
|
function $o(e2) {
|
|
return e2 = I({}, { codirected: false }, e2), function(t2) {
|
|
for (var n2 = [], r2 = this.edges(), i2 = e2, a2 = 0; a2 < r2.length; a2++) for (var o2 = r2[a2]._private, s2 = o2.source, l2 = s2._private.data.id, u2 = o2.data.target, c2 = s2._private.edges, d2 = 0; d2 < c2.length; d2++) {
|
|
var h2 = c2[d2], p2 = h2._private.data, f2 = p2.target, g2 = p2.source, v2 = f2 === u2 && g2 === l2, y2 = l2 === f2 && u2 === g2;
|
|
(i2.codirected && v2 || !i2.codirected && (v2 || y2)) && n2.push(h2);
|
|
}
|
|
return this.spawn(n2, true).filter(t2);
|
|
};
|
|
}
|
|
Wo.clearTraversalCache = function() {
|
|
for (var e2 = 0; e2 < this.length; e2++) this[e2]._private.traversalCache = null;
|
|
}, I(Wo, { roots: Ho({ noIncomingEdges: true }), leaves: Ho({ noOutgoingEdges: true }), outgoers: Sa(Ko({ outgoing: true }), "outgoers"), successors: Go({ outgoing: true }), incomers: Sa(Ko({ incoming: true }), "incomers"), predecessors: Go({ incoming: true }) }), I(Wo, { neighborhood: Sa(function(e2) {
|
|
for (var t2 = [], n2 = this.nodes(), r2 = 0; r2 < n2.length; r2++) for (var i2 = n2[r2], a2 = i2.connectedEdges(), o2 = 0; o2 < a2.length; o2++) {
|
|
var s2 = a2[o2], l2 = s2.source(), u2 = s2.target(), c2 = i2 === l2 ? u2 : l2;
|
|
c2.length > 0 && t2.push(c2[0]), t2.push(s2[0]);
|
|
}
|
|
return this.spawn(t2, true).filter(e2);
|
|
}, "neighborhood"), closedNeighborhood: function(e2) {
|
|
return this.neighborhood().add(this).filter(e2);
|
|
}, openNeighborhood: function(e2) {
|
|
return this.neighborhood(e2);
|
|
} }), Wo.neighbourhood = Wo.neighborhood, Wo.closedNeighbourhood = Wo.closedNeighborhood, Wo.openNeighbourhood = Wo.openNeighborhood, I(Wo, { source: Sa(function(e2) {
|
|
var t2, n2 = this[0];
|
|
return n2 && (t2 = n2._private.source || n2.cy().collection()), t2 && e2 ? t2.filter(e2) : t2;
|
|
}, "source"), target: Sa(function(e2) {
|
|
var t2, n2 = this[0];
|
|
return n2 && (t2 = n2._private.target || n2.cy().collection()), t2 && e2 ? t2.filter(e2) : t2;
|
|
}, "target"), sources: Uo({ attr: "source" }), targets: Uo({ attr: "target" }) }), I(Wo, { edgesWith: Sa(Zo(), "edgesWith"), edgesTo: Sa(Zo({ thisIsSrc: true }), "edgesTo") }), I(Wo, { connectedEdges: Sa(function(e2) {
|
|
for (var t2 = [], n2 = 0; n2 < this.length; n2++) {
|
|
var r2 = this[n2];
|
|
if (r2.isNode()) for (var i2 = r2._private.edges, a2 = 0; a2 < i2.length; a2++) {
|
|
var o2 = i2[a2];
|
|
t2.push(o2);
|
|
}
|
|
}
|
|
return this.spawn(t2, true).filter(e2);
|
|
}, "connectedEdges"), connectedNodes: Sa(function(e2) {
|
|
for (var t2 = [], n2 = 0; n2 < this.length; n2++) {
|
|
var r2 = this[n2];
|
|
r2.isEdge() && (t2.push(r2.source()[0]), t2.push(r2.target()[0]));
|
|
}
|
|
return this.spawn(t2, true).filter(e2);
|
|
}, "connectedNodes"), parallelEdges: Sa($o(), "parallelEdges"), codirectedEdges: Sa($o({ codirected: true }), "codirectedEdges") }), I(Wo, { components: function(e2) {
|
|
var t2 = this, n2 = t2.cy(), r2 = n2.collection(), i2 = null == e2 ? t2.nodes() : e2.nodes(), a2 = [];
|
|
null != e2 && i2.empty() && (i2 = e2.sources());
|
|
var o2 = function(e3, t3) {
|
|
r2.merge(e3), i2.unmerge(e3), t3.merge(e3);
|
|
};
|
|
if (i2.empty()) return t2.spawn();
|
|
var s2 = function() {
|
|
var e3 = n2.collection();
|
|
a2.push(e3);
|
|
var r3 = i2[0];
|
|
o2(r3, e3), t2.bfs({ directed: false, roots: r3, visit: function(t3) {
|
|
return o2(t3, e3);
|
|
} }), e3.forEach(function(n3) {
|
|
n3.connectedEdges().forEach(function(n4) {
|
|
t2.has(n4) && e3.has(n4.source()) && e3.has(n4.target()) && e3.merge(n4);
|
|
});
|
|
});
|
|
};
|
|
do {
|
|
s2();
|
|
} while (i2.length > 0);
|
|
return a2;
|
|
}, component: function() {
|
|
var e2 = this[0];
|
|
return e2.cy().mutableElements().components(e2)[0];
|
|
} }), Wo.componentsOf = Wo.components;
|
|
var Qo = function(e2, t2) {
|
|
var n2 = arguments.length > 2 && void 0 !== arguments[2] && arguments[2], r2 = arguments.length > 3 && void 0 !== arguments[3] && arguments[3];
|
|
if (void 0 !== e2) {
|
|
var i2 = new Ue(), a2 = false;
|
|
if (t2) {
|
|
if (t2.length > 0 && y(t2[0]) && !w(t2[0])) {
|
|
a2 = true;
|
|
for (var o2 = [], s2 = new $e(), l2 = 0, u2 = t2.length; l2 < u2; l2++) {
|
|
var c2 = t2[l2];
|
|
null == c2.data && (c2.data = {});
|
|
var d2 = c2.data;
|
|
if (null == d2.id) d2.id = je();
|
|
else if (e2.hasElementWithId(d2.id) || s2.has(d2.id)) continue;
|
|
var h2 = new Qe(e2, c2, false);
|
|
o2.push(h2), s2.add(d2.id);
|
|
}
|
|
t2 = o2;
|
|
}
|
|
} else t2 = [];
|
|
this.length = 0;
|
|
for (var p2 = 0, f2 = t2.length; p2 < f2; p2++) {
|
|
var g2 = t2[p2][0];
|
|
if (null != g2) {
|
|
var v2 = g2._private.data.id;
|
|
n2 && i2.has(v2) || (n2 && i2.set(v2, { index: this.length, ele: g2 }), this[this.length] = g2, this.length++);
|
|
}
|
|
}
|
|
this._private = { eles: this, cy: e2, get map() {
|
|
return null == this.lazyMap && this.rebuildMap(), this.lazyMap;
|
|
}, set map(e3) {
|
|
this.lazyMap = e3;
|
|
}, rebuildMap: function() {
|
|
for (var e3 = this.lazyMap = new Ue(), t3 = this.eles, n3 = 0; n3 < t3.length; n3++) {
|
|
var r3 = t3[n3];
|
|
e3.set(r3.id(), { index: n3, ele: r3 });
|
|
}
|
|
} }, n2 && (this._private.map = i2), a2 && !r2 && this.restore();
|
|
} else Oe("A collection must have a reference to the core");
|
|
}, Jo = Qe.prototype = Qo.prototype = Object.create(Array.prototype);
|
|
Jo.instanceString = function() {
|
|
return "collection";
|
|
}, Jo.spawn = function(e2, t2) {
|
|
return new Qo(this.cy(), e2, t2);
|
|
}, Jo.spawnSelf = function() {
|
|
return this.spawn(this);
|
|
}, Jo.cy = function() {
|
|
return this._private.cy;
|
|
}, Jo.renderer = function() {
|
|
return this._private.cy.renderer();
|
|
}, Jo.element = function() {
|
|
return this[0];
|
|
}, Jo.collection = function() {
|
|
return E(this) ? this : new Qo(this._private.cy, [this]);
|
|
}, Jo.unique = function() {
|
|
return new Qo(this._private.cy, this, true);
|
|
}, Jo.hasElementWithId = function(e2) {
|
|
return e2 = "" + e2, this._private.map.has(e2);
|
|
}, Jo.getElementById = function(e2) {
|
|
e2 = "" + e2;
|
|
var t2 = this._private.cy, n2 = this._private.map.get(e2);
|
|
return n2 ? n2.ele : new Qo(t2);
|
|
}, Jo.$id = Jo.getElementById, Jo.poolIndex = function() {
|
|
var e2 = this._private.cy._private.elements, t2 = this[0]._private.data.id;
|
|
return e2._private.map.get(t2).index;
|
|
}, Jo.indexOf = function(e2) {
|
|
var t2 = e2[0]._private.data.id;
|
|
return this._private.map.get(t2).index;
|
|
}, Jo.indexOfId = function(e2) {
|
|
return e2 = "" + e2, this._private.map.get(e2).index;
|
|
}, Jo.json = function(e2) {
|
|
var t2 = this.element(), n2 = this.cy();
|
|
if (null == t2 && e2) return this;
|
|
if (null != t2) {
|
|
var r2 = t2._private;
|
|
if (y(e2)) {
|
|
if (n2.startBatch(), e2.data) {
|
|
t2.data(e2.data);
|
|
var i2 = r2.data;
|
|
if (t2.isEdge()) {
|
|
var a2 = false, o2 = {}, s2 = e2.data.source, l2 = e2.data.target;
|
|
null != s2 && s2 != i2.source && (o2.source = "" + s2, a2 = true), null != l2 && l2 != i2.target && (o2.target = "" + l2, a2 = true), a2 && (t2 = t2.move(o2));
|
|
} else {
|
|
var u2 = "parent" in e2.data, c2 = e2.data.parent;
|
|
!u2 || null == c2 && null == i2.parent || c2 == i2.parent || (void 0 === c2 && (c2 = null), null != c2 && (c2 = "" + c2), t2 = t2.move({ parent: c2 }));
|
|
}
|
|
}
|
|
e2.position && t2.position(e2.position);
|
|
var d2 = function(n3, i3, a3) {
|
|
var o3 = e2[n3];
|
|
null != o3 && o3 !== r2[n3] && (o3 ? t2[i3]() : t2[a3]());
|
|
};
|
|
return d2("removed", "remove", "restore"), d2("selected", "select", "unselect"), d2("selectable", "selectify", "unselectify"), d2("locked", "lock", "unlock"), d2("grabbable", "grabify", "ungrabify"), d2("pannable", "panify", "unpanify"), null != e2.classes && t2.classes(e2.classes), n2.endBatch(), this;
|
|
}
|
|
if (void 0 === e2) {
|
|
var h2 = { data: Fe(r2.data), position: Fe(r2.position), group: r2.group, removed: r2.removed, selected: r2.selected, selectable: r2.selectable, locked: r2.locked, grabbable: r2.grabbable, pannable: r2.pannable, classes: null };
|
|
h2.classes = "";
|
|
var p2 = 0;
|
|
return r2.classes.forEach(function(e3) {
|
|
return h2.classes += 0 == p2++ ? e3 : " " + e3;
|
|
}), h2;
|
|
}
|
|
}
|
|
}, Jo.jsons = function() {
|
|
for (var e2 = [], t2 = 0; t2 < this.length; t2++) {
|
|
var n2 = this[t2].json();
|
|
e2.push(n2);
|
|
}
|
|
return e2;
|
|
}, Jo.clone = function() {
|
|
for (var e2 = this.cy(), t2 = [], n2 = 0; n2 < this.length; n2++) {
|
|
var r2 = this[n2].json(), i2 = new Qe(e2, r2, false);
|
|
t2.push(i2);
|
|
}
|
|
return new Qo(e2, t2);
|
|
}, Jo.copy = Jo.clone, Jo.restore = function() {
|
|
for (var e2, t2, n2 = !(arguments.length > 0 && void 0 !== arguments[0]) || arguments[0], r2 = !(arguments.length > 1 && void 0 !== arguments[1]) || arguments[1], i2 = this, a2 = i2.cy(), o2 = a2._private, s2 = [], l2 = [], u2 = 0, c2 = i2.length; u2 < c2; u2++) {
|
|
var d2 = i2[u2];
|
|
r2 && !d2.removed() || (d2.isNode() ? s2.push(d2) : l2.push(d2));
|
|
}
|
|
e2 = s2.concat(l2);
|
|
var h2 = function() {
|
|
e2.splice(t2, 1), t2--;
|
|
};
|
|
for (t2 = 0; t2 < e2.length; t2++) {
|
|
var p2 = e2[t2], g2 = p2._private, v2 = g2.data;
|
|
if (p2.clearTraversalCache(), r2 || g2.removed) if (void 0 === v2.id) v2.id = je();
|
|
else if (m(v2.id)) v2.id = "" + v2.id;
|
|
else {
|
|
if (S(v2.id) || !f(v2.id)) {
|
|
Oe("Can not create element with invalid string ID `" + v2.id + "`"), h2();
|
|
continue;
|
|
}
|
|
if (a2.hasElementWithId(v2.id)) {
|
|
Oe("Can not create second element with ID `" + v2.id + "`"), h2();
|
|
continue;
|
|
}
|
|
}
|
|
else ;
|
|
var y2 = v2.id;
|
|
if (p2.isNode()) {
|
|
var b2 = g2.position;
|
|
null == b2.x && (b2.x = 0), null == b2.y && (b2.y = 0);
|
|
}
|
|
if (p2.isEdge()) {
|
|
for (var x2 = p2, w2 = ["source", "target"], E2 = w2.length, k2 = false, C2 = 0; C2 < E2; C2++) {
|
|
var P2 = w2[C2], D2 = v2[P2];
|
|
m(D2) && (D2 = v2[P2] = "" + v2[P2]), null == D2 || "" === D2 ? (Oe("Can not create edge `" + y2 + "` with unspecified " + P2), k2 = true) : a2.hasElementWithId(D2) || (Oe("Can not create edge `" + y2 + "` with nonexistant " + P2 + " `" + D2 + "`"), k2 = true);
|
|
}
|
|
if (k2) {
|
|
h2();
|
|
continue;
|
|
}
|
|
var T2 = a2.getElementById(v2.source), _2 = a2.getElementById(v2.target);
|
|
T2.same(_2) ? T2._private.edges.push(x2) : (T2._private.edges.push(x2), _2._private.edges.push(x2)), x2._private.source = T2, x2._private.target = _2;
|
|
}
|
|
g2.map = new Ue(), g2.map.set(y2, { ele: p2, index: 0 }), g2.removed = false, r2 && a2.addToPool(p2);
|
|
}
|
|
for (var M2 = 0; M2 < s2.length; M2++) {
|
|
var B2 = s2[M2], N2 = B2._private.data;
|
|
m(N2.parent) && (N2.parent = "" + N2.parent);
|
|
var z2 = N2.parent, I2 = null != z2;
|
|
if (I2 || B2._private.parent) {
|
|
var L3 = B2._private.parent ? a2.collection().merge(B2._private.parent) : a2.getElementById(z2);
|
|
if (L3.empty()) N2.parent = void 0;
|
|
else if (L3[0].removed()) Ve("Node added with missing parent, reference to parent removed"), N2.parent = void 0, B2._private.parent = null;
|
|
else {
|
|
for (var A2 = false, O2 = L3; !O2.empty(); ) {
|
|
if (B2.same(O2)) {
|
|
A2 = true, N2.parent = void 0;
|
|
break;
|
|
}
|
|
O2 = O2.parent();
|
|
}
|
|
A2 || (L3[0]._private.children.push(B2), B2._private.parent = L3[0], o2.hasCompoundNodes = true);
|
|
}
|
|
}
|
|
}
|
|
if (e2.length > 0) {
|
|
for (var R2 = e2.length === i2.length ? i2 : new Qo(a2, e2), V2 = 0; V2 < R2.length; V2++) {
|
|
var F2 = R2[V2];
|
|
F2.isNode() || (F2.parallelEdges().clearTraversalCache(), F2.source().clearTraversalCache(), F2.target().clearTraversalCache());
|
|
}
|
|
(o2.hasCompoundNodes ? a2.collection().merge(R2).merge(R2.connectedNodes()).merge(R2.parent()) : R2).dirtyCompoundBoundsCache().dirtyBoundingBoxCache().updateStyle(n2), n2 ? R2.emitAndNotify("add") : r2 && R2.emit("add");
|
|
}
|
|
return i2;
|
|
}, Jo.removed = function() {
|
|
var e2 = this[0];
|
|
return e2 && e2._private.removed;
|
|
}, Jo.inside = function() {
|
|
var e2 = this[0];
|
|
return e2 && !e2._private.removed;
|
|
}, Jo.remove = function() {
|
|
var e2 = !(arguments.length > 0 && void 0 !== arguments[0]) || arguments[0], t2 = !(arguments.length > 1 && void 0 !== arguments[1]) || arguments[1], n2 = this, r2 = [], i2 = {}, a2 = n2._private.cy;
|
|
function o2(e3) {
|
|
for (var t3 = e3._private.edges, n3 = 0; n3 < t3.length; n3++) l2(t3[n3]);
|
|
}
|
|
function s2(e3) {
|
|
for (var t3 = e3._private.children, n3 = 0; n3 < t3.length; n3++) l2(t3[n3]);
|
|
}
|
|
function l2(e3) {
|
|
var n3 = i2[e3.id()];
|
|
t2 && e3.removed() || n3 || (i2[e3.id()] = true, e3.isNode() ? (r2.push(e3), o2(e3), s2(e3)) : r2.unshift(e3));
|
|
}
|
|
for (var u2 = 0, c2 = n2.length; u2 < c2; u2++) {
|
|
var d2 = n2[u2];
|
|
l2(d2);
|
|
}
|
|
function h2(e3, t3) {
|
|
var n3 = e3._private.edges;
|
|
We(n3, t3), e3.clearTraversalCache();
|
|
}
|
|
function p2(e3) {
|
|
e3.clearTraversalCache();
|
|
}
|
|
var f2 = [];
|
|
function g2(e3, t3) {
|
|
t3 = t3[0];
|
|
var n3 = (e3 = e3[0])._private.children, r3 = e3.id();
|
|
We(n3, t3), t3._private.parent = null, f2.ids[r3] || (f2.ids[r3] = true, f2.push(e3));
|
|
}
|
|
f2.ids = {}, n2.dirtyCompoundBoundsCache(), t2 && a2.removeFromPool(r2);
|
|
for (var v2 = 0; v2 < r2.length; v2++) {
|
|
var y2 = r2[v2];
|
|
if (y2.isEdge()) {
|
|
var m2 = y2.source()[0], b2 = y2.target()[0];
|
|
h2(m2, y2), h2(b2, y2);
|
|
for (var x2 = y2.parallelEdges(), w2 = 0; w2 < x2.length; w2++) {
|
|
var E2 = x2[w2];
|
|
p2(E2), E2.isBundledBezier() && E2.dirtyBoundingBoxCache();
|
|
}
|
|
} else {
|
|
var k2 = y2.parent();
|
|
0 !== k2.length && g2(k2, y2);
|
|
}
|
|
t2 && (y2._private.removed = true);
|
|
}
|
|
var C2 = a2._private.elements;
|
|
a2._private.hasCompoundNodes = false;
|
|
for (var S2 = 0; S2 < C2.length; S2++) {
|
|
var P2 = C2[S2];
|
|
if (P2.isParent()) {
|
|
a2._private.hasCompoundNodes = true;
|
|
break;
|
|
}
|
|
}
|
|
var D2 = new Qo(this.cy(), r2);
|
|
D2.size() > 0 && (e2 ? D2.emitAndNotify("remove") : t2 && D2.emit("remove"));
|
|
for (var T2 = 0; T2 < f2.length; T2++) {
|
|
var _2 = f2[T2];
|
|
t2 && _2.removed() || _2.updateStyle();
|
|
}
|
|
return D2;
|
|
}, Jo.move = function(e2) {
|
|
var t2 = this._private.cy, n2 = this, r2 = function(e3) {
|
|
return null == e3 ? e3 : "" + e3;
|
|
};
|
|
if (void 0 !== e2.source || void 0 !== e2.target) {
|
|
var i2 = r2(e2.source), a2 = r2(e2.target), o2 = null != i2 && t2.hasElementWithId(i2), s2 = null != a2 && t2.hasElementWithId(a2);
|
|
(o2 || s2) && (t2.batch(function() {
|
|
n2.remove(false, false), n2.emitAndNotify("moveout");
|
|
for (var e3 = 0; e3 < n2.length; e3++) {
|
|
var t3 = n2[e3], r3 = t3._private.data;
|
|
t3.isEdge() && (o2 && (r3.source = i2), s2 && (r3.target = a2));
|
|
}
|
|
n2.restore(false, false);
|
|
}), n2.emitAndNotify("move"));
|
|
} else if (void 0 !== e2.parent) {
|
|
var l2 = r2(e2.parent);
|
|
if (null === l2 || t2.hasElementWithId(l2)) {
|
|
var u2 = null === l2 ? void 0 : l2;
|
|
t2.batch(function() {
|
|
var e3 = n2.remove(false, false);
|
|
e3.emitAndNotify("moveout");
|
|
for (var t3 = 0; t3 < n2.length; t3++) {
|
|
var r3 = n2[t3], i3 = r3._private.data;
|
|
r3.isNode() && (i3.parent = u2);
|
|
}
|
|
e3.restore(false, false);
|
|
}), n2.emitAndNotify("move");
|
|
}
|
|
}
|
|
return this;
|
|
}, [or, Ri, Vi, Ea, Pa, za, Ia, lo, Co, So, { isNode: function() {
|
|
return "nodes" === this.group();
|
|
}, isEdge: function() {
|
|
return "edges" === this.group();
|
|
}, isLoop: function() {
|
|
return this.isEdge() && this.source()[0] === this.target()[0];
|
|
}, isSimple: function() {
|
|
return this.isEdge() && this.source()[0] !== this.target()[0];
|
|
}, group: function() {
|
|
var e2 = this[0];
|
|
if (e2) return e2._private.group;
|
|
} }, To, Mo, Io, qo, Wo].forEach(function(e2) {
|
|
I(Jo, e2);
|
|
});
|
|
var es = { add: function(e2) {
|
|
var t2, n2 = this;
|
|
if (x(e2)) {
|
|
var r2 = e2;
|
|
if (r2._private.cy === n2) t2 = r2.restore();
|
|
else {
|
|
for (var i2 = [], a2 = 0; a2 < r2.length; a2++) {
|
|
var o2 = r2[a2];
|
|
i2.push(o2.json());
|
|
}
|
|
t2 = new Qo(n2, i2);
|
|
}
|
|
} else if (v(e2)) {
|
|
t2 = new Qo(n2, e2);
|
|
} else if (y(e2) && (v(e2.nodes) || v(e2.edges))) {
|
|
for (var s2 = e2, l2 = [], u2 = ["nodes", "edges"], c2 = 0, d2 = u2.length; c2 < d2; c2++) {
|
|
var h2 = u2[c2], p2 = s2[h2];
|
|
if (v(p2)) for (var f2 = 0, g2 = p2.length; f2 < g2; f2++) {
|
|
var m2 = I({ group: h2 }, p2[f2]);
|
|
l2.push(m2);
|
|
}
|
|
}
|
|
t2 = new Qo(n2, l2);
|
|
} else {
|
|
t2 = new Qe(n2, e2).collection();
|
|
}
|
|
return t2;
|
|
}, remove: function(e2) {
|
|
if (x(e2)) ;
|
|
else if (f(e2)) {
|
|
var t2 = e2;
|
|
e2 = this.$(t2);
|
|
}
|
|
return e2.remove();
|
|
} };
|
|
var ts = /* @__PURE__ */ function() {
|
|
function e2(e3) {
|
|
return -e3.tension * e3.x - e3.friction * e3.v;
|
|
}
|
|
function t2(t3, n3, r2) {
|
|
var i2 = { x: t3.x + r2.dx * n3, v: t3.v + r2.dv * n3, tension: t3.tension, friction: t3.friction };
|
|
return { dx: i2.v, dv: e2(i2) };
|
|
}
|
|
function n2(n3, r2) {
|
|
var i2 = { dx: n3.v, dv: e2(n3) }, a2 = t2(n3, 0.5 * r2, i2), o2 = t2(n3, 0.5 * r2, a2), s2 = t2(n3, r2, o2), l2 = 1 / 6 * (i2.dx + 2 * (a2.dx + o2.dx) + s2.dx), u2 = 1 / 6 * (i2.dv + 2 * (a2.dv + o2.dv) + s2.dv);
|
|
return n3.x = n3.x + l2 * r2, n3.v = n3.v + u2 * r2, n3;
|
|
}
|
|
return function e3(t3, r2, i2) {
|
|
var a2, o2, s2, l2 = { x: -1, v: 0, tension: null, friction: null }, u2 = [0], c2 = 0;
|
|
for (t3 = parseFloat(t3) || 500, r2 = parseFloat(r2) || 20, i2 = i2 || null, l2.tension = t3, l2.friction = r2, o2 = (a2 = null !== i2) ? (c2 = e3(t3, r2)) / i2 * 0.016 : 0.016; s2 = n2(s2 || l2, o2), u2.push(1 + s2.x), c2 += 16, Math.abs(s2.x) > 1e-4 && Math.abs(s2.v) > 1e-4; ) ;
|
|
return a2 ? function(e4) {
|
|
return u2[e4 * (u2.length - 1) | 0];
|
|
} : c2;
|
|
};
|
|
}(), ns = function(e2, t2, n2, r2) {
|
|
var i2 = function(e3, t3, n3, r3) {
|
|
var i3 = 4, a2 = 1e-3, o2 = 1e-7, s2 = 10, l2 = 11, u2 = 1 / (l2 - 1), c2 = "undefined" != typeof Float32Array;
|
|
if (4 !== arguments.length) return false;
|
|
for (var d2 = 0; d2 < 4; ++d2) if ("number" != typeof arguments[d2] || isNaN(arguments[d2]) || !isFinite(arguments[d2])) return false;
|
|
e3 = Math.min(e3, 1), n3 = Math.min(n3, 1), e3 = Math.max(e3, 0), n3 = Math.max(n3, 0);
|
|
var h2 = c2 ? new Float32Array(l2) : new Array(l2);
|
|
function p2(e4, t4) {
|
|
return 1 - 3 * t4 + 3 * e4;
|
|
}
|
|
function f2(e4, t4) {
|
|
return 3 * t4 - 6 * e4;
|
|
}
|
|
function g2(e4) {
|
|
return 3 * e4;
|
|
}
|
|
function v2(e4, t4, n4) {
|
|
return ((p2(t4, n4) * e4 + f2(t4, n4)) * e4 + g2(t4)) * e4;
|
|
}
|
|
function y2(e4, t4, n4) {
|
|
return 3 * p2(t4, n4) * e4 * e4 + 2 * f2(t4, n4) * e4 + g2(t4);
|
|
}
|
|
function m2(t4, r4) {
|
|
for (var a3 = 0; a3 < i3; ++a3) {
|
|
var o3 = y2(r4, e3, n3);
|
|
if (0 === o3) return r4;
|
|
r4 -= (v2(r4, e3, n3) - t4) / o3;
|
|
}
|
|
return r4;
|
|
}
|
|
function b2() {
|
|
for (var t4 = 0; t4 < l2; ++t4) h2[t4] = v2(t4 * u2, e3, n3);
|
|
}
|
|
function x2(t4, r4, i4) {
|
|
var a3, l3, u3 = 0;
|
|
do {
|
|
(a3 = v2(l3 = r4 + (i4 - r4) / 2, e3, n3) - t4) > 0 ? i4 = l3 : r4 = l3;
|
|
} while (Math.abs(a3) > o2 && ++u3 < s2);
|
|
return l3;
|
|
}
|
|
function w2(t4) {
|
|
for (var r4 = 0, i4 = 1, o3 = l2 - 1; i4 !== o3 && h2[i4] <= t4; ++i4) r4 += u2;
|
|
--i4;
|
|
var s3 = r4 + (t4 - h2[i4]) / (h2[i4 + 1] - h2[i4]) * u2, c3 = y2(s3, e3, n3);
|
|
return c3 >= a2 ? m2(t4, s3) : 0 === c3 ? s3 : x2(t4, r4, r4 + u2);
|
|
}
|
|
var E2 = false;
|
|
function k2() {
|
|
E2 = true, e3 === t3 && n3 === r3 || b2();
|
|
}
|
|
var C2 = function(i4) {
|
|
return E2 || k2(), e3 === t3 && n3 === r3 ? i4 : 0 === i4 ? 0 : 1 === i4 ? 1 : v2(w2(i4), t3, r3);
|
|
};
|
|
C2.getControlPoints = function() {
|
|
return [{ x: e3, y: t3 }, { x: n3, y: r3 }];
|
|
};
|
|
var S2 = "generateBezier(" + [e3, t3, n3, r3] + ")";
|
|
return C2.toString = function() {
|
|
return S2;
|
|
}, C2;
|
|
}(e2, t2, n2, r2);
|
|
return function(e3, t3, n3) {
|
|
return e3 + (t3 - e3) * i2(n3);
|
|
};
|
|
}, rs = { linear: function(e2, t2, n2) {
|
|
return e2 + (t2 - e2) * n2;
|
|
}, ease: ns(0.25, 0.1, 0.25, 1), "ease-in": ns(0.42, 0, 1, 1), "ease-out": ns(0, 0, 0.58, 1), "ease-in-out": ns(0.42, 0, 0.58, 1), "ease-in-sine": ns(0.47, 0, 0.745, 0.715), "ease-out-sine": ns(0.39, 0.575, 0.565, 1), "ease-in-out-sine": ns(0.445, 0.05, 0.55, 0.95), "ease-in-quad": ns(0.55, 0.085, 0.68, 0.53), "ease-out-quad": ns(0.25, 0.46, 0.45, 0.94), "ease-in-out-quad": ns(0.455, 0.03, 0.515, 0.955), "ease-in-cubic": ns(0.55, 0.055, 0.675, 0.19), "ease-out-cubic": ns(0.215, 0.61, 0.355, 1), "ease-in-out-cubic": ns(0.645, 0.045, 0.355, 1), "ease-in-quart": ns(0.895, 0.03, 0.685, 0.22), "ease-out-quart": ns(0.165, 0.84, 0.44, 1), "ease-in-out-quart": ns(0.77, 0, 0.175, 1), "ease-in-quint": ns(0.755, 0.05, 0.855, 0.06), "ease-out-quint": ns(0.23, 1, 0.32, 1), "ease-in-out-quint": ns(0.86, 0, 0.07, 1), "ease-in-expo": ns(0.95, 0.05, 0.795, 0.035), "ease-out-expo": ns(0.19, 1, 0.22, 1), "ease-in-out-expo": ns(1, 0, 0, 1), "ease-in-circ": ns(0.6, 0.04, 0.98, 0.335), "ease-out-circ": ns(0.075, 0.82, 0.165, 1), "ease-in-out-circ": ns(0.785, 0.135, 0.15, 0.86), spring: function(e2, t2, n2) {
|
|
if (0 === n2) return rs.linear;
|
|
var r2 = ts(e2, t2, n2);
|
|
return function(e3, t3, n3) {
|
|
return e3 + (t3 - e3) * r2(n3);
|
|
};
|
|
}, "cubic-bezier": ns };
|
|
function is(e2, t2, n2, r2, i2) {
|
|
if (1 === r2) return n2;
|
|
if (t2 === n2) return n2;
|
|
var a2 = i2(t2, n2, r2);
|
|
return null == e2 || ((e2.roundValue || e2.color) && (a2 = Math.round(a2)), void 0 !== e2.min && (a2 = Math.max(a2, e2.min)), void 0 !== e2.max && (a2 = Math.min(a2, e2.max))), a2;
|
|
}
|
|
function as(e2, t2) {
|
|
return null != e2.pfValue || null != e2.value ? null == e2.pfValue || null != t2 && "%" === t2.type.units ? e2.value : e2.pfValue : e2;
|
|
}
|
|
function os(e2, t2, n2, r2, i2) {
|
|
var a2 = null != i2 ? i2.type : null;
|
|
n2 < 0 ? n2 = 0 : n2 > 1 && (n2 = 1);
|
|
var o2 = as(e2, i2), s2 = as(t2, i2);
|
|
if (m(o2) && m(s2)) return is(a2, o2, s2, n2, r2);
|
|
if (v(o2) && v(s2)) {
|
|
for (var l2 = [], u2 = 0; u2 < s2.length; u2++) {
|
|
var c2 = o2[u2], d2 = s2[u2];
|
|
if (null != c2 && null != d2) {
|
|
var h2 = is(a2, c2, d2, n2, r2);
|
|
l2.push(h2);
|
|
} else l2.push(d2);
|
|
}
|
|
return l2;
|
|
}
|
|
}
|
|
function ss(e2, t2, n2, r2) {
|
|
var i2 = !r2, a2 = e2._private, o2 = t2._private, s2 = o2.easing, l2 = o2.startTime, u2 = (r2 ? e2 : e2.cy()).style();
|
|
if (!o2.easingImpl) if (null == s2) o2.easingImpl = rs.linear;
|
|
else {
|
|
var c2, d2, h2;
|
|
if (f(s2)) c2 = u2.parse("transition-timing-function", s2).value;
|
|
else c2 = s2;
|
|
f(c2) ? (d2 = c2, h2 = []) : (d2 = c2[1], h2 = c2.slice(2).map(function(e3) {
|
|
return +e3;
|
|
})), h2.length > 0 ? ("spring" === d2 && h2.push(o2.duration), o2.easingImpl = rs[d2].apply(null, h2)) : o2.easingImpl = rs[d2];
|
|
}
|
|
var p2, g2 = o2.easingImpl;
|
|
if (p2 = 0 === o2.duration ? 1 : (n2 - l2) / o2.duration, o2.applying && (p2 = o2.progress), p2 < 0 ? p2 = 0 : p2 > 1 && (p2 = 1), null == o2.delay) {
|
|
var v2 = o2.startPosition, y2 = o2.position;
|
|
if (y2 && i2 && !e2.locked()) {
|
|
var m2 = {};
|
|
ls(v2.x, y2.x) && (m2.x = os(v2.x, y2.x, p2, g2)), ls(v2.y, y2.y) && (m2.y = os(v2.y, y2.y, p2, g2)), e2.position(m2);
|
|
}
|
|
var b2 = o2.startPan, x2 = o2.pan, w2 = a2.pan, E2 = null != x2 && r2;
|
|
E2 && (ls(b2.x, x2.x) && (w2.x = os(b2.x, x2.x, p2, g2)), ls(b2.y, x2.y) && (w2.y = os(b2.y, x2.y, p2, g2)), e2.emit("pan"));
|
|
var k2 = o2.startZoom, C2 = o2.zoom, S2 = null != C2 && r2;
|
|
S2 && (ls(k2, C2) && (a2.zoom = Pt(a2.minZoom, os(k2, C2, p2, g2), a2.maxZoom)), e2.emit("zoom")), (E2 || S2) && e2.emit("viewport");
|
|
var P2 = o2.style;
|
|
if (P2 && P2.length > 0 && i2) {
|
|
for (var D2 = 0; D2 < P2.length; D2++) {
|
|
var T2 = P2[D2], _2 = T2.name, M2 = T2, B2 = o2.startStyle[_2], N2 = os(B2, M2, p2, g2, u2.properties[B2.name]);
|
|
u2.overrideBypass(e2, _2, N2);
|
|
}
|
|
e2.emit("style");
|
|
}
|
|
}
|
|
return o2.progress = p2, p2;
|
|
}
|
|
function ls(e2, t2) {
|
|
return null != e2 && null != t2 && (!(!m(e2) || !m(t2)) || !(!e2 || !t2));
|
|
}
|
|
function us(e2, t2, n2, r2) {
|
|
var i2 = t2._private;
|
|
i2.started = true, i2.startTime = n2 - i2.progress * i2.duration;
|
|
}
|
|
function cs(e2, t2) {
|
|
var n2 = t2._private.aniEles, r2 = [];
|
|
function i2(t3, n3) {
|
|
var i3 = t3._private, a3 = i3.animation.current, o3 = i3.animation.queue, s3 = false;
|
|
if (0 === a3.length) {
|
|
var l3 = o3.shift();
|
|
l3 && a3.push(l3);
|
|
}
|
|
for (var u2 = function(e3) {
|
|
for (var t4 = e3.length - 1; t4 >= 0; t4--) {
|
|
(0, e3[t4])();
|
|
}
|
|
e3.splice(0, e3.length);
|
|
}, c2 = a3.length - 1; c2 >= 0; c2--) {
|
|
var d2 = a3[c2], h2 = d2._private;
|
|
h2.stopped ? (a3.splice(c2, 1), h2.hooked = false, h2.playing = false, h2.started = false, u2(h2.frames)) : (h2.playing || h2.applying) && (h2.playing && h2.applying && (h2.applying = false), h2.started || us(0, d2, e2), ss(t3, d2, e2, n3), h2.applying && (h2.applying = false), u2(h2.frames), null != h2.step && h2.step(e2), d2.completed() && (a3.splice(c2, 1), h2.hooked = false, h2.playing = false, h2.started = false, u2(h2.completes)), s3 = true);
|
|
}
|
|
return n3 || 0 !== a3.length || 0 !== o3.length || r2.push(t3), s3;
|
|
}
|
|
for (var a2 = false, o2 = 0; o2 < n2.length; o2++) {
|
|
var s2 = i2(n2[o2]);
|
|
a2 = a2 || s2;
|
|
}
|
|
var l2 = i2(t2, true);
|
|
(a2 || l2) && (n2.length > 0 ? t2.notify("draw", n2) : t2.notify("draw")), n2.unmerge(r2), t2.emit("step");
|
|
}
|
|
var ds = { animate: Oi.animate(), animation: Oi.animation(), animated: Oi.animated(), clearQueue: Oi.clearQueue(), delay: Oi.delay(), delayAnimation: Oi.delayAnimation(), stop: Oi.stop(), addToAnimationPool: function(e2) {
|
|
this.styleEnabled() && this._private.aniEles.merge(e2);
|
|
}, stopAnimationLoop: function() {
|
|
this._private.animationsRunning = false;
|
|
}, startAnimationLoop: function() {
|
|
var e2 = this;
|
|
if (e2._private.animationsRunning = true, e2.styleEnabled()) {
|
|
var t2 = e2.renderer();
|
|
t2 && t2.beforeRender ? t2.beforeRender(function(t3, n2) {
|
|
cs(n2, e2);
|
|
}, t2.beforeRenderPriorities.animations) : function t3() {
|
|
e2._private.animationsRunning && me(function(n2) {
|
|
cs(n2, e2), t3();
|
|
});
|
|
}();
|
|
}
|
|
} }, hs = { qualifierCompare: function(e2, t2) {
|
|
return null == e2 || null == t2 ? null == e2 && null == t2 : e2.sameText(t2);
|
|
}, eventMatches: function(e2, t2, n2) {
|
|
var r2 = t2.qualifier;
|
|
return null == r2 || e2 !== n2.target && w(n2.target) && r2.matches(n2.target);
|
|
}, addEventFields: function(e2, t2) {
|
|
t2.cy = e2, t2.target = e2;
|
|
}, callbackContext: function(e2, t2, n2) {
|
|
return null != t2.qualifier ? n2.target : e2;
|
|
} }, ps = function(e2) {
|
|
return f(e2) ? new xa(e2) : e2;
|
|
}, fs = { createEmitter: function() {
|
|
var e2 = this._private;
|
|
return e2.emitter || (e2.emitter = new yo(hs, this)), this;
|
|
}, emitter: function() {
|
|
return this._private.emitter;
|
|
}, on: function(e2, t2, n2) {
|
|
return this.emitter().on(e2, ps(t2), n2), this;
|
|
}, removeListener: function(e2, t2, n2) {
|
|
return this.emitter().removeListener(e2, ps(t2), n2), this;
|
|
}, removeAllListeners: function() {
|
|
return this.emitter().removeAllListeners(), this;
|
|
}, one: function(e2, t2, n2) {
|
|
return this.emitter().one(e2, ps(t2), n2), this;
|
|
}, once: function(e2, t2, n2) {
|
|
return this.emitter().one(e2, ps(t2), n2), this;
|
|
}, emit: function(e2, t2) {
|
|
return this.emitter().emit(e2, t2), this;
|
|
}, emitAndNotify: function(e2, t2) {
|
|
return this.emit(e2), this.notify(e2, t2), this;
|
|
} };
|
|
Oi.eventAliasesOn(fs);
|
|
var gs = { png: function(e2) {
|
|
return e2 = e2 || {}, this._private.renderer.png(e2);
|
|
}, jpg: function(e2) {
|
|
var t2 = this._private.renderer;
|
|
return (e2 = e2 || {}).bg = e2.bg || "#fff", t2.jpg(e2);
|
|
} };
|
|
gs.jpeg = gs.jpg;
|
|
var vs = { layout: function(e2) {
|
|
if (null != e2) if (null != e2.name) {
|
|
var t2 = e2.name, n2 = this.extension("layout", t2);
|
|
if (null != n2) {
|
|
var r2;
|
|
r2 = f(e2.eles) ? this.$(e2.eles) : null != e2.eles ? e2.eles : this.$();
|
|
var i2 = new n2(I({}, e2, { cy: this, eles: r2 }));
|
|
return i2;
|
|
}
|
|
Oe("No such layout `" + t2 + "` found. Did you forget to import it and `cytoscape.use()` it?");
|
|
} else Oe("A `name` must be specified to make a layout");
|
|
else Oe("Layout options must be specified to make a layout");
|
|
} };
|
|
vs.createLayout = vs.makeLayout = vs.layout;
|
|
var ys = { notify: function(e2, t2) {
|
|
var n2 = this._private;
|
|
if (this.batching()) {
|
|
n2.batchNotifications = n2.batchNotifications || {};
|
|
var r2 = n2.batchNotifications[e2] = n2.batchNotifications[e2] || this.collection();
|
|
null != t2 && r2.merge(t2);
|
|
} else if (n2.notificationsEnabled) {
|
|
var i2 = this.renderer();
|
|
!this.destroyed() && i2 && i2.notify(e2, t2);
|
|
}
|
|
}, notifications: function(e2) {
|
|
var t2 = this._private;
|
|
return void 0 === e2 ? t2.notificationsEnabled : (t2.notificationsEnabled = !!e2, this);
|
|
}, noNotifications: function(e2) {
|
|
this.notifications(false), e2(), this.notifications(true);
|
|
}, batching: function() {
|
|
return this._private.batchCount > 0;
|
|
}, startBatch: function() {
|
|
var e2 = this._private;
|
|
return null == e2.batchCount && (e2.batchCount = 0), 0 === e2.batchCount && (e2.batchStyleEles = this.collection(), e2.batchNotifications = {}), e2.batchCount++, this;
|
|
}, endBatch: function() {
|
|
var e2 = this._private;
|
|
if (0 === e2.batchCount) return this;
|
|
if (e2.batchCount--, 0 === e2.batchCount) {
|
|
e2.batchStyleEles.updateStyle();
|
|
var t2 = this.renderer();
|
|
Object.keys(e2.batchNotifications).forEach(function(n2) {
|
|
var r2 = e2.batchNotifications[n2];
|
|
r2.empty() ? t2.notify(n2) : t2.notify(n2, r2);
|
|
});
|
|
}
|
|
return this;
|
|
}, batch: function(e2) {
|
|
return this.startBatch(), e2(), this.endBatch(), this;
|
|
}, batchData: function(e2) {
|
|
var t2 = this;
|
|
return this.batch(function() {
|
|
for (var n2 = Object.keys(e2), r2 = 0; r2 < n2.length; r2++) {
|
|
var i2 = n2[r2], a2 = e2[i2];
|
|
t2.getElementById(i2).data(a2);
|
|
}
|
|
});
|
|
} }, ms = Xe({ hideEdgesOnViewport: false, textureOnViewport: false, motionBlur: false, motionBlurOpacity: 0.05, pixelRatio: void 0, desktopTapThreshold: 4, touchTapThreshold: 8, wheelSensitivity: 1, debug: false, showFps: false }), bs = { renderTo: function(e2, t2, n2, r2) {
|
|
return this._private.renderer.renderTo(e2, t2, n2, r2), this;
|
|
}, renderer: function() {
|
|
return this._private.renderer;
|
|
}, forceRender: function() {
|
|
return this.notify("draw"), this;
|
|
}, resize: function() {
|
|
return this.invalidateSize(), this.emitAndNotify("resize"), this;
|
|
}, initRenderer: function(e2) {
|
|
var t2 = this.extension("renderer", e2.name);
|
|
if (null != t2) {
|
|
void 0 !== e2.wheelSensitivity && Ve("You have set a custom wheel sensitivity. This will make your app zoom unnaturally when using mainstream mice. You should change this value from the default only if you can guarantee that all your users will use the same hardware and OS configuration as your current machine.");
|
|
var n2 = ms(e2);
|
|
n2.cy = this, this._private.renderer = new t2(n2), this.notify("init");
|
|
} else Oe("Can not initialise: No such renderer `".concat(e2.name, "` found. Did you forget to import it and `cytoscape.use()` it?"));
|
|
}, destroyRenderer: function() {
|
|
this.notify("destroy");
|
|
var e2 = this.container();
|
|
if (e2) for (e2._cyreg = null; e2.childNodes.length > 0; ) e2.removeChild(e2.childNodes[0]);
|
|
this._private.renderer = null, this.mutableElements().forEach(function(e3) {
|
|
var t2 = e3._private;
|
|
t2.rscratch = {}, t2.rstyle = {}, t2.animation.current = [], t2.animation.queue = [];
|
|
});
|
|
}, onRender: function(e2) {
|
|
return this.on("render", e2);
|
|
}, offRender: function(e2) {
|
|
return this.off("render", e2);
|
|
} };
|
|
bs.invalidateDimensions = bs.resize;
|
|
var xs = { collection: function(e2, t2) {
|
|
return f(e2) ? this.$(e2) : x(e2) ? e2.collection() : v(e2) ? (t2 || (t2 = {}), new Qo(this, e2, t2.unique, t2.removed)) : new Qo(this);
|
|
}, nodes: function(e2) {
|
|
var t2 = this.$(function(e3) {
|
|
return e3.isNode();
|
|
});
|
|
return e2 ? t2.filter(e2) : t2;
|
|
}, edges: function(e2) {
|
|
var t2 = this.$(function(e3) {
|
|
return e3.isEdge();
|
|
});
|
|
return e2 ? t2.filter(e2) : t2;
|
|
}, $: function(e2) {
|
|
var t2 = this._private.elements;
|
|
return e2 ? t2.filter(e2) : t2.spawnSelf();
|
|
}, mutableElements: function() {
|
|
return this._private.elements;
|
|
} };
|
|
xs.elements = xs.filter = xs.$;
|
|
var ws = {};
|
|
ws.apply = function(e2) {
|
|
for (var t2 = this._private.cy.collection(), n2 = 0; n2 < e2.length; n2++) {
|
|
var r2 = e2[n2], i2 = this.getContextMeta(r2);
|
|
if (!i2.empty) {
|
|
var a2 = this.getContextStyle(i2), o2 = this.applyContextStyle(i2, a2, r2);
|
|
r2._private.appliedInitStyle ? this.updateTransitions(r2, o2.diffProps) : r2._private.appliedInitStyle = true, this.updateStyleHints(r2) && t2.push(r2);
|
|
}
|
|
}
|
|
return t2;
|
|
}, ws.getPropertiesDiff = function(e2, t2) {
|
|
var n2 = this._private.propDiffs = this._private.propDiffs || {}, r2 = e2 + "-" + t2, i2 = n2[r2];
|
|
if (i2) return i2;
|
|
for (var a2 = [], o2 = {}, s2 = 0; s2 < this.length; s2++) {
|
|
var l2 = this[s2], u2 = "t" === e2[s2], c2 = "t" === t2[s2], d2 = u2 !== c2, h2 = l2.mappedProperties.length > 0;
|
|
if (d2 || c2 && h2) {
|
|
var p2 = void 0;
|
|
d2 && h2 || d2 ? p2 = l2.properties : h2 && (p2 = l2.mappedProperties);
|
|
for (var f2 = 0; f2 < p2.length; f2++) {
|
|
for (var g2 = p2[f2], v2 = g2.name, y2 = false, m2 = s2 + 1; m2 < this.length; m2++) {
|
|
var b2 = this[m2];
|
|
if ("t" === t2[m2] && (y2 = null != b2.properties[g2.name])) break;
|
|
}
|
|
o2[v2] || y2 || (o2[v2] = true, a2.push(v2));
|
|
}
|
|
}
|
|
}
|
|
return n2[r2] = a2, a2;
|
|
}, ws.getContextMeta = function(e2) {
|
|
for (var t2, n2 = "", r2 = e2._private.styleCxtKey || "", i2 = 0; i2 < this.length; i2++) {
|
|
var a2 = this[i2];
|
|
n2 += a2.selector && a2.selector.matches(e2) ? "t" : "f";
|
|
}
|
|
return t2 = this.getPropertiesDiff(r2, n2), e2._private.styleCxtKey = n2, { key: n2, diffPropNames: t2, empty: 0 === t2.length };
|
|
}, ws.getContextStyle = function(e2) {
|
|
var t2 = e2.key, n2 = this._private.contextStyles = this._private.contextStyles || {};
|
|
if (n2[t2]) return n2[t2];
|
|
for (var r2 = { _private: { key: t2 } }, i2 = 0; i2 < this.length; i2++) {
|
|
var a2 = this[i2];
|
|
if ("t" === t2[i2]) for (var o2 = 0; o2 < a2.properties.length; o2++) {
|
|
var s2 = a2.properties[o2];
|
|
r2[s2.name] = s2;
|
|
}
|
|
}
|
|
return n2[t2] = r2, r2;
|
|
}, ws.applyContextStyle = function(e2, t2, n2) {
|
|
for (var r2 = e2.diffPropNames, i2 = {}, a2 = this.types, o2 = 0; o2 < r2.length; o2++) {
|
|
var s2 = r2[o2], l2 = t2[s2], u2 = n2.pstyle(s2);
|
|
if (!l2) {
|
|
if (!u2) continue;
|
|
l2 = u2.bypass ? { name: s2, deleteBypassed: true } : { name: s2, delete: true };
|
|
}
|
|
if (u2 !== l2) {
|
|
if (l2.mapped === a2.fn && null != u2 && null != u2.mapping && u2.mapping.value === l2.value) {
|
|
var c2 = u2.mapping;
|
|
if ((c2.fnValue = l2.value(n2)) === c2.prevFnValue) continue;
|
|
}
|
|
var d2 = i2[s2] = { prev: u2 };
|
|
this.applyParsedProperty(n2, l2), d2.next = n2.pstyle(s2), d2.next && d2.next.bypass && (d2.next = d2.next.bypassed);
|
|
}
|
|
}
|
|
return { diffProps: i2 };
|
|
}, ws.updateStyleHints = function(e2) {
|
|
var t2 = e2._private, n2 = this, r2 = n2.propertyGroupNames, i2 = n2.propertyGroupKeys, a2 = function(e3, t3, r3) {
|
|
return n2.getPropertiesHash(e3, t3, r3);
|
|
}, o2 = t2.styleKey;
|
|
if (e2.removed()) return false;
|
|
var s2 = "nodes" === t2.group, l2 = e2._private.style;
|
|
r2 = Object.keys(l2);
|
|
for (var u2 = 0; u2 < i2.length; u2++) {
|
|
var c2 = i2[u2];
|
|
t2.styleKeys[c2] = [9261, 5381];
|
|
}
|
|
for (var d2, h2 = function(e3, n3) {
|
|
return t2.styleKeys[n3][0] = Ee(e3, t2.styleKeys[n3][0]);
|
|
}, p2 = function(e3, n3) {
|
|
return t2.styleKeys[n3][1] = ke(e3, t2.styleKeys[n3][1]);
|
|
}, f2 = function(e3, t3) {
|
|
h2(e3, t3), p2(e3, t3);
|
|
}, g2 = function(e3, t3) {
|
|
for (var n3 = 0; n3 < e3.length; n3++) {
|
|
var r3 = e3.charCodeAt(n3);
|
|
h2(r3, t3), p2(r3, t3);
|
|
}
|
|
}, v2 = 0; v2 < r2.length; v2++) {
|
|
var y2 = r2[v2], m2 = l2[y2];
|
|
if (null != m2) {
|
|
var b2 = this.properties[y2], x2 = b2.type, w2 = b2.groupKey, E2 = void 0;
|
|
null != b2.hashOverride ? E2 = b2.hashOverride(e2, m2) : null != m2.pfValue && (E2 = m2.pfValue);
|
|
var k2 = null == b2.enums ? m2.value : null, C2 = null != E2, S2 = C2 || null != k2, P2 = m2.units;
|
|
if (x2.number && S2 && !x2.multiple) f2(-128 < (d2 = C2 ? E2 : k2) && d2 < 128 && Math.floor(d2) !== d2 ? 2e9 - (1024 * d2 | 0) : d2, w2), C2 || null == P2 || g2(P2, w2);
|
|
else g2(m2.strValue, w2);
|
|
}
|
|
}
|
|
for (var D2, T2, _2 = [9261, 5381], M2 = 0; M2 < i2.length; M2++) {
|
|
var B2 = i2[M2], N2 = t2.styleKeys[B2];
|
|
_2[0] = Ee(N2[0], _2[0]), _2[1] = ke(N2[1], _2[1]);
|
|
}
|
|
t2.styleKey = (D2 = _2[0], T2 = _2[1], 2097152 * D2 + T2);
|
|
var z2 = t2.styleKeys;
|
|
t2.labelDimsKey = Ce(z2.labelDimensions);
|
|
var I2 = a2(e2, ["label"], z2.labelDimensions);
|
|
if (t2.labelKey = Ce(I2), t2.labelStyleKey = Ce(Se(z2.commonLabel, I2)), !s2) {
|
|
var L3 = a2(e2, ["source-label"], z2.labelDimensions);
|
|
t2.sourceLabelKey = Ce(L3), t2.sourceLabelStyleKey = Ce(Se(z2.commonLabel, L3));
|
|
var A2 = a2(e2, ["target-label"], z2.labelDimensions);
|
|
t2.targetLabelKey = Ce(A2), t2.targetLabelStyleKey = Ce(Se(z2.commonLabel, A2));
|
|
}
|
|
if (s2) {
|
|
var O2 = t2.styleKeys, R2 = O2.nodeBody, V2 = O2.nodeBorder, F2 = O2.nodeOutline, j2 = O2.backgroundImage, q2 = O2.compound, Y2 = O2.pie, X2 = [R2, V2, F2, j2, q2, Y2].filter(function(e3) {
|
|
return null != e3;
|
|
}).reduce(Se, [9261, 5381]);
|
|
t2.nodeKey = Ce(X2), t2.hasPie = null != Y2 && 9261 !== Y2[0] && 5381 !== Y2[1];
|
|
}
|
|
return o2 !== t2.styleKey;
|
|
}, ws.clearStyleHints = function(e2) {
|
|
var t2 = e2._private;
|
|
t2.styleCxtKey = "", t2.styleKeys = {}, t2.styleKey = null, t2.labelKey = null, t2.labelStyleKey = null, t2.sourceLabelKey = null, t2.sourceLabelStyleKey = null, t2.targetLabelKey = null, t2.targetLabelStyleKey = null, t2.nodeKey = null, t2.hasPie = null;
|
|
}, ws.applyParsedProperty = function(e2, t2) {
|
|
var n2, r2 = this, i2 = t2, a2 = e2._private.style, o2 = r2.types, s2 = r2.properties[i2.name].type, l2 = i2.bypass, u2 = a2[i2.name], c2 = u2 && u2.bypass, d2 = e2._private, h2 = function(e3) {
|
|
return null == e3 ? null : null != e3.pfValue ? e3.pfValue : e3.value;
|
|
}, p2 = function() {
|
|
var t3 = h2(u2), n3 = h2(i2);
|
|
r2.checkTriggers(e2, i2.name, t3, n3);
|
|
};
|
|
if ("curve-style" === t2.name && e2.isEdge() && ("bezier" !== t2.value && e2.isLoop() || "haystack" === t2.value && (e2.source().isParent() || e2.target().isParent())) && (i2 = t2 = this.parse(t2.name, "bezier", l2)), i2.delete) return a2[i2.name] = void 0, p2(), true;
|
|
if (i2.deleteBypassed) return u2 ? !!u2.bypass && (u2.bypassed = void 0, p2(), true) : (p2(), true);
|
|
if (i2.deleteBypass) return u2 ? !!u2.bypass && (a2[i2.name] = u2.bypassed, p2(), true) : (p2(), true);
|
|
var f2 = function() {
|
|
Ve("Do not assign mappings to elements without corresponding data (i.e. ele `" + e2.id() + "` has no mapping for property `" + i2.name + "` with data field `" + i2.field + "`); try a `[" + i2.field + "]` selector to limit scope to elements with `" + i2.field + "` defined");
|
|
};
|
|
switch (i2.mapped) {
|
|
case o2.mapData:
|
|
for (var g2, v2 = i2.field.split("."), y2 = d2.data, b2 = 0; b2 < v2.length && y2; b2++) {
|
|
y2 = y2[v2[b2]];
|
|
}
|
|
if (null == y2) return f2(), false;
|
|
if (!m(y2)) return Ve("Do not use continuous mappers without specifying numeric data (i.e. `" + i2.field + ": " + y2 + "` for `" + e2.id() + "` is non-numeric)"), false;
|
|
var x2 = i2.fieldMax - i2.fieldMin;
|
|
if ((g2 = 0 === x2 ? 0 : (y2 - i2.fieldMin) / x2) < 0 ? g2 = 0 : g2 > 1 && (g2 = 1), s2.color) {
|
|
var w2 = i2.valueMin[0], E2 = i2.valueMax[0], k2 = i2.valueMin[1], C2 = i2.valueMax[1], S2 = i2.valueMin[2], P2 = i2.valueMax[2], D2 = null == i2.valueMin[3] ? 1 : i2.valueMin[3], T2 = null == i2.valueMax[3] ? 1 : i2.valueMax[3], _2 = [Math.round(w2 + (E2 - w2) * g2), Math.round(k2 + (C2 - k2) * g2), Math.round(S2 + (P2 - S2) * g2), Math.round(D2 + (T2 - D2) * g2)];
|
|
n2 = { bypass: i2.bypass, name: i2.name, value: _2, strValue: "rgb(" + _2[0] + ", " + _2[1] + ", " + _2[2] + ")" };
|
|
} else {
|
|
if (!s2.number) return false;
|
|
var M2 = i2.valueMin + (i2.valueMax - i2.valueMin) * g2;
|
|
n2 = this.parse(i2.name, M2, i2.bypass, "mapping");
|
|
}
|
|
if (!n2) return f2(), false;
|
|
n2.mapping = i2, i2 = n2;
|
|
break;
|
|
case o2.data:
|
|
for (var B2 = i2.field.split("."), N2 = d2.data, z2 = 0; z2 < B2.length && N2; z2++) {
|
|
N2 = N2[B2[z2]];
|
|
}
|
|
if (null != N2 && (n2 = this.parse(i2.name, N2, i2.bypass, "mapping")), !n2) return f2(), false;
|
|
n2.mapping = i2, i2 = n2;
|
|
break;
|
|
case o2.fn:
|
|
var I2 = i2.value, L3 = null != i2.fnValue ? i2.fnValue : I2(e2);
|
|
if (i2.prevFnValue = L3, null == L3) return Ve("Custom function mappers may not return null (i.e. `" + i2.name + "` for ele `" + e2.id() + "` is null)"), false;
|
|
if (!(n2 = this.parse(i2.name, L3, i2.bypass, "mapping"))) return Ve("Custom function mappers may not return invalid values for the property type (i.e. `" + i2.name + "` for ele `" + e2.id() + "` is invalid)"), false;
|
|
n2.mapping = Fe(i2), i2 = n2;
|
|
break;
|
|
case void 0:
|
|
break;
|
|
default:
|
|
return false;
|
|
}
|
|
return l2 ? (i2.bypassed = c2 ? u2.bypassed : u2, a2[i2.name] = i2) : c2 ? u2.bypassed = i2 : a2[i2.name] = i2, p2(), true;
|
|
}, ws.cleanElements = function(e2, t2) {
|
|
for (var n2 = 0; n2 < e2.length; n2++) {
|
|
var r2 = e2[n2];
|
|
if (this.clearStyleHints(r2), r2.dirtyCompoundBoundsCache(), r2.dirtyBoundingBoxCache(), t2) for (var i2 = r2._private.style, a2 = Object.keys(i2), o2 = 0; o2 < a2.length; o2++) {
|
|
var s2 = a2[o2], l2 = i2[s2];
|
|
null != l2 && (l2.bypass ? l2.bypassed = null : i2[s2] = null);
|
|
}
|
|
else r2._private.style = {};
|
|
}
|
|
}, ws.update = function() {
|
|
this._private.cy.mutableElements().updateStyle();
|
|
}, ws.updateTransitions = function(e2, t2) {
|
|
var n2 = this, r2 = e2._private, i2 = e2.pstyle("transition-property").value, a2 = e2.pstyle("transition-duration").pfValue, o2 = e2.pstyle("transition-delay").pfValue;
|
|
if (i2.length > 0 && a2 > 0) {
|
|
for (var s2 = {}, l2 = false, u2 = 0; u2 < i2.length; u2++) {
|
|
var c2 = i2[u2], d2 = e2.pstyle(c2), h2 = t2[c2];
|
|
if (h2) {
|
|
var p2 = h2.prev, f2 = null != h2.next ? h2.next : d2, g2 = false, y2 = void 0;
|
|
p2 && (m(p2.pfValue) && m(f2.pfValue) ? (g2 = f2.pfValue - p2.pfValue, y2 = p2.pfValue + 1e-6 * g2) : m(p2.value) && m(f2.value) ? (g2 = f2.value - p2.value, y2 = p2.value + 1e-6 * g2) : v(p2.value) && v(f2.value) && (g2 = p2.value[0] !== f2.value[0] || p2.value[1] !== f2.value[1] || p2.value[2] !== f2.value[2], y2 = p2.strValue), g2 && (s2[c2] = f2.strValue, this.applyBypass(e2, c2, y2), l2 = true));
|
|
}
|
|
}
|
|
if (!l2) return;
|
|
r2.transitioning = true, new pr(function(t3) {
|
|
o2 > 0 ? e2.delayAnimation(o2).play().promise().then(t3) : t3();
|
|
}).then(function() {
|
|
return e2.animation({ style: s2, duration: a2, easing: e2.pstyle("transition-timing-function").value, queue: false }).play().promise();
|
|
}).then(function() {
|
|
n2.removeBypasses(e2, i2), e2.emitAndNotify("style"), r2.transitioning = false;
|
|
});
|
|
} else r2.transitioning && (this.removeBypasses(e2, i2), e2.emitAndNotify("style"), r2.transitioning = false);
|
|
}, ws.checkTrigger = function(e2, t2, n2, r2, i2, a2) {
|
|
var o2 = this.properties[t2], s2 = i2(o2);
|
|
null != s2 && s2(n2, r2) && a2(o2);
|
|
}, ws.checkZOrderTrigger = function(e2, t2, n2, r2) {
|
|
var i2 = this;
|
|
this.checkTrigger(e2, t2, n2, r2, function(e3) {
|
|
return e3.triggersZOrder;
|
|
}, function() {
|
|
i2._private.cy.notify("zorder", e2);
|
|
});
|
|
}, ws.checkBoundsTrigger = function(e2, t2, n2, r2) {
|
|
this.checkTrigger(e2, t2, n2, r2, function(e3) {
|
|
return e3.triggersBounds;
|
|
}, function(i2) {
|
|
e2.dirtyCompoundBoundsCache(), e2.dirtyBoundingBoxCache(), !i2.triggersBoundsOfParallelBeziers || "curve-style" !== t2 || "bezier" !== n2 && "bezier" !== r2 || e2.parallelEdges().forEach(function(e3) {
|
|
e3.isBundledBezier() && e3.dirtyBoundingBoxCache();
|
|
}), !i2.triggersBoundsOfConnectedEdges || "display" !== t2 || "none" !== n2 && "none" !== r2 || e2.connectedEdges().forEach(function(e3) {
|
|
e3.dirtyBoundingBoxCache();
|
|
});
|
|
});
|
|
}, ws.checkTriggers = function(e2, t2, n2, r2) {
|
|
e2.dirtyStyleCache(), this.checkZOrderTrigger(e2, t2, n2, r2), this.checkBoundsTrigger(e2, t2, n2, r2);
|
|
};
|
|
var Es = { applyBypass: function(e2, t2, n2, r2) {
|
|
var i2 = [];
|
|
if ("*" === t2 || "**" === t2) {
|
|
if (void 0 !== n2) for (var a2 = 0; a2 < this.properties.length; a2++) {
|
|
var o2 = this.properties[a2].name, s2 = this.parse(o2, n2, true);
|
|
s2 && i2.push(s2);
|
|
}
|
|
} else if (f(t2)) {
|
|
var l2 = this.parse(t2, n2, true);
|
|
l2 && i2.push(l2);
|
|
} else {
|
|
if (!y(t2)) return false;
|
|
var u2 = t2;
|
|
r2 = n2;
|
|
for (var c2 = Object.keys(u2), d2 = 0; d2 < c2.length; d2++) {
|
|
var h2 = c2[d2], p2 = u2[h2];
|
|
if (void 0 === p2 && (p2 = u2[_(h2)]), void 0 !== p2) {
|
|
var g2 = this.parse(h2, p2, true);
|
|
g2 && i2.push(g2);
|
|
}
|
|
}
|
|
}
|
|
if (0 === i2.length) return false;
|
|
for (var v2 = false, m2 = 0; m2 < e2.length; m2++) {
|
|
for (var b2 = e2[m2], x2 = {}, w2 = void 0, E2 = 0; E2 < i2.length; E2++) {
|
|
var k2 = i2[E2];
|
|
if (r2) {
|
|
var C2 = b2.pstyle(k2.name);
|
|
w2 = x2[k2.name] = { prev: C2 };
|
|
}
|
|
v2 = this.applyParsedProperty(b2, Fe(k2)) || v2, r2 && (w2.next = b2.pstyle(k2.name));
|
|
}
|
|
v2 && this.updateStyleHints(b2), r2 && this.updateTransitions(b2, x2, true);
|
|
}
|
|
return v2;
|
|
}, overrideBypass: function(e2, t2, n2) {
|
|
t2 = T(t2);
|
|
for (var r2 = 0; r2 < e2.length; r2++) {
|
|
var i2 = e2[r2], a2 = i2._private.style[t2], o2 = this.properties[t2].type, s2 = o2.color, l2 = o2.mutiple, u2 = a2 ? null != a2.pfValue ? a2.pfValue : a2.value : null;
|
|
a2 && a2.bypass ? (a2.value = n2, null != a2.pfValue && (a2.pfValue = n2), a2.strValue = s2 ? "rgb(" + n2.join(",") + ")" : l2 ? n2.join(" ") : "" + n2, this.updateStyleHints(i2)) : this.applyBypass(i2, t2, n2), this.checkTriggers(i2, t2, u2, n2);
|
|
}
|
|
}, removeAllBypasses: function(e2, t2) {
|
|
return this.removeBypasses(e2, this.propertyNames, t2);
|
|
}, removeBypasses: function(e2, t2, n2) {
|
|
for (var r2 = 0; r2 < e2.length; r2++) {
|
|
for (var i2 = e2[r2], a2 = {}, o2 = 0; o2 < t2.length; o2++) {
|
|
var s2 = t2[o2], l2 = this.properties[s2], u2 = i2.pstyle(l2.name);
|
|
if (u2 && u2.bypass) {
|
|
var c2 = this.parse(s2, "", true), d2 = a2[l2.name] = { prev: u2 };
|
|
this.applyParsedProperty(i2, c2), d2.next = i2.pstyle(l2.name);
|
|
}
|
|
}
|
|
this.updateStyleHints(i2), n2 && this.updateTransitions(i2, a2, true);
|
|
}
|
|
} }, ks = { getEmSizeInPixels: function() {
|
|
var e2 = this.containerCss("font-size");
|
|
return null != e2 ? parseFloat(e2) : 1;
|
|
}, containerCss: function(e2) {
|
|
var t2 = this._private.cy, n2 = t2.container(), r2 = t2.window();
|
|
if (r2 && n2 && r2.getComputedStyle) return r2.getComputedStyle(n2).getPropertyValue(e2);
|
|
} }, Cs = { getRenderedStyle: function(e2, t2) {
|
|
return t2 ? this.getStylePropertyValue(e2, t2, true) : this.getRawStyle(e2, true);
|
|
}, getRawStyle: function(e2, t2) {
|
|
if (e2 = e2[0]) {
|
|
for (var n2 = {}, r2 = 0; r2 < this.properties.length; r2++) {
|
|
var i2 = this.properties[r2], a2 = this.getStylePropertyValue(e2, i2.name, t2);
|
|
null != a2 && (n2[i2.name] = a2, n2[_(i2.name)] = a2);
|
|
}
|
|
return n2;
|
|
}
|
|
}, getIndexedStyle: function(e2, t2, n2, r2) {
|
|
var i2 = e2.pstyle(t2)[n2][r2];
|
|
return null != i2 ? i2 : e2.cy().style().getDefaultProperty(t2)[n2][0];
|
|
}, getStylePropertyValue: function(e2, t2, n2) {
|
|
if (e2 = e2[0]) {
|
|
var r2 = this.properties[t2];
|
|
r2.alias && (r2 = r2.pointsTo);
|
|
var i2 = r2.type, a2 = e2.pstyle(r2.name);
|
|
if (a2) {
|
|
var o2 = a2.value, s2 = a2.units, l2 = a2.strValue;
|
|
if (n2 && i2.number && null != o2 && m(o2)) {
|
|
var u2 = e2.cy().zoom(), c2 = function(e3) {
|
|
return e3 * u2;
|
|
}, d2 = function(e3, t3) {
|
|
return c2(e3) + t3;
|
|
}, h2 = v(o2);
|
|
return (h2 ? s2.every(function(e3) {
|
|
return null != e3;
|
|
}) : null != s2) ? h2 ? o2.map(function(e3, t3) {
|
|
return d2(e3, s2[t3]);
|
|
}).join(" ") : d2(o2, s2) : h2 ? o2.map(function(e3) {
|
|
return f(e3) ? e3 : "" + c2(e3);
|
|
}).join(" ") : "" + c2(o2);
|
|
}
|
|
if (null != l2) return l2;
|
|
}
|
|
return null;
|
|
}
|
|
}, getAnimationStartStyle: function(e2, t2) {
|
|
for (var n2 = {}, r2 = 0; r2 < t2.length; r2++) {
|
|
var i2 = t2[r2].name, a2 = e2.pstyle(i2);
|
|
void 0 !== a2 && (a2 = y(a2) ? this.parse(i2, a2.strValue) : this.parse(i2, a2)), a2 && (n2[i2] = a2);
|
|
}
|
|
return n2;
|
|
}, getPropsList: function(e2) {
|
|
var t2 = [], n2 = e2, r2 = this.properties;
|
|
if (n2) for (var i2 = Object.keys(n2), a2 = 0; a2 < i2.length; a2++) {
|
|
var o2 = i2[a2], s2 = n2[o2], l2 = r2[o2] || r2[T(o2)], u2 = this.parse(l2.name, s2);
|
|
u2 && t2.push(u2);
|
|
}
|
|
return t2;
|
|
}, getNonDefaultPropertiesHash: function(e2, t2, n2) {
|
|
var r2, i2, a2, o2, s2, l2, u2 = n2.slice();
|
|
for (s2 = 0; s2 < t2.length; s2++) if (r2 = t2[s2], null != (i2 = e2.pstyle(r2, false))) if (null != i2.pfValue) u2[0] = Ee(o2, u2[0]), u2[1] = ke(o2, u2[1]);
|
|
else for (a2 = i2.strValue, l2 = 0; l2 < a2.length; l2++) o2 = a2.charCodeAt(l2), u2[0] = Ee(o2, u2[0]), u2[1] = ke(o2, u2[1]);
|
|
return u2;
|
|
} };
|
|
Cs.getPropertiesHash = Cs.getNonDefaultPropertiesHash;
|
|
var Ss = { appendFromJson: function(e2) {
|
|
for (var t2 = 0; t2 < e2.length; t2++) {
|
|
var n2 = e2[t2], r2 = n2.selector, i2 = n2.style || n2.css, a2 = Object.keys(i2);
|
|
this.selector(r2);
|
|
for (var o2 = 0; o2 < a2.length; o2++) {
|
|
var s2 = a2[o2], l2 = i2[s2];
|
|
this.css(s2, l2);
|
|
}
|
|
}
|
|
return this;
|
|
}, fromJson: function(e2) {
|
|
return this.resetToDefault(), this.appendFromJson(e2), this;
|
|
}, json: function() {
|
|
for (var e2 = [], t2 = this.defaultLength; t2 < this.length; t2++) {
|
|
for (var n2 = this[t2], r2 = n2.selector, i2 = n2.properties, a2 = {}, o2 = 0; o2 < i2.length; o2++) {
|
|
var s2 = i2[o2];
|
|
a2[s2.name] = s2.strValue;
|
|
}
|
|
e2.push({ selector: r2 ? r2.toString() : "core", style: a2 });
|
|
}
|
|
return e2;
|
|
} }, Ps = { appendFromString: function(e2) {
|
|
var t2, n2, r2, i2 = "" + e2;
|
|
function a2() {
|
|
i2 = i2.length > t2.length ? i2.substr(t2.length) : "";
|
|
}
|
|
function o2() {
|
|
n2 = n2.length > r2.length ? n2.substr(r2.length) : "";
|
|
}
|
|
for (i2 = i2.replace(/[/][*](\s|.)+?[*][/]/g, ""); ; ) {
|
|
if (i2.match(/^\s*$/)) break;
|
|
var s2 = i2.match(/^\s*((?:.|\s)+?)\s*\{((?:.|\s)+?)\}/);
|
|
if (!s2) {
|
|
Ve("Halting stylesheet parsing: String stylesheet contains more to parse but no selector and block found in: " + i2);
|
|
break;
|
|
}
|
|
t2 = s2[0];
|
|
var l2 = s2[1];
|
|
if ("core" !== l2) {
|
|
if (new xa(l2).invalid) {
|
|
Ve("Skipping parsing of block: Invalid selector found in string stylesheet: " + l2), a2();
|
|
continue;
|
|
}
|
|
}
|
|
var u2 = s2[2], c2 = false;
|
|
n2 = u2;
|
|
for (var d2 = []; ; ) {
|
|
if (n2.match(/^\s*$/)) break;
|
|
var h2 = n2.match(/^\s*(.+?)\s*:\s*(.+?)(?:\s*;|\s*$)/);
|
|
if (!h2) {
|
|
Ve("Skipping parsing of block: Invalid formatting of style property and value definitions found in:" + u2), c2 = true;
|
|
break;
|
|
}
|
|
r2 = h2[0];
|
|
var p2 = h2[1], f2 = h2[2];
|
|
if (this.properties[p2]) this.parse(p2, f2) ? (d2.push({ name: p2, val: f2 }), o2()) : (Ve("Skipping property: Invalid property definition in: " + r2), o2());
|
|
else Ve("Skipping property: Invalid property name in: " + r2), o2();
|
|
}
|
|
if (c2) {
|
|
a2();
|
|
break;
|
|
}
|
|
this.selector(l2);
|
|
for (var g2 = 0; g2 < d2.length; g2++) {
|
|
var v2 = d2[g2];
|
|
this.css(v2.name, v2.val);
|
|
}
|
|
a2();
|
|
}
|
|
return this;
|
|
}, fromString: function(e2) {
|
|
return this.resetToDefault(), this.appendFromString(e2), this;
|
|
} }, Ds = {};
|
|
!function() {
|
|
var e2 = N, t2 = function(e3) {
|
|
return "^" + e3 + "\\s*\\(\\s*([\\w\\.]+)\\s*\\)$";
|
|
}, n2 = function(t3) {
|
|
var n3 = e2 + "|\\w+|rgb[a]?\\((?:(?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))[%]?)\\s*,\\s*(?:(?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))[%]?)\\s*,\\s*(?:(?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))[%]?)(?:\\s*,\\s*(?:(?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))))?\\)|hsl[a]?\\((?:(?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?)))\\s*,\\s*(?:(?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))[%])\\s*,\\s*(?:(?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))[%])(?:\\s*,\\s*(?:(?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))))?\\)|\\#[0-9a-fA-F]{3}|\\#[0-9a-fA-F]{6}";
|
|
return "^" + t3 + "\\s*\\(([\\w\\.]+)\\s*\\,\\s*(" + e2 + ")\\s*\\,\\s*(" + e2 + ")\\s*,\\s*(" + n3 + ")\\s*\\,\\s*(" + n3 + ")\\)$";
|
|
}, r2 = [`^url\\s*\\(\\s*['"]?(.+?)['"]?\\s*\\)$`, "^(none)$", "^(.+)$"];
|
|
Ds.types = { time: { number: true, min: 0, units: "s|ms", implicitUnits: "ms" }, percent: { number: true, min: 0, max: 100, units: "%", implicitUnits: "%" }, percentages: { number: true, min: 0, max: 100, units: "%", implicitUnits: "%", multiple: true }, zeroOneNumber: { number: true, min: 0, max: 1, unitless: true }, zeroOneNumbers: { number: true, min: 0, max: 1, unitless: true, multiple: true }, nOneOneNumber: { number: true, min: -1, max: 1, unitless: true }, nonNegativeInt: { number: true, min: 0, integer: true, unitless: true }, nonNegativeNumber: { number: true, min: 0, unitless: true }, position: { enums: ["parent", "origin"] }, nodeSize: { number: true, min: 0, enums: ["label"] }, number: { number: true, unitless: true }, numbers: { number: true, unitless: true, multiple: true }, positiveNumber: { number: true, unitless: true, min: 0, strictMin: true }, size: { number: true, min: 0 }, bidirectionalSize: { number: true }, bidirectionalSizeMaybePercent: { number: true, allowPercent: true }, bidirectionalSizes: { number: true, multiple: true }, sizeMaybePercent: { number: true, min: 0, allowPercent: true }, axisDirection: { enums: ["horizontal", "leftward", "rightward", "vertical", "upward", "downward", "auto"] }, paddingRelativeTo: { enums: ["width", "height", "average", "min", "max"] }, bgWH: { number: true, min: 0, allowPercent: true, enums: ["auto"], multiple: true }, bgPos: { number: true, allowPercent: true, multiple: true }, bgRelativeTo: { enums: ["inner", "include-padding"], multiple: true }, bgRepeat: { enums: ["repeat", "repeat-x", "repeat-y", "no-repeat"], multiple: true }, bgFit: { enums: ["none", "contain", "cover"], multiple: true }, bgCrossOrigin: { enums: ["anonymous", "use-credentials", "null"], multiple: true }, bgClip: { enums: ["none", "node"], multiple: true }, bgContainment: { enums: ["inside", "over"], multiple: true }, color: { color: true }, colors: { color: true, multiple: true }, fill: { enums: ["solid", "linear-gradient", "radial-gradient"] }, bool: { enums: ["yes", "no"] }, bools: { enums: ["yes", "no"], multiple: true }, lineStyle: { enums: ["solid", "dotted", "dashed"] }, lineCap: { enums: ["butt", "round", "square"] }, borderStyle: { enums: ["solid", "dotted", "dashed", "double"] }, curveStyle: { enums: ["bezier", "unbundled-bezier", "haystack", "segments", "straight", "straight-triangle", "taxi"] }, fontFamily: { regex: '^([\\w- \\"]+(?:\\s*,\\s*[\\w- \\"]+)*)$' }, fontStyle: { enums: ["italic", "normal", "oblique"] }, fontWeight: { enums: ["normal", "bold", "bolder", "lighter", "100", "200", "300", "400", "500", "600", "800", "900", 100, 200, 300, 400, 500, 600, 700, 800, 900] }, textDecoration: { enums: ["none", "underline", "overline", "line-through"] }, textTransform: { enums: ["none", "uppercase", "lowercase"] }, textWrap: { enums: ["none", "wrap", "ellipsis"] }, textOverflowWrap: { enums: ["whitespace", "anywhere"] }, textBackgroundShape: { enums: ["rectangle", "roundrectangle", "round-rectangle"] }, nodeShape: { enums: ["rectangle", "roundrectangle", "round-rectangle", "cutrectangle", "cut-rectangle", "bottomroundrectangle", "bottom-round-rectangle", "barrel", "ellipse", "triangle", "round-triangle", "square", "pentagon", "round-pentagon", "hexagon", "round-hexagon", "concavehexagon", "concave-hexagon", "heptagon", "round-heptagon", "octagon", "round-octagon", "tag", "round-tag", "star", "diamond", "round-diamond", "vee", "rhomboid", "right-rhomboid", "polygon"] }, overlayShape: { enums: ["roundrectangle", "round-rectangle", "ellipse"] }, compoundIncludeLabels: { enums: ["include", "exclude"] }, arrowShape: { enums: ["tee", "triangle", "triangle-tee", "circle-triangle", "triangle-cross", "triangle-backcurve", "vee", "square", "circle", "diamond", "chevron", "none"] }, arrowFill: { enums: ["filled", "hollow"] }, arrowWidth: { number: true, units: "%|px|em", implicitUnits: "px", enums: ["match-line"] }, display: { enums: ["element", "none"] }, visibility: { enums: ["hidden", "visible"] }, zCompoundDepth: { enums: ["bottom", "orphan", "auto", "top"] }, zIndexCompare: { enums: ["auto", "manual"] }, valign: { enums: ["top", "center", "bottom"] }, halign: { enums: ["left", "center", "right"] }, justification: { enums: ["left", "center", "right", "auto"] }, text: { string: true }, data: { mapping: true, regex: t2("data") }, layoutData: { mapping: true, regex: t2("layoutData") }, scratch: { mapping: true, regex: t2("scratch") }, mapData: { mapping: true, regex: n2("mapData") }, mapLayoutData: { mapping: true, regex: n2("mapLayoutData") }, mapScratch: { mapping: true, regex: n2("mapScratch") }, fn: { mapping: true, fn: true }, url: { regexes: r2, singleRegexMatchValue: true }, urls: { regexes: r2, singleRegexMatchValue: true, multiple: true }, propList: { propList: true }, angle: { number: true, units: "deg|rad", implicitUnits: "rad" }, textRotation: { number: true, units: "deg|rad", implicitUnits: "rad", enums: ["none", "autorotate"] }, polygonPointList: { number: true, multiple: true, evenMultiple: true, min: -1, max: 1, unitless: true }, edgeDistances: { enums: ["intersection", "node-position", "endpoints"] }, edgeEndpoint: { number: true, multiple: true, units: "%|px|em|deg|rad", implicitUnits: "px", enums: ["inside-to-node", "outside-to-node", "outside-to-node-or-label", "outside-to-line", "outside-to-line-or-label"], singleEnum: true, validate: function(e3, t3) {
|
|
switch (e3.length) {
|
|
case 2:
|
|
return "deg" !== t3[0] && "rad" !== t3[0] && "deg" !== t3[1] && "rad" !== t3[1];
|
|
case 1:
|
|
return f(e3[0]) || "deg" === t3[0] || "rad" === t3[0];
|
|
default:
|
|
return false;
|
|
}
|
|
} }, easing: { regexes: ["^(spring)\\s*\\(\\s*(" + e2 + ")\\s*,\\s*(" + e2 + ")\\s*\\)$", "^(cubic-bezier)\\s*\\(\\s*(" + e2 + ")\\s*,\\s*(" + e2 + ")\\s*,\\s*(" + e2 + ")\\s*,\\s*(" + e2 + ")\\s*\\)$"], enums: ["linear", "ease", "ease-in", "ease-out", "ease-in-out", "ease-in-sine", "ease-out-sine", "ease-in-out-sine", "ease-in-quad", "ease-out-quad", "ease-in-out-quad", "ease-in-cubic", "ease-out-cubic", "ease-in-out-cubic", "ease-in-quart", "ease-out-quart", "ease-in-out-quart", "ease-in-quint", "ease-out-quint", "ease-in-out-quint", "ease-in-expo", "ease-out-expo", "ease-in-out-expo", "ease-in-circ", "ease-out-circ", "ease-in-out-circ"] }, gradientDirection: { enums: ["to-bottom", "to-top", "to-left", "to-right", "to-bottom-right", "to-bottom-left", "to-top-right", "to-top-left", "to-right-bottom", "to-left-bottom", "to-right-top", "to-left-top"] }, boundsExpansion: { number: true, multiple: true, min: 0, validate: function(e3) {
|
|
var t3 = e3.length;
|
|
return 1 === t3 || 2 === t3 || 4 === t3;
|
|
} } };
|
|
var i2 = { zeroNonZero: function(e3, t3) {
|
|
return (null == e3 || null == t3) && e3 !== t3 || (0 == e3 && 0 != t3 || 0 != e3 && 0 == t3);
|
|
}, any: function(e3, t3) {
|
|
return e3 != t3;
|
|
}, emptyNonEmpty: function(e3, t3) {
|
|
var n3 = S(e3), r3 = S(t3);
|
|
return n3 && !r3 || !n3 && r3;
|
|
} }, a2 = Ds.types, o2 = [{ name: "label", type: a2.text, triggersBounds: i2.any, triggersZOrder: i2.emptyNonEmpty }, { name: "text-rotation", type: a2.textRotation, triggersBounds: i2.any }, { name: "text-margin-x", type: a2.bidirectionalSize, triggersBounds: i2.any }, { name: "text-margin-y", type: a2.bidirectionalSize, triggersBounds: i2.any }], s2 = [{ name: "source-label", type: a2.text, triggersBounds: i2.any }, { name: "source-text-rotation", type: a2.textRotation, triggersBounds: i2.any }, { name: "source-text-margin-x", type: a2.bidirectionalSize, triggersBounds: i2.any }, { name: "source-text-margin-y", type: a2.bidirectionalSize, triggersBounds: i2.any }, { name: "source-text-offset", type: a2.size, triggersBounds: i2.any }], l2 = [{ name: "target-label", type: a2.text, triggersBounds: i2.any }, { name: "target-text-rotation", type: a2.textRotation, triggersBounds: i2.any }, { name: "target-text-margin-x", type: a2.bidirectionalSize, triggersBounds: i2.any }, { name: "target-text-margin-y", type: a2.bidirectionalSize, triggersBounds: i2.any }, { name: "target-text-offset", type: a2.size, triggersBounds: i2.any }], u2 = [{ name: "font-family", type: a2.fontFamily, triggersBounds: i2.any }, { name: "font-style", type: a2.fontStyle, triggersBounds: i2.any }, { name: "font-weight", type: a2.fontWeight, triggersBounds: i2.any }, { name: "font-size", type: a2.size, triggersBounds: i2.any }, { name: "text-transform", type: a2.textTransform, triggersBounds: i2.any }, { name: "text-wrap", type: a2.textWrap, triggersBounds: i2.any }, { name: "text-overflow-wrap", type: a2.textOverflowWrap, triggersBounds: i2.any }, { name: "text-max-width", type: a2.size, triggersBounds: i2.any }, { name: "text-outline-width", type: a2.size, triggersBounds: i2.any }, { name: "line-height", type: a2.positiveNumber, triggersBounds: i2.any }], c2 = [{ name: "text-valign", type: a2.valign, triggersBounds: i2.any }, { name: "text-halign", type: a2.halign, triggersBounds: i2.any }, { name: "color", type: a2.color }, { name: "text-outline-color", type: a2.color }, { name: "text-outline-opacity", type: a2.zeroOneNumber }, { name: "text-background-color", type: a2.color }, { name: "text-background-opacity", type: a2.zeroOneNumber }, { name: "text-background-padding", type: a2.size, triggersBounds: i2.any }, { name: "text-border-opacity", type: a2.zeroOneNumber }, { name: "text-border-color", type: a2.color }, { name: "text-border-width", type: a2.size, triggersBounds: i2.any }, { name: "text-border-style", type: a2.borderStyle, triggersBounds: i2.any }, { name: "text-background-shape", type: a2.textBackgroundShape, triggersBounds: i2.any }, { name: "text-justification", type: a2.justification }], d2 = [{ name: "events", type: a2.bool, triggersZOrder: i2.any }, { name: "text-events", type: a2.bool, triggersZOrder: i2.any }], h2 = [{ name: "display", type: a2.display, triggersZOrder: i2.any, triggersBounds: i2.any, triggersBoundsOfConnectedEdges: true }, { name: "visibility", type: a2.visibility, triggersZOrder: i2.any }, { name: "opacity", type: a2.zeroOneNumber, triggersZOrder: i2.zeroNonZero }, { name: "text-opacity", type: a2.zeroOneNumber }, { name: "min-zoomed-font-size", type: a2.size }, { name: "z-compound-depth", type: a2.zCompoundDepth, triggersZOrder: i2.any }, { name: "z-index-compare", type: a2.zIndexCompare, triggersZOrder: i2.any }, { name: "z-index", type: a2.number, triggersZOrder: i2.any }], p2 = [{ name: "overlay-padding", type: a2.size, triggersBounds: i2.any }, { name: "overlay-color", type: a2.color }, { name: "overlay-opacity", type: a2.zeroOneNumber, triggersBounds: i2.zeroNonZero }, { name: "overlay-shape", type: a2.overlayShape, triggersBounds: i2.any }], g2 = [{ name: "underlay-padding", type: a2.size, triggersBounds: i2.any }, { name: "underlay-color", type: a2.color }, { name: "underlay-opacity", type: a2.zeroOneNumber, triggersBounds: i2.zeroNonZero }, { name: "underlay-shape", type: a2.overlayShape, triggersBounds: i2.any }], v2 = [{ name: "transition-property", type: a2.propList }, { name: "transition-duration", type: a2.time }, { name: "transition-delay", type: a2.time }, { name: "transition-timing-function", type: a2.easing }], y2 = function(e3, t3) {
|
|
return "label" === t3.value ? -e3.poolIndex() : t3.pfValue;
|
|
}, m2 = [{ name: "height", type: a2.nodeSize, triggersBounds: i2.any, hashOverride: y2 }, { name: "width", type: a2.nodeSize, triggersBounds: i2.any, hashOverride: y2 }, { name: "shape", type: a2.nodeShape, triggersBounds: i2.any }, { name: "shape-polygon-points", type: a2.polygonPointList, triggersBounds: i2.any }, { name: "background-color", type: a2.color }, { name: "background-fill", type: a2.fill }, { name: "background-opacity", type: a2.zeroOneNumber }, { name: "background-blacken", type: a2.nOneOneNumber }, { name: "background-gradient-stop-colors", type: a2.colors }, { name: "background-gradient-stop-positions", type: a2.percentages }, { name: "background-gradient-direction", type: a2.gradientDirection }, { name: "padding", type: a2.sizeMaybePercent, triggersBounds: i2.any }, { name: "padding-relative-to", type: a2.paddingRelativeTo, triggersBounds: i2.any }, { name: "bounds-expansion", type: a2.boundsExpansion, triggersBounds: i2.any }], b2 = [{ name: "border-color", type: a2.color }, { name: "border-opacity", type: a2.zeroOneNumber }, { name: "border-width", type: a2.size, triggersBounds: i2.any }, { name: "border-style", type: a2.borderStyle }], x2 = [{ name: "outline-color", type: a2.color }, { name: "outline-opacity", type: a2.zeroOneNumber }, { name: "outline-width", type: a2.size, triggersBounds: i2.any }, { name: "outline-style", type: a2.borderStyle }, { name: "outline-offset", type: a2.size, triggersBounds: i2.any }], w2 = [{ name: "background-image", type: a2.urls }, { name: "background-image-crossorigin", type: a2.bgCrossOrigin }, { name: "background-image-opacity", type: a2.zeroOneNumbers }, { name: "background-image-containment", type: a2.bgContainment }, { name: "background-image-smoothing", type: a2.bools }, { name: "background-position-x", type: a2.bgPos }, { name: "background-position-y", type: a2.bgPos }, { name: "background-width-relative-to", type: a2.bgRelativeTo }, { name: "background-height-relative-to", type: a2.bgRelativeTo }, { name: "background-repeat", type: a2.bgRepeat }, { name: "background-fit", type: a2.bgFit }, { name: "background-clip", type: a2.bgClip }, { name: "background-width", type: a2.bgWH }, { name: "background-height", type: a2.bgWH }, { name: "background-offset-x", type: a2.bgPos }, { name: "background-offset-y", type: a2.bgPos }], E2 = [{ name: "position", type: a2.position, triggersBounds: i2.any }, { name: "compound-sizing-wrt-labels", type: a2.compoundIncludeLabels, triggersBounds: i2.any }, { name: "min-width", type: a2.size, triggersBounds: i2.any }, { name: "min-width-bias-left", type: a2.sizeMaybePercent, triggersBounds: i2.any }, { name: "min-width-bias-right", type: a2.sizeMaybePercent, triggersBounds: i2.any }, { name: "min-height", type: a2.size, triggersBounds: i2.any }, { name: "min-height-bias-top", type: a2.sizeMaybePercent, triggersBounds: i2.any }, { name: "min-height-bias-bottom", type: a2.sizeMaybePercent, triggersBounds: i2.any }], k2 = [{ name: "line-style", type: a2.lineStyle }, { name: "line-color", type: a2.color }, { name: "line-fill", type: a2.fill }, { name: "line-cap", type: a2.lineCap }, { name: "line-opacity", type: a2.zeroOneNumber }, { name: "line-dash-pattern", type: a2.numbers }, { name: "line-dash-offset", type: a2.number }, { name: "line-gradient-stop-colors", type: a2.colors }, { name: "line-gradient-stop-positions", type: a2.percentages }, { name: "curve-style", type: a2.curveStyle, triggersBounds: i2.any, triggersBoundsOfParallelBeziers: true }, { name: "haystack-radius", type: a2.zeroOneNumber, triggersBounds: i2.any }, { name: "source-endpoint", type: a2.edgeEndpoint, triggersBounds: i2.any }, { name: "target-endpoint", type: a2.edgeEndpoint, triggersBounds: i2.any }, { name: "control-point-step-size", type: a2.size, triggersBounds: i2.any }, { name: "control-point-distances", type: a2.bidirectionalSizes, triggersBounds: i2.any }, { name: "control-point-weights", type: a2.numbers, triggersBounds: i2.any }, { name: "segment-distances", type: a2.bidirectionalSizes, triggersBounds: i2.any }, { name: "segment-weights", type: a2.numbers, triggersBounds: i2.any }, { name: "taxi-turn", type: a2.bidirectionalSizeMaybePercent, triggersBounds: i2.any }, { name: "taxi-turn-min-distance", type: a2.size, triggersBounds: i2.any }, { name: "taxi-direction", type: a2.axisDirection, triggersBounds: i2.any }, { name: "edge-distances", type: a2.edgeDistances, triggersBounds: i2.any }, { name: "arrow-scale", type: a2.positiveNumber, triggersBounds: i2.any }, { name: "loop-direction", type: a2.angle, triggersBounds: i2.any }, { name: "loop-sweep", type: a2.angle, triggersBounds: i2.any }, { name: "source-distance-from-node", type: a2.size, triggersBounds: i2.any }, { name: "target-distance-from-node", type: a2.size, triggersBounds: i2.any }], C2 = [{ name: "ghost", type: a2.bool, triggersBounds: i2.any }, { name: "ghost-offset-x", type: a2.bidirectionalSize, triggersBounds: i2.any }, { name: "ghost-offset-y", type: a2.bidirectionalSize, triggersBounds: i2.any }, { name: "ghost-opacity", type: a2.zeroOneNumber }], P2 = [{ name: "selection-box-color", type: a2.color }, { name: "selection-box-opacity", type: a2.zeroOneNumber }, { name: "selection-box-border-color", type: a2.color }, { name: "selection-box-border-width", type: a2.size }, { name: "active-bg-color", type: a2.color }, { name: "active-bg-opacity", type: a2.zeroOneNumber }, { name: "active-bg-size", type: a2.size }, { name: "outside-texture-bg-color", type: a2.color }, { name: "outside-texture-bg-opacity", type: a2.zeroOneNumber }], D2 = [];
|
|
Ds.pieBackgroundN = 16, D2.push({ name: "pie-size", type: a2.sizeMaybePercent });
|
|
for (var T2 = 1; T2 <= Ds.pieBackgroundN; T2++) D2.push({ name: "pie-" + T2 + "-background-color", type: a2.color }), D2.push({ name: "pie-" + T2 + "-background-size", type: a2.percent }), D2.push({ name: "pie-" + T2 + "-background-opacity", type: a2.zeroOneNumber });
|
|
var _2 = [], M2 = Ds.arrowPrefixes = ["source", "mid-source", "target", "mid-target"];
|
|
[{ name: "arrow-shape", type: a2.arrowShape, triggersBounds: i2.any }, { name: "arrow-color", type: a2.color }, { name: "arrow-fill", type: a2.arrowFill }, { name: "arrow-width", type: a2.arrowWidth }].forEach(function(e3) {
|
|
M2.forEach(function(t3) {
|
|
var n3 = t3 + "-" + e3.name, r3 = e3.type, i3 = e3.triggersBounds;
|
|
_2.push({ name: n3, type: r3, triggersBounds: i3 });
|
|
});
|
|
}, {});
|
|
var B2 = Ds.properties = [].concat(d2, v2, h2, p2, g2, C2, c2, u2, o2, s2, l2, m2, b2, x2, w2, D2, E2, k2, _2, P2), z2 = Ds.propertyGroups = { behavior: d2, transition: v2, visibility: h2, overlay: p2, underlay: g2, ghost: C2, commonLabel: c2, labelDimensions: u2, mainLabel: o2, sourceLabel: s2, targetLabel: l2, nodeBody: m2, nodeBorder: b2, nodeOutline: x2, backgroundImage: w2, pie: D2, compound: E2, edgeLine: k2, edgeArrow: _2, core: P2 }, I2 = Ds.propertyGroupNames = {};
|
|
(Ds.propertyGroupKeys = Object.keys(z2)).forEach(function(e3) {
|
|
I2[e3] = z2[e3].map(function(e4) {
|
|
return e4.name;
|
|
}), z2[e3].forEach(function(t3) {
|
|
return t3.groupKey = e3;
|
|
});
|
|
});
|
|
var L3 = Ds.aliases = [{ name: "content", pointsTo: "label" }, { name: "control-point-distance", pointsTo: "control-point-distances" }, { name: "control-point-weight", pointsTo: "control-point-weights" }, { name: "edge-text-rotation", pointsTo: "text-rotation" }, { name: "padding-left", pointsTo: "padding" }, { name: "padding-right", pointsTo: "padding" }, { name: "padding-top", pointsTo: "padding" }, { name: "padding-bottom", pointsTo: "padding" }];
|
|
Ds.propertyNames = B2.map(function(e3) {
|
|
return e3.name;
|
|
});
|
|
for (var A2 = 0; A2 < B2.length; A2++) {
|
|
var O2 = B2[A2];
|
|
B2[O2.name] = O2;
|
|
}
|
|
for (var R2 = 0; R2 < L3.length; R2++) {
|
|
var V2 = L3[R2], F2 = B2[V2.pointsTo], j2 = { name: V2.name, alias: true, pointsTo: F2 };
|
|
B2.push(j2), B2[V2.name] = j2;
|
|
}
|
|
}(), Ds.getDefaultProperty = function(e2) {
|
|
return this.getDefaultProperties()[e2];
|
|
}, Ds.getDefaultProperties = function() {
|
|
var e2 = this._private;
|
|
if (null != e2.defaultProperties) return e2.defaultProperties;
|
|
for (var t2 = I({ "selection-box-color": "#ddd", "selection-box-opacity": 0.65, "selection-box-border-color": "#aaa", "selection-box-border-width": 1, "active-bg-color": "black", "active-bg-opacity": 0.15, "active-bg-size": 30, "outside-texture-bg-color": "#000", "outside-texture-bg-opacity": 0.125, events: "yes", "text-events": "no", "text-valign": "top", "text-halign": "center", "text-justification": "auto", "line-height": 1, color: "#000", "text-outline-color": "#000", "text-outline-width": 0, "text-outline-opacity": 1, "text-opacity": 1, "text-decoration": "none", "text-transform": "none", "text-wrap": "none", "text-overflow-wrap": "whitespace", "text-max-width": 9999, "text-background-color": "#000", "text-background-opacity": 0, "text-background-shape": "rectangle", "text-background-padding": 0, "text-border-opacity": 0, "text-border-width": 0, "text-border-style": "solid", "text-border-color": "#000", "font-family": "Helvetica Neue, Helvetica, sans-serif", "font-style": "normal", "font-weight": "normal", "font-size": 16, "min-zoomed-font-size": 0, "text-rotation": "none", "source-text-rotation": "none", "target-text-rotation": "none", visibility: "visible", display: "element", opacity: 1, "z-compound-depth": "auto", "z-index-compare": "auto", "z-index": 0, label: "", "text-margin-x": 0, "text-margin-y": 0, "source-label": "", "source-text-offset": 0, "source-text-margin-x": 0, "source-text-margin-y": 0, "target-label": "", "target-text-offset": 0, "target-text-margin-x": 0, "target-text-margin-y": 0, "overlay-opacity": 0, "overlay-color": "#000", "overlay-padding": 10, "overlay-shape": "round-rectangle", "underlay-opacity": 0, "underlay-color": "#000", "underlay-padding": 10, "underlay-shape": "round-rectangle", "transition-property": "none", "transition-duration": 0, "transition-delay": 0, "transition-timing-function": "linear", "background-blacken": 0, "background-color": "#999", "background-fill": "solid", "background-opacity": 1, "background-image": "none", "background-image-crossorigin": "anonymous", "background-image-opacity": 1, "background-image-containment": "inside", "background-image-smoothing": "yes", "background-position-x": "50%", "background-position-y": "50%", "background-offset-x": 0, "background-offset-y": 0, "background-width-relative-to": "include-padding", "background-height-relative-to": "include-padding", "background-repeat": "no-repeat", "background-fit": "none", "background-clip": "node", "background-width": "auto", "background-height": "auto", "border-color": "#000", "border-opacity": 1, "border-width": 0, "border-style": "solid", "outline-color": "#999", "outline-opacity": 1, "outline-width": 0, "outline-offset": 0, "outline-style": "solid", height: 30, width: 30, shape: "ellipse", "shape-polygon-points": "-1, -1, 1, -1, 1, 1, -1, 1", "bounds-expansion": 0, "background-gradient-direction": "to-bottom", "background-gradient-stop-colors": "#999", "background-gradient-stop-positions": "0%", ghost: "no", "ghost-offset-y": 0, "ghost-offset-x": 0, "ghost-opacity": 0, padding: 0, "padding-relative-to": "width", position: "origin", "compound-sizing-wrt-labels": "include", "min-width": 0, "min-width-bias-left": 0, "min-width-bias-right": 0, "min-height": 0, "min-height-bias-top": 0, "min-height-bias-bottom": 0 }, { "pie-size": "100%" }, [{ name: "pie-{{i}}-background-color", value: "black" }, { name: "pie-{{i}}-background-size", value: "0%" }, { name: "pie-{{i}}-background-opacity", value: 1 }].reduce(function(e3, t3) {
|
|
for (var n3 = 1; n3 <= Ds.pieBackgroundN; n3++) {
|
|
var r3 = t3.name.replace("{{i}}", n3), i3 = t3.value;
|
|
e3[r3] = i3;
|
|
}
|
|
return e3;
|
|
}, {}), { "line-style": "solid", "line-color": "#999", "line-fill": "solid", "line-cap": "butt", "line-opacity": 1, "line-gradient-stop-colors": "#999", "line-gradient-stop-positions": "0%", "control-point-step-size": 40, "control-point-weights": 0.5, "segment-weights": 0.5, "segment-distances": 20, "taxi-turn": "50%", "taxi-turn-min-distance": 10, "taxi-direction": "auto", "edge-distances": "intersection", "curve-style": "haystack", "haystack-radius": 0, "arrow-scale": 1, "loop-direction": "-45deg", "loop-sweep": "-90deg", "source-distance-from-node": 0, "target-distance-from-node": 0, "source-endpoint": "outside-to-node", "target-endpoint": "outside-to-node", "line-dash-pattern": [6, 3], "line-dash-offset": 0 }, [{ name: "arrow-shape", value: "none" }, { name: "arrow-color", value: "#999" }, { name: "arrow-fill", value: "filled" }, { name: "arrow-width", value: 1 }].reduce(function(e3, t3) {
|
|
return Ds.arrowPrefixes.forEach(function(n3) {
|
|
var r3 = n3 + "-" + t3.name, i3 = t3.value;
|
|
e3[r3] = i3;
|
|
}), e3;
|
|
}, {})), n2 = {}, r2 = 0; r2 < this.properties.length; r2++) {
|
|
var i2 = this.properties[r2];
|
|
if (!i2.pointsTo) {
|
|
var a2 = i2.name, o2 = t2[a2], s2 = this.parse(a2, o2);
|
|
n2[a2] = s2;
|
|
}
|
|
}
|
|
return e2.defaultProperties = n2, e2.defaultProperties;
|
|
}, Ds.addDefaultStylesheet = function() {
|
|
this.selector(":parent").css({ shape: "rectangle", padding: 10, "background-color": "#eee", "border-color": "#ccc", "border-width": 1 }).selector("edge").css({ width: 3 }).selector(":loop").css({ "curve-style": "bezier" }).selector("edge:compound").css({ "curve-style": "bezier", "source-endpoint": "outside-to-line", "target-endpoint": "outside-to-line" }).selector(":selected").css({ "background-color": "#0169D9", "line-color": "#0169D9", "source-arrow-color": "#0169D9", "target-arrow-color": "#0169D9", "mid-source-arrow-color": "#0169D9", "mid-target-arrow-color": "#0169D9" }).selector(":parent:selected").css({ "background-color": "#CCE1F9", "border-color": "#aec8e5" }).selector(":active").css({ "overlay-color": "black", "overlay-padding": 10, "overlay-opacity": 0.25 }), this.defaultLength = this.length;
|
|
};
|
|
var Ts = { parse: function(e2, t2, n2, r2) {
|
|
if (g(t2)) return this.parseImplWarn(e2, t2, n2, r2);
|
|
var i2, a2 = De(e2, "" + t2, n2 ? "t" : "f", "mapping" === r2 || true === r2 || false === r2 || null == r2 ? "dontcare" : r2), o2 = this.propCache = this.propCache || [];
|
|
return (i2 = o2[a2]) || (i2 = o2[a2] = this.parseImplWarn(e2, t2, n2, r2)), (n2 || "mapping" === r2) && (i2 = Fe(i2)) && (i2.value = Fe(i2.value)), i2;
|
|
}, parseImplWarn: function(e2, t2, n2, r2) {
|
|
var i2 = this.parseImpl(e2, t2, n2, r2);
|
|
return i2 || null == t2 || Ve("The style property `".concat(e2, ": ").concat(t2, "` is invalid")), !i2 || "width" !== i2.name && "height" !== i2.name || "label" !== t2 || Ve("The style value of `label` is deprecated for `" + i2.name + "`"), i2;
|
|
} };
|
|
Ts.parseImpl = function(e2, t2, n2, r2) {
|
|
e2 = T(e2);
|
|
var i2 = this.properties[e2], a2 = t2, o2 = this.types;
|
|
if (!i2) return null;
|
|
if (void 0 === t2) return null;
|
|
i2.alias && (i2 = i2.pointsTo, e2 = i2.name);
|
|
var s2 = f(t2);
|
|
s2 && (t2 = t2.trim());
|
|
var l2, u2, c2 = i2.type;
|
|
if (!c2) return null;
|
|
if (n2 && ("" === t2 || null === t2)) return { name: e2, value: t2, bypass: true, deleteBypass: true };
|
|
if (g(t2)) return { name: e2, value: t2, strValue: "fn", mapped: o2.fn, bypass: n2 };
|
|
if (!s2 || r2 || t2.length < 7 || "a" !== t2[1]) ;
|
|
else {
|
|
if (t2.length >= 7 && "d" === t2[0] && (l2 = new RegExp(o2.data.regex).exec(t2))) {
|
|
if (n2) return false;
|
|
var d2 = o2.data;
|
|
return { name: e2, value: l2, strValue: "" + t2, mapped: d2, field: l2[1], bypass: n2 };
|
|
}
|
|
if (t2.length >= 10 && "m" === t2[0] && (u2 = new RegExp(o2.mapData.regex).exec(t2))) {
|
|
if (n2) return false;
|
|
if (c2.multiple) return false;
|
|
var h2 = o2.mapData;
|
|
if (!c2.color && !c2.number) return false;
|
|
var p2 = this.parse(e2, u2[4]);
|
|
if (!p2 || p2.mapped) return false;
|
|
var y2 = this.parse(e2, u2[5]);
|
|
if (!y2 || y2.mapped) return false;
|
|
if (p2.pfValue === y2.pfValue || p2.strValue === y2.strValue) return Ve("`" + e2 + ": " + t2 + "` is not a valid mapper because the output range is zero; converting to `" + e2 + ": " + p2.strValue + "`"), this.parse(e2, p2.strValue);
|
|
if (c2.color) {
|
|
var b2 = p2.value, x2 = y2.value;
|
|
if (!(b2[0] !== x2[0] || b2[1] !== x2[1] || b2[2] !== x2[2] || b2[3] !== x2[3] && (null != b2[3] && 1 !== b2[3] || null != x2[3] && 1 !== x2[3]))) return false;
|
|
}
|
|
return { name: e2, value: u2, strValue: "" + t2, mapped: h2, field: u2[1], fieldMin: parseFloat(u2[2]), fieldMax: parseFloat(u2[3]), valueMin: p2.value, valueMax: y2.value, bypass: n2 };
|
|
}
|
|
}
|
|
if (c2.multiple && "multiple" !== r2) {
|
|
var w2;
|
|
if (w2 = s2 ? t2.split(/\s+/) : v(t2) ? t2 : [t2], c2.evenMultiple && w2.length % 2 != 0) return null;
|
|
for (var E2 = [], k2 = [], C2 = [], S2 = "", P2 = false, D2 = 0; D2 < w2.length; D2++) {
|
|
var _2 = this.parse(e2, w2[D2], n2, "multiple");
|
|
P2 = P2 || f(_2.value), E2.push(_2.value), C2.push(null != _2.pfValue ? _2.pfValue : _2.value), k2.push(_2.units), S2 += (D2 > 0 ? " " : "") + _2.strValue;
|
|
}
|
|
return c2.validate && !c2.validate(E2, k2) ? null : c2.singleEnum && P2 ? 1 === E2.length && f(E2[0]) ? { name: e2, value: E2[0], strValue: E2[0], bypass: n2 } : null : { name: e2, value: E2, pfValue: C2, strValue: S2, bypass: n2, units: k2 };
|
|
}
|
|
var M2, B2, z2 = function() {
|
|
for (var r3 = 0; r3 < c2.enums.length; r3++) {
|
|
if (c2.enums[r3] === t2) return { name: e2, value: t2, strValue: "" + t2, bypass: n2 };
|
|
}
|
|
return null;
|
|
};
|
|
if (c2.number) {
|
|
var I2, A2 = "px";
|
|
if (c2.units && (I2 = c2.units), c2.implicitUnits && (A2 = c2.implicitUnits), !c2.unitless) if (s2) {
|
|
var O2 = "px|em" + (c2.allowPercent ? "|\\%" : "");
|
|
I2 && (O2 = I2);
|
|
var R2 = t2.match("^(" + N + ")(" + O2 + ")?$");
|
|
R2 && (t2 = R2[1], I2 = R2[2] || A2);
|
|
} else I2 && !c2.implicitUnits || (I2 = A2);
|
|
if (t2 = parseFloat(t2), isNaN(t2) && void 0 === c2.enums) return null;
|
|
if (isNaN(t2) && void 0 !== c2.enums) return t2 = a2, z2();
|
|
if (c2.integer && (!m(B2 = t2) || Math.floor(B2) !== B2)) return null;
|
|
if (void 0 !== c2.min && (t2 < c2.min || c2.strictMin && t2 === c2.min) || void 0 !== c2.max && (t2 > c2.max || c2.strictMax && t2 === c2.max)) return null;
|
|
var V2 = { name: e2, value: t2, strValue: "" + t2 + (I2 || ""), units: I2, bypass: n2 };
|
|
return c2.unitless || "px" !== I2 && "em" !== I2 ? V2.pfValue = t2 : V2.pfValue = "px" !== I2 && I2 ? this.getEmSizeInPixels() * t2 : t2, "ms" !== I2 && "s" !== I2 || (V2.pfValue = "ms" === I2 ? t2 : 1e3 * t2), "deg" !== I2 && "rad" !== I2 || (V2.pfValue = "rad" === I2 ? t2 : (M2 = t2, Math.PI * M2 / 180)), "%" === I2 && (V2.pfValue = t2 / 100), V2;
|
|
}
|
|
if (c2.propList) {
|
|
var F2 = [], j2 = "" + t2;
|
|
if ("none" === j2) ;
|
|
else {
|
|
for (var q2 = j2.split(/\s*,\s*|\s+/), Y2 = 0; Y2 < q2.length; Y2++) {
|
|
var X2 = q2[Y2].trim();
|
|
this.properties[X2] ? F2.push(X2) : Ve("`" + X2 + "` is not a valid property name");
|
|
}
|
|
if (0 === F2.length) return null;
|
|
}
|
|
return { name: e2, value: F2, strValue: 0 === F2.length ? "none" : F2.join(" "), bypass: n2 };
|
|
}
|
|
if (c2.color) {
|
|
var W2 = L2(t2);
|
|
return W2 ? { name: e2, value: W2, pfValue: W2, strValue: "rgb(" + W2[0] + "," + W2[1] + "," + W2[2] + ")", bypass: n2 } : null;
|
|
}
|
|
if (c2.regex || c2.regexes) {
|
|
if (c2.enums) {
|
|
var H2 = z2();
|
|
if (H2) return H2;
|
|
}
|
|
for (var K2 = c2.regexes ? c2.regexes : [c2.regex], G2 = 0; G2 < K2.length; G2++) {
|
|
var U2 = new RegExp(K2[G2]).exec(t2);
|
|
if (U2) return { name: e2, value: c2.singleRegexMatchValue ? U2[1] : U2, strValue: "" + t2, bypass: n2 };
|
|
}
|
|
return null;
|
|
}
|
|
return c2.string ? { name: e2, value: "" + t2, strValue: "" + t2, bypass: n2 } : c2.enums ? z2() : null;
|
|
};
|
|
var _s = function e2(t2) {
|
|
if (!(this instanceof e2)) return new e2(t2);
|
|
k(t2) ? (this._private = { cy: t2, coreStyle: {} }, this.length = 0, this.resetToDefault()) : Oe("A style must have a core reference");
|
|
}, Ms = _s.prototype;
|
|
Ms.instanceString = function() {
|
|
return "style";
|
|
}, Ms.clear = function() {
|
|
for (var e2 = this._private, t2 = e2.cy.elements(), n2 = 0; n2 < this.length; n2++) this[n2] = void 0;
|
|
return this.length = 0, e2.contextStyles = {}, e2.propDiffs = {}, this.cleanElements(t2, true), t2.forEach(function(e3) {
|
|
var t3 = e3[0]._private;
|
|
t3.styleDirty = true, t3.appliedInitStyle = false;
|
|
}), this;
|
|
}, Ms.resetToDefault = function() {
|
|
return this.clear(), this.addDefaultStylesheet(), this;
|
|
}, Ms.core = function(e2) {
|
|
return this._private.coreStyle[e2] || this.getDefaultProperty(e2);
|
|
}, Ms.selector = function(e2) {
|
|
var t2 = "core" === e2 ? null : new xa(e2), n2 = this.length++;
|
|
return this[n2] = { selector: t2, properties: [], mappedProperties: [], index: n2 }, this;
|
|
}, Ms.css = function() {
|
|
var e2 = this, t2 = arguments;
|
|
if (1 === t2.length) for (var n2 = t2[0], r2 = 0; r2 < e2.properties.length; r2++) {
|
|
var i2 = e2.properties[r2], a2 = n2[i2.name];
|
|
void 0 === a2 && (a2 = n2[_(i2.name)]), void 0 !== a2 && this.cssRule(i2.name, a2);
|
|
}
|
|
else 2 === t2.length && this.cssRule(t2[0], t2[1]);
|
|
return this;
|
|
}, Ms.style = Ms.css, Ms.cssRule = function(e2, t2) {
|
|
var n2 = this.parse(e2, t2);
|
|
if (n2) {
|
|
var r2 = this.length - 1;
|
|
this[r2].properties.push(n2), this[r2].properties[n2.name] = n2, n2.name.match(/pie-(\d+)-background-size/) && n2.value && (this._private.hasPie = true), n2.mapped && this[r2].mappedProperties.push(n2), !this[r2].selector && (this._private.coreStyle[n2.name] = n2);
|
|
}
|
|
return this;
|
|
}, Ms.append = function(e2) {
|
|
return C(e2) ? e2.appendToStyle(this) : v(e2) ? this.appendFromJson(e2) : f(e2) && this.appendFromString(e2), this;
|
|
}, _s.fromJson = function(e2, t2) {
|
|
var n2 = new _s(e2);
|
|
return n2.fromJson(t2), n2;
|
|
}, _s.fromString = function(e2, t2) {
|
|
return new _s(e2).fromString(t2);
|
|
}, [ws, Es, ks, Cs, Ss, Ps, Ds, Ts].forEach(function(e2) {
|
|
I(Ms, e2);
|
|
}), _s.types = Ms.types, _s.properties = Ms.properties, _s.propertyGroups = Ms.propertyGroups, _s.propertyGroupNames = Ms.propertyGroupNames, _s.propertyGroupKeys = Ms.propertyGroupKeys;
|
|
var Bs = { style: function(e2) {
|
|
e2 && this.setStyle(e2).update();
|
|
return this._private.style;
|
|
}, setStyle: function(e2) {
|
|
var t2 = this._private;
|
|
return C(e2) ? t2.style = e2.generateStyle(this) : v(e2) ? t2.style = _s.fromJson(this, e2) : f(e2) ? t2.style = _s.fromString(this, e2) : t2.style = _s(this), t2.style;
|
|
}, updateStyle: function() {
|
|
this.mutableElements().updateStyle();
|
|
} }, Ns = { autolock: function(e2) {
|
|
return void 0 === e2 ? this._private.autolock : (this._private.autolock = !!e2, this);
|
|
}, autoungrabify: function(e2) {
|
|
return void 0 === e2 ? this._private.autoungrabify : (this._private.autoungrabify = !!e2, this);
|
|
}, autounselectify: function(e2) {
|
|
return void 0 === e2 ? this._private.autounselectify : (this._private.autounselectify = !!e2, this);
|
|
}, selectionType: function(e2) {
|
|
var t2 = this._private;
|
|
return null == t2.selectionType && (t2.selectionType = "single"), void 0 === e2 ? t2.selectionType : ("additive" !== e2 && "single" !== e2 || (t2.selectionType = e2), this);
|
|
}, panningEnabled: function(e2) {
|
|
return void 0 === e2 ? this._private.panningEnabled : (this._private.panningEnabled = !!e2, this);
|
|
}, userPanningEnabled: function(e2) {
|
|
return void 0 === e2 ? this._private.userPanningEnabled : (this._private.userPanningEnabled = !!e2, this);
|
|
}, zoomingEnabled: function(e2) {
|
|
return void 0 === e2 ? this._private.zoomingEnabled : (this._private.zoomingEnabled = !!e2, this);
|
|
}, userZoomingEnabled: function(e2) {
|
|
return void 0 === e2 ? this._private.userZoomingEnabled : (this._private.userZoomingEnabled = !!e2, this);
|
|
}, boxSelectionEnabled: function(e2) {
|
|
return void 0 === e2 ? this._private.boxSelectionEnabled : (this._private.boxSelectionEnabled = !!e2, this);
|
|
}, pan: function() {
|
|
var e2, t2, n2, r2, i2, a2 = arguments, o2 = this._private.pan;
|
|
switch (a2.length) {
|
|
case 0:
|
|
return o2;
|
|
case 1:
|
|
if (f(a2[0])) return o2[e2 = a2[0]];
|
|
if (y(a2[0])) {
|
|
if (!this._private.panningEnabled) return this;
|
|
r2 = (n2 = a2[0]).x, i2 = n2.y, m(r2) && (o2.x = r2), m(i2) && (o2.y = i2), this.emit("pan viewport");
|
|
}
|
|
break;
|
|
case 2:
|
|
if (!this._private.panningEnabled) return this;
|
|
e2 = a2[0], t2 = a2[1], "x" !== e2 && "y" !== e2 || !m(t2) || (o2[e2] = t2), this.emit("pan viewport");
|
|
}
|
|
return this.notify("viewport"), this;
|
|
}, panBy: function(e2, t2) {
|
|
var n2, r2, i2, a2, o2, s2 = arguments, l2 = this._private.pan;
|
|
if (!this._private.panningEnabled) return this;
|
|
switch (s2.length) {
|
|
case 1:
|
|
y(e2) && (a2 = (i2 = s2[0]).x, o2 = i2.y, m(a2) && (l2.x += a2), m(o2) && (l2.y += o2), this.emit("pan viewport"));
|
|
break;
|
|
case 2:
|
|
r2 = t2, "x" !== (n2 = e2) && "y" !== n2 || !m(r2) || (l2[n2] += r2), this.emit("pan viewport");
|
|
}
|
|
return this.notify("viewport"), this;
|
|
}, fit: function(e2, t2) {
|
|
var n2 = this.getFitViewport(e2, t2);
|
|
if (n2) {
|
|
var r2 = this._private;
|
|
r2.zoom = n2.zoom, r2.pan = n2.pan, this.emit("pan zoom viewport"), this.notify("viewport");
|
|
}
|
|
return this;
|
|
}, getFitViewport: function(e2, t2) {
|
|
if (m(e2) && void 0 === t2 && (t2 = e2, e2 = void 0), this._private.panningEnabled && this._private.zoomingEnabled) {
|
|
var n2, r2;
|
|
if (f(e2)) {
|
|
var i2 = e2;
|
|
e2 = this.$(i2);
|
|
} else if (y(r2 = e2) && m(r2.x1) && m(r2.x2) && m(r2.y1) && m(r2.y2)) {
|
|
var a2 = e2;
|
|
(n2 = { x1: a2.x1, y1: a2.y1, x2: a2.x2, y2: a2.y2 }).w = n2.x2 - n2.x1, n2.h = n2.y2 - n2.y1;
|
|
} else x(e2) || (e2 = this.mutableElements());
|
|
if (!x(e2) || !e2.empty()) {
|
|
n2 = n2 || e2.boundingBox();
|
|
var o2, s2 = this.width(), l2 = this.height();
|
|
if (t2 = m(t2) ? t2 : 0, !isNaN(s2) && !isNaN(l2) && s2 > 0 && l2 > 0 && !isNaN(n2.w) && !isNaN(n2.h) && n2.w > 0 && n2.h > 0) return { zoom: o2 = (o2 = (o2 = Math.min((s2 - 2 * t2) / n2.w, (l2 - 2 * t2) / n2.h)) > this._private.maxZoom ? this._private.maxZoom : o2) < this._private.minZoom ? this._private.minZoom : o2, pan: { x: (s2 - o2 * (n2.x1 + n2.x2)) / 2, y: (l2 - o2 * (n2.y1 + n2.y2)) / 2 } };
|
|
}
|
|
}
|
|
}, zoomRange: function(e2, t2) {
|
|
var n2 = this._private;
|
|
if (null == t2) {
|
|
var r2 = e2;
|
|
e2 = r2.min, t2 = r2.max;
|
|
}
|
|
return m(e2) && m(t2) && e2 <= t2 ? (n2.minZoom = e2, n2.maxZoom = t2) : m(e2) && void 0 === t2 && e2 <= n2.maxZoom ? n2.minZoom = e2 : m(t2) && void 0 === e2 && t2 >= n2.minZoom && (n2.maxZoom = t2), this;
|
|
}, minZoom: function(e2) {
|
|
return void 0 === e2 ? this._private.minZoom : this.zoomRange({ min: e2 });
|
|
}, maxZoom: function(e2) {
|
|
return void 0 === e2 ? this._private.maxZoom : this.zoomRange({ max: e2 });
|
|
}, getZoomedViewport: function(e2) {
|
|
var t2, n2, r2 = this._private, i2 = r2.pan, a2 = r2.zoom, o2 = false;
|
|
if (r2.zoomingEnabled || (o2 = true), m(e2) ? n2 = e2 : y(e2) && (n2 = e2.level, null != e2.position ? t2 = gt(e2.position, a2, i2) : null != e2.renderedPosition && (t2 = e2.renderedPosition), null == t2 || r2.panningEnabled || (o2 = true)), n2 = (n2 = n2 > r2.maxZoom ? r2.maxZoom : n2) < r2.minZoom ? r2.minZoom : n2, o2 || !m(n2) || n2 === a2 || null != t2 && (!m(t2.x) || !m(t2.y))) return null;
|
|
if (null != t2) {
|
|
var s2 = i2, l2 = a2, u2 = n2;
|
|
return { zoomed: true, panned: true, zoom: u2, pan: { x: -u2 / l2 * (t2.x - s2.x) + t2.x, y: -u2 / l2 * (t2.y - s2.y) + t2.y } };
|
|
}
|
|
return { zoomed: true, panned: false, zoom: n2, pan: i2 };
|
|
}, zoom: function(e2) {
|
|
if (void 0 === e2) return this._private.zoom;
|
|
var t2 = this.getZoomedViewport(e2), n2 = this._private;
|
|
return null != t2 && t2.zoomed ? (n2.zoom = t2.zoom, t2.panned && (n2.pan.x = t2.pan.x, n2.pan.y = t2.pan.y), this.emit("zoom" + (t2.panned ? " pan" : "") + " viewport"), this.notify("viewport"), this) : this;
|
|
}, viewport: function(e2) {
|
|
var t2 = this._private, n2 = true, r2 = true, i2 = [], a2 = false, o2 = false;
|
|
if (!e2) return this;
|
|
if (m(e2.zoom) || (n2 = false), y(e2.pan) || (r2 = false), !n2 && !r2) return this;
|
|
if (n2) {
|
|
var s2 = e2.zoom;
|
|
s2 < t2.minZoom || s2 > t2.maxZoom || !t2.zoomingEnabled ? a2 = true : (t2.zoom = s2, i2.push("zoom"));
|
|
}
|
|
if (r2 && (!a2 || !e2.cancelOnFailedZoom) && t2.panningEnabled) {
|
|
var l2 = e2.pan;
|
|
m(l2.x) && (t2.pan.x = l2.x, o2 = false), m(l2.y) && (t2.pan.y = l2.y, o2 = false), o2 || i2.push("pan");
|
|
}
|
|
return i2.length > 0 && (i2.push("viewport"), this.emit(i2.join(" ")), this.notify("viewport")), this;
|
|
}, center: function(e2) {
|
|
var t2 = this.getCenterPan(e2);
|
|
return t2 && (this._private.pan = t2, this.emit("pan viewport"), this.notify("viewport")), this;
|
|
}, getCenterPan: function(e2, t2) {
|
|
if (this._private.panningEnabled) {
|
|
if (f(e2)) {
|
|
var n2 = e2;
|
|
e2 = this.mutableElements().filter(n2);
|
|
} else x(e2) || (e2 = this.mutableElements());
|
|
if (0 !== e2.length) {
|
|
var r2 = e2.boundingBox(), i2 = this.width(), a2 = this.height();
|
|
return { x: (i2 - (t2 = void 0 === t2 ? this._private.zoom : t2) * (r2.x1 + r2.x2)) / 2, y: (a2 - t2 * (r2.y1 + r2.y2)) / 2 };
|
|
}
|
|
}
|
|
}, reset: function() {
|
|
return this._private.panningEnabled && this._private.zoomingEnabled ? (this.viewport({ pan: { x: 0, y: 0 }, zoom: 1 }), this) : this;
|
|
}, invalidateSize: function() {
|
|
this._private.sizeCache = null;
|
|
}, size: function() {
|
|
var e2, t2, n2 = this._private, r2 = n2.container, i2 = this;
|
|
return n2.sizeCache = n2.sizeCache || (r2 ? (e2 = i2.window().getComputedStyle(r2), t2 = function(t3) {
|
|
return parseFloat(e2.getPropertyValue(t3));
|
|
}, { width: r2.clientWidth - t2("padding-left") - t2("padding-right"), height: r2.clientHeight - t2("padding-top") - t2("padding-bottom") }) : { width: 1, height: 1 });
|
|
}, width: function() {
|
|
return this.size().width;
|
|
}, height: function() {
|
|
return this.size().height;
|
|
}, extent: function() {
|
|
var e2 = this._private.pan, t2 = this._private.zoom, n2 = this.renderedExtent(), r2 = { x1: (n2.x1 - e2.x) / t2, x2: (n2.x2 - e2.x) / t2, y1: (n2.y1 - e2.y) / t2, y2: (n2.y2 - e2.y) / t2 };
|
|
return r2.w = r2.x2 - r2.x1, r2.h = r2.y2 - r2.y1, r2;
|
|
}, renderedExtent: function() {
|
|
var e2 = this.width(), t2 = this.height();
|
|
return { x1: 0, y1: 0, x2: e2, y2: t2, w: e2, h: t2 };
|
|
}, multiClickDebounceTime: function(e2) {
|
|
return e2 ? (this._private.multiClickDebounceTime = e2, this) : this._private.multiClickDebounceTime;
|
|
} };
|
|
Ns.centre = Ns.center, Ns.autolockNodes = Ns.autolock, Ns.autoungrabifyNodes = Ns.autoungrabify;
|
|
var zs = { data: Oi.data({ field: "data", bindingEvent: "data", allowBinding: true, allowSetting: true, settingEvent: "data", settingTriggersEvent: true, triggerFnName: "trigger", allowGetting: true, updateStyle: true }), removeData: Oi.removeData({ field: "data", event: "data", triggerFnName: "trigger", triggerEvent: true, updateStyle: true }), scratch: Oi.data({ field: "scratch", bindingEvent: "scratch", allowBinding: true, allowSetting: true, settingEvent: "scratch", settingTriggersEvent: true, triggerFnName: "trigger", allowGetting: true, updateStyle: true }), removeScratch: Oi.removeData({ field: "scratch", event: "scratch", triggerFnName: "trigger", triggerEvent: true, updateStyle: true }) };
|
|
zs.attr = zs.data, zs.removeAttr = zs.removeData;
|
|
var Is = function(e2) {
|
|
var t2 = this, n2 = (e2 = I({}, e2)).container;
|
|
n2 && !b(n2) && b(n2[0]) && (n2 = n2[0]);
|
|
var r2 = n2 ? n2._cyreg : null;
|
|
(r2 = r2 || {}) && r2.cy && (r2.cy.destroy(), r2 = {});
|
|
var i2 = r2.readies = r2.readies || [];
|
|
n2 && (n2._cyreg = r2), r2.cy = t2;
|
|
var a2 = void 0 !== s && void 0 !== n2 && !e2.headless, o2 = e2;
|
|
o2.layout = I({ name: a2 ? "grid" : "null" }, o2.layout), o2.renderer = I({ name: a2 ? "canvas" : "null" }, o2.renderer);
|
|
var l2 = function(e3, t3, n3) {
|
|
return void 0 !== t3 ? t3 : void 0 !== n3 ? n3 : e3;
|
|
}, u2 = this._private = { container: n2, ready: false, options: o2, elements: new Qo(this), listeners: [], aniEles: new Qo(this), data: o2.data || {}, scratch: {}, layout: null, renderer: null, destroyed: false, notificationsEnabled: true, minZoom: 1e-50, maxZoom: 1e50, zoomingEnabled: l2(true, o2.zoomingEnabled), userZoomingEnabled: l2(true, o2.userZoomingEnabled), panningEnabled: l2(true, o2.panningEnabled), userPanningEnabled: l2(true, o2.userPanningEnabled), boxSelectionEnabled: l2(true, o2.boxSelectionEnabled), autolock: l2(false, o2.autolock, o2.autolockNodes), autoungrabify: l2(false, o2.autoungrabify, o2.autoungrabifyNodes), autounselectify: l2(false, o2.autounselectify), styleEnabled: void 0 === o2.styleEnabled ? a2 : o2.styleEnabled, zoom: m(o2.zoom) ? o2.zoom : 1, pan: { x: y(o2.pan) && m(o2.pan.x) ? o2.pan.x : 0, y: y(o2.pan) && m(o2.pan.y) ? o2.pan.y : 0 }, animation: { current: [], queue: [] }, hasCompoundNodes: false, multiClickDebounceTime: l2(250, o2.multiClickDebounceTime) };
|
|
this.createEmitter(), this.selectionType(o2.selectionType), this.zoomRange({ min: o2.minZoom, max: o2.maxZoom });
|
|
u2.styleEnabled && t2.setStyle([]);
|
|
var c2 = I({}, o2, o2.renderer);
|
|
t2.initRenderer(c2);
|
|
!function(e3, t3) {
|
|
if (e3.some(P)) return pr.all(e3).then(t3);
|
|
t3(e3);
|
|
}([o2.style, o2.elements], function(e3) {
|
|
var n3 = e3[0], a3 = e3[1];
|
|
u2.styleEnabled && t2.style().append(n3), function(e4, n4, r3) {
|
|
t2.notifications(false);
|
|
var i3 = t2.mutableElements();
|
|
i3.length > 0 && i3.remove(), null != e4 && (y(e4) || v(e4)) && t2.add(e4), t2.one("layoutready", function(e5) {
|
|
t2.notifications(true), t2.emit(e5), t2.one("load", n4), t2.emitAndNotify("load");
|
|
}).one("layoutstop", function() {
|
|
t2.one("done", r3), t2.emit("done");
|
|
});
|
|
var a4 = I({}, t2._private.options.layout);
|
|
a4.eles = t2.elements(), t2.layout(a4).run();
|
|
}(a3, function() {
|
|
t2.startAnimationLoop(), u2.ready = true, g(o2.ready) && t2.on("ready", o2.ready);
|
|
for (var e4 = 0; e4 < i2.length; e4++) {
|
|
var n4 = i2[e4];
|
|
t2.on("ready", n4);
|
|
}
|
|
r2 && (r2.readies = []), t2.emit("ready");
|
|
}, o2.done);
|
|
});
|
|
}, Ls = Is.prototype;
|
|
I(Ls, { instanceString: function() {
|
|
return "core";
|
|
}, isReady: function() {
|
|
return this._private.ready;
|
|
}, destroyed: function() {
|
|
return this._private.destroyed;
|
|
}, ready: function(e2) {
|
|
return this.isReady() ? this.emitter().emit("ready", [], e2) : this.on("ready", e2), this;
|
|
}, destroy: function() {
|
|
var e2 = this;
|
|
if (!e2.destroyed()) return e2.stopAnimationLoop(), e2.destroyRenderer(), this.emit("destroy"), e2._private.destroyed = true, e2;
|
|
}, hasElementWithId: function(e2) {
|
|
return this._private.elements.hasElementWithId(e2);
|
|
}, getElementById: function(e2) {
|
|
return this._private.elements.getElementById(e2);
|
|
}, hasCompoundNodes: function() {
|
|
return this._private.hasCompoundNodes;
|
|
}, headless: function() {
|
|
return this._private.renderer.isHeadless();
|
|
}, styleEnabled: function() {
|
|
return this._private.styleEnabled;
|
|
}, addToPool: function(e2) {
|
|
return this._private.elements.merge(e2), this;
|
|
}, removeFromPool: function(e2) {
|
|
return this._private.elements.unmerge(e2), this;
|
|
}, container: function() {
|
|
return this._private.container || null;
|
|
}, window: function() {
|
|
if (null == this._private.container) return s;
|
|
var e2 = this._private.container.ownerDocument;
|
|
return void 0 === e2 || null == e2 ? s : e2.defaultView || s;
|
|
}, mount: function(e2) {
|
|
if (null != e2) {
|
|
var t2 = this, n2 = t2._private, r2 = n2.options;
|
|
return !b(e2) && b(e2[0]) && (e2 = e2[0]), t2.stopAnimationLoop(), t2.destroyRenderer(), n2.container = e2, n2.styleEnabled = true, t2.invalidateSize(), t2.initRenderer(I({}, r2, r2.renderer, { name: "null" === r2.renderer.name ? "canvas" : r2.renderer.name })), t2.startAnimationLoop(), t2.style(r2.style), t2.emit("mount"), t2;
|
|
}
|
|
}, unmount: function() {
|
|
var e2 = this;
|
|
return e2.stopAnimationLoop(), e2.destroyRenderer(), e2.initRenderer({ name: "null" }), e2.emit("unmount"), e2;
|
|
}, options: function() {
|
|
return Fe(this._private.options);
|
|
}, json: function(e2) {
|
|
var t2 = this, n2 = t2._private, r2 = t2.mutableElements();
|
|
if (y(e2)) {
|
|
if (t2.startBatch(), e2.elements) {
|
|
var i2 = {}, a2 = function(e3, n3) {
|
|
for (var r3 = [], a3 = [], o3 = 0; o3 < e3.length; o3++) {
|
|
var s3 = e3[o3];
|
|
if (s3.data.id) {
|
|
var l3 = "" + s3.data.id, u3 = t2.getElementById(l3);
|
|
i2[l3] = true, 0 !== u3.length ? a3.push({ ele: u3, json: s3 }) : n3 ? (s3.group = n3, r3.push(s3)) : r3.push(s3);
|
|
} else Ve("cy.json() cannot handle elements without an ID attribute");
|
|
}
|
|
t2.add(r3);
|
|
for (var c3 = 0; c3 < a3.length; c3++) {
|
|
var d3 = a3[c3], h3 = d3.ele, p3 = d3.json;
|
|
h3.json(p3);
|
|
}
|
|
};
|
|
if (v(e2.elements)) a2(e2.elements);
|
|
else for (var o2 = ["nodes", "edges"], s2 = 0; s2 < o2.length; s2++) {
|
|
var l2 = o2[s2], u2 = e2.elements[l2];
|
|
v(u2) && a2(u2, l2);
|
|
}
|
|
var c2 = t2.collection();
|
|
r2.filter(function(e3) {
|
|
return !i2[e3.id()];
|
|
}).forEach(function(e3) {
|
|
e3.isParent() ? c2.merge(e3) : e3.remove();
|
|
}), c2.forEach(function(e3) {
|
|
return e3.children().move({ parent: null });
|
|
}), c2.forEach(function(e3) {
|
|
return function(e4) {
|
|
return t2.getElementById(e4.id());
|
|
}(e3).remove();
|
|
});
|
|
}
|
|
e2.style && t2.style(e2.style), null != e2.zoom && e2.zoom !== n2.zoom && t2.zoom(e2.zoom), e2.pan && (e2.pan.x === n2.pan.x && e2.pan.y === n2.pan.y || t2.pan(e2.pan)), e2.data && t2.data(e2.data);
|
|
for (var d2 = ["minZoom", "maxZoom", "zoomingEnabled", "userZoomingEnabled", "panningEnabled", "userPanningEnabled", "boxSelectionEnabled", "autolock", "autoungrabify", "autounselectify", "multiClickDebounceTime"], h2 = 0; h2 < d2.length; h2++) {
|
|
var p2 = d2[h2];
|
|
null != e2[p2] && t2[p2](e2[p2]);
|
|
}
|
|
return t2.endBatch(), this;
|
|
}
|
|
var f2 = {};
|
|
!!e2 ? f2.elements = this.elements().map(function(e3) {
|
|
return e3.json();
|
|
}) : (f2.elements = {}, r2.forEach(function(e3) {
|
|
var t3 = e3.group();
|
|
f2.elements[t3] || (f2.elements[t3] = []), f2.elements[t3].push(e3.json());
|
|
})), this._private.styleEnabled && (f2.style = t2.style().json()), f2.data = Fe(t2.data());
|
|
var g2 = n2.options;
|
|
return f2.zoomingEnabled = n2.zoomingEnabled, f2.userZoomingEnabled = n2.userZoomingEnabled, f2.zoom = n2.zoom, f2.minZoom = n2.minZoom, f2.maxZoom = n2.maxZoom, f2.panningEnabled = n2.panningEnabled, f2.userPanningEnabled = n2.userPanningEnabled, f2.pan = Fe(n2.pan), f2.boxSelectionEnabled = n2.boxSelectionEnabled, f2.renderer = Fe(g2.renderer), f2.hideEdgesOnViewport = g2.hideEdgesOnViewport, f2.textureOnViewport = g2.textureOnViewport, f2.wheelSensitivity = g2.wheelSensitivity, f2.motionBlur = g2.motionBlur, f2.multiClickDebounceTime = g2.multiClickDebounceTime, f2;
|
|
} }), Ls.$id = Ls.getElementById, [es, ds, fs, gs, vs, ys, bs, xs, Bs, Ns, zs].forEach(function(e2) {
|
|
I(Ls, e2);
|
|
});
|
|
var As = { fit: true, directed: false, padding: 30, circle: false, grid: false, spacingFactor: 1.75, boundingBox: void 0, avoidOverlap: true, nodeDimensionsIncludeLabels: false, roots: void 0, depthSort: void 0, animate: false, animationDuration: 500, animationEasing: void 0, animateFilter: function(e2, t2) {
|
|
return true;
|
|
}, ready: void 0, stop: void 0, transform: function(e2, t2) {
|
|
return t2;
|
|
} }, Os = { maximal: false, acyclic: false }, Rs = function(e2) {
|
|
return e2.scratch("breadthfirst");
|
|
}, Vs = function(e2, t2) {
|
|
return e2.scratch("breadthfirst", t2);
|
|
};
|
|
function Fs(e2) {
|
|
this.options = I({}, As, Os, e2);
|
|
}
|
|
Fs.prototype.run = function() {
|
|
var e2, t2 = this.options, n2 = t2, r2 = t2.cy, i2 = n2.eles, a2 = i2.nodes().filter(function(e3) {
|
|
return !e3.isParent();
|
|
}), o2 = i2, s2 = n2.directed, l2 = n2.acyclic || n2.maximal || n2.maximalAdjustments > 0, u2 = Dt(n2.boundingBox ? n2.boundingBox : { x1: 0, y1: 0, w: r2.width(), h: r2.height() });
|
|
if (x(n2.roots)) e2 = n2.roots;
|
|
else if (v(n2.roots)) {
|
|
for (var c2 = [], d2 = 0; d2 < n2.roots.length; d2++) {
|
|
var h2 = n2.roots[d2], p2 = r2.getElementById(h2);
|
|
c2.push(p2);
|
|
}
|
|
e2 = r2.collection(c2);
|
|
} else if (f(n2.roots)) e2 = r2.$(n2.roots);
|
|
else if (s2) e2 = a2.roots();
|
|
else {
|
|
var g2 = i2.components();
|
|
e2 = r2.collection();
|
|
for (var y2 = function(t3) {
|
|
var n3 = g2[t3], r3 = n3.maxDegree(false), i3 = n3.filter(function(e3) {
|
|
return e3.degree(false) === r3;
|
|
});
|
|
e2 = e2.add(i3);
|
|
}, m2 = 0; m2 < g2.length; m2++) y2(m2);
|
|
}
|
|
var b2 = [], w2 = {}, E2 = function(e3, t3) {
|
|
null == b2[t3] && (b2[t3] = []);
|
|
var n3 = b2[t3].length;
|
|
b2[t3].push(e3), Vs(e3, { index: n3, depth: t3 });
|
|
};
|
|
o2.bfs({ roots: e2, directed: n2.directed, visit: function(e3, t3, n3, r3, i3) {
|
|
var a3 = e3[0], o3 = a3.id();
|
|
E2(a3, i3), w2[o3] = true;
|
|
} });
|
|
for (var k2 = [], C2 = 0; C2 < a2.length; C2++) {
|
|
var S2 = a2[C2];
|
|
w2[S2.id()] || k2.push(S2);
|
|
}
|
|
var P2 = function(e3) {
|
|
for (var t3 = b2[e3], n3 = 0; n3 < t3.length; n3++) {
|
|
var r3 = t3[n3];
|
|
null != r3 ? Vs(r3, { depth: e3, index: n3 }) : (t3.splice(n3, 1), n3--);
|
|
}
|
|
}, D2 = function() {
|
|
for (var e3 = 0; e3 < b2.length; e3++) P2(e3);
|
|
}, T2 = function(e3, t3) {
|
|
for (var r3 = Rs(e3), a3 = e3.incomers().filter(function(e4) {
|
|
return e4.isNode() && i2.has(e4);
|
|
}), o3 = -1, s3 = e3.id(), l3 = 0; l3 < a3.length; l3++) {
|
|
var u3 = a3[l3], c3 = Rs(u3);
|
|
o3 = Math.max(o3, c3.depth);
|
|
}
|
|
if (r3.depth <= o3) {
|
|
if (!n2.acyclic && t3[s3]) return null;
|
|
var d3 = o3 + 1;
|
|
return function(e4, t4) {
|
|
var n3 = Rs(e4), r4 = n3.depth, i3 = n3.index;
|
|
b2[r4][i3] = null, E2(e4, t4);
|
|
}(e3, d3), t3[s3] = d3, true;
|
|
}
|
|
return false;
|
|
};
|
|
if (s2 && l2) {
|
|
var _2 = [], M2 = {}, B2 = function(e3) {
|
|
return _2.push(e3);
|
|
};
|
|
for (a2.forEach(function(e3) {
|
|
return _2.push(e3);
|
|
}); _2.length > 0; ) {
|
|
var N2 = _2.shift(), I2 = T2(N2, M2);
|
|
if (I2) N2.outgoers().filter(function(e3) {
|
|
return e3.isNode() && i2.has(e3);
|
|
}).forEach(B2);
|
|
else if (null === I2) {
|
|
Ve("Detected double maximal shift for node `" + N2.id() + "`. Bailing maximal adjustment due to cycle. Use `options.maximal: true` only on DAGs.");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
D2();
|
|
var L3 = 0;
|
|
if (n2.avoidOverlap) for (var A2 = 0; A2 < a2.length; A2++) {
|
|
var O2 = a2[A2].layoutDimensions(n2), R2 = O2.w, V2 = O2.h;
|
|
L3 = Math.max(L3, R2, V2);
|
|
}
|
|
var F2 = {}, j2 = function(e3) {
|
|
if (F2[e3.id()]) return F2[e3.id()];
|
|
for (var t3 = Rs(e3).depth, n3 = e3.neighborhood(), r3 = 0, i3 = 0, o3 = 0; o3 < n3.length; o3++) {
|
|
var s3 = n3[o3];
|
|
if (!s3.isEdge() && !s3.isParent() && a2.has(s3)) {
|
|
var l3 = Rs(s3);
|
|
if (null != l3) {
|
|
var u3 = l3.index, c3 = l3.depth;
|
|
if (null != u3 && null != c3) {
|
|
var d3 = b2[c3].length;
|
|
c3 < t3 && (r3 += u3 / d3, i3++);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return r3 /= i3 = Math.max(1, i3), 0 === i3 && (r3 = 0), F2[e3.id()] = r3, r3;
|
|
}, q2 = function(e3, t3) {
|
|
var n3 = j2(e3) - j2(t3);
|
|
return 0 === n3 ? z(e3.id(), t3.id()) : n3;
|
|
};
|
|
void 0 !== n2.depthSort && (q2 = n2.depthSort);
|
|
for (var Y2 = 0; Y2 < b2.length; Y2++) b2[Y2].sort(q2), P2(Y2);
|
|
for (var X2 = [], W2 = 0; W2 < k2.length; W2++) X2.push(k2[W2]);
|
|
b2.unshift(X2), D2();
|
|
for (var H2 = 0, K2 = 0; K2 < b2.length; K2++) H2 = Math.max(b2[K2].length, H2);
|
|
var G2 = u2.x1 + u2.w / 2, U2 = u2.x1 + u2.h / 2, Z2 = b2.reduce(function(e3, t3) {
|
|
return Math.max(e3, t3.length);
|
|
}, 0);
|
|
return i2.nodes().layoutPositions(this, n2, function(e3) {
|
|
var t3 = Rs(e3), r3 = t3.depth, i3 = t3.index, a3 = b2[r3].length, o3 = Math.max(u2.w / ((n2.grid ? Z2 : a3) + 1), L3), s3 = Math.max(u2.h / (b2.length + 1), L3), l3 = Math.min(u2.w / 2 / b2.length, u2.h / 2 / b2.length);
|
|
if (l3 = Math.max(l3, L3), n2.circle) {
|
|
var c3 = l3 * r3 + l3 - (b2.length > 0 && b2[0].length <= 3 ? l3 / 2 : 0), d3 = 2 * Math.PI / b2[r3].length * i3;
|
|
return 0 === r3 && 1 === b2[0].length && (c3 = 1), { x: G2 + c3 * Math.cos(d3), y: U2 + c3 * Math.sin(d3) };
|
|
}
|
|
return { x: G2 + (i3 + 1 - (a3 + 1) / 2) * o3, y: (r3 + 1) * s3 };
|
|
}), this;
|
|
};
|
|
var js = { fit: true, padding: 30, boundingBox: void 0, avoidOverlap: true, nodeDimensionsIncludeLabels: false, spacingFactor: void 0, radius: void 0, startAngle: 1.5 * Math.PI, sweep: void 0, clockwise: true, sort: void 0, animate: false, animationDuration: 500, animationEasing: void 0, animateFilter: function(e2, t2) {
|
|
return true;
|
|
}, ready: void 0, stop: void 0, transform: function(e2, t2) {
|
|
return t2;
|
|
} };
|
|
function qs(e2) {
|
|
this.options = I({}, js, e2);
|
|
}
|
|
qs.prototype.run = function() {
|
|
var e2 = this.options, t2 = e2, n2 = e2.cy, r2 = t2.eles, i2 = void 0 !== t2.counterclockwise ? !t2.counterclockwise : t2.clockwise, a2 = r2.nodes().not(":parent");
|
|
t2.sort && (a2 = a2.sort(t2.sort));
|
|
for (var o2, s2 = Dt(t2.boundingBox ? t2.boundingBox : { x1: 0, y1: 0, w: n2.width(), h: n2.height() }), l2 = s2.x1 + s2.w / 2, u2 = s2.y1 + s2.h / 2, c2 = (void 0 === t2.sweep ? 2 * Math.PI - 2 * Math.PI / a2.length : t2.sweep) / Math.max(1, a2.length - 1), d2 = 0, h2 = 0; h2 < a2.length; h2++) {
|
|
var p2 = a2[h2].layoutDimensions(t2), f2 = p2.w, g2 = p2.h;
|
|
d2 = Math.max(d2, f2, g2);
|
|
}
|
|
if (o2 = m(t2.radius) ? t2.radius : a2.length <= 1 ? 0 : Math.min(s2.h, s2.w) / 2 - d2, a2.length > 1 && t2.avoidOverlap) {
|
|
d2 *= 1.75;
|
|
var v2 = Math.cos(c2) - Math.cos(0), y2 = Math.sin(c2) - Math.sin(0), b2 = Math.sqrt(d2 * d2 / (v2 * v2 + y2 * y2));
|
|
o2 = Math.max(b2, o2);
|
|
}
|
|
return r2.nodes().layoutPositions(this, t2, function(e3, n3) {
|
|
var r3 = t2.startAngle + n3 * c2 * (i2 ? 1 : -1), a3 = o2 * Math.cos(r3), s3 = o2 * Math.sin(r3);
|
|
return { x: l2 + a3, y: u2 + s3 };
|
|
}), this;
|
|
};
|
|
var Ys, Xs = { fit: true, padding: 30, startAngle: 1.5 * Math.PI, sweep: void 0, clockwise: true, equidistant: false, minNodeSpacing: 10, boundingBox: void 0, avoidOverlap: true, nodeDimensionsIncludeLabels: false, height: void 0, width: void 0, spacingFactor: void 0, concentric: function(e2) {
|
|
return e2.degree();
|
|
}, levelWidth: function(e2) {
|
|
return e2.maxDegree() / 4;
|
|
}, animate: false, animationDuration: 500, animationEasing: void 0, animateFilter: function(e2, t2) {
|
|
return true;
|
|
}, ready: void 0, stop: void 0, transform: function(e2, t2) {
|
|
return t2;
|
|
} };
|
|
function Ws(e2) {
|
|
this.options = I({}, Xs, e2);
|
|
}
|
|
Ws.prototype.run = function() {
|
|
for (var e2 = this.options, t2 = e2, n2 = void 0 !== t2.counterclockwise ? !t2.counterclockwise : t2.clockwise, r2 = e2.cy, i2 = t2.eles, a2 = i2.nodes().not(":parent"), o2 = Dt(t2.boundingBox ? t2.boundingBox : { x1: 0, y1: 0, w: r2.width(), h: r2.height() }), s2 = o2.x1 + o2.w / 2, l2 = o2.y1 + o2.h / 2, u2 = [], c2 = 0, d2 = 0; d2 < a2.length; d2++) {
|
|
var h2, p2 = a2[d2];
|
|
h2 = t2.concentric(p2), u2.push({ value: h2, node: p2 }), p2._private.scratch.concentric = h2;
|
|
}
|
|
a2.updateStyle();
|
|
for (var f2 = 0; f2 < a2.length; f2++) {
|
|
var g2 = a2[f2].layoutDimensions(t2);
|
|
c2 = Math.max(c2, g2.w, g2.h);
|
|
}
|
|
u2.sort(function(e3, t3) {
|
|
return t3.value - e3.value;
|
|
});
|
|
for (var v2 = t2.levelWidth(a2), y2 = [[]], m2 = y2[0], b2 = 0; b2 < u2.length; b2++) {
|
|
var x2 = u2[b2];
|
|
if (m2.length > 0) Math.abs(m2[0].value - x2.value) >= v2 && (m2 = [], y2.push(m2));
|
|
m2.push(x2);
|
|
}
|
|
var w2 = c2 + t2.minNodeSpacing;
|
|
if (!t2.avoidOverlap) {
|
|
var E2 = y2.length > 0 && y2[0].length > 1, k2 = (Math.min(o2.w, o2.h) / 2 - w2) / (y2.length + E2 ? 1 : 0);
|
|
w2 = Math.min(w2, k2);
|
|
}
|
|
for (var C2 = 0, S2 = 0; S2 < y2.length; S2++) {
|
|
var P2 = y2[S2], D2 = void 0 === t2.sweep ? 2 * Math.PI - 2 * Math.PI / P2.length : t2.sweep, T2 = P2.dTheta = D2 / Math.max(1, P2.length - 1);
|
|
if (P2.length > 1 && t2.avoidOverlap) {
|
|
var _2 = Math.cos(T2) - Math.cos(0), M2 = Math.sin(T2) - Math.sin(0), B2 = Math.sqrt(w2 * w2 / (_2 * _2 + M2 * M2));
|
|
C2 = Math.max(B2, C2);
|
|
}
|
|
P2.r = C2, C2 += w2;
|
|
}
|
|
if (t2.equidistant) {
|
|
for (var N2 = 0, z2 = 0, I2 = 0; I2 < y2.length; I2++) {
|
|
var L3 = y2[I2].r - z2;
|
|
N2 = Math.max(N2, L3);
|
|
}
|
|
z2 = 0;
|
|
for (var A2 = 0; A2 < y2.length; A2++) {
|
|
var O2 = y2[A2];
|
|
0 === A2 && (z2 = O2.r), O2.r = z2, z2 += N2;
|
|
}
|
|
}
|
|
for (var R2 = {}, V2 = 0; V2 < y2.length; V2++) for (var F2 = y2[V2], j2 = F2.dTheta, q2 = F2.r, Y2 = 0; Y2 < F2.length; Y2++) {
|
|
var X2 = F2[Y2], W2 = t2.startAngle + (n2 ? 1 : -1) * j2 * Y2, H2 = { x: s2 + q2 * Math.cos(W2), y: l2 + q2 * Math.sin(W2) };
|
|
R2[X2.node.id()] = H2;
|
|
}
|
|
return i2.nodes().layoutPositions(this, t2, function(e3) {
|
|
var t3 = e3.id();
|
|
return R2[t3];
|
|
}), this;
|
|
};
|
|
var Hs = { ready: function() {
|
|
}, stop: function() {
|
|
}, animate: true, animationEasing: void 0, animationDuration: void 0, animateFilter: function(e2, t2) {
|
|
return true;
|
|
}, animationThreshold: 250, refresh: 20, fit: true, padding: 30, boundingBox: void 0, nodeDimensionsIncludeLabels: false, randomize: false, componentSpacing: 40, nodeRepulsion: function(e2) {
|
|
return 2048;
|
|
}, nodeOverlap: 4, idealEdgeLength: function(e2) {
|
|
return 32;
|
|
}, edgeElasticity: function(e2) {
|
|
return 32;
|
|
}, nestingFactor: 1.2, gravity: 1, numIter: 1e3, initialTemp: 1e3, coolingFactor: 0.99, minTemp: 1 };
|
|
function Ks(e2) {
|
|
this.options = I({}, Hs, e2), this.options.layout = this;
|
|
var t2 = this.options.eles.nodes(), n2 = this.options.eles.edges().filter(function(e3) {
|
|
var n3 = e3.source().data("id"), r2 = e3.target().data("id"), i2 = t2.some(function(e4) {
|
|
return e4.data("id") === n3;
|
|
}), a2 = t2.some(function(e4) {
|
|
return e4.data("id") === r2;
|
|
});
|
|
return !i2 || !a2;
|
|
});
|
|
this.options.eles = this.options.eles.not(n2);
|
|
}
|
|
Ks.prototype.run = function() {
|
|
var e2 = this.options, t2 = e2.cy, n2 = this;
|
|
n2.stopped = false, true !== e2.animate && false !== e2.animate || n2.emit({ type: "layoutstart", layout: n2 }), Ys = true === e2.debug;
|
|
var r2 = Gs(t2, n2, e2);
|
|
Ys && (void 0)(r2), e2.randomize && $s(r2);
|
|
var i2 = be(), a2 = function() {
|
|
Js(r2, t2, e2), true === e2.fit && t2.fit(e2.padding);
|
|
}, o2 = function(t3) {
|
|
return !(n2.stopped || t3 >= e2.numIter) && (el(r2, e2), r2.temperature = r2.temperature * e2.coolingFactor, !(r2.temperature < e2.minTemp));
|
|
}, s2 = function() {
|
|
if (true === e2.animate || false === e2.animate) a2(), n2.one("layoutstop", e2.stop), n2.emit({ type: "layoutstop", layout: n2 });
|
|
else {
|
|
var t3 = e2.eles.nodes(), i3 = Qs(r2, e2, t3);
|
|
t3.layoutPositions(n2, e2, i3);
|
|
}
|
|
}, l2 = 0, u2 = true;
|
|
if (true === e2.animate) {
|
|
!function t3() {
|
|
for (var n3 = 0; u2 && n3 < e2.refresh; ) u2 = o2(l2), l2++, n3++;
|
|
u2 ? (be() - i2 >= e2.animationThreshold && a2(), me(t3)) : (hl(r2, e2), s2());
|
|
}();
|
|
} else {
|
|
for (; u2; ) u2 = o2(l2), l2++;
|
|
hl(r2, e2), s2();
|
|
}
|
|
return this;
|
|
}, Ks.prototype.stop = function() {
|
|
return this.stopped = true, this.thread && this.thread.stop(), this.emit("layoutstop"), this;
|
|
}, Ks.prototype.destroy = function() {
|
|
return this.thread && this.thread.stop(), this;
|
|
};
|
|
var Gs = function(e2, t2, n2) {
|
|
for (var r2 = n2.eles.edges(), i2 = n2.eles.nodes(), a2 = Dt(n2.boundingBox ? n2.boundingBox : { x1: 0, y1: 0, w: e2.width(), h: e2.height() }), o2 = { isCompound: e2.hasCompoundNodes(), layoutNodes: [], idToIndex: {}, nodeSize: i2.size(), graphSet: [], indexToGraph: [], layoutEdges: [], edgeSize: r2.size(), temperature: n2.initialTemp, clientWidth: a2.w, clientHeight: a2.h, boundingBox: a2 }, s2 = n2.eles.components(), l2 = {}, u2 = 0; u2 < s2.length; u2++) for (var c2 = s2[u2], d2 = 0; d2 < c2.length; d2++) {
|
|
l2[c2[d2].id()] = u2;
|
|
}
|
|
for (u2 = 0; u2 < o2.nodeSize; u2++) {
|
|
var h2 = (m2 = i2[u2]).layoutDimensions(n2);
|
|
(I2 = {}).isLocked = m2.locked(), I2.id = m2.data("id"), I2.parentId = m2.data("parent"), I2.cmptId = l2[m2.id()], I2.children = [], I2.positionX = m2.position("x"), I2.positionY = m2.position("y"), I2.offsetX = 0, I2.offsetY = 0, I2.height = h2.w, I2.width = h2.h, I2.maxX = I2.positionX + I2.width / 2, I2.minX = I2.positionX - I2.width / 2, I2.maxY = I2.positionY + I2.height / 2, I2.minY = I2.positionY - I2.height / 2, I2.padLeft = parseFloat(m2.style("padding")), I2.padRight = parseFloat(m2.style("padding")), I2.padTop = parseFloat(m2.style("padding")), I2.padBottom = parseFloat(m2.style("padding")), I2.nodeRepulsion = g(n2.nodeRepulsion) ? n2.nodeRepulsion(m2) : n2.nodeRepulsion, o2.layoutNodes.push(I2), o2.idToIndex[I2.id] = u2;
|
|
}
|
|
var p2 = [], f2 = 0, v2 = -1, y2 = [];
|
|
for (u2 = 0; u2 < o2.nodeSize; u2++) {
|
|
var m2, b2 = (m2 = o2.layoutNodes[u2]).parentId;
|
|
null != b2 ? o2.layoutNodes[o2.idToIndex[b2]].children.push(m2.id) : (p2[++v2] = m2.id, y2.push(m2.id));
|
|
}
|
|
for (o2.graphSet.push(y2); f2 <= v2; ) {
|
|
var x2 = p2[f2++], w2 = o2.idToIndex[x2], E2 = o2.layoutNodes[w2].children;
|
|
if (E2.length > 0) {
|
|
o2.graphSet.push(E2);
|
|
for (u2 = 0; u2 < E2.length; u2++) p2[++v2] = E2[u2];
|
|
}
|
|
}
|
|
for (u2 = 0; u2 < o2.graphSet.length; u2++) {
|
|
var k2 = o2.graphSet[u2];
|
|
for (d2 = 0; d2 < k2.length; d2++) {
|
|
var C2 = o2.idToIndex[k2[d2]];
|
|
o2.indexToGraph[C2] = u2;
|
|
}
|
|
}
|
|
for (u2 = 0; u2 < o2.edgeSize; u2++) {
|
|
var S2 = r2[u2], P2 = {};
|
|
P2.id = S2.data("id"), P2.sourceId = S2.data("source"), P2.targetId = S2.data("target");
|
|
var D2 = g(n2.idealEdgeLength) ? n2.idealEdgeLength(S2) : n2.idealEdgeLength, T2 = g(n2.edgeElasticity) ? n2.edgeElasticity(S2) : n2.edgeElasticity, _2 = o2.idToIndex[P2.sourceId], M2 = o2.idToIndex[P2.targetId];
|
|
if (o2.indexToGraph[_2] != o2.indexToGraph[M2]) {
|
|
for (var B2 = Us(P2.sourceId, P2.targetId, o2), N2 = o2.graphSet[B2], z2 = 0, I2 = o2.layoutNodes[_2]; -1 === N2.indexOf(I2.id); ) I2 = o2.layoutNodes[o2.idToIndex[I2.parentId]], z2++;
|
|
for (I2 = o2.layoutNodes[M2]; -1 === N2.indexOf(I2.id); ) I2 = o2.layoutNodes[o2.idToIndex[I2.parentId]], z2++;
|
|
D2 *= z2 * n2.nestingFactor;
|
|
}
|
|
P2.idealLength = D2, P2.elasticity = T2, o2.layoutEdges.push(P2);
|
|
}
|
|
return o2;
|
|
}, Us = function(e2, t2, n2) {
|
|
var r2 = Zs(e2, t2, 0, n2);
|
|
return 2 > r2.count ? 0 : r2.graph;
|
|
}, Zs = function e2(t2, n2, r2, i2) {
|
|
var a2 = i2.graphSet[r2];
|
|
if (-1 < a2.indexOf(t2) && -1 < a2.indexOf(n2)) return { count: 2, graph: r2 };
|
|
for (var o2 = 0, s2 = 0; s2 < a2.length; s2++) {
|
|
var l2 = a2[s2], u2 = i2.idToIndex[l2], c2 = i2.layoutNodes[u2].children;
|
|
if (0 !== c2.length) {
|
|
var d2 = e2(t2, n2, i2.indexToGraph[i2.idToIndex[c2[0]]], i2);
|
|
if (0 !== d2.count) {
|
|
if (1 !== d2.count) return d2;
|
|
if (2 === ++o2) break;
|
|
}
|
|
}
|
|
}
|
|
return { count: o2, graph: r2 };
|
|
}, $s = function(e2, t2) {
|
|
for (var n2 = e2.clientWidth, r2 = e2.clientHeight, i2 = 0; i2 < e2.nodeSize; i2++) {
|
|
var a2 = e2.layoutNodes[i2];
|
|
0 !== a2.children.length || a2.isLocked || (a2.positionX = Math.random() * n2, a2.positionY = Math.random() * r2);
|
|
}
|
|
}, Qs = function(e2, t2, n2) {
|
|
var r2 = e2.boundingBox, i2 = { x1: 1 / 0, x2: -1 / 0, y1: 1 / 0, y2: -1 / 0 };
|
|
return t2.boundingBox && (n2.forEach(function(t3) {
|
|
var n3 = e2.layoutNodes[e2.idToIndex[t3.data("id")]];
|
|
i2.x1 = Math.min(i2.x1, n3.positionX), i2.x2 = Math.max(i2.x2, n3.positionX), i2.y1 = Math.min(i2.y1, n3.positionY), i2.y2 = Math.max(i2.y2, n3.positionY);
|
|
}), i2.w = i2.x2 - i2.x1, i2.h = i2.y2 - i2.y1), function(n3, a2) {
|
|
var o2 = e2.layoutNodes[e2.idToIndex[n3.data("id")]];
|
|
if (t2.boundingBox) {
|
|
var s2 = (o2.positionX - i2.x1) / i2.w, l2 = (o2.positionY - i2.y1) / i2.h;
|
|
return { x: r2.x1 + s2 * r2.w, y: r2.y1 + l2 * r2.h };
|
|
}
|
|
return { x: o2.positionX, y: o2.positionY };
|
|
};
|
|
}, Js = function(e2, t2, n2) {
|
|
var r2 = n2.layout, i2 = n2.eles.nodes(), a2 = Qs(e2, n2, i2);
|
|
i2.positions(a2), true !== e2.ready && (e2.ready = true, r2.one("layoutready", n2.ready), r2.emit({ type: "layoutready", layout: this }));
|
|
}, el = function(e2, t2, n2) {
|
|
tl(e2, t2), ol(e2), sl(e2, t2), ll(e2), ul(e2);
|
|
}, tl = function(e2, t2) {
|
|
for (var n2 = 0; n2 < e2.graphSet.length; n2++) for (var r2 = e2.graphSet[n2], i2 = r2.length, a2 = 0; a2 < i2; a2++) for (var o2 = e2.layoutNodes[e2.idToIndex[r2[a2]]], s2 = a2 + 1; s2 < i2; s2++) {
|
|
var l2 = e2.layoutNodes[e2.idToIndex[r2[s2]]];
|
|
rl(o2, l2, e2, t2);
|
|
}
|
|
}, nl = function(e2) {
|
|
return -e2 + 2 * e2 * Math.random();
|
|
}, rl = function(e2, t2, n2, r2) {
|
|
if (e2.cmptId === t2.cmptId || n2.isCompound) {
|
|
var i2 = t2.positionX - e2.positionX, a2 = t2.positionY - e2.positionY;
|
|
0 === i2 && 0 === a2 && (i2 = nl(1), a2 = nl(1));
|
|
var o2 = il(e2, t2, i2, a2);
|
|
if (o2 > 0) var s2 = (u2 = r2.nodeOverlap * o2) * i2 / (g2 = Math.sqrt(i2 * i2 + a2 * a2)), l2 = u2 * a2 / g2;
|
|
else {
|
|
var u2, c2 = al(e2, i2, a2), d2 = al(t2, -1 * i2, -1 * a2), h2 = d2.x - c2.x, p2 = d2.y - c2.y, f2 = h2 * h2 + p2 * p2, g2 = Math.sqrt(f2);
|
|
s2 = (u2 = (e2.nodeRepulsion + t2.nodeRepulsion) / f2) * h2 / g2, l2 = u2 * p2 / g2;
|
|
}
|
|
e2.isLocked || (e2.offsetX -= s2, e2.offsetY -= l2), t2.isLocked || (t2.offsetX += s2, t2.offsetY += l2);
|
|
}
|
|
}, il = function(e2, t2, n2, r2) {
|
|
if (n2 > 0) var i2 = e2.maxX - t2.minX;
|
|
else i2 = t2.maxX - e2.minX;
|
|
if (r2 > 0) var a2 = e2.maxY - t2.minY;
|
|
else a2 = t2.maxY - e2.minY;
|
|
return i2 >= 0 && a2 >= 0 ? Math.sqrt(i2 * i2 + a2 * a2) : 0;
|
|
}, al = function(e2, t2, n2) {
|
|
var r2 = e2.positionX, i2 = e2.positionY, a2 = e2.height || 1, o2 = e2.width || 1, s2 = n2 / t2, l2 = a2 / o2, u2 = {};
|
|
return 0 === t2 && 0 < n2 || 0 === t2 && 0 > n2 ? (u2.x = r2, u2.y = i2 + a2 / 2, u2) : 0 < t2 && -1 * l2 <= s2 && s2 <= l2 ? (u2.x = r2 + o2 / 2, u2.y = i2 + o2 * n2 / 2 / t2, u2) : 0 > t2 && -1 * l2 <= s2 && s2 <= l2 ? (u2.x = r2 - o2 / 2, u2.y = i2 - o2 * n2 / 2 / t2, u2) : 0 < n2 && (s2 <= -1 * l2 || s2 >= l2) ? (u2.x = r2 + a2 * t2 / 2 / n2, u2.y = i2 + a2 / 2, u2) : 0 > n2 && (s2 <= -1 * l2 || s2 >= l2) ? (u2.x = r2 - a2 * t2 / 2 / n2, u2.y = i2 - a2 / 2, u2) : u2;
|
|
}, ol = function(e2, t2) {
|
|
for (var n2 = 0; n2 < e2.edgeSize; n2++) {
|
|
var r2 = e2.layoutEdges[n2], i2 = e2.idToIndex[r2.sourceId], a2 = e2.layoutNodes[i2], o2 = e2.idToIndex[r2.targetId], s2 = e2.layoutNodes[o2], l2 = s2.positionX - a2.positionX, u2 = s2.positionY - a2.positionY;
|
|
if (0 !== l2 || 0 !== u2) {
|
|
var c2 = al(a2, l2, u2), d2 = al(s2, -1 * l2, -1 * u2), h2 = d2.x - c2.x, p2 = d2.y - c2.y, f2 = Math.sqrt(h2 * h2 + p2 * p2), g2 = Math.pow(r2.idealLength - f2, 2) / r2.elasticity;
|
|
if (0 !== f2) var v2 = g2 * h2 / f2, y2 = g2 * p2 / f2;
|
|
else v2 = 0, y2 = 0;
|
|
a2.isLocked || (a2.offsetX += v2, a2.offsetY += y2), s2.isLocked || (s2.offsetX -= v2, s2.offsetY -= y2);
|
|
}
|
|
}
|
|
}, sl = function(e2, t2) {
|
|
if (0 !== t2.gravity) for (var n2 = 0; n2 < e2.graphSet.length; n2++) {
|
|
var r2 = e2.graphSet[n2], i2 = r2.length;
|
|
if (0 === n2) var a2 = e2.clientHeight / 2, o2 = e2.clientWidth / 2;
|
|
else {
|
|
var s2 = e2.layoutNodes[e2.idToIndex[r2[0]]], l2 = e2.layoutNodes[e2.idToIndex[s2.parentId]];
|
|
a2 = l2.positionX, o2 = l2.positionY;
|
|
}
|
|
for (var u2 = 0; u2 < i2; u2++) {
|
|
var c2 = e2.layoutNodes[e2.idToIndex[r2[u2]]];
|
|
if (!c2.isLocked) {
|
|
var d2 = a2 - c2.positionX, h2 = o2 - c2.positionY, p2 = Math.sqrt(d2 * d2 + h2 * h2);
|
|
if (p2 > 1) {
|
|
var f2 = t2.gravity * d2 / p2, g2 = t2.gravity * h2 / p2;
|
|
c2.offsetX += f2, c2.offsetY += g2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}, ll = function(e2, t2) {
|
|
var n2 = [], r2 = 0, i2 = -1;
|
|
for (n2.push.apply(n2, e2.graphSet[0]), i2 += e2.graphSet[0].length; r2 <= i2; ) {
|
|
var a2 = n2[r2++], o2 = e2.idToIndex[a2], s2 = e2.layoutNodes[o2], l2 = s2.children;
|
|
if (0 < l2.length && !s2.isLocked) {
|
|
for (var u2 = s2.offsetX, c2 = s2.offsetY, d2 = 0; d2 < l2.length; d2++) {
|
|
var h2 = e2.layoutNodes[e2.idToIndex[l2[d2]]];
|
|
h2.offsetX += u2, h2.offsetY += c2, n2[++i2] = l2[d2];
|
|
}
|
|
s2.offsetX = 0, s2.offsetY = 0;
|
|
}
|
|
}
|
|
}, ul = function(e2, t2) {
|
|
for (var n2 = 0; n2 < e2.nodeSize; n2++) {
|
|
0 < (i2 = e2.layoutNodes[n2]).children.length && (i2.maxX = void 0, i2.minX = void 0, i2.maxY = void 0, i2.minY = void 0);
|
|
}
|
|
for (n2 = 0; n2 < e2.nodeSize; n2++) {
|
|
if (!(0 < (i2 = e2.layoutNodes[n2]).children.length || i2.isLocked)) {
|
|
var r2 = cl(i2.offsetX, i2.offsetY, e2.temperature);
|
|
i2.positionX += r2.x, i2.positionY += r2.y, i2.offsetX = 0, i2.offsetY = 0, i2.minX = i2.positionX - i2.width, i2.maxX = i2.positionX + i2.width, i2.minY = i2.positionY - i2.height, i2.maxY = i2.positionY + i2.height, dl(i2, e2);
|
|
}
|
|
}
|
|
for (n2 = 0; n2 < e2.nodeSize; n2++) {
|
|
var i2;
|
|
0 < (i2 = e2.layoutNodes[n2]).children.length && !i2.isLocked && (i2.positionX = (i2.maxX + i2.minX) / 2, i2.positionY = (i2.maxY + i2.minY) / 2, i2.width = i2.maxX - i2.minX, i2.height = i2.maxY - i2.minY);
|
|
}
|
|
}, cl = function(e2, t2, n2) {
|
|
var r2 = Math.sqrt(e2 * e2 + t2 * t2);
|
|
if (r2 > n2) var i2 = { x: n2 * e2 / r2, y: n2 * t2 / r2 };
|
|
else i2 = { x: e2, y: t2 };
|
|
return i2;
|
|
}, dl = function e2(t2, n2) {
|
|
var r2 = t2.parentId;
|
|
if (null != r2) {
|
|
var i2 = n2.layoutNodes[n2.idToIndex[r2]], a2 = false;
|
|
return (null == i2.maxX || t2.maxX + i2.padRight > i2.maxX) && (i2.maxX = t2.maxX + i2.padRight, a2 = true), (null == i2.minX || t2.minX - i2.padLeft < i2.minX) && (i2.minX = t2.minX - i2.padLeft, a2 = true), (null == i2.maxY || t2.maxY + i2.padBottom > i2.maxY) && (i2.maxY = t2.maxY + i2.padBottom, a2 = true), (null == i2.minY || t2.minY - i2.padTop < i2.minY) && (i2.minY = t2.minY - i2.padTop, a2 = true), a2 ? e2(i2, n2) : void 0;
|
|
}
|
|
}, hl = function(e2, t2) {
|
|
for (var n2 = e2.layoutNodes, r2 = [], i2 = 0; i2 < n2.length; i2++) {
|
|
var a2 = n2[i2], o2 = a2.cmptId;
|
|
(r2[o2] = r2[o2] || []).push(a2);
|
|
}
|
|
var s2 = 0;
|
|
for (i2 = 0; i2 < r2.length; i2++) {
|
|
if (g2 = r2[i2]) {
|
|
g2.x1 = 1 / 0, g2.x2 = -1 / 0, g2.y1 = 1 / 0, g2.y2 = -1 / 0;
|
|
for (var l2 = 0; l2 < g2.length; l2++) {
|
|
var u2 = g2[l2];
|
|
g2.x1 = Math.min(g2.x1, u2.positionX - u2.width / 2), g2.x2 = Math.max(g2.x2, u2.positionX + u2.width / 2), g2.y1 = Math.min(g2.y1, u2.positionY - u2.height / 2), g2.y2 = Math.max(g2.y2, u2.positionY + u2.height / 2);
|
|
}
|
|
g2.w = g2.x2 - g2.x1, g2.h = g2.y2 - g2.y1, s2 += g2.w * g2.h;
|
|
}
|
|
}
|
|
r2.sort(function(e3, t3) {
|
|
return t3.w * t3.h - e3.w * e3.h;
|
|
});
|
|
var c2 = 0, d2 = 0, h2 = 0, p2 = 0, f2 = Math.sqrt(s2) * e2.clientWidth / e2.clientHeight;
|
|
for (i2 = 0; i2 < r2.length; i2++) {
|
|
var g2;
|
|
if (g2 = r2[i2]) {
|
|
for (l2 = 0; l2 < g2.length; l2++) {
|
|
(u2 = g2[l2]).isLocked || (u2.positionX += c2 - g2.x1, u2.positionY += d2 - g2.y1);
|
|
}
|
|
c2 += g2.w + t2.componentSpacing, h2 += g2.w + t2.componentSpacing, p2 = Math.max(p2, g2.h), h2 > f2 && (d2 += p2 + t2.componentSpacing, c2 = 0, h2 = 0, p2 = 0);
|
|
}
|
|
}
|
|
}, pl = { fit: true, padding: 30, boundingBox: void 0, avoidOverlap: true, avoidOverlapPadding: 10, nodeDimensionsIncludeLabels: false, spacingFactor: void 0, condense: false, rows: void 0, cols: void 0, position: function(e2) {
|
|
}, sort: void 0, animate: false, animationDuration: 500, animationEasing: void 0, animateFilter: function(e2, t2) {
|
|
return true;
|
|
}, ready: void 0, stop: void 0, transform: function(e2, t2) {
|
|
return t2;
|
|
} };
|
|
function fl(e2) {
|
|
this.options = I({}, pl, e2);
|
|
}
|
|
fl.prototype.run = function() {
|
|
var e2 = this.options, t2 = e2, n2 = e2.cy, r2 = t2.eles, i2 = r2.nodes().not(":parent");
|
|
t2.sort && (i2 = i2.sort(t2.sort));
|
|
var a2 = Dt(t2.boundingBox ? t2.boundingBox : { x1: 0, y1: 0, w: n2.width(), h: n2.height() });
|
|
if (0 === a2.h || 0 === a2.w) r2.nodes().layoutPositions(this, t2, function(e3) {
|
|
return { x: a2.x1, y: a2.y1 };
|
|
});
|
|
else {
|
|
var o2 = i2.size(), s2 = Math.sqrt(o2 * a2.h / a2.w), l2 = Math.round(s2), u2 = Math.round(a2.w / a2.h * s2), c2 = function(e3) {
|
|
if (null == e3) return Math.min(l2, u2);
|
|
Math.min(l2, u2) == l2 ? l2 = e3 : u2 = e3;
|
|
}, d2 = function(e3) {
|
|
if (null == e3) return Math.max(l2, u2);
|
|
Math.max(l2, u2) == l2 ? l2 = e3 : u2 = e3;
|
|
}, h2 = t2.rows, p2 = null != t2.cols ? t2.cols : t2.columns;
|
|
if (null != h2 && null != p2) l2 = h2, u2 = p2;
|
|
else if (null != h2 && null == p2) l2 = h2, u2 = Math.ceil(o2 / l2);
|
|
else if (null == h2 && null != p2) u2 = p2, l2 = Math.ceil(o2 / u2);
|
|
else if (u2 * l2 > o2) {
|
|
var f2 = c2(), g2 = d2();
|
|
(f2 - 1) * g2 >= o2 ? c2(f2 - 1) : (g2 - 1) * f2 >= o2 && d2(g2 - 1);
|
|
} else for (; u2 * l2 < o2; ) {
|
|
var v2 = c2(), y2 = d2();
|
|
(y2 + 1) * v2 >= o2 ? d2(y2 + 1) : c2(v2 + 1);
|
|
}
|
|
var m2 = a2.w / u2, b2 = a2.h / l2;
|
|
if (t2.condense && (m2 = 0, b2 = 0), t2.avoidOverlap) for (var x2 = 0; x2 < i2.length; x2++) {
|
|
var w2 = i2[x2], E2 = w2._private.position;
|
|
null != E2.x && null != E2.y || (E2.x = 0, E2.y = 0);
|
|
var k2 = w2.layoutDimensions(t2), C2 = t2.avoidOverlapPadding, S2 = k2.w + C2, P2 = k2.h + C2;
|
|
m2 = Math.max(m2, S2), b2 = Math.max(b2, P2);
|
|
}
|
|
for (var D2 = {}, T2 = function(e3, t3) {
|
|
return !!D2["c-" + e3 + "-" + t3];
|
|
}, _2 = function(e3, t3) {
|
|
D2["c-" + e3 + "-" + t3] = true;
|
|
}, M2 = 0, B2 = 0, N2 = function() {
|
|
++B2 >= u2 && (B2 = 0, M2++);
|
|
}, z2 = {}, I2 = 0; I2 < i2.length; I2++) {
|
|
var L3 = i2[I2], A2 = t2.position(L3);
|
|
if (A2 && (void 0 !== A2.row || void 0 !== A2.col)) {
|
|
var O2 = { row: A2.row, col: A2.col };
|
|
if (void 0 === O2.col) for (O2.col = 0; T2(O2.row, O2.col); ) O2.col++;
|
|
else if (void 0 === O2.row) for (O2.row = 0; T2(O2.row, O2.col); ) O2.row++;
|
|
z2[L3.id()] = O2, _2(O2.row, O2.col);
|
|
}
|
|
}
|
|
i2.layoutPositions(this, t2, function(e3, t3) {
|
|
var n3, r3;
|
|
if (e3.locked() || e3.isParent()) return false;
|
|
var i3 = z2[e3.id()];
|
|
if (i3) n3 = i3.col * m2 + m2 / 2 + a2.x1, r3 = i3.row * b2 + b2 / 2 + a2.y1;
|
|
else {
|
|
for (; T2(M2, B2); ) N2();
|
|
n3 = B2 * m2 + m2 / 2 + a2.x1, r3 = M2 * b2 + b2 / 2 + a2.y1, _2(M2, B2), N2();
|
|
}
|
|
return { x: n3, y: r3 };
|
|
});
|
|
}
|
|
return this;
|
|
};
|
|
var gl = { ready: function() {
|
|
}, stop: function() {
|
|
} };
|
|
function vl(e2) {
|
|
this.options = I({}, gl, e2);
|
|
}
|
|
vl.prototype.run = function() {
|
|
var e2 = this.options, t2 = e2.eles;
|
|
return e2.cy, this.emit("layoutstart"), t2.nodes().positions(function() {
|
|
return { x: 0, y: 0 };
|
|
}), this.one("layoutready", e2.ready), this.emit("layoutready"), this.one("layoutstop", e2.stop), this.emit("layoutstop"), this;
|
|
}, vl.prototype.stop = function() {
|
|
return this;
|
|
};
|
|
var yl = { positions: void 0, zoom: void 0, pan: void 0, fit: true, padding: 30, spacingFactor: void 0, animate: false, animationDuration: 500, animationEasing: void 0, animateFilter: function(e2, t2) {
|
|
return true;
|
|
}, ready: void 0, stop: void 0, transform: function(e2, t2) {
|
|
return t2;
|
|
} };
|
|
function ml(e2) {
|
|
this.options = I({}, yl, e2);
|
|
}
|
|
ml.prototype.run = function() {
|
|
var e2 = this.options, t2 = e2.eles.nodes(), n2 = g(e2.positions);
|
|
return t2.layoutPositions(this, e2, function(t3, r2) {
|
|
var i2 = function(t4) {
|
|
if (null == e2.positions) return function(e3) {
|
|
return { x: e3.x, y: e3.y };
|
|
}(t4.position());
|
|
if (n2) return e2.positions(t4);
|
|
var r3 = e2.positions[t4._private.data.id];
|
|
return null == r3 ? null : r3;
|
|
}(t3);
|
|
return !t3.locked() && null != i2 && i2;
|
|
}), this;
|
|
};
|
|
var bl = { fit: true, padding: 30, boundingBox: void 0, animate: false, animationDuration: 500, animationEasing: void 0, animateFilter: function(e2, t2) {
|
|
return true;
|
|
}, ready: void 0, stop: void 0, transform: function(e2, t2) {
|
|
return t2;
|
|
} };
|
|
function xl(e2) {
|
|
this.options = I({}, bl, e2);
|
|
}
|
|
xl.prototype.run = function() {
|
|
var e2 = this.options, t2 = e2.cy, n2 = e2.eles, r2 = Dt(e2.boundingBox ? e2.boundingBox : { x1: 0, y1: 0, w: t2.width(), h: t2.height() });
|
|
return n2.nodes().layoutPositions(this, e2, function(e3, t3) {
|
|
return { x: r2.x1 + Math.round(Math.random() * r2.w), y: r2.y1 + Math.round(Math.random() * r2.h) };
|
|
}), this;
|
|
};
|
|
var wl = [{ name: "breadthfirst", impl: Fs }, { name: "circle", impl: qs }, { name: "concentric", impl: Ws }, { name: "cose", impl: Ks }, { name: "grid", impl: fl }, { name: "null", impl: vl }, { name: "preset", impl: ml }, { name: "random", impl: xl }];
|
|
function El(e2) {
|
|
this.options = e2, this.notifications = 0;
|
|
}
|
|
var kl = function() {
|
|
}, Cl = function() {
|
|
throw new Error("A headless instance can not render images");
|
|
};
|
|
El.prototype = { recalculateRenderedStyle: kl, notify: function() {
|
|
this.notifications++;
|
|
}, init: kl, isHeadless: function() {
|
|
return true;
|
|
}, png: Cl, jpg: Cl };
|
|
var Sl = { arrowShapeWidth: 0.3, registerArrowShapes: function() {
|
|
var e2 = this.arrowShapes = {}, t2 = this, n2 = function(e3, t3, n3, r3, i3, a3, o3) {
|
|
var s3 = i3.x - n3 / 2 - o3, l2 = i3.x + n3 / 2 + o3, u2 = i3.y - n3 / 2 - o3, c2 = i3.y + n3 / 2 + o3;
|
|
return s3 <= e3 && e3 <= l2 && u2 <= t3 && t3 <= c2;
|
|
}, r2 = function(e3, t3, n3, r3, i3) {
|
|
var a3 = e3 * Math.cos(r3) - t3 * Math.sin(r3), o3 = (e3 * Math.sin(r3) + t3 * Math.cos(r3)) * n3;
|
|
return { x: a3 * n3 + i3.x, y: o3 + i3.y };
|
|
}, i2 = function(e3, t3, n3, i3) {
|
|
for (var a3 = [], o3 = 0; o3 < e3.length; o3 += 2) {
|
|
var s3 = e3[o3], l2 = e3[o3 + 1];
|
|
a3.push(r2(s3, l2, t3, n3, i3));
|
|
}
|
|
return a3;
|
|
}, a2 = function(e3) {
|
|
for (var t3 = [], n3 = 0; n3 < e3.length; n3++) {
|
|
var r3 = e3[n3];
|
|
t3.push(r3.x, r3.y);
|
|
}
|
|
return t3;
|
|
}, o2 = function(e3) {
|
|
return e3.pstyle("width").pfValue * e3.pstyle("arrow-scale").pfValue * 2;
|
|
}, s2 = function(r3, s3) {
|
|
f(s3) && (s3 = e2[s3]), e2[r3] = I({ name: r3, points: [-0.15, -0.3, 0.15, -0.3, 0.15, 0.3, -0.15, 0.3], collide: function(e3, t3, n3, r4, o3, s4) {
|
|
var l2 = a2(i2(this.points, n3 + 2 * s4, r4, o3));
|
|
return jt(e3, t3, l2);
|
|
}, roughCollide: n2, draw: function(e3, n3, r4, a3) {
|
|
var o3 = i2(this.points, n3, r4, a3);
|
|
t2.arrowShapeImpl("polygon")(e3, o3);
|
|
}, spacing: function(e3) {
|
|
return 0;
|
|
}, gap: o2 }, s3);
|
|
};
|
|
s2("none", { collide: Ie, roughCollide: Ie, draw: Ae, spacing: Le, gap: Le }), s2("triangle", { points: [-0.15, -0.3, 0, 0, 0.15, -0.3] }), s2("arrow", "triangle"), s2("triangle-backcurve", { points: e2.triangle.points, controlPoint: [0, -0.15], roughCollide: n2, draw: function(e3, n3, a3, o3, s3) {
|
|
var l2 = i2(this.points, n3, a3, o3), u2 = this.controlPoint, c2 = r2(u2[0], u2[1], n3, a3, o3);
|
|
t2.arrowShapeImpl(this.name)(e3, l2, c2);
|
|
}, gap: function(e3) {
|
|
return 0.8 * o2(e3);
|
|
} }), s2("triangle-tee", { points: [0, 0, 0.15, -0.3, -0.15, -0.3, 0, 0], pointsTee: [-0.15, -0.4, -0.15, -0.5, 0.15, -0.5, 0.15, -0.4], collide: function(e3, t3, n3, r3, o3, s3, l2) {
|
|
var u2 = a2(i2(this.points, n3 + 2 * l2, r3, o3)), c2 = a2(i2(this.pointsTee, n3 + 2 * l2, r3, o3));
|
|
return jt(e3, t3, u2) || jt(e3, t3, c2);
|
|
}, draw: function(e3, n3, r3, a3, o3) {
|
|
var s3 = i2(this.points, n3, r3, a3), l2 = i2(this.pointsTee, n3, r3, a3);
|
|
t2.arrowShapeImpl(this.name)(e3, s3, l2);
|
|
} }), s2("circle-triangle", { radius: 0.15, pointsTr: [0, -0.15, 0.15, -0.45, -0.15, -0.45, 0, -0.15], collide: function(e3, t3, n3, r3, o3, s3, l2) {
|
|
var u2 = o3, c2 = Math.pow(u2.x - e3, 2) + Math.pow(u2.y - t3, 2) <= Math.pow((n3 + 2 * l2) * this.radius, 2), d2 = a2(i2(this.points, n3 + 2 * l2, r3, o3));
|
|
return jt(e3, t3, d2) || c2;
|
|
}, draw: function(e3, n3, r3, a3, o3) {
|
|
var s3 = i2(this.pointsTr, n3, r3, a3);
|
|
t2.arrowShapeImpl(this.name)(e3, s3, a3.x, a3.y, this.radius * n3);
|
|
}, spacing: function(e3) {
|
|
return t2.getArrowWidth(e3.pstyle("width").pfValue, e3.pstyle("arrow-scale").value) * this.radius;
|
|
} }), s2("triangle-cross", { points: [0, 0, 0.15, -0.3, -0.15, -0.3, 0, 0], baseCrossLinePts: [-0.15, -0.4, -0.15, -0.4, 0.15, -0.4, 0.15, -0.4], crossLinePts: function(e3, t3) {
|
|
var n3 = this.baseCrossLinePts.slice(), r3 = t3 / e3;
|
|
return n3[3] = n3[3] - r3, n3[5] = n3[5] - r3, n3;
|
|
}, collide: function(e3, t3, n3, r3, o3, s3, l2) {
|
|
var u2 = a2(i2(this.points, n3 + 2 * l2, r3, o3)), c2 = a2(i2(this.crossLinePts(n3, s3), n3 + 2 * l2, r3, o3));
|
|
return jt(e3, t3, u2) || jt(e3, t3, c2);
|
|
}, draw: function(e3, n3, r3, a3, o3) {
|
|
var s3 = i2(this.points, n3, r3, a3), l2 = i2(this.crossLinePts(n3, o3), n3, r3, a3);
|
|
t2.arrowShapeImpl(this.name)(e3, s3, l2);
|
|
} }), s2("vee", { points: [-0.15, -0.3, 0, 0, 0.15, -0.3, 0, -0.15], gap: function(e3) {
|
|
return 0.525 * o2(e3);
|
|
} }), s2("circle", { radius: 0.15, collide: function(e3, t3, n3, r3, i3, a3, o3) {
|
|
var s3 = i3;
|
|
return Math.pow(s3.x - e3, 2) + Math.pow(s3.y - t3, 2) <= Math.pow((n3 + 2 * o3) * this.radius, 2);
|
|
}, draw: function(e3, n3, r3, i3, a3) {
|
|
t2.arrowShapeImpl(this.name)(e3, i3.x, i3.y, this.radius * n3);
|
|
}, spacing: function(e3) {
|
|
return t2.getArrowWidth(e3.pstyle("width").pfValue, e3.pstyle("arrow-scale").value) * this.radius;
|
|
} }), s2("tee", { points: [-0.15, 0, -0.15, -0.1, 0.15, -0.1, 0.15, 0], spacing: function(e3) {
|
|
return 1;
|
|
}, gap: function(e3) {
|
|
return 1;
|
|
} }), s2("square", { points: [-0.15, 0, 0.15, 0, 0.15, -0.3, -0.15, -0.3] }), s2("diamond", { points: [-0.15, -0.15, 0, -0.3, 0.15, -0.15, 0, 0], gap: function(e3) {
|
|
return e3.pstyle("width").pfValue * e3.pstyle("arrow-scale").value;
|
|
} }), s2("chevron", { points: [0, 0, -0.15, -0.15, -0.1, -0.2, 0, -0.1, 0.1, -0.2, 0.15, -0.15], gap: function(e3) {
|
|
return 0.95 * e3.pstyle("width").pfValue * e3.pstyle("arrow-scale").value;
|
|
} });
|
|
} }, Pl = { projectIntoViewport: function(e2, t2) {
|
|
var n2 = this.cy, r2 = this.findContainerClientCoords(), i2 = r2[0], a2 = r2[1], o2 = r2[4], s2 = n2.pan(), l2 = n2.zoom();
|
|
return [((e2 - i2) / o2 - s2.x) / l2, ((t2 - a2) / o2 - s2.y) / l2];
|
|
}, findContainerClientCoords: function() {
|
|
if (this.containerBB) return this.containerBB;
|
|
var e2 = this.container, t2 = e2.getBoundingClientRect(), n2 = this.cy.window().getComputedStyle(e2), r2 = function(e3) {
|
|
return parseFloat(n2.getPropertyValue(e3));
|
|
}, i2 = r2("padding-left"), a2 = r2("padding-right"), o2 = r2("padding-top"), s2 = r2("padding-bottom"), l2 = r2("border-left-width"), u2 = r2("border-right-width"), c2 = r2("border-top-width"), d2 = (r2("border-bottom-width"), e2.clientWidth), h2 = e2.clientHeight, p2 = i2 + a2, f2 = o2 + s2, g2 = l2 + u2, v2 = t2.width / (d2 + g2), y2 = d2 - p2, m2 = h2 - f2, b2 = t2.left + i2 + l2, x2 = t2.top + o2 + c2;
|
|
return this.containerBB = [b2, x2, y2, m2, v2];
|
|
}, invalidateContainerClientCoordsCache: function() {
|
|
this.containerBB = null;
|
|
}, findNearestElement: function(e2, t2, n2, r2) {
|
|
return this.findNearestElements(e2, t2, n2, r2)[0];
|
|
}, findNearestElements: function(e2, t2, n2, r2) {
|
|
var i2, a2, o2 = this, s2 = this, l2 = s2.getCachedZSortedEles(), u2 = [], c2 = s2.cy.zoom(), d2 = s2.cy.hasCompoundNodes(), h2 = (r2 ? 24 : 8) / c2, p2 = (r2 ? 8 : 2) / c2, f2 = (r2 ? 8 : 2) / c2, g2 = 1 / 0;
|
|
function v2(e3, t3) {
|
|
if (e3.isNode()) {
|
|
if (a2) return;
|
|
a2 = e3, u2.push(e3);
|
|
}
|
|
if (e3.isEdge() && (null == t3 || t3 < g2)) if (i2) {
|
|
if (i2.pstyle("z-compound-depth").value === e3.pstyle("z-compound-depth").value && i2.pstyle("z-compound-depth").value === e3.pstyle("z-compound-depth").value) {
|
|
for (var n3 = 0; n3 < u2.length; n3++) if (u2[n3].isEdge()) {
|
|
u2[n3] = e3, i2 = e3, g2 = null != t3 ? t3 : g2;
|
|
break;
|
|
}
|
|
}
|
|
} else u2.push(e3), i2 = e3, g2 = null != t3 ? t3 : g2;
|
|
}
|
|
function y2(n3) {
|
|
var r3 = n3.outerWidth() + 2 * p2, i3 = n3.outerHeight() + 2 * p2, a3 = r3 / 2, l3 = i3 / 2, u3 = n3.position();
|
|
if (u3.x - a3 <= e2 && e2 <= u3.x + a3 && u3.y - l3 <= t2 && t2 <= u3.y + l3 && s2.nodeShapes[o2.getNodeShape(n3)].checkPoint(e2, t2, 0, r3, i3, u3.x, u3.y)) return v2(n3, 0), true;
|
|
}
|
|
function m2(n3) {
|
|
var r3, i3 = n3._private, a3 = i3.rscratch, l3 = n3.pstyle("width").pfValue, c3 = n3.pstyle("arrow-scale").value, p3 = l3 / 2 + h2, f3 = p3 * p3, g3 = 2 * p3, m3 = i3.source, b3 = i3.target;
|
|
if ("segments" === a3.edgeType || "straight" === a3.edgeType || "haystack" === a3.edgeType) {
|
|
for (var x3 = a3.allpts, w3 = 0; w3 + 3 < x3.length; w3 += 2) if (Ot(e2, t2, x3[w3], x3[w3 + 1], x3[w3 + 2], x3[w3 + 3], g3) && f3 > (r3 = Ft(e2, t2, x3[w3], x3[w3 + 1], x3[w3 + 2], x3[w3 + 3]))) return v2(n3, r3), true;
|
|
} else if ("bezier" === a3.edgeType || "multibezier" === a3.edgeType || "self" === a3.edgeType || "compound" === a3.edgeType) {
|
|
for (x3 = a3.allpts, w3 = 0; w3 + 5 < a3.allpts.length; w3 += 4) if (Rt(e2, t2, x3[w3], x3[w3 + 1], x3[w3 + 2], x3[w3 + 3], x3[w3 + 4], x3[w3 + 5], g3) && f3 > (r3 = Vt(e2, t2, x3[w3], x3[w3 + 1], x3[w3 + 2], x3[w3 + 3], x3[w3 + 4], x3[w3 + 5]))) return v2(n3, r3), true;
|
|
}
|
|
m3 = m3 || i3.source, b3 = b3 || i3.target;
|
|
var E3 = o2.getArrowWidth(l3, c3), k2 = [{ name: "source", x: a3.arrowStartX, y: a3.arrowStartY, angle: a3.srcArrowAngle }, { name: "target", x: a3.arrowEndX, y: a3.arrowEndY, angle: a3.tgtArrowAngle }, { name: "mid-source", x: a3.midX, y: a3.midY, angle: a3.midsrcArrowAngle }, { name: "mid-target", x: a3.midX, y: a3.midY, angle: a3.midtgtArrowAngle }];
|
|
for (w3 = 0; w3 < k2.length; w3++) {
|
|
var C2 = k2[w3], S2 = s2.arrowShapes[n3.pstyle(C2.name + "-arrow-shape").value], P2 = n3.pstyle("width").pfValue;
|
|
if (S2.roughCollide(e2, t2, E3, C2.angle, { x: C2.x, y: C2.y }, P2, h2) && S2.collide(e2, t2, E3, C2.angle, { x: C2.x, y: C2.y }, P2, h2)) return v2(n3), true;
|
|
}
|
|
d2 && u2.length > 0 && (y2(m3), y2(b3));
|
|
}
|
|
function b2(e3, t3, n3) {
|
|
return Ke(e3, t3, n3);
|
|
}
|
|
function x2(n3, r3) {
|
|
var i3, a3 = n3._private, o3 = f2;
|
|
i3 = r3 ? r3 + "-" : "", n3.boundingBox();
|
|
var s3 = a3.labelBounds[r3 || "main"], l3 = n3.pstyle(i3 + "label").value;
|
|
if ("yes" === n3.pstyle("text-events").strValue && l3) {
|
|
var u3 = b2(a3.rscratch, "labelX", r3), c3 = b2(a3.rscratch, "labelY", r3), d3 = b2(a3.rscratch, "labelAngle", r3), h3 = n3.pstyle(i3 + "text-margin-x").pfValue, p3 = n3.pstyle(i3 + "text-margin-y").pfValue, g3 = s3.x1 - o3 - h3, y3 = s3.x2 + o3 - h3, m3 = s3.y1 - o3 - p3, x3 = s3.y2 + o3 - p3;
|
|
if (d3) {
|
|
var w3 = Math.cos(d3), E3 = Math.sin(d3), k2 = function(e3, t3) {
|
|
return { x: (e3 -= u3) * w3 - (t3 -= c3) * E3 + u3, y: e3 * E3 + t3 * w3 + c3 };
|
|
}, C2 = k2(g3, m3), S2 = k2(g3, x3), P2 = k2(y3, m3), D2 = k2(y3, x3), T2 = [C2.x + h3, C2.y + p3, P2.x + h3, P2.y + p3, D2.x + h3, D2.y + p3, S2.x + h3, S2.y + p3];
|
|
if (jt(e2, t2, T2)) return v2(n3), true;
|
|
} else if (It(s3, e2, t2)) return v2(n3), true;
|
|
}
|
|
}
|
|
n2 && (l2 = l2.interactive);
|
|
for (var w2 = l2.length - 1; w2 >= 0; w2--) {
|
|
var E2 = l2[w2];
|
|
E2.isNode() ? y2(E2) || x2(E2) : m2(E2) || x2(E2) || x2(E2, "source") || x2(E2, "target");
|
|
}
|
|
return u2;
|
|
}, getAllInBox: function(e2, t2, n2, r2) {
|
|
for (var i2, a2, o2 = this.getCachedZSortedEles().interactive, s2 = [], l2 = Math.min(e2, n2), u2 = Math.max(e2, n2), c2 = Math.min(t2, r2), d2 = Math.max(t2, r2), h2 = Dt({ x1: e2 = l2, y1: t2 = c2, x2: n2 = u2, y2: r2 = d2 }), p2 = 0; p2 < o2.length; p2++) {
|
|
var f2 = o2[p2];
|
|
if (f2.isNode()) {
|
|
var g2 = f2, v2 = g2.boundingBox({ includeNodes: true, includeEdges: false, includeLabels: false });
|
|
zt(h2, v2) && !Lt(v2, h2) && s2.push(g2);
|
|
} else {
|
|
var y2 = f2, m2 = y2._private, b2 = m2.rscratch;
|
|
if (null != b2.startX && null != b2.startY && !It(h2, b2.startX, b2.startY)) continue;
|
|
if (null != b2.endX && null != b2.endY && !It(h2, b2.endX, b2.endY)) continue;
|
|
if ("bezier" === b2.edgeType || "multibezier" === b2.edgeType || "self" === b2.edgeType || "compound" === b2.edgeType || "segments" === b2.edgeType || "haystack" === b2.edgeType) {
|
|
for (var x2 = m2.rstyle.bezierPts || m2.rstyle.linePts || m2.rstyle.haystackPts, w2 = true, E2 = 0; E2 < x2.length; E2++) if (i2 = h2, a2 = x2[E2], !It(i2, a2.x, a2.y)) {
|
|
w2 = false;
|
|
break;
|
|
}
|
|
w2 && s2.push(y2);
|
|
} else "haystack" !== b2.edgeType && "straight" !== b2.edgeType || s2.push(y2);
|
|
}
|
|
}
|
|
return s2;
|
|
} }, Dl = { calculateArrowAngles: function(e2) {
|
|
var t2, n2, r2, i2, a2, o2, s2 = e2._private.rscratch, l2 = "haystack" === s2.edgeType, u2 = "bezier" === s2.edgeType, c2 = "multibezier" === s2.edgeType, d2 = "segments" === s2.edgeType, h2 = "compound" === s2.edgeType, p2 = "self" === s2.edgeType;
|
|
if (l2 ? (r2 = s2.haystackPts[0], i2 = s2.haystackPts[1], a2 = s2.haystackPts[2], o2 = s2.haystackPts[3]) : (r2 = s2.arrowStartX, i2 = s2.arrowStartY, a2 = s2.arrowEndX, o2 = s2.arrowEndY), g2 = s2.midX, v2 = s2.midY, d2) t2 = r2 - s2.segpts[0], n2 = i2 - s2.segpts[1];
|
|
else if (c2 || h2 || p2 || u2) {
|
|
var f2 = s2.allpts;
|
|
t2 = r2 - Ct(f2[0], f2[2], f2[4], 0.1), n2 = i2 - Ct(f2[1], f2[3], f2[5], 0.1);
|
|
} else t2 = r2 - g2, n2 = i2 - v2;
|
|
s2.srcArrowAngle = mt(t2, n2);
|
|
var g2 = s2.midX, v2 = s2.midY;
|
|
if (l2 && (g2 = (r2 + a2) / 2, v2 = (i2 + o2) / 2), t2 = a2 - r2, n2 = o2 - i2, d2) if ((f2 = s2.allpts).length / 2 % 2 == 0) {
|
|
var y2 = (m2 = f2.length / 2) - 2;
|
|
t2 = f2[m2] - f2[y2], n2 = f2[m2 + 1] - f2[y2 + 1];
|
|
} else {
|
|
y2 = (m2 = f2.length / 2 - 1) - 2;
|
|
var m2, b2 = m2 + 2;
|
|
t2 = f2[m2] - f2[y2], n2 = f2[m2 + 1] - f2[y2 + 1];
|
|
}
|
|
else if (c2 || h2 || p2) {
|
|
var x2, w2, E2, k2, f2 = s2.allpts;
|
|
if (s2.ctrlpts.length / 2 % 2 == 0) {
|
|
var C2 = (S2 = (P2 = f2.length / 2 - 1) + 2) + 2;
|
|
x2 = Ct(f2[P2], f2[S2], f2[C2], 0), w2 = Ct(f2[P2 + 1], f2[S2 + 1], f2[C2 + 1], 0), E2 = Ct(f2[P2], f2[S2], f2[C2], 1e-4), k2 = Ct(f2[P2 + 1], f2[S2 + 1], f2[C2 + 1], 1e-4);
|
|
} else {
|
|
var S2, P2;
|
|
C2 = (S2 = f2.length / 2 - 1) + 2;
|
|
x2 = Ct(f2[P2 = S2 - 2], f2[S2], f2[C2], 0.4999), w2 = Ct(f2[P2 + 1], f2[S2 + 1], f2[C2 + 1], 0.4999), E2 = Ct(f2[P2], f2[S2], f2[C2], 0.5), k2 = Ct(f2[P2 + 1], f2[S2 + 1], f2[C2 + 1], 0.5);
|
|
}
|
|
t2 = E2 - x2, n2 = k2 - w2;
|
|
}
|
|
(s2.midtgtArrowAngle = mt(t2, n2), s2.midDispX = t2, s2.midDispY = n2, t2 *= -1, n2 *= -1, d2) && ((f2 = s2.allpts).length / 2 % 2 == 0 || (t2 = -(f2[b2 = (m2 = f2.length / 2 - 1) + 2] - f2[m2]), n2 = -(f2[b2 + 1] - f2[m2 + 1])));
|
|
if (s2.midsrcArrowAngle = mt(t2, n2), d2) t2 = a2 - s2.segpts[s2.segpts.length - 2], n2 = o2 - s2.segpts[s2.segpts.length - 1];
|
|
else if (c2 || h2 || p2 || u2) {
|
|
var D2 = (f2 = s2.allpts).length;
|
|
t2 = a2 - Ct(f2[D2 - 6], f2[D2 - 4], f2[D2 - 2], 0.9), n2 = o2 - Ct(f2[D2 - 5], f2[D2 - 3], f2[D2 - 1], 0.9);
|
|
} else t2 = a2 - g2, n2 = o2 - v2;
|
|
s2.tgtArrowAngle = mt(t2, n2);
|
|
} };
|
|
Dl.getArrowWidth = Dl.getArrowHeight = function(e2, t2) {
|
|
var n2 = this.arrowWidthCache = this.arrowWidthCache || {}, r2 = n2[e2 + ", " + t2];
|
|
return r2 || (r2 = Math.max(Math.pow(13.37 * e2, 0.9), 29) * t2, n2[e2 + ", " + t2] = r2, r2);
|
|
};
|
|
var Tl = {};
|
|
function _l(e2) {
|
|
var t2 = [];
|
|
if (null != e2) {
|
|
for (var n2 = 0; n2 < e2.length; n2 += 2) {
|
|
var r2 = e2[n2], i2 = e2[n2 + 1];
|
|
t2.push({ x: r2, y: i2 });
|
|
}
|
|
return t2;
|
|
}
|
|
}
|
|
Tl.findMidptPtsEtc = function(e2, t2) {
|
|
var n2, r2 = t2.posPts, i2 = t2.intersectionPts, o2 = t2.vectorNormInverse, s2 = e2.pstyle("source-endpoint"), l2 = e2.pstyle("target-endpoint"), u2 = null != s2.units && null != l2.units;
|
|
switch (e2.pstyle("edge-distances").value) {
|
|
case "node-position":
|
|
n2 = r2;
|
|
break;
|
|
case "intersection":
|
|
n2 = i2;
|
|
break;
|
|
case "endpoints":
|
|
if (u2) {
|
|
var c2 = a(this.manualEndptToPx(e2.source()[0], s2), 2), d2 = c2[0], h2 = c2[1], p2 = a(this.manualEndptToPx(e2.target()[0], l2), 2), f2 = p2[0], g2 = p2[1], v2 = { x1: d2, y1: h2, x2: f2, y2: g2 };
|
|
o2 = function(e3, t3, n3, r3) {
|
|
var i3 = r3 - t3, a2 = n3 - e3, o3 = Math.sqrt(a2 * a2 + i3 * i3);
|
|
return { x: -i3 / o3, y: a2 / o3 };
|
|
}(d2, h2, f2, g2), n2 = v2;
|
|
} else Ve("Edge ".concat(e2.id(), " has edge-distances:endpoints specified without manual endpoints specified via source-endpoint and target-endpoint. Falling back on edge-distances:intersection (default).")), n2 = i2;
|
|
}
|
|
return { midptPts: n2, vectorNormInverse: o2 };
|
|
}, Tl.findHaystackPoints = function(e2) {
|
|
for (var t2 = 0; t2 < e2.length; t2++) {
|
|
var n2 = e2[t2], r2 = n2._private, i2 = r2.rscratch;
|
|
if (!i2.haystack) {
|
|
var a2 = 2 * Math.random() * Math.PI;
|
|
i2.source = { x: Math.cos(a2), y: Math.sin(a2) }, a2 = 2 * Math.random() * Math.PI, i2.target = { x: Math.cos(a2), y: Math.sin(a2) };
|
|
}
|
|
var o2 = r2.source, s2 = r2.target, l2 = o2.position(), u2 = s2.position(), c2 = o2.width(), d2 = s2.width(), h2 = o2.height(), p2 = s2.height(), f2 = n2.pstyle("haystack-radius").value / 2;
|
|
i2.haystackPts = i2.allpts = [i2.source.x * c2 * f2 + l2.x, i2.source.y * h2 * f2 + l2.y, i2.target.x * d2 * f2 + u2.x, i2.target.y * p2 * f2 + u2.y], i2.midX = (i2.allpts[0] + i2.allpts[2]) / 2, i2.midY = (i2.allpts[1] + i2.allpts[3]) / 2, i2.edgeType = "haystack", i2.haystack = true, this.storeEdgeProjections(n2), this.calculateArrowAngles(n2), this.recalculateEdgeLabelProjections(n2), this.calculateLabelAngles(n2);
|
|
}
|
|
}, Tl.findSegmentsPoints = function(e2, t2) {
|
|
var n2 = e2._private.rscratch, r2 = e2.pstyle("segment-weights"), i2 = e2.pstyle("segment-distances"), a2 = Math.min(r2.pfValue.length, i2.pfValue.length);
|
|
n2.edgeType = "segments", n2.segpts = [];
|
|
for (var o2 = 0; o2 < a2; o2++) {
|
|
var s2 = r2.pfValue[o2], l2 = i2.pfValue[o2], u2 = 1 - s2, c2 = s2, d2 = this.findMidptPtsEtc(e2, t2), h2 = d2.midptPts, p2 = d2.vectorNormInverse, f2 = { x: h2.x1 * u2 + h2.x2 * c2, y: h2.y1 * u2 + h2.y2 * c2 };
|
|
n2.segpts.push(f2.x + p2.x * l2, f2.y + p2.y * l2);
|
|
}
|
|
}, Tl.findLoopPoints = function(e2, t2, n2, r2) {
|
|
var i2 = e2._private.rscratch, a2 = t2.dirCounts, o2 = t2.srcPos, s2 = e2.pstyle("control-point-distances"), l2 = s2 ? s2.pfValue[0] : void 0, u2 = e2.pstyle("loop-direction").pfValue, c2 = e2.pstyle("loop-sweep").pfValue, d2 = e2.pstyle("control-point-step-size").pfValue;
|
|
i2.edgeType = "self";
|
|
var h2 = n2, p2 = d2;
|
|
r2 && (h2 = 0, p2 = l2);
|
|
var f2 = u2 - Math.PI / 2, g2 = f2 - c2 / 2, v2 = f2 + c2 / 2, y2 = String(u2 + "_" + c2);
|
|
h2 = void 0 === a2[y2] ? a2[y2] = 0 : ++a2[y2], i2.ctrlpts = [o2.x + 1.4 * Math.cos(g2) * p2 * (h2 / 3 + 1), o2.y + 1.4 * Math.sin(g2) * p2 * (h2 / 3 + 1), o2.x + 1.4 * Math.cos(v2) * p2 * (h2 / 3 + 1), o2.y + 1.4 * Math.sin(v2) * p2 * (h2 / 3 + 1)];
|
|
}, Tl.findCompoundLoopPoints = function(e2, t2, n2, r2) {
|
|
var i2 = e2._private.rscratch;
|
|
i2.edgeType = "compound";
|
|
var a2 = t2.srcPos, o2 = t2.tgtPos, s2 = t2.srcW, l2 = t2.srcH, u2 = t2.tgtW, c2 = t2.tgtH, d2 = e2.pstyle("control-point-step-size").pfValue, h2 = e2.pstyle("control-point-distances"), p2 = h2 ? h2.pfValue[0] : void 0, f2 = n2, g2 = d2;
|
|
r2 && (f2 = 0, g2 = p2);
|
|
var v2 = { x: a2.x - s2 / 2, y: a2.y - l2 / 2 }, y2 = { x: o2.x - u2 / 2, y: o2.y - c2 / 2 }, m2 = { x: Math.min(v2.x, y2.x), y: Math.min(v2.y, y2.y) }, b2 = Math.max(0.5, Math.log(0.01 * s2)), x2 = Math.max(0.5, Math.log(0.01 * u2));
|
|
i2.ctrlpts = [m2.x, m2.y - (1 + Math.pow(50, 1.12) / 100) * g2 * (f2 / 3 + 1) * b2, m2.x - (1 + Math.pow(50, 1.12) / 100) * g2 * (f2 / 3 + 1) * x2, m2.y];
|
|
}, Tl.findStraightEdgePoints = function(e2) {
|
|
e2._private.rscratch.edgeType = "straight";
|
|
}, Tl.findBezierPoints = function(e2, t2, n2, r2, i2) {
|
|
var a2 = e2._private.rscratch, o2 = e2.pstyle("control-point-step-size").pfValue, s2 = e2.pstyle("control-point-distances"), l2 = e2.pstyle("control-point-weights"), u2 = s2 && l2 ? Math.min(s2.value.length, l2.value.length) : 1, c2 = s2 ? s2.pfValue[0] : void 0, d2 = l2.value[0], h2 = r2;
|
|
a2.edgeType = h2 ? "multibezier" : "bezier", a2.ctrlpts = [];
|
|
for (var p2 = 0; p2 < u2; p2++) {
|
|
var f2 = (0.5 - t2.eles.length / 2 + n2) * o2 * (i2 ? -1 : 1), g2 = void 0, v2 = xt(f2);
|
|
h2 && (c2 = s2 ? s2.pfValue[p2] : o2, d2 = l2.value[p2]);
|
|
var y2 = void 0 !== (g2 = r2 ? c2 : void 0 !== c2 ? v2 * c2 : void 0) ? g2 : f2, m2 = 1 - d2, b2 = d2, x2 = this.findMidptPtsEtc(e2, t2), w2 = x2.midptPts, E2 = x2.vectorNormInverse, k2 = { x: w2.x1 * m2 + w2.x2 * b2, y: w2.y1 * m2 + w2.y2 * b2 };
|
|
a2.ctrlpts.push(k2.x + E2.x * y2, k2.y + E2.y * y2);
|
|
}
|
|
}, Tl.findTaxiPoints = function(e2, t2) {
|
|
var n2 = e2._private.rscratch;
|
|
n2.edgeType = "segments";
|
|
var r2 = t2.posPts, i2 = t2.srcW, a2 = t2.srcH, o2 = t2.tgtW, s2 = t2.tgtH, l2 = "node-position" !== e2.pstyle("edge-distances").value, u2 = e2.pstyle("taxi-direction").value, c2 = u2, d2 = e2.pstyle("taxi-turn"), h2 = "%" === d2.units, p2 = d2.pfValue, f2 = p2 < 0, g2 = e2.pstyle("taxi-turn-min-distance").pfValue, v2 = l2 ? (i2 + o2) / 2 : 0, y2 = l2 ? (a2 + s2) / 2 : 0, m2 = r2.x2 - r2.x1, b2 = r2.y2 - r2.y1, x2 = function(e3, t3) {
|
|
return e3 > 0 ? Math.max(e3 - t3, 0) : Math.min(e3 + t3, 0);
|
|
}, w2 = x2(m2, v2), E2 = x2(b2, y2), k2 = false;
|
|
"auto" === c2 ? u2 = Math.abs(w2) > Math.abs(E2) ? "horizontal" : "vertical" : "upward" === c2 || "downward" === c2 ? (u2 = "vertical", k2 = true) : "leftward" !== c2 && "rightward" !== c2 || (u2 = "horizontal", k2 = true);
|
|
var C2, S2 = "vertical" === u2, P2 = S2 ? E2 : w2, D2 = S2 ? b2 : m2, T2 = xt(D2), _2 = false;
|
|
(k2 && (h2 || f2) || !("downward" === c2 && D2 < 0 || "upward" === c2 && D2 > 0 || "leftward" === c2 && D2 > 0 || "rightward" === c2 && D2 < 0) || (P2 = (T2 *= -1) * Math.abs(P2), _2 = true), h2) ? C2 = (p2 < 0 ? 1 + p2 : p2) * P2 : C2 = (p2 < 0 ? P2 : 0) + p2 * T2;
|
|
var M2 = function(e3) {
|
|
return Math.abs(e3) < g2 || Math.abs(e3) >= Math.abs(P2);
|
|
}, B2 = M2(C2), N2 = M2(Math.abs(P2) - Math.abs(C2));
|
|
if ((B2 || N2) && !_2) if (S2) {
|
|
var z2 = Math.abs(D2) <= a2 / 2, I2 = Math.abs(m2) <= o2 / 2;
|
|
if (z2) {
|
|
var L3 = (r2.x1 + r2.x2) / 2, A2 = r2.y1, O2 = r2.y2;
|
|
n2.segpts = [L3, A2, L3, O2];
|
|
} else if (I2) {
|
|
var R2 = (r2.y1 + r2.y2) / 2, V2 = r2.x1, F2 = r2.x2;
|
|
n2.segpts = [V2, R2, F2, R2];
|
|
} else n2.segpts = [r2.x1, r2.y2];
|
|
} else {
|
|
var j2 = Math.abs(D2) <= i2 / 2, q2 = Math.abs(b2) <= s2 / 2;
|
|
if (j2) {
|
|
var Y2 = (r2.y1 + r2.y2) / 2, X2 = r2.x1, W2 = r2.x2;
|
|
n2.segpts = [X2, Y2, W2, Y2];
|
|
} else if (q2) {
|
|
var H2 = (r2.x1 + r2.x2) / 2, K2 = r2.y1, G2 = r2.y2;
|
|
n2.segpts = [H2, K2, H2, G2];
|
|
} else n2.segpts = [r2.x2, r2.y1];
|
|
}
|
|
else if (S2) {
|
|
var U2 = r2.y1 + C2 + (l2 ? a2 / 2 * T2 : 0), Z2 = r2.x1, $2 = r2.x2;
|
|
n2.segpts = [Z2, U2, $2, U2];
|
|
} else {
|
|
var Q2 = r2.x1 + C2 + (l2 ? i2 / 2 * T2 : 0), J2 = r2.y1, ee2 = r2.y2;
|
|
n2.segpts = [Q2, J2, Q2, ee2];
|
|
}
|
|
}, Tl.tryToCorrectInvalidPoints = function(e2, t2) {
|
|
var n2 = e2._private.rscratch;
|
|
if ("bezier" === n2.edgeType) {
|
|
var r2 = t2.srcPos, i2 = t2.tgtPos, a2 = t2.srcW, o2 = t2.srcH, s2 = t2.tgtW, l2 = t2.tgtH, u2 = t2.srcShape, c2 = t2.tgtShape, d2 = !m(n2.startX) || !m(n2.startY), h2 = !m(n2.arrowStartX) || !m(n2.arrowStartY), p2 = !m(n2.endX) || !m(n2.endY), f2 = !m(n2.arrowEndX) || !m(n2.arrowEndY), g2 = 3 * (this.getArrowWidth(e2.pstyle("width").pfValue, e2.pstyle("arrow-scale").value) * this.arrowShapeWidth), v2 = wt({ x: n2.ctrlpts[0], y: n2.ctrlpts[1] }, { x: n2.startX, y: n2.startY }), y2 = v2 < g2, b2 = wt({ x: n2.ctrlpts[0], y: n2.ctrlpts[1] }, { x: n2.endX, y: n2.endY }), x2 = b2 < g2, w2 = false;
|
|
if (d2 || h2 || y2) {
|
|
w2 = true;
|
|
var E2 = { x: n2.ctrlpts[0] - r2.x, y: n2.ctrlpts[1] - r2.y }, k2 = Math.sqrt(E2.x * E2.x + E2.y * E2.y), C2 = { x: E2.x / k2, y: E2.y / k2 }, S2 = Math.max(a2, o2), P2 = { x: n2.ctrlpts[0] + 2 * C2.x * S2, y: n2.ctrlpts[1] + 2 * C2.y * S2 }, D2 = u2.intersectLine(r2.x, r2.y, a2, o2, P2.x, P2.y, 0);
|
|
y2 ? (n2.ctrlpts[0] = n2.ctrlpts[0] + C2.x * (g2 - v2), n2.ctrlpts[1] = n2.ctrlpts[1] + C2.y * (g2 - v2)) : (n2.ctrlpts[0] = D2[0] + C2.x * g2, n2.ctrlpts[1] = D2[1] + C2.y * g2);
|
|
}
|
|
if (p2 || f2 || x2) {
|
|
w2 = true;
|
|
var T2 = { x: n2.ctrlpts[0] - i2.x, y: n2.ctrlpts[1] - i2.y }, _2 = Math.sqrt(T2.x * T2.x + T2.y * T2.y), M2 = { x: T2.x / _2, y: T2.y / _2 }, B2 = Math.max(a2, o2), N2 = { x: n2.ctrlpts[0] + 2 * M2.x * B2, y: n2.ctrlpts[1] + 2 * M2.y * B2 }, z2 = c2.intersectLine(i2.x, i2.y, s2, l2, N2.x, N2.y, 0);
|
|
x2 ? (n2.ctrlpts[0] = n2.ctrlpts[0] + M2.x * (g2 - b2), n2.ctrlpts[1] = n2.ctrlpts[1] + M2.y * (g2 - b2)) : (n2.ctrlpts[0] = z2[0] + M2.x * g2, n2.ctrlpts[1] = z2[1] + M2.y * g2);
|
|
}
|
|
w2 && this.findEndpoints(e2);
|
|
}
|
|
}, Tl.storeAllpts = function(e2) {
|
|
var t2 = e2._private.rscratch;
|
|
if ("multibezier" === t2.edgeType || "bezier" === t2.edgeType || "self" === t2.edgeType || "compound" === t2.edgeType) {
|
|
t2.allpts = [], t2.allpts.push(t2.startX, t2.startY);
|
|
for (var n2 = 0; n2 + 1 < t2.ctrlpts.length; n2 += 2) t2.allpts.push(t2.ctrlpts[n2], t2.ctrlpts[n2 + 1]), n2 + 3 < t2.ctrlpts.length && t2.allpts.push((t2.ctrlpts[n2] + t2.ctrlpts[n2 + 2]) / 2, (t2.ctrlpts[n2 + 1] + t2.ctrlpts[n2 + 3]) / 2);
|
|
var r2;
|
|
t2.allpts.push(t2.endX, t2.endY), t2.ctrlpts.length / 2 % 2 == 0 ? (r2 = t2.allpts.length / 2 - 1, t2.midX = t2.allpts[r2], t2.midY = t2.allpts[r2 + 1]) : (r2 = t2.allpts.length / 2 - 3, 0.5, t2.midX = Ct(t2.allpts[r2], t2.allpts[r2 + 2], t2.allpts[r2 + 4], 0.5), t2.midY = Ct(t2.allpts[r2 + 1], t2.allpts[r2 + 3], t2.allpts[r2 + 5], 0.5));
|
|
} else if ("straight" === t2.edgeType) t2.allpts = [t2.startX, t2.startY, t2.endX, t2.endY], t2.midX = (t2.startX + t2.endX + t2.arrowStartX + t2.arrowEndX) / 4, t2.midY = (t2.startY + t2.endY + t2.arrowStartY + t2.arrowEndY) / 4;
|
|
else if ("segments" === t2.edgeType) if (t2.allpts = [], t2.allpts.push(t2.startX, t2.startY), t2.allpts.push.apply(t2.allpts, t2.segpts), t2.allpts.push(t2.endX, t2.endY), t2.segpts.length % 4 == 0) {
|
|
var i2 = t2.segpts.length / 2, a2 = i2 - 2;
|
|
t2.midX = (t2.segpts[a2] + t2.segpts[i2]) / 2, t2.midY = (t2.segpts[a2 + 1] + t2.segpts[i2 + 1]) / 2;
|
|
} else {
|
|
var o2 = t2.segpts.length / 2 - 1;
|
|
t2.midX = t2.segpts[o2], t2.midY = t2.segpts[o2 + 1];
|
|
}
|
|
}, Tl.checkForInvalidEdgeWarning = function(e2) {
|
|
var t2 = e2[0]._private.rscratch;
|
|
t2.nodesOverlap || m(t2.startX) && m(t2.startY) && m(t2.endX) && m(t2.endY) ? t2.loggedErr = false : t2.loggedErr || (t2.loggedErr = true, Ve("Edge `" + e2.id() + "` has invalid endpoints and so it is impossible to draw. Adjust your edge style (e.g. control points) accordingly or use an alternative edge type. This is expected behaviour when the source node and the target node overlap."));
|
|
}, Tl.findEdgeControlPoints = function(e2) {
|
|
var t2 = this;
|
|
if (e2 && 0 !== e2.length) {
|
|
for (var n2 = this, r2 = n2.cy.hasCompoundNodes(), i2 = { map: new Ue(), get: function(e3) {
|
|
var t3 = this.map.get(e3[0]);
|
|
return null != t3 ? t3.get(e3[1]) : null;
|
|
}, set: function(e3, t3) {
|
|
var n3 = this.map.get(e3[0]);
|
|
null == n3 && (n3 = new Ue(), this.map.set(e3[0], n3)), n3.set(e3[1], t3);
|
|
} }, a2 = [], o2 = [], s2 = 0; s2 < e2.length; s2++) {
|
|
var l2 = e2[s2], u2 = l2._private, c2 = l2.pstyle("curve-style").value;
|
|
if (!l2.removed() && l2.takesUpSpace()) if ("haystack" !== c2) {
|
|
var d2 = "unbundled-bezier" === c2 || "segments" === c2 || "straight" === c2 || "straight-triangle" === c2 || "taxi" === c2, h2 = "unbundled-bezier" === c2 || "bezier" === c2, p2 = u2.source, f2 = u2.target, g2 = [p2.poolIndex(), f2.poolIndex()].sort(), v2 = i2.get(g2);
|
|
null == v2 && (v2 = { eles: [] }, i2.set(g2, v2), a2.push(g2)), v2.eles.push(l2), d2 && (v2.hasUnbundled = true), h2 && (v2.hasBezier = true);
|
|
} else o2.push(l2);
|
|
}
|
|
for (var y2 = function(e3) {
|
|
var o3 = a2[e3], s3 = i2.get(o3), l3 = void 0;
|
|
if (!s3.hasUnbundled) {
|
|
var u3 = s3.eles[0].parallelEdges().filter(function(e4) {
|
|
return e4.isBundledBezier();
|
|
});
|
|
He(s3.eles), u3.forEach(function(e4) {
|
|
return s3.eles.push(e4);
|
|
}), s3.eles.sort(function(e4, t3) {
|
|
return e4.poolIndex() - t3.poolIndex();
|
|
});
|
|
}
|
|
var c3 = s3.eles[0], d3 = c3.source(), h3 = c3.target();
|
|
if (d3.poolIndex() > h3.poolIndex()) {
|
|
var p3 = d3;
|
|
d3 = h3, h3 = p3;
|
|
}
|
|
var f3 = s3.srcPos = d3.position(), g3 = s3.tgtPos = h3.position(), v3 = s3.srcW = d3.outerWidth(), y3 = s3.srcH = d3.outerHeight(), b3 = s3.tgtW = h3.outerWidth(), x2 = s3.tgtH = h3.outerHeight(), w2 = s3.srcShape = n2.nodeShapes[t2.getNodeShape(d3)], E2 = s3.tgtShape = n2.nodeShapes[t2.getNodeShape(h3)];
|
|
s3.dirCounts = { north: 0, west: 0, south: 0, east: 0, northwest: 0, southwest: 0, northeast: 0, southeast: 0 };
|
|
for (var k2 = 0; k2 < s3.eles.length; k2++) {
|
|
var C2 = s3.eles[k2], S2 = C2[0]._private.rscratch, P2 = C2.pstyle("curve-style").value, D2 = "unbundled-bezier" === P2 || "segments" === P2 || "taxi" === P2, T2 = !d3.same(C2.source());
|
|
if (!s3.calculatedIntersection && d3 !== h3 && (s3.hasBezier || s3.hasUnbundled)) {
|
|
s3.calculatedIntersection = true;
|
|
var _2 = w2.intersectLine(f3.x, f3.y, v3, y3, g3.x, g3.y, 0), M2 = s3.srcIntn = _2, B2 = E2.intersectLine(g3.x, g3.y, b3, x2, f3.x, f3.y, 0), N2 = s3.tgtIntn = B2, z2 = s3.intersectionPts = { x1: _2[0], x2: B2[0], y1: _2[1], y2: B2[1] }, I2 = s3.posPts = { x1: f3.x, x2: g3.x, y1: f3.y, y2: g3.y }, L3 = B2[1] - _2[1], A2 = B2[0] - _2[0], O2 = Math.sqrt(A2 * A2 + L3 * L3), R2 = s3.vector = { x: A2, y: L3 }, V2 = s3.vectorNorm = { x: R2.x / O2, y: R2.y / O2 }, F2 = { x: -V2.y, y: V2.x };
|
|
s3.nodesOverlap = !m(O2) || E2.checkPoint(_2[0], _2[1], 0, b3, x2, g3.x, g3.y) || w2.checkPoint(B2[0], B2[1], 0, v3, y3, f3.x, f3.y), s3.vectorNormInverse = F2, l3 = { nodesOverlap: s3.nodesOverlap, dirCounts: s3.dirCounts, calculatedIntersection: true, hasBezier: s3.hasBezier, hasUnbundled: s3.hasUnbundled, eles: s3.eles, srcPos: g3, tgtPos: f3, srcW: b3, srcH: x2, tgtW: v3, tgtH: y3, srcIntn: N2, tgtIntn: M2, srcShape: E2, tgtShape: w2, posPts: { x1: I2.x2, y1: I2.y2, x2: I2.x1, y2: I2.y1 }, intersectionPts: { x1: z2.x2, y1: z2.y2, x2: z2.x1, y2: z2.y1 }, vector: { x: -R2.x, y: -R2.y }, vectorNorm: { x: -V2.x, y: -V2.y }, vectorNormInverse: { x: -F2.x, y: -F2.y } };
|
|
}
|
|
var j2 = T2 ? l3 : s3;
|
|
S2.nodesOverlap = j2.nodesOverlap, S2.srcIntn = j2.srcIntn, S2.tgtIntn = j2.tgtIntn, r2 && (d3.isParent() || d3.isChild() || h3.isParent() || h3.isChild()) && (d3.parents().anySame(h3) || h3.parents().anySame(d3) || d3.same(h3) && d3.isParent()) ? t2.findCompoundLoopPoints(C2, j2, k2, D2) : d3 === h3 ? t2.findLoopPoints(C2, j2, k2, D2) : "segments" === P2 ? t2.findSegmentsPoints(C2, j2) : "taxi" === P2 ? t2.findTaxiPoints(C2, j2) : "straight" === P2 || !D2 && s3.eles.length % 2 == 1 && k2 === Math.floor(s3.eles.length / 2) ? t2.findStraightEdgePoints(C2) : t2.findBezierPoints(C2, j2, k2, D2, T2), t2.findEndpoints(C2), t2.tryToCorrectInvalidPoints(C2, j2), t2.checkForInvalidEdgeWarning(C2), t2.storeAllpts(C2), t2.storeEdgeProjections(C2), t2.calculateArrowAngles(C2), t2.recalculateEdgeLabelProjections(C2), t2.calculateLabelAngles(C2);
|
|
}
|
|
}, b2 = 0; b2 < a2.length; b2++) y2(b2);
|
|
this.findHaystackPoints(o2);
|
|
}
|
|
}, Tl.getSegmentPoints = function(e2) {
|
|
var t2 = e2[0]._private.rscratch;
|
|
if ("segments" === t2.edgeType) return this.recalculateRenderedStyle(e2), _l(t2.segpts);
|
|
}, Tl.getControlPoints = function(e2) {
|
|
var t2 = e2[0]._private.rscratch, n2 = t2.edgeType;
|
|
if ("bezier" === n2 || "multibezier" === n2 || "self" === n2 || "compound" === n2) return this.recalculateRenderedStyle(e2), _l(t2.ctrlpts);
|
|
}, Tl.getEdgeMidpoint = function(e2) {
|
|
var t2 = e2[0]._private.rscratch;
|
|
return this.recalculateRenderedStyle(e2), { x: t2.midX, y: t2.midY };
|
|
};
|
|
var Ml = { manualEndptToPx: function(e2, t2) {
|
|
var n2 = e2.position(), r2 = e2.outerWidth(), i2 = e2.outerHeight();
|
|
if (2 === t2.value.length) {
|
|
var a2 = [t2.pfValue[0], t2.pfValue[1]];
|
|
return "%" === t2.units[0] && (a2[0] = a2[0] * r2), "%" === t2.units[1] && (a2[1] = a2[1] * i2), a2[0] += n2.x, a2[1] += n2.y, a2;
|
|
}
|
|
var o2 = t2.pfValue[0];
|
|
o2 = -Math.PI / 2 + o2;
|
|
var s2 = 2 * Math.max(r2, i2), l2 = [n2.x + Math.cos(o2) * s2, n2.y + Math.sin(o2) * s2];
|
|
return this.nodeShapes[this.getNodeShape(e2)].intersectLine(n2.x, n2.y, r2, i2, l2[0], l2[1], 0);
|
|
}, findEndpoints: function(e2) {
|
|
var t2, n2, r2, i2, a2, o2 = this, s2 = e2.source()[0], l2 = e2.target()[0], u2 = s2.position(), c2 = l2.position(), d2 = e2.pstyle("target-arrow-shape").value, h2 = e2.pstyle("source-arrow-shape").value, p2 = e2.pstyle("target-distance-from-node").pfValue, f2 = e2.pstyle("source-distance-from-node").pfValue, g2 = e2.pstyle("curve-style").value, v2 = e2._private.rscratch, y2 = v2.edgeType, b2 = "self" === y2 || "compound" === y2, x2 = "bezier" === y2 || "multibezier" === y2 || b2, w2 = "bezier" !== y2, E2 = "straight" === y2 || "segments" === y2, k2 = "segments" === y2, C2 = x2 || w2 || E2, S2 = b2 || "taxi" === g2, P2 = e2.pstyle("source-endpoint"), D2 = S2 ? "outside-to-node" : P2.value, T2 = e2.pstyle("target-endpoint"), _2 = S2 ? "outside-to-node" : T2.value;
|
|
if (v2.srcManEndpt = P2, v2.tgtManEndpt = T2, x2) {
|
|
var M2 = [v2.ctrlpts[0], v2.ctrlpts[1]];
|
|
n2 = w2 ? [v2.ctrlpts[v2.ctrlpts.length - 2], v2.ctrlpts[v2.ctrlpts.length - 1]] : M2, r2 = M2;
|
|
} else if (E2) {
|
|
var B2 = k2 ? v2.segpts.slice(0, 2) : [c2.x, c2.y];
|
|
n2 = k2 ? v2.segpts.slice(v2.segpts.length - 2) : [u2.x, u2.y], r2 = B2;
|
|
}
|
|
if ("inside-to-node" === _2) t2 = [c2.x, c2.y];
|
|
else if (T2.units) t2 = this.manualEndptToPx(l2, T2);
|
|
else if ("outside-to-line" === _2) t2 = v2.tgtIntn;
|
|
else if ("outside-to-node" === _2 || "outside-to-node-or-label" === _2 ? i2 = n2 : "outside-to-line" !== _2 && "outside-to-line-or-label" !== _2 || (i2 = [u2.x, u2.y]), t2 = o2.nodeShapes[this.getNodeShape(l2)].intersectLine(c2.x, c2.y, l2.outerWidth(), l2.outerHeight(), i2[0], i2[1], 0), "outside-to-node-or-label" === _2 || "outside-to-line-or-label" === _2) {
|
|
var N2 = l2._private.rscratch, z2 = N2.labelWidth, I2 = N2.labelHeight, L3 = N2.labelX, A2 = N2.labelY, O2 = z2 / 2, R2 = I2 / 2, V2 = l2.pstyle("text-valign").value;
|
|
"top" === V2 ? A2 -= R2 : "bottom" === V2 && (A2 += R2);
|
|
var F2 = l2.pstyle("text-halign").value;
|
|
"left" === F2 ? L3 -= O2 : "right" === F2 && (L3 += O2);
|
|
var j2 = Ut(i2[0], i2[1], [L3 - O2, A2 - R2, L3 + O2, A2 - R2, L3 + O2, A2 + R2, L3 - O2, A2 + R2], c2.x, c2.y);
|
|
if (j2.length > 0) {
|
|
var q2 = u2, Y2 = Et(q2, yt(t2)), X2 = Et(q2, yt(j2)), W2 = Y2;
|
|
if (X2 < Y2 && (t2 = j2, W2 = X2), j2.length > 2) Et(q2, { x: j2[2], y: j2[3] }) < W2 && (t2 = [j2[2], j2[3]]);
|
|
}
|
|
}
|
|
var H2 = Zt(t2, n2, o2.arrowShapes[d2].spacing(e2) + p2), K2 = Zt(t2, n2, o2.arrowShapes[d2].gap(e2) + p2);
|
|
if (v2.endX = K2[0], v2.endY = K2[1], v2.arrowEndX = H2[0], v2.arrowEndY = H2[1], "inside-to-node" === D2) t2 = [u2.x, u2.y];
|
|
else if (P2.units) t2 = this.manualEndptToPx(s2, P2);
|
|
else if ("outside-to-line" === D2) t2 = v2.srcIntn;
|
|
else if ("outside-to-node" === D2 || "outside-to-node-or-label" === D2 ? a2 = r2 : "outside-to-line" !== D2 && "outside-to-line-or-label" !== D2 || (a2 = [c2.x, c2.y]), t2 = o2.nodeShapes[this.getNodeShape(s2)].intersectLine(u2.x, u2.y, s2.outerWidth(), s2.outerHeight(), a2[0], a2[1], 0), "outside-to-node-or-label" === D2 || "outside-to-line-or-label" === D2) {
|
|
var G2 = s2._private.rscratch, U2 = G2.labelWidth, Z2 = G2.labelHeight, $2 = G2.labelX, Q2 = G2.labelY, J2 = U2 / 2, ee2 = Z2 / 2, te2 = s2.pstyle("text-valign").value;
|
|
"top" === te2 ? Q2 -= ee2 : "bottom" === te2 && (Q2 += ee2);
|
|
var ne2 = s2.pstyle("text-halign").value;
|
|
"left" === ne2 ? $2 -= J2 : "right" === ne2 && ($2 += J2);
|
|
var re2 = Ut(a2[0], a2[1], [$2 - J2, Q2 - ee2, $2 + J2, Q2 - ee2, $2 + J2, Q2 + ee2, $2 - J2, Q2 + ee2], u2.x, u2.y);
|
|
if (re2.length > 0) {
|
|
var ie2 = c2, ae2 = Et(ie2, yt(t2)), oe2 = Et(ie2, yt(re2)), se2 = ae2;
|
|
if (oe2 < ae2 && (t2 = [re2[0], re2[1]], se2 = oe2), re2.length > 2) Et(ie2, { x: re2[2], y: re2[3] }) < se2 && (t2 = [re2[2], re2[3]]);
|
|
}
|
|
}
|
|
var le2 = Zt(t2, r2, o2.arrowShapes[h2].spacing(e2) + f2), ue2 = Zt(t2, r2, o2.arrowShapes[h2].gap(e2) + f2);
|
|
v2.startX = ue2[0], v2.startY = ue2[1], v2.arrowStartX = le2[0], v2.arrowStartY = le2[1], C2 && (m(v2.startX) && m(v2.startY) && m(v2.endX) && m(v2.endY) ? v2.badLine = false : v2.badLine = true);
|
|
}, getSourceEndpoint: function(e2) {
|
|
var t2 = e2[0]._private.rscratch;
|
|
switch (this.recalculateRenderedStyle(e2), t2.edgeType) {
|
|
case "haystack":
|
|
return { x: t2.haystackPts[0], y: t2.haystackPts[1] };
|
|
default:
|
|
return { x: t2.arrowStartX, y: t2.arrowStartY };
|
|
}
|
|
}, getTargetEndpoint: function(e2) {
|
|
var t2 = e2[0]._private.rscratch;
|
|
switch (this.recalculateRenderedStyle(e2), t2.edgeType) {
|
|
case "haystack":
|
|
return { x: t2.haystackPts[2], y: t2.haystackPts[3] };
|
|
default:
|
|
return { x: t2.arrowEndX, y: t2.arrowEndY };
|
|
}
|
|
} }, Bl = {};
|
|
function Nl(e2, t2, n2) {
|
|
for (var r2 = function(e3, t3, n3, r3) {
|
|
return Ct(e3, t3, n3, r3);
|
|
}, i2 = t2._private.rstyle.bezierPts, a2 = 0; a2 < e2.bezierProjPcts.length; a2++) {
|
|
var o2 = e2.bezierProjPcts[a2];
|
|
i2.push({ x: r2(n2[0], n2[2], n2[4], o2), y: r2(n2[1], n2[3], n2[5], o2) });
|
|
}
|
|
}
|
|
Bl.storeEdgeProjections = function(e2) {
|
|
var t2 = e2._private, n2 = t2.rscratch, r2 = n2.edgeType;
|
|
if (t2.rstyle.bezierPts = null, t2.rstyle.linePts = null, t2.rstyle.haystackPts = null, "multibezier" === r2 || "bezier" === r2 || "self" === r2 || "compound" === r2) {
|
|
t2.rstyle.bezierPts = [];
|
|
for (var i2 = 0; i2 + 5 < n2.allpts.length; i2 += 4) Nl(this, e2, n2.allpts.slice(i2, i2 + 6));
|
|
} else if ("segments" === r2) {
|
|
var a2 = t2.rstyle.linePts = [];
|
|
for (i2 = 0; i2 + 1 < n2.allpts.length; i2 += 2) a2.push({ x: n2.allpts[i2], y: n2.allpts[i2 + 1] });
|
|
} else if ("haystack" === r2) {
|
|
var o2 = n2.haystackPts;
|
|
t2.rstyle.haystackPts = [{ x: o2[0], y: o2[1] }, { x: o2[2], y: o2[3] }];
|
|
}
|
|
t2.rstyle.arrowWidth = this.getArrowWidth(e2.pstyle("width").pfValue, e2.pstyle("arrow-scale").value) * this.arrowShapeWidth;
|
|
}, Bl.recalculateEdgeProjections = function(e2) {
|
|
this.findEdgeControlPoints(e2);
|
|
};
|
|
var zl = { recalculateNodeLabelProjection: function(e2) {
|
|
var t2 = e2.pstyle("label").strValue;
|
|
if (!S(t2)) {
|
|
var n2, r2, i2 = e2._private, a2 = e2.width(), o2 = e2.height(), s2 = e2.padding(), l2 = e2.position(), u2 = e2.pstyle("text-halign").strValue, c2 = e2.pstyle("text-valign").strValue, d2 = i2.rscratch, h2 = i2.rstyle;
|
|
switch (u2) {
|
|
case "left":
|
|
n2 = l2.x - a2 / 2 - s2;
|
|
break;
|
|
case "right":
|
|
n2 = l2.x + a2 / 2 + s2;
|
|
break;
|
|
default:
|
|
n2 = l2.x;
|
|
}
|
|
switch (c2) {
|
|
case "top":
|
|
r2 = l2.y - o2 / 2 - s2;
|
|
break;
|
|
case "bottom":
|
|
r2 = l2.y + o2 / 2 + s2;
|
|
break;
|
|
default:
|
|
r2 = l2.y;
|
|
}
|
|
d2.labelX = n2, d2.labelY = r2, h2.labelX = n2, h2.labelY = r2, this.calculateLabelAngles(e2), this.applyLabelDimensions(e2);
|
|
}
|
|
} }, Il = function(e2, t2) {
|
|
var n2 = Math.atan(t2 / e2);
|
|
return 0 === e2 && n2 < 0 && (n2 *= -1), n2;
|
|
}, Ll = function(e2, t2) {
|
|
var n2 = t2.x - e2.x, r2 = t2.y - e2.y;
|
|
return Il(n2, r2);
|
|
};
|
|
zl.recalculateEdgeLabelProjections = function(e2) {
|
|
var t2, n2 = e2._private, r2 = n2.rscratch, i2 = this, a2 = { mid: e2.pstyle("label").strValue, source: e2.pstyle("source-label").strValue, target: e2.pstyle("target-label").strValue };
|
|
if (a2.mid || a2.source || a2.target) {
|
|
t2 = { x: r2.midX, y: r2.midY };
|
|
var o2 = function(e3, t3, r3) {
|
|
Ge(n2.rscratch, e3, t3, r3), Ge(n2.rstyle, e3, t3, r3);
|
|
};
|
|
o2("labelX", null, t2.x), o2("labelY", null, t2.y);
|
|
var s2 = Il(r2.midDispX, r2.midDispY);
|
|
o2("labelAutoAngle", null, s2);
|
|
var l2 = function(s3) {
|
|
var l3, u2 = "source" === s3;
|
|
if (a2[s3]) {
|
|
var c2 = e2.pstyle(s3 + "-text-offset").pfValue;
|
|
switch (r2.edgeType) {
|
|
case "self":
|
|
case "compound":
|
|
case "bezier":
|
|
case "multibezier":
|
|
for (var d2, h2 = function e3() {
|
|
if (e3.cache) return e3.cache;
|
|
for (var t3 = [], a3 = 0; a3 + 5 < r2.allpts.length; a3 += 4) {
|
|
var o3 = { x: r2.allpts[a3], y: r2.allpts[a3 + 1] }, s4 = { x: r2.allpts[a3 + 2], y: r2.allpts[a3 + 3] }, l4 = { x: r2.allpts[a3 + 4], y: r2.allpts[a3 + 5] };
|
|
t3.push({ p0: o3, p1: s4, p2: l4, startDist: 0, length: 0, segments: [] });
|
|
}
|
|
var u3 = n2.rstyle.bezierPts, c3 = i2.bezierProjPcts.length;
|
|
function d3(e4, t4, n3, r3, i3) {
|
|
var a4 = wt(t4, n3), o4 = e4.segments[e4.segments.length - 1], s5 = { p0: t4, p1: n3, t0: r3, t1: i3, startDist: o4 ? o4.startDist + o4.length : 0, length: a4 };
|
|
e4.segments.push(s5), e4.length += a4;
|
|
}
|
|
for (var h3 = 0; h3 < t3.length; h3++) {
|
|
var p3 = t3[h3], f3 = t3[h3 - 1];
|
|
f3 && (p3.startDist = f3.startDist + f3.length), d3(p3, p3.p0, u3[h3 * c3], 0, i2.bezierProjPcts[0]);
|
|
for (var g3 = 0; g3 < c3 - 1; g3++) d3(p3, u3[h3 * c3 + g3], u3[h3 * c3 + g3 + 1], i2.bezierProjPcts[g3], i2.bezierProjPcts[g3 + 1]);
|
|
d3(p3, u3[h3 * c3 + c3 - 1], p3.p2, i2.bezierProjPcts[c3 - 1], 1);
|
|
}
|
|
return e3.cache = t3;
|
|
}(), p2 = 0, f2 = 0, g2 = 0; g2 < h2.length; g2++) {
|
|
for (var v2 = h2[u2 ? g2 : h2.length - 1 - g2], y2 = 0; y2 < v2.segments.length; y2++) {
|
|
var m2 = v2.segments[u2 ? y2 : v2.segments.length - 1 - y2], b2 = g2 === h2.length - 1 && y2 === v2.segments.length - 1;
|
|
if (p2 = f2, (f2 += m2.length) >= c2 || b2) {
|
|
d2 = { cp: v2, segment: m2 };
|
|
break;
|
|
}
|
|
}
|
|
if (d2) break;
|
|
}
|
|
var x2 = d2.cp, w2 = d2.segment, E2 = (c2 - p2) / w2.length, k2 = w2.t1 - w2.t0, C2 = u2 ? w2.t0 + k2 * E2 : w2.t1 - k2 * E2;
|
|
C2 = Pt(0, C2, 1), t2 = St(x2.p0, x2.p1, x2.p2, C2), l3 = function(e3, t3, n3, r3) {
|
|
var i3 = Pt(0, r3 - 1e-3, 1), a3 = Pt(0, r3 + 1e-3, 1), o3 = St(e3, t3, n3, i3), s4 = St(e3, t3, n3, a3);
|
|
return Ll(o3, s4);
|
|
}(x2.p0, x2.p1, x2.p2, C2);
|
|
break;
|
|
case "straight":
|
|
case "segments":
|
|
case "haystack":
|
|
for (var S2, P2, D2, T2, _2 = 0, M2 = r2.allpts.length, B2 = 0; B2 + 3 < M2 && (u2 ? (D2 = { x: r2.allpts[B2], y: r2.allpts[B2 + 1] }, T2 = { x: r2.allpts[B2 + 2], y: r2.allpts[B2 + 3] }) : (D2 = { x: r2.allpts[M2 - 2 - B2], y: r2.allpts[M2 - 1 - B2] }, T2 = { x: r2.allpts[M2 - 4 - B2], y: r2.allpts[M2 - 3 - B2] }), P2 = _2, !((_2 += S2 = wt(D2, T2)) >= c2)); B2 += 2) ;
|
|
var N2 = (c2 - P2) / S2;
|
|
N2 = Pt(0, N2, 1), t2 = function(e3, t3, n3, r3) {
|
|
var i3 = t3.x - e3.x, a3 = t3.y - e3.y, o3 = wt(e3, t3), s4 = i3 / o3, l4 = a3 / o3;
|
|
return n3 = null == n3 ? 0 : n3, r3 = null != r3 ? r3 : n3 * o3, { x: e3.x + s4 * r3, y: e3.y + l4 * r3 };
|
|
}(D2, T2, N2), l3 = Ll(D2, T2);
|
|
}
|
|
o2("labelX", s3, t2.x), o2("labelY", s3, t2.y), o2("labelAutoAngle", s3, l3);
|
|
}
|
|
};
|
|
l2("source"), l2("target"), this.applyLabelDimensions(e2);
|
|
}
|
|
}, zl.applyLabelDimensions = function(e2) {
|
|
this.applyPrefixedLabelDimensions(e2), e2.isEdge() && (this.applyPrefixedLabelDimensions(e2, "source"), this.applyPrefixedLabelDimensions(e2, "target"));
|
|
}, zl.applyPrefixedLabelDimensions = function(e2, t2) {
|
|
var n2 = e2._private, r2 = this.getLabelText(e2, t2), i2 = this.calculateLabelDimensions(e2, r2), a2 = e2.pstyle("line-height").pfValue, o2 = e2.pstyle("text-wrap").strValue, s2 = Ke(n2.rscratch, "labelWrapCachedLines", t2) || [], l2 = "wrap" !== o2 ? 1 : Math.max(s2.length, 1), u2 = i2.height / l2, c2 = u2 * a2, d2 = i2.width, h2 = i2.height + (l2 - 1) * (a2 - 1) * u2;
|
|
Ge(n2.rstyle, "labelWidth", t2, d2), Ge(n2.rscratch, "labelWidth", t2, d2), Ge(n2.rstyle, "labelHeight", t2, h2), Ge(n2.rscratch, "labelHeight", t2, h2), Ge(n2.rscratch, "labelLineHeight", t2, c2);
|
|
}, zl.getLabelText = function(e2, t2) {
|
|
var n2 = e2._private, r2 = t2 ? t2 + "-" : "", i2 = e2.pstyle(r2 + "label").strValue, a2 = e2.pstyle("text-transform").value, o2 = function(e3, r3) {
|
|
return r3 ? (Ge(n2.rscratch, e3, t2, r3), r3) : Ke(n2.rscratch, e3, t2);
|
|
};
|
|
if (!i2) return "";
|
|
"none" == a2 || ("uppercase" == a2 ? i2 = i2.toUpperCase() : "lowercase" == a2 && (i2 = i2.toLowerCase()));
|
|
var s2 = e2.pstyle("text-wrap").value;
|
|
if ("wrap" === s2) {
|
|
var l2 = o2("labelKey");
|
|
if (null != l2 && o2("labelWrapKey") === l2) return o2("labelWrapCachedText");
|
|
for (var u2 = i2.split("\n"), c2 = e2.pstyle("text-max-width").pfValue, d2 = "anywhere" === e2.pstyle("text-overflow-wrap").value, h2 = [], p2 = /[\s\u200b]+/, f2 = d2 ? "" : " ", g2 = 0; g2 < u2.length; g2++) {
|
|
var v2 = u2[g2], y2 = this.calculateLabelDimensions(e2, v2).width;
|
|
if (d2) {
|
|
var m2 = v2.split("").join("\u200B");
|
|
v2 = m2;
|
|
}
|
|
if (y2 > c2) {
|
|
for (var b2 = v2.split(p2), x2 = "", w2 = 0; w2 < b2.length; w2++) {
|
|
var E2 = b2[w2], k2 = 0 === x2.length ? E2 : x2 + f2 + E2;
|
|
this.calculateLabelDimensions(e2, k2).width <= c2 ? x2 += E2 + f2 : (x2 && h2.push(x2), x2 = E2 + f2);
|
|
}
|
|
x2.match(/^[\s\u200b]+$/) || h2.push(x2);
|
|
} else h2.push(v2);
|
|
}
|
|
o2("labelWrapCachedLines", h2), i2 = o2("labelWrapCachedText", h2.join("\n")), o2("labelWrapKey", l2);
|
|
} else if ("ellipsis" === s2) {
|
|
var C2 = e2.pstyle("text-max-width").pfValue, S2 = "", P2 = false;
|
|
if (this.calculateLabelDimensions(e2, i2).width < C2) return i2;
|
|
for (var D2 = 0; D2 < i2.length; D2++) {
|
|
if (this.calculateLabelDimensions(e2, S2 + i2[D2] + "\u2026").width > C2) break;
|
|
S2 += i2[D2], D2 === i2.length - 1 && (P2 = true);
|
|
}
|
|
return P2 || (S2 += "\u2026"), S2;
|
|
}
|
|
return i2;
|
|
}, zl.getLabelJustification = function(e2) {
|
|
var t2 = e2.pstyle("text-justification").strValue, n2 = e2.pstyle("text-halign").strValue;
|
|
if ("auto" !== t2) return t2;
|
|
if (!e2.isNode()) return "center";
|
|
switch (n2) {
|
|
case "left":
|
|
return "right";
|
|
case "right":
|
|
return "left";
|
|
default:
|
|
return "center";
|
|
}
|
|
}, zl.calculateLabelDimensions = function(e2, t2) {
|
|
var n2 = Pe(t2, e2._private.labelDimsKey), r2 = this.labelDimCache || (this.labelDimCache = []), i2 = r2[n2];
|
|
if (null != i2) return i2;
|
|
var a2 = e2.pstyle("font-style").strValue, o2 = e2.pstyle("font-size").pfValue, s2 = e2.pstyle("font-family").strValue, l2 = e2.pstyle("font-weight").strValue, u2 = this.labelCalcCanvas, c2 = this.labelCalcCanvasContext;
|
|
if (!u2) {
|
|
u2 = this.labelCalcCanvas = document.createElement("canvas"), c2 = this.labelCalcCanvasContext = u2.getContext("2d");
|
|
var d2 = u2.style;
|
|
d2.position = "absolute", d2.left = "-9999px", d2.top = "-9999px", d2.zIndex = "-1", d2.visibility = "hidden", d2.pointerEvents = "none";
|
|
}
|
|
c2.font = "".concat(a2, " ").concat(l2, " ").concat(o2, "px ").concat(s2);
|
|
for (var h2 = 0, p2 = 0, f2 = t2.split("\n"), g2 = 0; g2 < f2.length; g2++) {
|
|
var v2 = f2[g2], y2 = c2.measureText(v2), m2 = Math.ceil(y2.width), b2 = o2;
|
|
h2 = Math.max(m2, h2), p2 += b2;
|
|
}
|
|
return h2 += 0, p2 += 0, r2[n2] = { width: h2, height: p2 };
|
|
}, zl.calculateLabelAngle = function(e2, t2) {
|
|
var n2 = e2._private.rscratch, r2 = e2.isEdge(), i2 = t2 ? t2 + "-" : "", a2 = e2.pstyle(i2 + "text-rotation"), o2 = a2.strValue;
|
|
return "none" === o2 ? 0 : r2 && "autorotate" === o2 ? n2.labelAutoAngle : "autorotate" === o2 ? 0 : a2.pfValue;
|
|
}, zl.calculateLabelAngles = function(e2) {
|
|
var t2 = this, n2 = e2.isEdge(), r2 = e2._private.rscratch;
|
|
r2.labelAngle = t2.calculateLabelAngle(e2), n2 && (r2.sourceLabelAngle = t2.calculateLabelAngle(e2, "source"), r2.targetLabelAngle = t2.calculateLabelAngle(e2, "target"));
|
|
};
|
|
var Al = {}, Ol = false;
|
|
Al.getNodeShape = function(e2) {
|
|
var t2 = e2.pstyle("shape").value;
|
|
if ("cutrectangle" === t2 && (e2.width() < 28 || e2.height() < 28)) return Ol || (Ve("The `cutrectangle` node shape can not be used at small sizes so `rectangle` is used instead"), Ol = true), "rectangle";
|
|
if (e2.isParent()) return "rectangle" === t2 || "roundrectangle" === t2 || "round-rectangle" === t2 || "cutrectangle" === t2 || "cut-rectangle" === t2 || "barrel" === t2 ? t2 : "rectangle";
|
|
if ("polygon" === t2) {
|
|
var n2 = e2.pstyle("shape-polygon-points").value;
|
|
return this.nodeShapes.makePolygon(n2).name;
|
|
}
|
|
return t2;
|
|
};
|
|
var Rl = { registerCalculationListeners: function() {
|
|
var e2 = this.cy, t2 = e2.collection(), n2 = this, r2 = function(e3) {
|
|
var n3 = !(arguments.length > 1 && void 0 !== arguments[1]) || arguments[1];
|
|
if (t2.merge(e3), n3) for (var r3 = 0; r3 < e3.length; r3++) {
|
|
var i3 = e3[r3], a2 = i3._private, o2 = a2.rstyle;
|
|
o2.clean = false, o2.cleanConnected = false;
|
|
}
|
|
};
|
|
n2.binder(e2).on("bounds.* dirty.*", function(e3) {
|
|
var t3 = e3.target;
|
|
r2(t3);
|
|
}).on("style.* background.*", function(e3) {
|
|
var t3 = e3.target;
|
|
r2(t3, false);
|
|
});
|
|
var i2 = function(i3) {
|
|
if (i3) {
|
|
var a2 = n2.onUpdateEleCalcsFns;
|
|
t2.cleanStyle();
|
|
for (var o2 = 0; o2 < t2.length; o2++) {
|
|
var s2 = t2[o2], l2 = s2._private.rstyle;
|
|
s2.isNode() && !l2.cleanConnected && (r2(s2.connectedEdges()), l2.cleanConnected = true);
|
|
}
|
|
if (a2) for (var u2 = 0; u2 < a2.length; u2++) {
|
|
(0, a2[u2])(i3, t2);
|
|
}
|
|
n2.recalculateRenderedStyle(t2), t2 = e2.collection();
|
|
}
|
|
};
|
|
n2.flushRenderedStyleQueue = function() {
|
|
i2(true);
|
|
}, n2.beforeRender(i2, n2.beforeRenderPriorities.eleCalcs);
|
|
}, onUpdateEleCalcs: function(e2) {
|
|
(this.onUpdateEleCalcsFns = this.onUpdateEleCalcsFns || []).push(e2);
|
|
}, recalculateRenderedStyle: function(e2, t2) {
|
|
var n2 = function(e3) {
|
|
return e3._private.rstyle.cleanConnected;
|
|
}, r2 = [], i2 = [];
|
|
if (!this.destroyed) {
|
|
void 0 === t2 && (t2 = true);
|
|
for (var a2 = 0; a2 < e2.length; a2++) {
|
|
var o2 = e2[a2], s2 = o2._private, l2 = s2.rstyle;
|
|
!o2.isEdge() || n2(o2.source()) && n2(o2.target()) || (l2.clean = false), t2 && l2.clean || o2.removed() || "none" !== o2.pstyle("display").value && ("nodes" === s2.group ? i2.push(o2) : r2.push(o2), l2.clean = true);
|
|
}
|
|
for (var u2 = 0; u2 < i2.length; u2++) {
|
|
var c2 = i2[u2], d2 = c2._private.rstyle, h2 = c2.position();
|
|
this.recalculateNodeLabelProjection(c2), d2.nodeX = h2.x, d2.nodeY = h2.y, d2.nodeW = c2.pstyle("width").pfValue, d2.nodeH = c2.pstyle("height").pfValue;
|
|
}
|
|
this.recalculateEdgeProjections(r2);
|
|
for (var p2 = 0; p2 < r2.length; p2++) {
|
|
var f2 = r2[p2]._private, g2 = f2.rstyle, v2 = f2.rscratch;
|
|
g2.srcX = v2.arrowStartX, g2.srcY = v2.arrowStartY, g2.tgtX = v2.arrowEndX, g2.tgtY = v2.arrowEndY, g2.midX = v2.midX, g2.midY = v2.midY, g2.labelAngle = v2.labelAngle, g2.sourceLabelAngle = v2.sourceLabelAngle, g2.targetLabelAngle = v2.targetLabelAngle;
|
|
}
|
|
}
|
|
} }, Vl = { updateCachedGrabbedEles: function() {
|
|
var e2 = this.cachedZSortedEles;
|
|
if (e2) {
|
|
e2.drag = [], e2.nondrag = [];
|
|
for (var t2 = [], n2 = 0; n2 < e2.length; n2++) {
|
|
var r2 = (i2 = e2[n2])._private.rscratch;
|
|
i2.grabbed() && !i2.isParent() ? t2.push(i2) : r2.inDragLayer ? e2.drag.push(i2) : e2.nondrag.push(i2);
|
|
}
|
|
for (n2 = 0; n2 < t2.length; n2++) {
|
|
var i2 = t2[n2];
|
|
e2.drag.push(i2);
|
|
}
|
|
}
|
|
}, invalidateCachedZSortedEles: function() {
|
|
this.cachedZSortedEles = null;
|
|
}, getCachedZSortedEles: function(e2) {
|
|
if (e2 || !this.cachedZSortedEles) {
|
|
var t2 = this.cy.mutableElements().toArray();
|
|
t2.sort(Do), t2.interactive = t2.filter(function(e3) {
|
|
return e3.interactive();
|
|
}), this.cachedZSortedEles = t2, this.updateCachedGrabbedEles();
|
|
} else t2 = this.cachedZSortedEles;
|
|
return t2;
|
|
} }, Fl = {};
|
|
[Pl, Dl, Tl, Ml, Bl, zl, Al, Rl, Vl].forEach(function(e2) {
|
|
I(Fl, e2);
|
|
});
|
|
var jl = { getCachedImage: function(e2, t2, n2) {
|
|
var r2 = this.imageCache = this.imageCache || {}, i2 = r2[e2];
|
|
if (i2) return i2.image.complete || i2.image.addEventListener("load", n2), i2.image;
|
|
var a2 = (i2 = r2[e2] = r2[e2] || {}).image = new Image();
|
|
a2.addEventListener("load", n2), a2.addEventListener("error", function() {
|
|
a2.error = true;
|
|
});
|
|
return "data:" === e2.substring(0, "data:".length).toLowerCase() || (t2 = "null" === t2 ? null : t2, a2.crossOrigin = t2), a2.src = e2, a2;
|
|
} }, ql = { registerBinding: function(e2, t2, n2, r2) {
|
|
var i2 = Array.prototype.slice.apply(arguments, [1]), a2 = this.binder(e2);
|
|
return a2.on.apply(a2, i2);
|
|
} };
|
|
ql.binder = function(e2) {
|
|
var t2, n2 = this, r2 = n2.cy.window(), i2 = e2 === r2 || e2 === r2.document || e2 === r2.document.body || (t2 = e2, "undefined" != typeof HTMLElement && t2 instanceof HTMLElement);
|
|
if (null == n2.supportsPassiveEvents) {
|
|
var a2 = false;
|
|
try {
|
|
var o2 = Object.defineProperty({}, "passive", { get: function() {
|
|
return a2 = true, true;
|
|
} });
|
|
r2.addEventListener("test", null, o2);
|
|
} catch (e3) {
|
|
}
|
|
n2.supportsPassiveEvents = a2;
|
|
}
|
|
var s2 = function(t3, r3, a3) {
|
|
var o3 = Array.prototype.slice.call(arguments);
|
|
return i2 && n2.supportsPassiveEvents && (o3[2] = { capture: null != a3 && a3, passive: false, once: false }), n2.bindings.push({ target: e2, args: o3 }), (e2.addEventListener || e2.on).apply(e2, o3), this;
|
|
};
|
|
return { on: s2, addEventListener: s2, addListener: s2, bind: s2 };
|
|
}, ql.nodeIsDraggable = function(e2) {
|
|
return e2 && e2.isNode() && !e2.locked() && e2.grabbable();
|
|
}, ql.nodeIsGrabbable = function(e2) {
|
|
return this.nodeIsDraggable(e2) && e2.interactive();
|
|
}, ql.load = function() {
|
|
var e2 = this, t2 = e2.cy.window(), n2 = function(e3) {
|
|
return e3.selected();
|
|
}, r2 = function(t3, n3, r3, i3) {
|
|
null == t3 && (t3 = e2.cy);
|
|
for (var a3 = 0; a3 < n3.length; a3++) {
|
|
var o3 = n3[a3];
|
|
t3.emit({ originalEvent: r3, type: o3, position: i3 });
|
|
}
|
|
}, i2 = function(e3) {
|
|
return e3.shiftKey || e3.metaKey || e3.ctrlKey;
|
|
}, a2 = function(t3, n3) {
|
|
var r3 = true;
|
|
if (e2.cy.hasCompoundNodes() && t3 && t3.pannable()) for (var i3 = 0; n3 && i3 < n3.length; i3++) {
|
|
if ((t3 = n3[i3]).isNode() && t3.isParent() && !t3.pannable()) {
|
|
r3 = false;
|
|
break;
|
|
}
|
|
}
|
|
else r3 = true;
|
|
return r3;
|
|
}, o2 = function(e3) {
|
|
e3[0]._private.rscratch.inDragLayer = true;
|
|
}, s2 = function(e3) {
|
|
e3[0]._private.rscratch.isGrabTarget = true;
|
|
}, l2 = function(e3, t3) {
|
|
var n3 = t3.addToList;
|
|
n3.has(e3) || !e3.grabbable() || e3.locked() || (n3.merge(e3), function(e4) {
|
|
e4[0]._private.grabbed = true;
|
|
}(e3));
|
|
}, u2 = function(t3, n3) {
|
|
n3 = n3 || {};
|
|
var r3 = t3.cy().hasCompoundNodes();
|
|
n3.inDragLayer && (t3.forEach(o2), t3.neighborhood().stdFilter(function(e3) {
|
|
return !r3 || e3.isEdge();
|
|
}).forEach(o2)), n3.addToList && t3.forEach(function(e3) {
|
|
l2(e3, n3);
|
|
}), function(e3, t4) {
|
|
if (e3.cy().hasCompoundNodes() && (null != t4.inDragLayer || null != t4.addToList)) {
|
|
var n4 = e3.descendants();
|
|
t4.inDragLayer && (n4.forEach(o2), n4.connectedEdges().forEach(o2)), t4.addToList && l2(n4, t4);
|
|
}
|
|
}(t3, n3), h2(t3, { inDragLayer: n3.inDragLayer }), e2.updateCachedGrabbedEles();
|
|
}, c2 = u2, d2 = function(t3) {
|
|
t3 && (e2.getCachedZSortedEles().forEach(function(e3) {
|
|
!function(e4) {
|
|
e4[0]._private.grabbed = false;
|
|
}(e3), function(e4) {
|
|
e4[0]._private.rscratch.inDragLayer = false;
|
|
}(e3), function(e4) {
|
|
e4[0]._private.rscratch.isGrabTarget = false;
|
|
}(e3);
|
|
}), e2.updateCachedGrabbedEles());
|
|
}, h2 = function(e3, t3) {
|
|
if ((null != t3.inDragLayer || null != t3.addToList) && e3.cy().hasCompoundNodes()) {
|
|
var n3 = e3.ancestors().orphans();
|
|
if (!n3.same(e3)) {
|
|
var r3 = n3.descendants().spawnSelf().merge(n3).unmerge(e3).unmerge(e3.descendants()), i3 = r3.connectedEdges();
|
|
t3.inDragLayer && (i3.forEach(o2), r3.forEach(o2)), t3.addToList && r3.forEach(function(e4) {
|
|
l2(e4, t3);
|
|
});
|
|
}
|
|
}
|
|
}, p2 = function() {
|
|
null != document.activeElement && null != document.activeElement.blur && document.activeElement.blur();
|
|
}, f2 = "undefined" != typeof MutationObserver, g2 = "undefined" != typeof ResizeObserver;
|
|
f2 ? (e2.removeObserver = new MutationObserver(function(t3) {
|
|
for (var n3 = 0; n3 < t3.length; n3++) {
|
|
var r3 = t3[n3].removedNodes;
|
|
if (r3) for (var i3 = 0; i3 < r3.length; i3++) {
|
|
if (r3[i3] === e2.container) {
|
|
e2.destroy();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}), e2.container.parentNode && e2.removeObserver.observe(e2.container.parentNode, { childList: true })) : e2.registerBinding(e2.container, "DOMNodeRemoved", function(t3) {
|
|
e2.destroy();
|
|
});
|
|
var v2 = fe(function() {
|
|
e2.cy.resize();
|
|
}, 100);
|
|
f2 && (e2.styleObserver = new MutationObserver(v2), e2.styleObserver.observe(e2.container, { attributes: true })), e2.registerBinding(t2, "resize", v2), g2 && (e2.resizeObserver = new ResizeObserver(v2), e2.resizeObserver.observe(e2.container));
|
|
var y2 = function() {
|
|
e2.invalidateContainerClientCoordsCache();
|
|
};
|
|
!function(e3, t3) {
|
|
for (; null != e3; ) t3(e3), e3 = e3.parentNode;
|
|
}(e2.container, function(t3) {
|
|
e2.registerBinding(t3, "transitionend", y2), e2.registerBinding(t3, "animationend", y2), e2.registerBinding(t3, "scroll", y2);
|
|
}), e2.registerBinding(e2.container, "contextmenu", function(e3) {
|
|
e3.preventDefault();
|
|
});
|
|
var b2, x2, w2, E2 = function(t3) {
|
|
for (var n3 = e2.findContainerClientCoords(), r3 = n3[0], i3 = n3[1], a3 = n3[2], o3 = n3[3], s3 = t3.touches ? t3.touches : [t3], l3 = false, u3 = 0; u3 < s3.length; u3++) {
|
|
var c3 = s3[u3];
|
|
if (r3 <= c3.clientX && c3.clientX <= r3 + a3 && i3 <= c3.clientY && c3.clientY <= i3 + o3) {
|
|
l3 = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!l3) return false;
|
|
for (var d3 = e2.container, h3 = t3.target.parentNode, p3 = false; h3; ) {
|
|
if (h3 === d3) {
|
|
p3 = true;
|
|
break;
|
|
}
|
|
h3 = h3.parentNode;
|
|
}
|
|
return !!p3;
|
|
};
|
|
e2.registerBinding(e2.container, "mousedown", function(t3) {
|
|
if (E2(t3)) {
|
|
t3.preventDefault(), p2(), e2.hoverData.capture = true, e2.hoverData.which = t3.which;
|
|
var n3 = e2.cy, i3 = [t3.clientX, t3.clientY], a3 = e2.projectIntoViewport(i3[0], i3[1]), o3 = e2.selection, l3 = e2.findNearestElements(a3[0], a3[1], true, false), d3 = l3[0], h3 = e2.dragData.possibleDragElements;
|
|
e2.hoverData.mdownPos = a3, e2.hoverData.mdownGPos = i3;
|
|
if (3 == t3.which) {
|
|
e2.hoverData.cxtStarted = true;
|
|
var f3 = { originalEvent: t3, type: "cxttapstart", position: { x: a3[0], y: a3[1] } };
|
|
d3 ? (d3.activate(), d3.emit(f3), e2.hoverData.down = d3) : n3.emit(f3), e2.hoverData.downTime = (/* @__PURE__ */ new Date()).getTime(), e2.hoverData.cxtDragged = false;
|
|
} else if (1 == t3.which) {
|
|
if (d3 && d3.activate(), null != d3 && e2.nodeIsGrabbable(d3)) {
|
|
var g3 = function(e3) {
|
|
return { originalEvent: t3, type: e3, position: { x: a3[0], y: a3[1] } };
|
|
};
|
|
if (s2(d3), d3.selected()) {
|
|
h3 = e2.dragData.possibleDragElements = n3.collection();
|
|
var v3 = n3.$(function(t4) {
|
|
return t4.isNode() && t4.selected() && e2.nodeIsGrabbable(t4);
|
|
});
|
|
u2(v3, { addToList: h3 }), d3.emit(g3("grabon")), v3.forEach(function(e3) {
|
|
e3.emit(g3("grab"));
|
|
});
|
|
} else h3 = e2.dragData.possibleDragElements = n3.collection(), c2(d3, { addToList: h3 }), d3.emit(g3("grabon")).emit(g3("grab"));
|
|
e2.redrawHint("eles", true), e2.redrawHint("drag", true);
|
|
}
|
|
e2.hoverData.down = d3, e2.hoverData.downs = l3, e2.hoverData.downTime = (/* @__PURE__ */ new Date()).getTime(), r2(d3, ["mousedown", "tapstart", "vmousedown"], t3, { x: a3[0], y: a3[1] }), null == d3 ? (o3[4] = 1, e2.data.bgActivePosistion = { x: a3[0], y: a3[1] }, e2.redrawHint("select", true), e2.redraw()) : d3.pannable() && (o3[4] = 1), e2.hoverData.tapholdCancelled = false, clearTimeout(e2.hoverData.tapholdTimeout), e2.hoverData.tapholdTimeout = setTimeout(function() {
|
|
if (!e2.hoverData.tapholdCancelled) {
|
|
var r3 = e2.hoverData.down;
|
|
r3 ? r3.emit({ originalEvent: t3, type: "taphold", position: { x: a3[0], y: a3[1] } }) : n3.emit({ originalEvent: t3, type: "taphold", position: { x: a3[0], y: a3[1] } });
|
|
}
|
|
}, e2.tapholdDuration);
|
|
}
|
|
o3[0] = o3[2] = a3[0], o3[1] = o3[3] = a3[1];
|
|
}
|
|
}, false), e2.registerBinding(t2, "mousemove", function(t3) {
|
|
if (e2.hoverData.capture || E2(t3)) {
|
|
var n3 = false, o3 = e2.cy, s3 = o3.zoom(), l3 = [t3.clientX, t3.clientY], c3 = e2.projectIntoViewport(l3[0], l3[1]), h3 = e2.hoverData.mdownPos, p3 = e2.hoverData.mdownGPos, f3 = e2.selection, g3 = null;
|
|
e2.hoverData.draggingEles || e2.hoverData.dragging || e2.hoverData.selecting || (g3 = e2.findNearestElement(c3[0], c3[1], true, false));
|
|
var v3, y3 = e2.hoverData.last, b3 = e2.hoverData.down, x3 = [c3[0] - f3[2], c3[1] - f3[3]], w3 = e2.dragData.possibleDragElements;
|
|
if (p3) {
|
|
var k3 = l3[0] - p3[0], C3 = k3 * k3, S3 = l3[1] - p3[1], P3 = C3 + S3 * S3;
|
|
e2.hoverData.isOverThresholdDrag = v3 = P3 >= e2.desktopTapThreshold2;
|
|
}
|
|
var D3 = i2(t3);
|
|
v3 && (e2.hoverData.tapholdCancelled = true);
|
|
n3 = true, r2(g3, ["mousemove", "vmousemove", "tapdrag"], t3, { x: c3[0], y: c3[1] });
|
|
var T3 = function() {
|
|
e2.data.bgActivePosistion = void 0, e2.hoverData.selecting || o3.emit({ originalEvent: t3, type: "boxstart", position: { x: c3[0], y: c3[1] } }), f3[4] = 1, e2.hoverData.selecting = true, e2.redrawHint("select", true), e2.redraw();
|
|
};
|
|
if (3 === e2.hoverData.which) {
|
|
if (v3) {
|
|
var _3 = { originalEvent: t3, type: "cxtdrag", position: { x: c3[0], y: c3[1] } };
|
|
b3 ? b3.emit(_3) : o3.emit(_3), e2.hoverData.cxtDragged = true, e2.hoverData.cxtOver && g3 === e2.hoverData.cxtOver || (e2.hoverData.cxtOver && e2.hoverData.cxtOver.emit({ originalEvent: t3, type: "cxtdragout", position: { x: c3[0], y: c3[1] } }), e2.hoverData.cxtOver = g3, g3 && g3.emit({ originalEvent: t3, type: "cxtdragover", position: { x: c3[0], y: c3[1] } }));
|
|
}
|
|
} else if (e2.hoverData.dragging) {
|
|
if (n3 = true, o3.panningEnabled() && o3.userPanningEnabled()) {
|
|
var M3;
|
|
if (e2.hoverData.justStartedPan) {
|
|
var B3 = e2.hoverData.mdownPos;
|
|
M3 = { x: (c3[0] - B3[0]) * s3, y: (c3[1] - B3[1]) * s3 }, e2.hoverData.justStartedPan = false;
|
|
} else M3 = { x: x3[0] * s3, y: x3[1] * s3 };
|
|
o3.panBy(M3), o3.emit("dragpan"), e2.hoverData.dragged = true;
|
|
}
|
|
c3 = e2.projectIntoViewport(t3.clientX, t3.clientY);
|
|
} else if (1 != f3[4] || null != b3 && !b3.pannable()) {
|
|
if (b3 && b3.pannable() && b3.active() && b3.unactivate(), b3 && b3.grabbed() || g3 == y3 || (y3 && r2(y3, ["mouseout", "tapdragout"], t3, { x: c3[0], y: c3[1] }), g3 && r2(g3, ["mouseover", "tapdragover"], t3, { x: c3[0], y: c3[1] }), e2.hoverData.last = g3), b3) if (v3) {
|
|
if (o3.boxSelectionEnabled() && D3) b3 && b3.grabbed() && (d2(w3), b3.emit("freeon"), w3.emit("free"), e2.dragData.didDrag && (b3.emit("dragfreeon"), w3.emit("dragfree"))), T3();
|
|
else if (b3 && b3.grabbed() && e2.nodeIsDraggable(b3)) {
|
|
var N3 = !e2.dragData.didDrag;
|
|
N3 && e2.redrawHint("eles", true), e2.dragData.didDrag = true, e2.hoverData.draggingEles || u2(w3, { inDragLayer: true });
|
|
var z3 = { x: 0, y: 0 };
|
|
if (m(x3[0]) && m(x3[1]) && (z3.x += x3[0], z3.y += x3[1], N3)) {
|
|
var I3 = e2.hoverData.dragDelta;
|
|
I3 && m(I3[0]) && m(I3[1]) && (z3.x += I3[0], z3.y += I3[1]);
|
|
}
|
|
e2.hoverData.draggingEles = true, w3.silentShift(z3).emit("position drag"), e2.redrawHint("drag", true), e2.redraw();
|
|
}
|
|
} else !function() {
|
|
var t4 = e2.hoverData.dragDelta = e2.hoverData.dragDelta || [];
|
|
0 === t4.length ? (t4.push(x3[0]), t4.push(x3[1])) : (t4[0] += x3[0], t4[1] += x3[1]);
|
|
}();
|
|
n3 = true;
|
|
} else if (v3) {
|
|
if (e2.hoverData.dragging || !o3.boxSelectionEnabled() || !D3 && o3.panningEnabled() && o3.userPanningEnabled()) {
|
|
if (!e2.hoverData.selecting && o3.panningEnabled() && o3.userPanningEnabled()) {
|
|
a2(b3, e2.hoverData.downs) && (e2.hoverData.dragging = true, e2.hoverData.justStartedPan = true, f3[4] = 0, e2.data.bgActivePosistion = yt(h3), e2.redrawHint("select", true), e2.redraw());
|
|
}
|
|
} else T3();
|
|
b3 && b3.pannable() && b3.active() && b3.unactivate();
|
|
}
|
|
return f3[2] = c3[0], f3[3] = c3[1], n3 ? (t3.stopPropagation && t3.stopPropagation(), t3.preventDefault && t3.preventDefault(), false) : void 0;
|
|
}
|
|
}, false), e2.registerBinding(t2, "mouseup", function(t3) {
|
|
if (e2.hoverData.capture) {
|
|
e2.hoverData.capture = false;
|
|
var a3 = e2.cy, o3 = e2.projectIntoViewport(t3.clientX, t3.clientY), s3 = e2.selection, l3 = e2.findNearestElement(o3[0], o3[1], true, false), u3 = e2.dragData.possibleDragElements, c3 = e2.hoverData.down, h3 = i2(t3);
|
|
if (e2.data.bgActivePosistion && (e2.redrawHint("select", true), e2.redraw()), e2.hoverData.tapholdCancelled = true, e2.data.bgActivePosistion = void 0, c3 && c3.unactivate(), 3 === e2.hoverData.which) {
|
|
var p3 = { originalEvent: t3, type: "cxttapend", position: { x: o3[0], y: o3[1] } };
|
|
if (c3 ? c3.emit(p3) : a3.emit(p3), !e2.hoverData.cxtDragged) {
|
|
var f3 = { originalEvent: t3, type: "cxttap", position: { x: o3[0], y: o3[1] } };
|
|
c3 ? c3.emit(f3) : a3.emit(f3);
|
|
}
|
|
e2.hoverData.cxtDragged = false, e2.hoverData.which = null;
|
|
} else if (1 === e2.hoverData.which) {
|
|
if (r2(l3, ["mouseup", "tapend", "vmouseup"], t3, { x: o3[0], y: o3[1] }), e2.dragData.didDrag || e2.hoverData.dragged || e2.hoverData.selecting || e2.hoverData.isOverThresholdDrag || (r2(c3, ["click", "tap", "vclick"], t3, { x: o3[0], y: o3[1] }), x2 = false, t3.timeStamp - w2 <= a3.multiClickDebounceTime() ? (b2 && clearTimeout(b2), x2 = true, w2 = null, r2(c3, ["dblclick", "dbltap", "vdblclick"], t3, { x: o3[0], y: o3[1] })) : (b2 = setTimeout(function() {
|
|
x2 || r2(c3, ["oneclick", "onetap", "voneclick"], t3, { x: o3[0], y: o3[1] });
|
|
}, a3.multiClickDebounceTime()), w2 = t3.timeStamp)), null != c3 || e2.dragData.didDrag || e2.hoverData.selecting || e2.hoverData.dragged || i2(t3) || (a3.$(n2).unselect(["tapunselect"]), u3.length > 0 && e2.redrawHint("eles", true), e2.dragData.possibleDragElements = u3 = a3.collection()), l3 != c3 || e2.dragData.didDrag || e2.hoverData.selecting || null != l3 && l3._private.selectable && (e2.hoverData.dragging || ("additive" === a3.selectionType() || h3 ? l3.selected() ? l3.unselect(["tapunselect"]) : l3.select(["tapselect"]) : h3 || (a3.$(n2).unmerge(l3).unselect(["tapunselect"]), l3.select(["tapselect"]))), e2.redrawHint("eles", true)), e2.hoverData.selecting) {
|
|
var g3 = a3.collection(e2.getAllInBox(s3[0], s3[1], s3[2], s3[3]));
|
|
e2.redrawHint("select", true), g3.length > 0 && e2.redrawHint("eles", true), a3.emit({ type: "boxend", originalEvent: t3, position: { x: o3[0], y: o3[1] } });
|
|
var v3 = function(e3) {
|
|
return e3.selectable() && !e3.selected();
|
|
};
|
|
"additive" === a3.selectionType() || h3 || a3.$(n2).unmerge(g3).unselect(), g3.emit("box").stdFilter(v3).select().emit("boxselect"), e2.redraw();
|
|
}
|
|
if (e2.hoverData.dragging && (e2.hoverData.dragging = false, e2.redrawHint("select", true), e2.redrawHint("eles", true), e2.redraw()), !s3[4]) {
|
|
e2.redrawHint("drag", true), e2.redrawHint("eles", true);
|
|
var y3 = c3 && c3.grabbed();
|
|
d2(u3), y3 && (c3.emit("freeon"), u3.emit("free"), e2.dragData.didDrag && (c3.emit("dragfreeon"), u3.emit("dragfree")));
|
|
}
|
|
}
|
|
s3[4] = 0, e2.hoverData.down = null, e2.hoverData.cxtStarted = false, e2.hoverData.draggingEles = false, e2.hoverData.selecting = false, e2.hoverData.isOverThresholdDrag = false, e2.dragData.didDrag = false, e2.hoverData.dragged = false, e2.hoverData.dragDelta = [], e2.hoverData.mdownPos = null, e2.hoverData.mdownGPos = null;
|
|
}
|
|
}, false);
|
|
var k2, C2, S2, P2, D2, T2, _2, M2, B2, N2, z2, I2, L3, A2 = function(t3) {
|
|
if (!e2.scrollingPage) {
|
|
var n3 = e2.cy, r3 = n3.zoom(), i3 = n3.pan(), a3 = e2.projectIntoViewport(t3.clientX, t3.clientY), o3 = [a3[0] * r3 + i3.x, a3[1] * r3 + i3.y];
|
|
if (e2.hoverData.draggingEles || e2.hoverData.dragging || e2.hoverData.cxtStarted || 0 !== e2.selection[4]) t3.preventDefault();
|
|
else if (n3.panningEnabled() && n3.userPanningEnabled() && n3.zoomingEnabled() && n3.userZoomingEnabled()) {
|
|
var s3;
|
|
t3.preventDefault(), e2.data.wheelZooming = true, clearTimeout(e2.data.wheelTimeout), e2.data.wheelTimeout = setTimeout(function() {
|
|
e2.data.wheelZooming = false, e2.redrawHint("eles", true), e2.redraw();
|
|
}, 150), s3 = null != t3.deltaY ? t3.deltaY / -250 : null != t3.wheelDeltaY ? t3.wheelDeltaY / 1e3 : t3.wheelDelta / 1e3, s3 *= e2.wheelSensitivity, 1 === t3.deltaMode && (s3 *= 33);
|
|
var l3 = n3.zoom() * Math.pow(10, s3);
|
|
"gesturechange" === t3.type && (l3 = e2.gestureStartZoom * t3.scale), n3.zoom({ level: l3, renderedPosition: { x: o3[0], y: o3[1] } }), n3.emit("gesturechange" === t3.type ? "pinchzoom" : "scrollzoom");
|
|
}
|
|
}
|
|
};
|
|
e2.registerBinding(e2.container, "wheel", A2, true), e2.registerBinding(t2, "scroll", function(t3) {
|
|
e2.scrollingPage = true, clearTimeout(e2.scrollingPageTimeout), e2.scrollingPageTimeout = setTimeout(function() {
|
|
e2.scrollingPage = false;
|
|
}, 250);
|
|
}, true), e2.registerBinding(e2.container, "gesturestart", function(t3) {
|
|
e2.gestureStartZoom = e2.cy.zoom(), e2.hasTouchStarted || t3.preventDefault();
|
|
}, true), e2.registerBinding(e2.container, "gesturechange", function(t3) {
|
|
e2.hasTouchStarted || A2(t3);
|
|
}, true), e2.registerBinding(e2.container, "mouseout", function(t3) {
|
|
var n3 = e2.projectIntoViewport(t3.clientX, t3.clientY);
|
|
e2.cy.emit({ originalEvent: t3, type: "mouseout", position: { x: n3[0], y: n3[1] } });
|
|
}, false), e2.registerBinding(e2.container, "mouseover", function(t3) {
|
|
var n3 = e2.projectIntoViewport(t3.clientX, t3.clientY);
|
|
e2.cy.emit({ originalEvent: t3, type: "mouseover", position: { x: n3[0], y: n3[1] } });
|
|
}, false);
|
|
var O2, R2, V2, F2, j2, q2, Y2, X2 = function(e3, t3, n3, r3) {
|
|
return Math.sqrt((n3 - e3) * (n3 - e3) + (r3 - t3) * (r3 - t3));
|
|
}, W2 = function(e3, t3, n3, r3) {
|
|
return (n3 - e3) * (n3 - e3) + (r3 - t3) * (r3 - t3);
|
|
};
|
|
if (e2.registerBinding(e2.container, "touchstart", O2 = function(t3) {
|
|
if (e2.hasTouchStarted = true, E2(t3)) {
|
|
p2(), e2.touchData.capture = true, e2.data.bgActivePosistion = void 0;
|
|
var n3 = e2.cy, i3 = e2.touchData.now, a3 = e2.touchData.earlier;
|
|
if (t3.touches[0]) {
|
|
var o3 = e2.projectIntoViewport(t3.touches[0].clientX, t3.touches[0].clientY);
|
|
i3[0] = o3[0], i3[1] = o3[1];
|
|
}
|
|
if (t3.touches[1]) {
|
|
o3 = e2.projectIntoViewport(t3.touches[1].clientX, t3.touches[1].clientY);
|
|
i3[2] = o3[0], i3[3] = o3[1];
|
|
}
|
|
if (t3.touches[2]) {
|
|
o3 = e2.projectIntoViewport(t3.touches[2].clientX, t3.touches[2].clientY);
|
|
i3[4] = o3[0], i3[5] = o3[1];
|
|
}
|
|
if (t3.touches[1]) {
|
|
e2.touchData.singleTouchMoved = true, d2(e2.dragData.touchDragEles);
|
|
var l3 = e2.findContainerClientCoords();
|
|
B2 = l3[0], N2 = l3[1], z2 = l3[2], I2 = l3[3], k2 = t3.touches[0].clientX - B2, C2 = t3.touches[0].clientY - N2, S2 = t3.touches[1].clientX - B2, P2 = t3.touches[1].clientY - N2, L3 = 0 <= k2 && k2 <= z2 && 0 <= S2 && S2 <= z2 && 0 <= C2 && C2 <= I2 && 0 <= P2 && P2 <= I2;
|
|
var h3 = n3.pan(), f3 = n3.zoom();
|
|
D2 = X2(k2, C2, S2, P2), T2 = W2(k2, C2, S2, P2), M2 = [((_2 = [(k2 + S2) / 2, (C2 + P2) / 2])[0] - h3.x) / f3, (_2[1] - h3.y) / f3];
|
|
if (T2 < 4e4 && !t3.touches[2]) {
|
|
var g3 = e2.findNearestElement(i3[0], i3[1], true, true), v3 = e2.findNearestElement(i3[2], i3[3], true, true);
|
|
return g3 && g3.isNode() ? (g3.activate().emit({ originalEvent: t3, type: "cxttapstart", position: { x: i3[0], y: i3[1] } }), e2.touchData.start = g3) : v3 && v3.isNode() ? (v3.activate().emit({ originalEvent: t3, type: "cxttapstart", position: { x: i3[0], y: i3[1] } }), e2.touchData.start = v3) : n3.emit({ originalEvent: t3, type: "cxttapstart", position: { x: i3[0], y: i3[1] } }), e2.touchData.start && (e2.touchData.start._private.grabbed = false), e2.touchData.cxt = true, e2.touchData.cxtDragged = false, e2.data.bgActivePosistion = void 0, void e2.redraw();
|
|
}
|
|
}
|
|
if (t3.touches[2]) n3.boxSelectionEnabled() && t3.preventDefault();
|
|
else if (t3.touches[1]) ;
|
|
else if (t3.touches[0]) {
|
|
var y3 = e2.findNearestElements(i3[0], i3[1], true, true), m2 = y3[0];
|
|
if (null != m2 && (m2.activate(), e2.touchData.start = m2, e2.touchData.starts = y3, e2.nodeIsGrabbable(m2))) {
|
|
var b3 = e2.dragData.touchDragEles = n3.collection(), x3 = null;
|
|
e2.redrawHint("eles", true), e2.redrawHint("drag", true), m2.selected() ? (x3 = n3.$(function(t4) {
|
|
return t4.selected() && e2.nodeIsGrabbable(t4);
|
|
}), u2(x3, { addToList: b3 })) : c2(m2, { addToList: b3 }), s2(m2);
|
|
var w3 = function(e3) {
|
|
return { originalEvent: t3, type: e3, position: { x: i3[0], y: i3[1] } };
|
|
};
|
|
m2.emit(w3("grabon")), x3 ? x3.forEach(function(e3) {
|
|
e3.emit(w3("grab"));
|
|
}) : m2.emit(w3("grab"));
|
|
}
|
|
r2(m2, ["touchstart", "tapstart", "vmousedown"], t3, { x: i3[0], y: i3[1] }), null == m2 && (e2.data.bgActivePosistion = { x: o3[0], y: o3[1] }, e2.redrawHint("select", true), e2.redraw()), e2.touchData.singleTouchMoved = false, e2.touchData.singleTouchStartTime = +/* @__PURE__ */ new Date(), clearTimeout(e2.touchData.tapholdTimeout), e2.touchData.tapholdTimeout = setTimeout(function() {
|
|
false !== e2.touchData.singleTouchMoved || e2.pinching || e2.touchData.selecting || r2(e2.touchData.start, ["taphold"], t3, { x: i3[0], y: i3[1] });
|
|
}, e2.tapholdDuration);
|
|
}
|
|
if (t3.touches.length >= 1) {
|
|
for (var A3 = e2.touchData.startPosition = [null, null, null, null, null, null], O3 = 0; O3 < i3.length; O3++) A3[O3] = a3[O3] = i3[O3];
|
|
var R3 = t3.touches[0];
|
|
e2.touchData.startGPosition = [R3.clientX, R3.clientY];
|
|
}
|
|
}
|
|
}, false), e2.registerBinding(window, "touchmove", R2 = function(t3) {
|
|
var n3 = e2.touchData.capture;
|
|
if (n3 || E2(t3)) {
|
|
var i3 = e2.selection, o3 = e2.cy, s3 = e2.touchData.now, l3 = e2.touchData.earlier, c3 = o3.zoom();
|
|
if (t3.touches[0]) {
|
|
var h3 = e2.projectIntoViewport(t3.touches[0].clientX, t3.touches[0].clientY);
|
|
s3[0] = h3[0], s3[1] = h3[1];
|
|
}
|
|
if (t3.touches[1]) {
|
|
h3 = e2.projectIntoViewport(t3.touches[1].clientX, t3.touches[1].clientY);
|
|
s3[2] = h3[0], s3[3] = h3[1];
|
|
}
|
|
if (t3.touches[2]) {
|
|
h3 = e2.projectIntoViewport(t3.touches[2].clientX, t3.touches[2].clientY);
|
|
s3[4] = h3[0], s3[5] = h3[1];
|
|
}
|
|
var p3, f3 = e2.touchData.startGPosition;
|
|
if (n3 && t3.touches[0] && f3) {
|
|
for (var g3 = [], v3 = 0; v3 < s3.length; v3++) g3[v3] = s3[v3] - l3[v3];
|
|
var y3 = t3.touches[0].clientX - f3[0], b3 = y3 * y3, x3 = t3.touches[0].clientY - f3[1];
|
|
p3 = b3 + x3 * x3 >= e2.touchTapThreshold2;
|
|
}
|
|
if (n3 && e2.touchData.cxt) {
|
|
t3.preventDefault();
|
|
var w3 = t3.touches[0].clientX - B2, _3 = t3.touches[0].clientY - N2, z3 = t3.touches[1].clientX - B2, I3 = t3.touches[1].clientY - N2, A3 = W2(w3, _3, z3, I3);
|
|
if (A3 / T2 >= 2.25 || A3 >= 22500) {
|
|
e2.touchData.cxt = false, e2.data.bgActivePosistion = void 0, e2.redrawHint("select", true);
|
|
var O3 = { originalEvent: t3, type: "cxttapend", position: { x: s3[0], y: s3[1] } };
|
|
e2.touchData.start ? (e2.touchData.start.unactivate().emit(O3), e2.touchData.start = null) : o3.emit(O3);
|
|
}
|
|
}
|
|
if (n3 && e2.touchData.cxt) {
|
|
O3 = { originalEvent: t3, type: "cxtdrag", position: { x: s3[0], y: s3[1] } };
|
|
e2.data.bgActivePosistion = void 0, e2.redrawHint("select", true), e2.touchData.start ? e2.touchData.start.emit(O3) : o3.emit(O3), e2.touchData.start && (e2.touchData.start._private.grabbed = false), e2.touchData.cxtDragged = true;
|
|
var R3 = e2.findNearestElement(s3[0], s3[1], true, true);
|
|
e2.touchData.cxtOver && R3 === e2.touchData.cxtOver || (e2.touchData.cxtOver && e2.touchData.cxtOver.emit({ originalEvent: t3, type: "cxtdragout", position: { x: s3[0], y: s3[1] } }), e2.touchData.cxtOver = R3, R3 && R3.emit({ originalEvent: t3, type: "cxtdragover", position: { x: s3[0], y: s3[1] } }));
|
|
} else if (n3 && t3.touches[2] && o3.boxSelectionEnabled()) t3.preventDefault(), e2.data.bgActivePosistion = void 0, this.lastThreeTouch = +/* @__PURE__ */ new Date(), e2.touchData.selecting || o3.emit({ originalEvent: t3, type: "boxstart", position: { x: s3[0], y: s3[1] } }), e2.touchData.selecting = true, e2.touchData.didSelect = true, i3[4] = 1, i3 && 0 !== i3.length && void 0 !== i3[0] ? (i3[2] = (s3[0] + s3[2] + s3[4]) / 3, i3[3] = (s3[1] + s3[3] + s3[5]) / 3) : (i3[0] = (s3[0] + s3[2] + s3[4]) / 3, i3[1] = (s3[1] + s3[3] + s3[5]) / 3, i3[2] = (s3[0] + s3[2] + s3[4]) / 3 + 1, i3[3] = (s3[1] + s3[3] + s3[5]) / 3 + 1), e2.redrawHint("select", true), e2.redraw();
|
|
else if (n3 && t3.touches[1] && !e2.touchData.didSelect && o3.zoomingEnabled() && o3.panningEnabled() && o3.userZoomingEnabled() && o3.userPanningEnabled()) {
|
|
if (t3.preventDefault(), e2.data.bgActivePosistion = void 0, e2.redrawHint("select", true), ee2 = e2.dragData.touchDragEles) {
|
|
e2.redrawHint("drag", true);
|
|
for (var V3 = 0; V3 < ee2.length; V3++) {
|
|
var F3 = ee2[V3]._private;
|
|
F3.grabbed = false, F3.rscratch.inDragLayer = false;
|
|
}
|
|
}
|
|
var j3 = e2.touchData.start, q3 = (w3 = t3.touches[0].clientX - B2, _3 = t3.touches[0].clientY - N2, z3 = t3.touches[1].clientX - B2, I3 = t3.touches[1].clientY - N2, X2(w3, _3, z3, I3)), Y3 = q3 / D2;
|
|
if (L3) {
|
|
var H3 = (w3 - k2 + (z3 - S2)) / 2, K3 = (_3 - C2 + (I3 - P2)) / 2, G3 = o3.zoom(), U3 = G3 * Y3, Z3 = o3.pan(), $3 = M2[0] * G3 + Z3.x, Q2 = M2[1] * G3 + Z3.y, J2 = { x: -U3 / G3 * ($3 - Z3.x - H3) + $3, y: -U3 / G3 * (Q2 - Z3.y - K3) + Q2 };
|
|
if (j3 && j3.active()) {
|
|
var ee2 = e2.dragData.touchDragEles;
|
|
d2(ee2), e2.redrawHint("drag", true), e2.redrawHint("eles", true), j3.unactivate().emit("freeon"), ee2.emit("free"), e2.dragData.didDrag && (j3.emit("dragfreeon"), ee2.emit("dragfree"));
|
|
}
|
|
o3.viewport({ zoom: U3, pan: J2, cancelOnFailedZoom: true }), o3.emit("pinchzoom"), D2 = q3, k2 = w3, C2 = _3, S2 = z3, P2 = I3, e2.pinching = true;
|
|
}
|
|
if (t3.touches[0]) {
|
|
h3 = e2.projectIntoViewport(t3.touches[0].clientX, t3.touches[0].clientY);
|
|
s3[0] = h3[0], s3[1] = h3[1];
|
|
}
|
|
if (t3.touches[1]) {
|
|
h3 = e2.projectIntoViewport(t3.touches[1].clientX, t3.touches[1].clientY);
|
|
s3[2] = h3[0], s3[3] = h3[1];
|
|
}
|
|
if (t3.touches[2]) {
|
|
h3 = e2.projectIntoViewport(t3.touches[2].clientX, t3.touches[2].clientY);
|
|
s3[4] = h3[0], s3[5] = h3[1];
|
|
}
|
|
} else if (t3.touches[0] && !e2.touchData.didSelect) {
|
|
var te2 = e2.touchData.start, ne2 = e2.touchData.last;
|
|
if (e2.hoverData.draggingEles || e2.swipePanning || (R3 = e2.findNearestElement(s3[0], s3[1], true, true)), n3 && null != te2 && t3.preventDefault(), n3 && null != te2 && e2.nodeIsDraggable(te2)) if (p3) {
|
|
ee2 = e2.dragData.touchDragEles;
|
|
var re2 = !e2.dragData.didDrag;
|
|
re2 && u2(ee2, { inDragLayer: true }), e2.dragData.didDrag = true;
|
|
var ie2 = { x: 0, y: 0 };
|
|
if (m(g3[0]) && m(g3[1])) {
|
|
if (ie2.x += g3[0], ie2.y += g3[1], re2) e2.redrawHint("eles", true), (ae2 = e2.touchData.dragDelta) && m(ae2[0]) && m(ae2[1]) && (ie2.x += ae2[0], ie2.y += ae2[1]);
|
|
}
|
|
e2.hoverData.draggingEles = true, ee2.silentShift(ie2).emit("position drag"), e2.redrawHint("drag", true), e2.touchData.startPosition[0] == l3[0] && e2.touchData.startPosition[1] == l3[1] && e2.redrawHint("eles", true), e2.redraw();
|
|
} else {
|
|
var ae2;
|
|
0 === (ae2 = e2.touchData.dragDelta = e2.touchData.dragDelta || []).length ? (ae2.push(g3[0]), ae2.push(g3[1])) : (ae2[0] += g3[0], ae2[1] += g3[1]);
|
|
}
|
|
if (r2(te2 || R3, ["touchmove", "tapdrag", "vmousemove"], t3, { x: s3[0], y: s3[1] }), te2 && te2.grabbed() || R3 == ne2 || (ne2 && ne2.emit({ originalEvent: t3, type: "tapdragout", position: { x: s3[0], y: s3[1] } }), R3 && R3.emit({ originalEvent: t3, type: "tapdragover", position: { x: s3[0], y: s3[1] } })), e2.touchData.last = R3, n3) for (V3 = 0; V3 < s3.length; V3++) s3[V3] && e2.touchData.startPosition[V3] && p3 && (e2.touchData.singleTouchMoved = true);
|
|
if (n3 && (null == te2 || te2.pannable()) && o3.panningEnabled() && o3.userPanningEnabled()) {
|
|
a2(te2, e2.touchData.starts) && (t3.preventDefault(), e2.data.bgActivePosistion || (e2.data.bgActivePosistion = yt(e2.touchData.startPosition)), e2.swipePanning ? (o3.panBy({ x: g3[0] * c3, y: g3[1] * c3 }), o3.emit("dragpan")) : p3 && (e2.swipePanning = true, o3.panBy({ x: y3 * c3, y: x3 * c3 }), o3.emit("dragpan"), te2 && (te2.unactivate(), e2.redrawHint("select", true), e2.touchData.start = null)));
|
|
h3 = e2.projectIntoViewport(t3.touches[0].clientX, t3.touches[0].clientY);
|
|
s3[0] = h3[0], s3[1] = h3[1];
|
|
}
|
|
}
|
|
for (v3 = 0; v3 < s3.length; v3++) l3[v3] = s3[v3];
|
|
n3 && t3.touches.length > 0 && !e2.hoverData.draggingEles && !e2.swipePanning && null != e2.data.bgActivePosistion && (e2.data.bgActivePosistion = void 0, e2.redrawHint("select", true), e2.redraw());
|
|
}
|
|
}, false), e2.registerBinding(t2, "touchcancel", V2 = function(t3) {
|
|
var n3 = e2.touchData.start;
|
|
e2.touchData.capture = false, n3 && n3.unactivate();
|
|
}), e2.registerBinding(t2, "touchend", F2 = function(t3) {
|
|
var i3 = e2.touchData.start;
|
|
if (e2.touchData.capture) {
|
|
0 === t3.touches.length && (e2.touchData.capture = false), t3.preventDefault();
|
|
var a3 = e2.selection;
|
|
e2.swipePanning = false, e2.hoverData.draggingEles = false;
|
|
var o3, s3 = e2.cy, l3 = s3.zoom(), u3 = e2.touchData.now, c3 = e2.touchData.earlier;
|
|
if (t3.touches[0]) {
|
|
var h3 = e2.projectIntoViewport(t3.touches[0].clientX, t3.touches[0].clientY);
|
|
u3[0] = h3[0], u3[1] = h3[1];
|
|
}
|
|
if (t3.touches[1]) {
|
|
h3 = e2.projectIntoViewport(t3.touches[1].clientX, t3.touches[1].clientY);
|
|
u3[2] = h3[0], u3[3] = h3[1];
|
|
}
|
|
if (t3.touches[2]) {
|
|
h3 = e2.projectIntoViewport(t3.touches[2].clientX, t3.touches[2].clientY);
|
|
u3[4] = h3[0], u3[5] = h3[1];
|
|
}
|
|
if (i3 && i3.unactivate(), e2.touchData.cxt) {
|
|
if (o3 = { originalEvent: t3, type: "cxttapend", position: { x: u3[0], y: u3[1] } }, i3 ? i3.emit(o3) : s3.emit(o3), !e2.touchData.cxtDragged) {
|
|
var p3 = { originalEvent: t3, type: "cxttap", position: { x: u3[0], y: u3[1] } };
|
|
i3 ? i3.emit(p3) : s3.emit(p3);
|
|
}
|
|
return e2.touchData.start && (e2.touchData.start._private.grabbed = false), e2.touchData.cxt = false, e2.touchData.start = null, void e2.redraw();
|
|
}
|
|
if (!t3.touches[2] && s3.boxSelectionEnabled() && e2.touchData.selecting) {
|
|
e2.touchData.selecting = false;
|
|
var f3 = s3.collection(e2.getAllInBox(a3[0], a3[1], a3[2], a3[3]));
|
|
a3[0] = void 0, a3[1] = void 0, a3[2] = void 0, a3[3] = void 0, a3[4] = 0, e2.redrawHint("select", true), s3.emit({ type: "boxend", originalEvent: t3, position: { x: u3[0], y: u3[1] } });
|
|
f3.emit("box").stdFilter(function(e3) {
|
|
return e3.selectable() && !e3.selected();
|
|
}).select().emit("boxselect"), f3.nonempty() && e2.redrawHint("eles", true), e2.redraw();
|
|
}
|
|
if (null != i3 && i3.unactivate(), t3.touches[2]) e2.data.bgActivePosistion = void 0, e2.redrawHint("select", true);
|
|
else if (t3.touches[1]) ;
|
|
else if (t3.touches[0]) ;
|
|
else if (!t3.touches[0]) {
|
|
e2.data.bgActivePosistion = void 0, e2.redrawHint("select", true);
|
|
var g3 = e2.dragData.touchDragEles;
|
|
if (null != i3) {
|
|
var v3 = i3._private.grabbed;
|
|
d2(g3), e2.redrawHint("drag", true), e2.redrawHint("eles", true), v3 && (i3.emit("freeon"), g3.emit("free"), e2.dragData.didDrag && (i3.emit("dragfreeon"), g3.emit("dragfree"))), r2(i3, ["touchend", "tapend", "vmouseup", "tapdragout"], t3, { x: u3[0], y: u3[1] }), i3.unactivate(), e2.touchData.start = null;
|
|
} else {
|
|
var y3 = e2.findNearestElement(u3[0], u3[1], true, true);
|
|
r2(y3, ["touchend", "tapend", "vmouseup", "tapdragout"], t3, { x: u3[0], y: u3[1] });
|
|
}
|
|
var m2 = e2.touchData.startPosition[0] - u3[0], b3 = m2 * m2, x3 = e2.touchData.startPosition[1] - u3[1], w3 = (b3 + x3 * x3) * l3 * l3;
|
|
e2.touchData.singleTouchMoved || (i3 || s3.$(":selected").unselect(["tapunselect"]), r2(i3, ["tap", "vclick"], t3, { x: u3[0], y: u3[1] }), j2 = false, t3.timeStamp - Y2 <= s3.multiClickDebounceTime() ? (q2 && clearTimeout(q2), j2 = true, Y2 = null, r2(i3, ["dbltap", "vdblclick"], t3, { x: u3[0], y: u3[1] })) : (q2 = setTimeout(function() {
|
|
j2 || r2(i3, ["onetap", "voneclick"], t3, { x: u3[0], y: u3[1] });
|
|
}, s3.multiClickDebounceTime()), Y2 = t3.timeStamp)), null != i3 && !e2.dragData.didDrag && i3._private.selectable && w3 < e2.touchTapThreshold2 && !e2.pinching && ("single" === s3.selectionType() ? (s3.$(n2).unmerge(i3).unselect(["tapunselect"]), i3.select(["tapselect"])) : i3.selected() ? i3.unselect(["tapunselect"]) : i3.select(["tapselect"]), e2.redrawHint("eles", true)), e2.touchData.singleTouchMoved = true;
|
|
}
|
|
for (var E3 = 0; E3 < u3.length; E3++) c3[E3] = u3[E3];
|
|
e2.dragData.didDrag = false, 0 === t3.touches.length && (e2.touchData.dragDelta = [], e2.touchData.startPosition = [null, null, null, null, null, null], e2.touchData.startGPosition = null, e2.touchData.didSelect = false), t3.touches.length < 2 && (1 === t3.touches.length && (e2.touchData.startGPosition = [t3.touches[0].clientX, t3.touches[0].clientY]), e2.pinching = false, e2.redrawHint("eles", true), e2.redraw());
|
|
}
|
|
}, false), "undefined" == typeof TouchEvent) {
|
|
var H2 = [], K2 = function(e3) {
|
|
return { clientX: e3.clientX, clientY: e3.clientY, force: 1, identifier: e3.pointerId, pageX: e3.pageX, pageY: e3.pageY, radiusX: e3.width / 2, radiusY: e3.height / 2, screenX: e3.screenX, screenY: e3.screenY, target: e3.target };
|
|
}, G2 = function(e3) {
|
|
H2.push(function(e4) {
|
|
return { event: e4, touch: K2(e4) };
|
|
}(e3));
|
|
}, U2 = function(e3) {
|
|
for (var t3 = 0; t3 < H2.length; t3++) {
|
|
if (H2[t3].event.pointerId === e3.pointerId) return void H2.splice(t3, 1);
|
|
}
|
|
}, Z2 = function(e3) {
|
|
e3.touches = H2.map(function(e4) {
|
|
return e4.touch;
|
|
});
|
|
}, $2 = function(e3) {
|
|
return "mouse" === e3.pointerType || 4 === e3.pointerType;
|
|
};
|
|
e2.registerBinding(e2.container, "pointerdown", function(e3) {
|
|
$2(e3) || (e3.preventDefault(), G2(e3), Z2(e3), O2(e3));
|
|
}), e2.registerBinding(e2.container, "pointerup", function(e3) {
|
|
$2(e3) || (U2(e3), Z2(e3), F2(e3));
|
|
}), e2.registerBinding(e2.container, "pointercancel", function(e3) {
|
|
$2(e3) || (U2(e3), Z2(e3), V2());
|
|
}), e2.registerBinding(e2.container, "pointermove", function(e3) {
|
|
$2(e3) || (e3.preventDefault(), function(e4) {
|
|
var t3 = H2.filter(function(t4) {
|
|
return t4.event.pointerId === e4.pointerId;
|
|
})[0];
|
|
t3.event = e4, t3.touch = K2(e4);
|
|
}(e3), Z2(e3), R2(e3));
|
|
});
|
|
}
|
|
};
|
|
var Yl = { generatePolygon: function(e2, t2) {
|
|
return this.nodeShapes[e2] = { renderer: this, name: e2, points: t2, draw: function(e3, t3, n2, r2, i2) {
|
|
this.renderer.nodeShapeImpl("polygon", e3, t3, n2, r2, i2, this.points);
|
|
}, intersectLine: function(e3, t3, n2, r2, i2, a2, o2) {
|
|
return Ut(i2, a2, this.points, e3, t3, n2 / 2, r2 / 2, o2);
|
|
}, checkPoint: function(e3, t3, n2, r2, i2, a2, o2) {
|
|
return qt(e3, t3, this.points, a2, o2, r2, i2, [0, -1], n2);
|
|
} };
|
|
} };
|
|
Yl.generateEllipse = function() {
|
|
return this.nodeShapes.ellipse = { renderer: this, name: "ellipse", draw: function(e2, t2, n2, r2, i2) {
|
|
this.renderer.nodeShapeImpl(this.name, e2, t2, n2, r2, i2);
|
|
}, intersectLine: function(e2, t2, n2, r2, i2, a2, o2) {
|
|
return function(e3, t3, n3, r3, i3, a3) {
|
|
var o3 = n3 - e3, s2 = r3 - t3;
|
|
o3 /= i3, s2 /= a3;
|
|
var l2 = Math.sqrt(o3 * o3 + s2 * s2), u2 = l2 - 1;
|
|
if (u2 < 0) return [];
|
|
var c2 = u2 / l2;
|
|
return [(n3 - e3) * c2 + e3, (r3 - t3) * c2 + t3];
|
|
}(i2, a2, e2, t2, n2 / 2 + o2, r2 / 2 + o2);
|
|
}, checkPoint: function(e2, t2, n2, r2, i2, a2, o2) {
|
|
return Wt(e2, t2, r2, i2, a2, o2, n2);
|
|
} };
|
|
}, Yl.generateRoundPolygon = function(e2, t2) {
|
|
for (var n2 = new Array(2 * t2.length), r2 = 0; r2 < t2.length / 2; r2++) {
|
|
var i2 = 2 * r2, a2 = void 0;
|
|
a2 = r2 < t2.length / 2 - 1 ? 2 * (r2 + 1) : 0, n2[4 * r2] = t2[i2], n2[4 * r2 + 1] = t2[i2 + 1];
|
|
var o2 = t2[a2] - t2[i2], s2 = t2[a2 + 1] - t2[i2 + 1], l2 = Math.sqrt(o2 * o2 + s2 * s2);
|
|
n2[4 * r2 + 2] = o2 / l2, n2[4 * r2 + 3] = s2 / l2;
|
|
}
|
|
return this.nodeShapes[e2] = { renderer: this, name: e2, points: n2, draw: function(e3, t3, n3, r3, i3) {
|
|
this.renderer.nodeShapeImpl("round-polygon", e3, t3, n3, r3, i3, this.points);
|
|
}, intersectLine: function(e3, t3, n3, r3, i3, a3, o3) {
|
|
return function(e4, t4, n4, r4, i4, a4, o4, s3) {
|
|
for (var l3, u2 = [], c2 = new Array(n4.length), d2 = a4 / 2, h2 = o4 / 2, p2 = tn(a4, o4), f2 = 0; f2 < n4.length / 4; f2++) {
|
|
var g2, v2 = void 0;
|
|
v2 = 0 === f2 ? n4.length - 2 : 4 * f2 - 2, g2 = 4 * f2 + 2;
|
|
var y2 = r4 + d2 * n4[4 * f2], m2 = i4 + h2 * n4[4 * f2 + 1], b2 = -n4[v2] * n4[g2] - n4[v2 + 1] * n4[g2 + 1], x2 = p2 / Math.tan(Math.acos(b2) / 2), w2 = y2 - x2 * n4[v2], E2 = m2 - x2 * n4[v2 + 1], k2 = y2 + x2 * n4[g2], C2 = m2 + x2 * n4[g2 + 1];
|
|
0 === f2 ? (c2[n4.length - 2] = w2, c2[n4.length - 1] = E2) : (c2[4 * f2 - 2] = w2, c2[4 * f2 - 1] = E2), c2[4 * f2] = k2, c2[4 * f2 + 1] = C2;
|
|
var S2 = n4[v2 + 1], P2 = -n4[v2];
|
|
S2 * n4[g2] + P2 * n4[g2 + 1] < 0 && (S2 *= -1, P2 *= -1), 0 !== (l3 = Ht(e4, t4, r4, i4, w2 + S2 * p2, E2 + P2 * p2, p2)).length && u2.push(l3[0], l3[1]);
|
|
}
|
|
for (var D2 = 0; D2 < c2.length / 4; D2++) 0 !== (l3 = Gt(e4, t4, r4, i4, c2[4 * D2], c2[4 * D2 + 1], c2[4 * D2 + 2], c2[4 * D2 + 3], false)).length && u2.push(l3[0], l3[1]);
|
|
if (u2.length > 2) {
|
|
for (var T2 = [u2[0], u2[1]], _2 = Math.pow(T2[0] - e4, 2) + Math.pow(T2[1] - t4, 2), M2 = 1; M2 < u2.length / 2; M2++) {
|
|
var B2 = Math.pow(u2[2 * M2] - e4, 2) + Math.pow(u2[2 * M2 + 1] - t4, 2);
|
|
B2 <= _2 && (T2[0] = u2[2 * M2], T2[1] = u2[2 * M2 + 1], _2 = B2);
|
|
}
|
|
return T2;
|
|
}
|
|
return u2;
|
|
}(i3, a3, this.points, e3, t3, n3, r3);
|
|
}, checkPoint: function(e3, t3, n3, r3, i3, a3, o3) {
|
|
return function(e4, t4, n4, r4, i4, a4, o4) {
|
|
for (var s3 = new Array(n4.length), l3 = a4 / 2, u2 = o4 / 2, c2 = tn(a4, o4), d2 = c2 * c2, h2 = 0; h2 < n4.length / 4; h2++) {
|
|
var p2, f2 = void 0;
|
|
f2 = 0 === h2 ? n4.length - 2 : 4 * h2 - 2, p2 = 4 * h2 + 2;
|
|
var g2 = r4 + l3 * n4[4 * h2], v2 = i4 + u2 * n4[4 * h2 + 1], y2 = -n4[f2] * n4[p2] - n4[f2 + 1] * n4[p2 + 1], m2 = c2 / Math.tan(Math.acos(y2) / 2), b2 = g2 - m2 * n4[f2], x2 = v2 - m2 * n4[f2 + 1], w2 = g2 + m2 * n4[p2], E2 = v2 + m2 * n4[p2 + 1];
|
|
s3[4 * h2] = b2, s3[4 * h2 + 1] = x2, s3[4 * h2 + 2] = w2, s3[4 * h2 + 3] = E2;
|
|
var k2 = n4[f2 + 1], C2 = -n4[f2];
|
|
k2 * n4[p2] + C2 * n4[p2 + 1] < 0 && (k2 *= -1, C2 *= -1);
|
|
var S2 = b2 + k2 * c2, P2 = x2 + C2 * c2;
|
|
if (Math.pow(S2 - e4, 2) + Math.pow(P2 - t4, 2) <= d2) return true;
|
|
}
|
|
return jt(e4, t4, s3);
|
|
}(e3, t3, this.points, a3, o3, r3, i3);
|
|
} };
|
|
}, Yl.generateRoundRectangle = function() {
|
|
return this.nodeShapes["round-rectangle"] = this.nodeShapes.roundrectangle = { renderer: this, name: "round-rectangle", points: $t(4, 0), draw: function(e2, t2, n2, r2, i2) {
|
|
this.renderer.nodeShapeImpl(this.name, e2, t2, n2, r2, i2);
|
|
}, intersectLine: function(e2, t2, n2, r2, i2, a2, o2) {
|
|
return At(i2, a2, e2, t2, n2, r2, o2);
|
|
}, checkPoint: function(e2, t2, n2, r2, i2, a2, o2) {
|
|
var s2 = en(r2, i2), l2 = 2 * s2;
|
|
return !!qt(e2, t2, this.points, a2, o2, r2, i2 - l2, [0, -1], n2) || (!!qt(e2, t2, this.points, a2, o2, r2 - l2, i2, [0, -1], n2) || (!!Wt(e2, t2, l2, l2, a2 - r2 / 2 + s2, o2 - i2 / 2 + s2, n2) || (!!Wt(e2, t2, l2, l2, a2 + r2 / 2 - s2, o2 - i2 / 2 + s2, n2) || (!!Wt(e2, t2, l2, l2, a2 + r2 / 2 - s2, o2 + i2 / 2 - s2, n2) || !!Wt(e2, t2, l2, l2, a2 - r2 / 2 + s2, o2 + i2 / 2 - s2, n2)))));
|
|
} };
|
|
}, Yl.generateCutRectangle = function() {
|
|
return this.nodeShapes["cut-rectangle"] = this.nodeShapes.cutrectangle = { renderer: this, name: "cut-rectangle", cornerLength: 8, points: $t(4, 0), draw: function(e2, t2, n2, r2, i2) {
|
|
this.renderer.nodeShapeImpl(this.name, e2, t2, n2, r2, i2);
|
|
}, generateCutTrianglePts: function(e2, t2, n2, r2) {
|
|
var i2 = this.cornerLength, a2 = t2 / 2, o2 = e2 / 2, s2 = n2 - o2, l2 = n2 + o2, u2 = r2 - a2, c2 = r2 + a2;
|
|
return { topLeft: [s2, u2 + i2, s2 + i2, u2, s2 + i2, u2 + i2], topRight: [l2 - i2, u2, l2, u2 + i2, l2 - i2, u2 + i2], bottomRight: [l2, c2 - i2, l2 - i2, c2, l2 - i2, c2 - i2], bottomLeft: [s2 + i2, c2, s2, c2 - i2, s2 + i2, c2 - i2] };
|
|
}, intersectLine: function(e2, t2, n2, r2, i2, a2, o2) {
|
|
var s2 = this.generateCutTrianglePts(n2 + 2 * o2, r2 + 2 * o2, e2, t2), l2 = [].concat.apply([], [s2.topLeft.splice(0, 4), s2.topRight.splice(0, 4), s2.bottomRight.splice(0, 4), s2.bottomLeft.splice(0, 4)]);
|
|
return Ut(i2, a2, l2, e2, t2);
|
|
}, checkPoint: function(e2, t2, n2, r2, i2, a2, o2) {
|
|
if (qt(e2, t2, this.points, a2, o2, r2, i2 - 2 * this.cornerLength, [0, -1], n2)) return true;
|
|
if (qt(e2, t2, this.points, a2, o2, r2 - 2 * this.cornerLength, i2, [0, -1], n2)) return true;
|
|
var s2 = this.generateCutTrianglePts(r2, i2, a2, o2);
|
|
return jt(e2, t2, s2.topLeft) || jt(e2, t2, s2.topRight) || jt(e2, t2, s2.bottomRight) || jt(e2, t2, s2.bottomLeft);
|
|
} };
|
|
}, Yl.generateBarrel = function() {
|
|
return this.nodeShapes.barrel = { renderer: this, name: "barrel", points: $t(4, 0), draw: function(e2, t2, n2, r2, i2) {
|
|
this.renderer.nodeShapeImpl(this.name, e2, t2, n2, r2, i2);
|
|
}, intersectLine: function(e2, t2, n2, r2, i2, a2, o2) {
|
|
var s2 = this.generateBarrelBezierPts(n2 + 2 * o2, r2 + 2 * o2, e2, t2), l2 = function(e3) {
|
|
var t3 = St({ x: e3[0], y: e3[1] }, { x: e3[2], y: e3[3] }, { x: e3[4], y: e3[5] }, 0.15), n3 = St({ x: e3[0], y: e3[1] }, { x: e3[2], y: e3[3] }, { x: e3[4], y: e3[5] }, 0.5), r3 = St({ x: e3[0], y: e3[1] }, { x: e3[2], y: e3[3] }, { x: e3[4], y: e3[5] }, 0.85);
|
|
return [e3[0], e3[1], t3.x, t3.y, n3.x, n3.y, r3.x, r3.y, e3[4], e3[5]];
|
|
}, u2 = [].concat(l2(s2.topLeft), l2(s2.topRight), l2(s2.bottomRight), l2(s2.bottomLeft));
|
|
return Ut(i2, a2, u2, e2, t2);
|
|
}, generateBarrelBezierPts: function(e2, t2, n2, r2) {
|
|
var i2 = t2 / 2, a2 = e2 / 2, o2 = n2 - a2, s2 = n2 + a2, l2 = r2 - i2, u2 = r2 + i2, c2 = nn(e2, t2), d2 = c2.heightOffset, h2 = c2.widthOffset, p2 = c2.ctrlPtOffsetPct * e2, f2 = { topLeft: [o2, l2 + d2, o2 + p2, l2, o2 + h2, l2], topRight: [s2 - h2, l2, s2 - p2, l2, s2, l2 + d2], bottomRight: [s2, u2 - d2, s2 - p2, u2, s2 - h2, u2], bottomLeft: [o2 + h2, u2, o2 + p2, u2, o2, u2 - d2] };
|
|
return f2.topLeft.isTop = true, f2.topRight.isTop = true, f2.bottomLeft.isBottom = true, f2.bottomRight.isBottom = true, f2;
|
|
}, checkPoint: function(e2, t2, n2, r2, i2, a2, o2) {
|
|
var s2 = nn(r2, i2), l2 = s2.heightOffset, u2 = s2.widthOffset;
|
|
if (qt(e2, t2, this.points, a2, o2, r2, i2 - 2 * l2, [0, -1], n2)) return true;
|
|
if (qt(e2, t2, this.points, a2, o2, r2 - 2 * u2, i2, [0, -1], n2)) return true;
|
|
for (var c2 = this.generateBarrelBezierPts(r2, i2, a2, o2), d2 = function(e3, t3, n3) {
|
|
var r3, i3, a3 = n3[4], o3 = n3[2], s3 = n3[0], l3 = n3[5], u3 = n3[1], c3 = Math.min(a3, s3), d3 = Math.max(a3, s3), h3 = Math.min(l3, u3), p3 = Math.max(l3, u3);
|
|
if (c3 <= e3 && e3 <= d3 && h3 <= t3 && t3 <= p3) {
|
|
var f3 = [(r3 = a3) - 2 * (i3 = o3) + s3, 2 * (i3 - r3), r3], g3 = function(e4, t4, n4, r4) {
|
|
var i4 = t4 * t4 - 4 * e4 * (n4 -= r4);
|
|
if (i4 < 0) return [];
|
|
var a4 = Math.sqrt(i4), o4 = 2 * e4;
|
|
return [(-t4 + a4) / o4, (-t4 - a4) / o4];
|
|
}(f3[0], f3[1], f3[2], e3).filter(function(e4) {
|
|
return 0 <= e4 && e4 <= 1;
|
|
});
|
|
if (g3.length > 0) return g3[0];
|
|
}
|
|
return null;
|
|
}, h2 = Object.keys(c2), p2 = 0; p2 < h2.length; p2++) {
|
|
var f2 = c2[h2[p2]], g2 = d2(e2, t2, f2);
|
|
if (null != g2) {
|
|
var v2 = f2[5], y2 = f2[3], m2 = f2[1], b2 = Ct(v2, y2, m2, g2);
|
|
if (f2.isTop && b2 <= t2) return true;
|
|
if (f2.isBottom && t2 <= b2) return true;
|
|
}
|
|
}
|
|
return false;
|
|
} };
|
|
}, Yl.generateBottomRoundrectangle = function() {
|
|
return this.nodeShapes["bottom-round-rectangle"] = this.nodeShapes.bottomroundrectangle = { renderer: this, name: "bottom-round-rectangle", points: $t(4, 0), draw: function(e2, t2, n2, r2, i2) {
|
|
this.renderer.nodeShapeImpl(this.name, e2, t2, n2, r2, i2);
|
|
}, intersectLine: function(e2, t2, n2, r2, i2, a2, o2) {
|
|
var s2 = t2 - (r2 / 2 + o2), l2 = Gt(i2, a2, e2, t2, e2 - (n2 / 2 + o2), s2, e2 + (n2 / 2 + o2), s2, false);
|
|
return l2.length > 0 ? l2 : At(i2, a2, e2, t2, n2, r2, o2);
|
|
}, checkPoint: function(e2, t2, n2, r2, i2, a2, o2) {
|
|
var s2 = en(r2, i2), l2 = 2 * s2;
|
|
if (qt(e2, t2, this.points, a2, o2, r2, i2 - l2, [0, -1], n2)) return true;
|
|
if (qt(e2, t2, this.points, a2, o2, r2 - l2, i2, [0, -1], n2)) return true;
|
|
var u2 = r2 / 2 + 2 * n2, c2 = i2 / 2 + 2 * n2;
|
|
return !!jt(e2, t2, [a2 - u2, o2 - c2, a2 - u2, o2, a2 + u2, o2, a2 + u2, o2 - c2]) || (!!Wt(e2, t2, l2, l2, a2 + r2 / 2 - s2, o2 + i2 / 2 - s2, n2) || !!Wt(e2, t2, l2, l2, a2 - r2 / 2 + s2, o2 + i2 / 2 - s2, n2));
|
|
} };
|
|
}, Yl.registerNodeShapes = function() {
|
|
var e2 = this.nodeShapes = {}, t2 = this;
|
|
this.generateEllipse(), this.generatePolygon("triangle", $t(3, 0)), this.generateRoundPolygon("round-triangle", $t(3, 0)), this.generatePolygon("rectangle", $t(4, 0)), e2.square = e2.rectangle, this.generateRoundRectangle(), this.generateCutRectangle(), this.generateBarrel(), this.generateBottomRoundrectangle();
|
|
var n2 = [0, 1, 1, 0, 0, -1, -1, 0];
|
|
this.generatePolygon("diamond", n2), this.generateRoundPolygon("round-diamond", n2), this.generatePolygon("pentagon", $t(5, 0)), this.generateRoundPolygon("round-pentagon", $t(5, 0)), this.generatePolygon("hexagon", $t(6, 0)), this.generateRoundPolygon("round-hexagon", $t(6, 0)), this.generatePolygon("heptagon", $t(7, 0)), this.generateRoundPolygon("round-heptagon", $t(7, 0)), this.generatePolygon("octagon", $t(8, 0)), this.generateRoundPolygon("round-octagon", $t(8, 0));
|
|
var r2 = new Array(20), i2 = Jt(5, 0), a2 = Jt(5, Math.PI / 5), o2 = 0.5 * (3 - Math.sqrt(5));
|
|
o2 *= 1.57;
|
|
for (var s2 = 0; s2 < a2.length / 2; s2++) a2[2 * s2] *= o2, a2[2 * s2 + 1] *= o2;
|
|
for (s2 = 0; s2 < 5; s2++) r2[4 * s2] = i2[2 * s2], r2[4 * s2 + 1] = i2[2 * s2 + 1], r2[4 * s2 + 2] = a2[2 * s2], r2[4 * s2 + 3] = a2[2 * s2 + 1];
|
|
r2 = Qt(r2), this.generatePolygon("star", r2), this.generatePolygon("vee", [-1, -1, 0, -0.333, 1, -1, 0, 1]), this.generatePolygon("rhomboid", [-1, -1, 0.333, -1, 1, 1, -0.333, 1]), this.generatePolygon("right-rhomboid", [-0.333, -1, 1, -1, 0.333, 1, -1, 1]), this.nodeShapes.concavehexagon = this.generatePolygon("concave-hexagon", [-1, -0.95, -0.75, 0, -1, 0.95, 1, 0.95, 0.75, 0, 1, -0.95]);
|
|
var l2 = [-1, -1, 0.25, -1, 1, 0, 0.25, 1, -1, 1];
|
|
this.generatePolygon("tag", l2), this.generateRoundPolygon("round-tag", l2), e2.makePolygon = function(e3) {
|
|
var n3, r3 = "polygon-" + e3.join("$");
|
|
return (n3 = this[r3]) ? n3 : t2.generatePolygon(r3, e3);
|
|
};
|
|
};
|
|
var Xl = { timeToRender: function() {
|
|
return this.redrawTotalTime / this.redrawCount;
|
|
}, redraw: function(e2) {
|
|
e2 = e2 || Ye();
|
|
var t2 = this;
|
|
void 0 === t2.averageRedrawTime && (t2.averageRedrawTime = 0), void 0 === t2.lastRedrawTime && (t2.lastRedrawTime = 0), void 0 === t2.lastDrawTime && (t2.lastDrawTime = 0), t2.requestedFrame = true, t2.renderOptions = e2;
|
|
}, beforeRender: function(e2, t2) {
|
|
if (!this.destroyed) {
|
|
null == t2 && Oe("Priority is not optional for beforeRender");
|
|
var n2 = this.beforeRenderCallbacks;
|
|
n2.push({ fn: e2, priority: t2 }), n2.sort(function(e3, t3) {
|
|
return t3.priority - e3.priority;
|
|
});
|
|
}
|
|
} }, Wl = function(e2, t2, n2) {
|
|
for (var r2 = e2.beforeRenderCallbacks, i2 = 0; i2 < r2.length; i2++) r2[i2].fn(t2, n2);
|
|
};
|
|
Xl.startRenderLoop = function() {
|
|
var e2 = this, t2 = e2.cy;
|
|
if (!e2.renderLoopStarted) {
|
|
e2.renderLoopStarted = true;
|
|
me(function n2(r2) {
|
|
if (!e2.destroyed) {
|
|
if (t2.batching()) ;
|
|
else if (e2.requestedFrame && !e2.skipFrame) {
|
|
Wl(e2, true, r2);
|
|
var i2 = be();
|
|
e2.render(e2.renderOptions);
|
|
var a2 = e2.lastDrawTime = be();
|
|
void 0 === e2.averageRedrawTime && (e2.averageRedrawTime = a2 - i2), void 0 === e2.redrawCount && (e2.redrawCount = 0), e2.redrawCount++, void 0 === e2.redrawTotalTime && (e2.redrawTotalTime = 0);
|
|
var o2 = a2 - i2;
|
|
e2.redrawTotalTime += o2, e2.lastRedrawTime = o2, e2.averageRedrawTime = e2.averageRedrawTime / 2 + o2 / 2, e2.requestedFrame = false;
|
|
} else Wl(e2, false, r2);
|
|
e2.skipFrame = false, me(n2);
|
|
}
|
|
});
|
|
}
|
|
};
|
|
var Hl = function(e2) {
|
|
this.init(e2);
|
|
}, Kl = Hl.prototype;
|
|
Kl.clientFunctions = ["redrawHint", "render", "renderTo", "matchCanvasSize", "nodeShapeImpl", "arrowShapeImpl"], Kl.init = function(e2) {
|
|
var t2 = this;
|
|
t2.options = e2, t2.cy = e2.cy;
|
|
var n2 = t2.container = e2.cy.container(), r2 = t2.cy.window();
|
|
if (r2) {
|
|
var i2 = r2.document, a2 = i2.head, o2 = "__________cytoscape_container", s2 = null != i2.getElementById("__________cytoscape_stylesheet");
|
|
if (n2.className.indexOf(o2) < 0 && (n2.className = (n2.className || "") + " " + o2), !s2) {
|
|
var l2 = i2.createElement("style");
|
|
l2.id = "__________cytoscape_stylesheet", l2.textContent = "." + o2 + " { position: relative; }", a2.insertBefore(l2, a2.children[0]);
|
|
}
|
|
"static" === r2.getComputedStyle(n2).getPropertyValue("position") && Ve("A Cytoscape container has style position:static and so can not use UI extensions properly");
|
|
}
|
|
t2.selection = [void 0, void 0, void 0, void 0, 0], t2.bezierProjPcts = [0.05, 0.225, 0.4, 0.5, 0.6, 0.775, 0.95], t2.hoverData = { down: null, last: null, downTime: null, triggerMode: null, dragging: false, initialPan: [null, null], capture: false }, t2.dragData = { possibleDragElements: [] }, t2.touchData = { start: null, capture: false, startPosition: [null, null, null, null, null, null], singleTouchStartTime: null, singleTouchMoved: true, now: [null, null, null, null, null, null], earlier: [null, null, null, null, null, null] }, t2.redraws = 0, t2.showFps = e2.showFps, t2.debug = e2.debug, t2.hideEdgesOnViewport = e2.hideEdgesOnViewport, t2.textureOnViewport = e2.textureOnViewport, t2.wheelSensitivity = e2.wheelSensitivity, t2.motionBlurEnabled = e2.motionBlur, t2.forcedPixelRatio = m(e2.pixelRatio) ? e2.pixelRatio : null, t2.motionBlur = e2.motionBlur, t2.motionBlurOpacity = e2.motionBlurOpacity, t2.motionBlurTransparency = 1 - t2.motionBlurOpacity, t2.motionBlurPxRatio = 1, t2.mbPxRBlurry = 1, t2.minMbLowQualFrames = 4, t2.fullQualityMb = false, t2.clearedForMotionBlur = [], t2.desktopTapThreshold = e2.desktopTapThreshold, t2.desktopTapThreshold2 = e2.desktopTapThreshold * e2.desktopTapThreshold, t2.touchTapThreshold = e2.touchTapThreshold, t2.touchTapThreshold2 = e2.touchTapThreshold * e2.touchTapThreshold, t2.tapholdDuration = 500, t2.bindings = [], t2.beforeRenderCallbacks = [], t2.beforeRenderPriorities = { animations: 400, eleCalcs: 300, eleTxrDeq: 200, lyrTxrDeq: 150, lyrTxrSkip: 100 }, t2.registerNodeShapes(), t2.registerArrowShapes(), t2.registerCalculationListeners();
|
|
}, Kl.notify = function(e2, t2) {
|
|
var n2 = this, r2 = n2.cy;
|
|
this.destroyed || ("init" !== e2 ? "destroy" !== e2 ? (("add" === e2 || "remove" === e2 || "move" === e2 && r2.hasCompoundNodes() || "load" === e2 || "zorder" === e2 || "mount" === e2) && n2.invalidateCachedZSortedEles(), "viewport" === e2 && n2.redrawHint("select", true), "load" !== e2 && "resize" !== e2 && "mount" !== e2 || (n2.invalidateContainerClientCoordsCache(), n2.matchCanvasSize(n2.container)), n2.redrawHint("eles", true), n2.redrawHint("drag", true), this.startRenderLoop(), this.redraw()) : n2.destroy() : n2.load());
|
|
}, Kl.destroy = function() {
|
|
var e2 = this;
|
|
e2.destroyed = true, e2.cy.stopAnimationLoop();
|
|
for (var t2 = 0; t2 < e2.bindings.length; t2++) {
|
|
var n2 = e2.bindings[t2], r2 = n2.target;
|
|
(r2.off || r2.removeEventListener).apply(r2, n2.args);
|
|
}
|
|
if (e2.bindings = [], e2.beforeRenderCallbacks = [], e2.onUpdateEleCalcsFns = [], e2.removeObserver && e2.removeObserver.disconnect(), e2.styleObserver && e2.styleObserver.disconnect(), e2.resizeObserver && e2.resizeObserver.disconnect(), e2.labelCalcDiv) try {
|
|
document.body.removeChild(e2.labelCalcDiv);
|
|
} catch (e3) {
|
|
}
|
|
}, Kl.isHeadless = function() {
|
|
return false;
|
|
}, [Sl, Fl, jl, ql, Yl, Xl].forEach(function(e2) {
|
|
I(Kl, e2);
|
|
});
|
|
var Gl = function(e2) {
|
|
return function() {
|
|
var t2 = this, n2 = this.renderer;
|
|
if (!t2.dequeueingSetup) {
|
|
t2.dequeueingSetup = true;
|
|
var r2 = fe(function() {
|
|
n2.redrawHint("eles", true), n2.redrawHint("drag", true), n2.redraw();
|
|
}, e2.deqRedrawThreshold), i2 = e2.priority || Ae;
|
|
n2.beforeRender(function(i3, a2) {
|
|
var o2 = be(), s2 = n2.averageRedrawTime, l2 = n2.lastRedrawTime, u2 = [], c2 = n2.cy.extent(), d2 = n2.getPixelRatio();
|
|
for (i3 || n2.flushRenderedStyleQueue(); ; ) {
|
|
var h2 = be(), p2 = h2 - o2, f2 = h2 - a2;
|
|
if (l2 < 1e3 / 60) {
|
|
var g2 = 1e3 / 60 - (i3 ? s2 : 0);
|
|
if (f2 >= e2.deqFastCost * g2) break;
|
|
} else if (i3) {
|
|
if (p2 >= e2.deqCost * l2 || p2 >= e2.deqAvgCost * s2) break;
|
|
} else if (f2 >= e2.deqNoDrawCost * (1e3 / 60)) break;
|
|
var v2 = e2.deq(t2, d2, c2);
|
|
if (!(v2.length > 0)) break;
|
|
for (var y2 = 0; y2 < v2.length; y2++) u2.push(v2[y2]);
|
|
}
|
|
u2.length > 0 && (e2.onDeqd(t2, u2), !i3 && e2.shouldRedraw(t2, u2, d2, c2) && r2());
|
|
}, i2(t2));
|
|
}
|
|
};
|
|
}, Ul = function() {
|
|
function e2(n2) {
|
|
var r2 = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : Ie;
|
|
t(this, e2), this.idsByKey = new Ue(), this.keyForId = new Ue(), this.cachesByLvl = new Ue(), this.lvls = [], this.getKey = n2, this.doesEleInvalidateKey = r2;
|
|
}
|
|
return r(e2, [{ key: "getIdsFor", value: function(e3) {
|
|
null == e3 && Oe("Can not get id list for null key");
|
|
var t2 = this.idsByKey, n2 = this.idsByKey.get(e3);
|
|
return n2 || (n2 = new $e(), t2.set(e3, n2)), n2;
|
|
} }, { key: "addIdForKey", value: function(e3, t2) {
|
|
null != e3 && this.getIdsFor(e3).add(t2);
|
|
} }, { key: "deleteIdForKey", value: function(e3, t2) {
|
|
null != e3 && this.getIdsFor(e3).delete(t2);
|
|
} }, { key: "getNumberOfIdsForKey", value: function(e3) {
|
|
return null == e3 ? 0 : this.getIdsFor(e3).size;
|
|
} }, { key: "updateKeyMappingFor", value: function(e3) {
|
|
var t2 = e3.id(), n2 = this.keyForId.get(t2), r2 = this.getKey(e3);
|
|
this.deleteIdForKey(n2, t2), this.addIdForKey(r2, t2), this.keyForId.set(t2, r2);
|
|
} }, { key: "deleteKeyMappingFor", value: function(e3) {
|
|
var t2 = e3.id(), n2 = this.keyForId.get(t2);
|
|
this.deleteIdForKey(n2, t2), this.keyForId.delete(t2);
|
|
} }, { key: "keyHasChangedFor", value: function(e3) {
|
|
var t2 = e3.id();
|
|
return this.keyForId.get(t2) !== this.getKey(e3);
|
|
} }, { key: "isInvalid", value: function(e3) {
|
|
return this.keyHasChangedFor(e3) || this.doesEleInvalidateKey(e3);
|
|
} }, { key: "getCachesAt", value: function(e3) {
|
|
var t2 = this.cachesByLvl, n2 = this.lvls, r2 = t2.get(e3);
|
|
return r2 || (r2 = new Ue(), t2.set(e3, r2), n2.push(e3)), r2;
|
|
} }, { key: "getCache", value: function(e3, t2) {
|
|
return this.getCachesAt(t2).get(e3);
|
|
} }, { key: "get", value: function(e3, t2) {
|
|
var n2 = this.getKey(e3), r2 = this.getCache(n2, t2);
|
|
return null != r2 && this.updateKeyMappingFor(e3), r2;
|
|
} }, { key: "getForCachedKey", value: function(e3, t2) {
|
|
var n2 = this.keyForId.get(e3.id());
|
|
return this.getCache(n2, t2);
|
|
} }, { key: "hasCache", value: function(e3, t2) {
|
|
return this.getCachesAt(t2).has(e3);
|
|
} }, { key: "has", value: function(e3, t2) {
|
|
var n2 = this.getKey(e3);
|
|
return this.hasCache(n2, t2);
|
|
} }, { key: "setCache", value: function(e3, t2, n2) {
|
|
n2.key = e3, this.getCachesAt(t2).set(e3, n2);
|
|
} }, { key: "set", value: function(e3, t2, n2) {
|
|
var r2 = this.getKey(e3);
|
|
this.setCache(r2, t2, n2), this.updateKeyMappingFor(e3);
|
|
} }, { key: "deleteCache", value: function(e3, t2) {
|
|
this.getCachesAt(t2).delete(e3);
|
|
} }, { key: "delete", value: function(e3, t2) {
|
|
var n2 = this.getKey(e3);
|
|
this.deleteCache(n2, t2);
|
|
} }, { key: "invalidateKey", value: function(e3) {
|
|
var t2 = this;
|
|
this.lvls.forEach(function(n2) {
|
|
return t2.deleteCache(e3, n2);
|
|
});
|
|
} }, { key: "invalidate", value: function(e3) {
|
|
var t2 = e3.id(), n2 = this.keyForId.get(t2);
|
|
this.deleteKeyMappingFor(e3);
|
|
var r2 = this.doesEleInvalidateKey(e3);
|
|
return r2 && this.invalidateKey(n2), r2 || 0 === this.getNumberOfIdsForKey(n2);
|
|
} }]), e2;
|
|
}(), Zl = { dequeue: "dequeue", downscale: "downscale", highQuality: "highQuality" }, $l = Xe({ getKey: null, doesEleInvalidateKey: Ie, drawElement: null, getBoundingBox: null, getRotationPoint: null, getRotationOffset: null, isVisible: ze, allowEdgeTxrCaching: true, allowParentTxrCaching: true }), Ql = function(e2, t2) {
|
|
this.renderer = e2, this.onDequeues = [];
|
|
var n2 = $l(t2);
|
|
I(this, n2), this.lookup = new Ul(n2.getKey, n2.doesEleInvalidateKey), this.setupDequeueing();
|
|
}, Jl = Ql.prototype;
|
|
Jl.reasons = Zl, Jl.getTextureQueue = function(e2) {
|
|
return this.eleImgCaches = this.eleImgCaches || {}, this.eleImgCaches[e2] = this.eleImgCaches[e2] || [];
|
|
}, Jl.getRetiredTextureQueue = function(e2) {
|
|
var t2 = this.eleImgCaches.retired = this.eleImgCaches.retired || {};
|
|
return t2[e2] = t2[e2] || [];
|
|
}, Jl.getElementQueue = function() {
|
|
return this.eleCacheQueue = this.eleCacheQueue || new tt(function(e2, t2) {
|
|
return t2.reqs - e2.reqs;
|
|
});
|
|
}, Jl.getElementKeyToQueue = function() {
|
|
return this.eleKeyToCacheQueue = this.eleKeyToCacheQueue || {};
|
|
}, Jl.getElement = function(e2, t2, n2, r2, i2) {
|
|
var a2 = this, o2 = this.renderer, s2 = o2.cy.zoom(), l2 = this.lookup;
|
|
if (!t2 || 0 === t2.w || 0 === t2.h || isNaN(t2.w) || isNaN(t2.h) || !e2.visible() || e2.removed()) return null;
|
|
if (!a2.allowEdgeTxrCaching && e2.isEdge() || !a2.allowParentTxrCaching && e2.isParent()) return null;
|
|
if (null == r2 && (r2 = Math.ceil(bt(s2 * n2))), r2 < -4) r2 = -4;
|
|
else if (s2 >= 7.99 || r2 > 3) return null;
|
|
var u2 = Math.pow(2, r2), c2 = t2.h * u2, d2 = t2.w * u2, h2 = o2.eleTextBiggerThanMin(e2, u2);
|
|
if (!this.isVisible(e2, h2)) return null;
|
|
var p2, f2 = l2.get(e2, r2);
|
|
if (f2 && f2.invalidated && (f2.invalidated = false, f2.texture.invalidatedWidth -= f2.width), f2) return f2;
|
|
if (p2 = c2 <= 25 ? 25 : c2 <= 50 ? 50 : 50 * Math.ceil(c2 / 50), c2 > 1024 || d2 > 1024) return null;
|
|
var g2 = a2.getTextureQueue(p2), v2 = g2[g2.length - 2], y2 = function() {
|
|
return a2.recycleTexture(p2, d2) || a2.addTexture(p2, d2);
|
|
};
|
|
v2 || (v2 = g2[g2.length - 1]), v2 || (v2 = y2()), v2.width - v2.usedWidth < d2 && (v2 = y2());
|
|
for (var m2, b2 = function(e3) {
|
|
return e3 && e3.scaledLabelShown === h2;
|
|
}, x2 = i2 && i2 === Zl.dequeue, w2 = i2 && i2 === Zl.highQuality, E2 = i2 && i2 === Zl.downscale, k2 = r2 + 1; k2 <= 3; k2++) {
|
|
var C2 = l2.get(e2, k2);
|
|
if (C2) {
|
|
m2 = C2;
|
|
break;
|
|
}
|
|
}
|
|
var S2 = m2 && m2.level === r2 + 1 ? m2 : null, P2 = function() {
|
|
v2.context.drawImage(S2.texture.canvas, S2.x, 0, S2.width, S2.height, v2.usedWidth, 0, d2, c2);
|
|
};
|
|
if (v2.context.setTransform(1, 0, 0, 1, 0, 0), v2.context.clearRect(v2.usedWidth, 0, d2, p2), b2(S2)) P2();
|
|
else if (b2(m2)) {
|
|
if (!w2) return a2.queueElement(e2, m2.level - 1), m2;
|
|
for (var D2 = m2.level; D2 > r2; D2--) S2 = a2.getElement(e2, t2, n2, D2, Zl.downscale);
|
|
P2();
|
|
} else {
|
|
var T2;
|
|
if (!x2 && !w2 && !E2) for (var _2 = r2 - 1; _2 >= -4; _2--) {
|
|
var M2 = l2.get(e2, _2);
|
|
if (M2) {
|
|
T2 = M2;
|
|
break;
|
|
}
|
|
}
|
|
if (b2(T2)) return a2.queueElement(e2, r2), T2;
|
|
v2.context.translate(v2.usedWidth, 0), v2.context.scale(u2, u2), this.drawElement(v2.context, e2, t2, h2, false), v2.context.scale(1 / u2, 1 / u2), v2.context.translate(-v2.usedWidth, 0);
|
|
}
|
|
return f2 = { x: v2.usedWidth, texture: v2, level: r2, scale: u2, width: d2, height: c2, scaledLabelShown: h2 }, v2.usedWidth += Math.ceil(d2 + 8), v2.eleCaches.push(f2), l2.set(e2, r2, f2), a2.checkTextureFullness(v2), f2;
|
|
}, Jl.invalidateElements = function(e2) {
|
|
for (var t2 = 0; t2 < e2.length; t2++) this.invalidateElement(e2[t2]);
|
|
}, Jl.invalidateElement = function(e2) {
|
|
var t2 = this.lookup, n2 = [];
|
|
if (t2.isInvalid(e2)) {
|
|
for (var r2 = -4; r2 <= 3; r2++) {
|
|
var i2 = t2.getForCachedKey(e2, r2);
|
|
i2 && n2.push(i2);
|
|
}
|
|
if (t2.invalidate(e2)) for (var a2 = 0; a2 < n2.length; a2++) {
|
|
var o2 = n2[a2], s2 = o2.texture;
|
|
s2.invalidatedWidth += o2.width, o2.invalidated = true, this.checkTextureUtility(s2);
|
|
}
|
|
this.removeFromQueue(e2);
|
|
}
|
|
}, Jl.checkTextureUtility = function(e2) {
|
|
e2.invalidatedWidth >= 0.2 * e2.width && this.retireTexture(e2);
|
|
}, Jl.checkTextureFullness = function(e2) {
|
|
var t2 = this.getTextureQueue(e2.height);
|
|
e2.usedWidth / e2.width > 0.8 && e2.fullnessChecks >= 10 ? We(t2, e2) : e2.fullnessChecks++;
|
|
}, Jl.retireTexture = function(e2) {
|
|
var t2 = e2.height, n2 = this.getTextureQueue(t2), r2 = this.lookup;
|
|
We(n2, e2), e2.retired = true;
|
|
for (var i2 = e2.eleCaches, a2 = 0; a2 < i2.length; a2++) {
|
|
var o2 = i2[a2];
|
|
r2.deleteCache(o2.key, o2.level);
|
|
}
|
|
He(i2), this.getRetiredTextureQueue(t2).push(e2);
|
|
}, Jl.addTexture = function(e2, t2) {
|
|
var n2 = {};
|
|
return this.getTextureQueue(e2).push(n2), n2.eleCaches = [], n2.height = e2, n2.width = Math.max(1024, t2), n2.usedWidth = 0, n2.invalidatedWidth = 0, n2.fullnessChecks = 0, n2.canvas = this.renderer.makeOffscreenCanvas(n2.width, n2.height), n2.context = n2.canvas.getContext("2d"), n2;
|
|
}, Jl.recycleTexture = function(e2, t2) {
|
|
for (var n2 = this.getTextureQueue(e2), r2 = this.getRetiredTextureQueue(e2), i2 = 0; i2 < r2.length; i2++) {
|
|
var a2 = r2[i2];
|
|
if (a2.width >= t2) return a2.retired = false, a2.usedWidth = 0, a2.invalidatedWidth = 0, a2.fullnessChecks = 0, He(a2.eleCaches), a2.context.setTransform(1, 0, 0, 1, 0, 0), a2.context.clearRect(0, 0, a2.width, a2.height), We(r2, a2), n2.push(a2), a2;
|
|
}
|
|
}, Jl.queueElement = function(e2, t2) {
|
|
var n2 = this.getElementQueue(), r2 = this.getElementKeyToQueue(), i2 = this.getKey(e2), a2 = r2[i2];
|
|
if (a2) a2.level = Math.max(a2.level, t2), a2.eles.merge(e2), a2.reqs++, n2.updateItem(a2);
|
|
else {
|
|
var o2 = { eles: e2.spawn().merge(e2), level: t2, reqs: 1, key: i2 };
|
|
n2.push(o2), r2[i2] = o2;
|
|
}
|
|
}, Jl.dequeue = function(e2) {
|
|
for (var t2 = this.getElementQueue(), n2 = this.getElementKeyToQueue(), r2 = [], i2 = this.lookup, a2 = 0; a2 < 1 && t2.size() > 0; a2++) {
|
|
var o2 = t2.pop(), s2 = o2.key, l2 = o2.eles[0], u2 = i2.hasCache(l2, o2.level);
|
|
if (n2[s2] = null, !u2) {
|
|
r2.push(o2);
|
|
var c2 = this.getBoundingBox(l2);
|
|
this.getElement(l2, c2, e2, o2.level, Zl.dequeue);
|
|
}
|
|
}
|
|
return r2;
|
|
}, Jl.removeFromQueue = function(e2) {
|
|
var t2 = this.getElementQueue(), n2 = this.getElementKeyToQueue(), r2 = this.getKey(e2), i2 = n2[r2];
|
|
null != i2 && (1 === i2.eles.length ? (i2.reqs = Ne, t2.updateItem(i2), t2.pop(), n2[r2] = null) : i2.eles.unmerge(e2));
|
|
}, Jl.onDequeue = function(e2) {
|
|
this.onDequeues.push(e2);
|
|
}, Jl.offDequeue = function(e2) {
|
|
We(this.onDequeues, e2);
|
|
}, Jl.setupDequeueing = Gl({ deqRedrawThreshold: 100, deqCost: 0.15, deqAvgCost: 0.1, deqNoDrawCost: 0.9, deqFastCost: 0.9, deq: function(e2, t2, n2) {
|
|
return e2.dequeue(t2, n2);
|
|
}, onDeqd: function(e2, t2) {
|
|
for (var n2 = 0; n2 < e2.onDequeues.length; n2++) {
|
|
(0, e2.onDequeues[n2])(t2);
|
|
}
|
|
}, shouldRedraw: function(e2, t2, n2, r2) {
|
|
for (var i2 = 0; i2 < t2.length; i2++) for (var a2 = t2[i2].eles, o2 = 0; o2 < a2.length; o2++) {
|
|
var s2 = a2[o2].boundingBox();
|
|
if (zt(s2, r2)) return true;
|
|
}
|
|
return false;
|
|
}, priority: function(e2) {
|
|
return e2.renderer.beforeRenderPriorities.eleTxrDeq;
|
|
} });
|
|
var eu = function(e2) {
|
|
var t2 = this, n2 = t2.renderer = e2, r2 = n2.cy;
|
|
t2.layersByLevel = {}, t2.firstGet = true, t2.lastInvalidationTime = be() - 500, t2.skipping = false, t2.eleTxrDeqs = r2.collection(), t2.scheduleElementRefinement = fe(function() {
|
|
t2.refineElementTextures(t2.eleTxrDeqs), t2.eleTxrDeqs.unmerge(t2.eleTxrDeqs);
|
|
}, 50), n2.beforeRender(function(e3, n3) {
|
|
n3 - t2.lastInvalidationTime <= 250 ? t2.skipping = true : t2.skipping = false;
|
|
}, n2.beforeRenderPriorities.lyrTxrSkip);
|
|
t2.layersQueue = new tt(function(e3, t3) {
|
|
return t3.reqs - e3.reqs;
|
|
}), t2.setupDequeueing();
|
|
}, tu = eu.prototype, nu = 0, ru = Math.pow(2, 53) - 1;
|
|
tu.makeLayer = function(e2, t2) {
|
|
var n2 = Math.pow(2, t2), r2 = Math.ceil(e2.w * n2), i2 = Math.ceil(e2.h * n2), a2 = this.renderer.makeOffscreenCanvas(r2, i2), o2 = { id: nu = ++nu % ru, bb: e2, level: t2, width: r2, height: i2, canvas: a2, context: a2.getContext("2d"), eles: [], elesQueue: [], reqs: 0 }, s2 = o2.context, l2 = -o2.bb.x1, u2 = -o2.bb.y1;
|
|
return s2.scale(n2, n2), s2.translate(l2, u2), o2;
|
|
}, tu.getLayers = function(e2, t2, n2) {
|
|
var r2 = this, i2 = r2.renderer.cy.zoom(), a2 = r2.firstGet;
|
|
if (r2.firstGet = false, null == n2) {
|
|
if ((n2 = Math.ceil(bt(i2 * t2))) < -4) n2 = -4;
|
|
else if (i2 >= 3.99 || n2 > 2) return null;
|
|
}
|
|
r2.validateLayersElesOrdering(n2, e2);
|
|
var o2, s2, l2 = r2.layersByLevel, u2 = Math.pow(2, n2), c2 = l2[n2] = l2[n2] || [];
|
|
if (r2.levelIsComplete(n2, e2)) return c2;
|
|
!function() {
|
|
var t3 = function(t4) {
|
|
if (r2.validateLayersElesOrdering(t4, e2), r2.levelIsComplete(t4, e2)) return s2 = l2[t4], true;
|
|
}, i3 = function(e3) {
|
|
if (!s2) for (var r3 = n2 + e3; -4 <= r3 && r3 <= 2 && !t3(r3); r3 += e3) ;
|
|
};
|
|
i3(1), i3(-1);
|
|
for (var a3 = c2.length - 1; a3 >= 0; a3--) {
|
|
var o3 = c2[a3];
|
|
o3.invalid && We(c2, o3);
|
|
}
|
|
}();
|
|
var d2 = function(t3) {
|
|
var i3 = (t3 = t3 || {}).after;
|
|
if (function() {
|
|
if (!o2) {
|
|
o2 = Dt();
|
|
for (var t4 = 0; t4 < e2.length; t4++) Tt(o2, e2[t4].boundingBox());
|
|
}
|
|
}(), o2.w * u2 * (o2.h * u2) > 16e6) return null;
|
|
var a3 = r2.makeLayer(o2, n2);
|
|
if (null != i3) {
|
|
var s3 = c2.indexOf(i3) + 1;
|
|
c2.splice(s3, 0, a3);
|
|
} else (void 0 === t3.insert || t3.insert) && c2.unshift(a3);
|
|
return a3;
|
|
};
|
|
if (r2.skipping && !a2) return null;
|
|
for (var h2 = null, p2 = e2.length / 1, f2 = !a2, g2 = 0; g2 < e2.length; g2++) {
|
|
var v2 = e2[g2], y2 = v2._private.rscratch, m2 = y2.imgLayerCaches = y2.imgLayerCaches || {}, b2 = m2[n2];
|
|
if (b2) h2 = b2;
|
|
else {
|
|
if ((!h2 || h2.eles.length >= p2 || !Lt(h2.bb, v2.boundingBox())) && !(h2 = d2({ insert: true, after: h2 }))) return null;
|
|
s2 || f2 ? r2.queueLayer(h2, v2) : r2.drawEleInLayer(h2, v2, n2, t2), h2.eles.push(v2), m2[n2] = h2;
|
|
}
|
|
}
|
|
return s2 || (f2 ? null : c2);
|
|
}, tu.getEleLevelForLayerLevel = function(e2, t2) {
|
|
return e2;
|
|
}, tu.drawEleInLayer = function(e2, t2, n2, r2) {
|
|
var i2 = this.renderer, a2 = e2.context, o2 = t2.boundingBox();
|
|
0 !== o2.w && 0 !== o2.h && t2.visible() && (n2 = this.getEleLevelForLayerLevel(n2, r2), i2.setImgSmoothing(a2, false), i2.drawCachedElement(a2, t2, null, null, n2, true), i2.setImgSmoothing(a2, true));
|
|
}, tu.levelIsComplete = function(e2, t2) {
|
|
var n2 = this.layersByLevel[e2];
|
|
if (!n2 || 0 === n2.length) return false;
|
|
for (var r2 = 0, i2 = 0; i2 < n2.length; i2++) {
|
|
var a2 = n2[i2];
|
|
if (a2.reqs > 0) return false;
|
|
if (a2.invalid) return false;
|
|
r2 += a2.eles.length;
|
|
}
|
|
return r2 === t2.length;
|
|
}, tu.validateLayersElesOrdering = function(e2, t2) {
|
|
var n2 = this.layersByLevel[e2];
|
|
if (n2) for (var r2 = 0; r2 < n2.length; r2++) {
|
|
for (var i2 = n2[r2], a2 = -1, o2 = 0; o2 < t2.length; o2++) if (i2.eles[0] === t2[o2]) {
|
|
a2 = o2;
|
|
break;
|
|
}
|
|
if (a2 < 0) this.invalidateLayer(i2);
|
|
else {
|
|
var s2 = a2;
|
|
for (o2 = 0; o2 < i2.eles.length; o2++) if (i2.eles[o2] !== t2[s2 + o2]) {
|
|
this.invalidateLayer(i2);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}, tu.updateElementsInLayers = function(e2, t2) {
|
|
for (var n2 = w(e2[0]), r2 = 0; r2 < e2.length; r2++) for (var i2 = n2 ? null : e2[r2], a2 = n2 ? e2[r2] : e2[r2].ele, o2 = a2._private.rscratch, s2 = o2.imgLayerCaches = o2.imgLayerCaches || {}, l2 = -4; l2 <= 2; l2++) {
|
|
var u2 = s2[l2];
|
|
u2 && (i2 && this.getEleLevelForLayerLevel(u2.level) !== i2.level || t2(u2, a2, i2));
|
|
}
|
|
}, tu.haveLayers = function() {
|
|
for (var e2 = false, t2 = -4; t2 <= 2; t2++) {
|
|
var n2 = this.layersByLevel[t2];
|
|
if (n2 && n2.length > 0) {
|
|
e2 = true;
|
|
break;
|
|
}
|
|
}
|
|
return e2;
|
|
}, tu.invalidateElements = function(e2) {
|
|
var t2 = this;
|
|
0 !== e2.length && (t2.lastInvalidationTime = be(), 0 !== e2.length && t2.haveLayers() && t2.updateElementsInLayers(e2, function(e3, n2, r2) {
|
|
t2.invalidateLayer(e3);
|
|
}));
|
|
}, tu.invalidateLayer = function(e2) {
|
|
if (this.lastInvalidationTime = be(), !e2.invalid) {
|
|
var t2 = e2.level, n2 = e2.eles, r2 = this.layersByLevel[t2];
|
|
We(r2, e2), e2.elesQueue = [], e2.invalid = true, e2.replacement && (e2.replacement.invalid = true);
|
|
for (var i2 = 0; i2 < n2.length; i2++) {
|
|
var a2 = n2[i2]._private.rscratch.imgLayerCaches;
|
|
a2 && (a2[t2] = null);
|
|
}
|
|
}
|
|
}, tu.refineElementTextures = function(e2) {
|
|
var t2 = this;
|
|
t2.updateElementsInLayers(e2, function(e3, n2, r2) {
|
|
var i2 = e3.replacement;
|
|
if (i2 || ((i2 = e3.replacement = t2.makeLayer(e3.bb, e3.level)).replaces = e3, i2.eles = e3.eles), !i2.reqs) for (var a2 = 0; a2 < i2.eles.length; a2++) t2.queueLayer(i2, i2.eles[a2]);
|
|
});
|
|
}, tu.enqueueElementRefinement = function(e2) {
|
|
this.eleTxrDeqs.merge(e2), this.scheduleElementRefinement();
|
|
}, tu.queueLayer = function(e2, t2) {
|
|
var n2 = this.layersQueue, r2 = e2.elesQueue, i2 = r2.hasId = r2.hasId || {};
|
|
if (!e2.replacement) {
|
|
if (t2) {
|
|
if (i2[t2.id()]) return;
|
|
r2.push(t2), i2[t2.id()] = true;
|
|
}
|
|
e2.reqs ? (e2.reqs++, n2.updateItem(e2)) : (e2.reqs = 1, n2.push(e2));
|
|
}
|
|
}, tu.dequeue = function(e2) {
|
|
for (var t2 = this.layersQueue, n2 = [], r2 = 0; r2 < 1 && 0 !== t2.size(); ) {
|
|
var i2 = t2.peek();
|
|
if (i2.replacement) t2.pop();
|
|
else if (i2.replaces && i2 !== i2.replaces.replacement) t2.pop();
|
|
else if (i2.invalid) t2.pop();
|
|
else {
|
|
var a2 = i2.elesQueue.shift();
|
|
a2 && (this.drawEleInLayer(i2, a2, i2.level, e2), r2++), 0 === n2.length && n2.push(true), 0 === i2.elesQueue.length && (t2.pop(), i2.reqs = 0, i2.replaces && this.applyLayerReplacement(i2), this.requestRedraw());
|
|
}
|
|
}
|
|
return n2;
|
|
}, tu.applyLayerReplacement = function(e2) {
|
|
var t2 = this.layersByLevel[e2.level], n2 = e2.replaces, r2 = t2.indexOf(n2);
|
|
if (!(r2 < 0 || n2.invalid)) {
|
|
t2[r2] = e2;
|
|
for (var i2 = 0; i2 < e2.eles.length; i2++) {
|
|
var a2 = e2.eles[i2]._private, o2 = a2.imgLayerCaches = a2.imgLayerCaches || {};
|
|
o2 && (o2[e2.level] = e2);
|
|
}
|
|
this.requestRedraw();
|
|
}
|
|
}, tu.requestRedraw = fe(function() {
|
|
var e2 = this.renderer;
|
|
e2.redrawHint("eles", true), e2.redrawHint("drag", true), e2.redraw();
|
|
}, 100), tu.setupDequeueing = Gl({ deqRedrawThreshold: 50, deqCost: 0.15, deqAvgCost: 0.1, deqNoDrawCost: 0.9, deqFastCost: 0.9, deq: function(e2, t2) {
|
|
return e2.dequeue(t2);
|
|
}, onDeqd: Ae, shouldRedraw: ze, priority: function(e2) {
|
|
return e2.renderer.beforeRenderPriorities.lyrTxrDeq;
|
|
} });
|
|
var iu, au = {};
|
|
function ou(e2, t2) {
|
|
for (var n2 = 0; n2 < t2.length; n2++) {
|
|
var r2 = t2[n2];
|
|
e2.lineTo(r2.x, r2.y);
|
|
}
|
|
}
|
|
function su(e2, t2, n2) {
|
|
for (var r2, i2 = 0; i2 < t2.length; i2++) {
|
|
var a2 = t2[i2];
|
|
0 === i2 && (r2 = a2), e2.lineTo(a2.x, a2.y);
|
|
}
|
|
e2.quadraticCurveTo(n2.x, n2.y, r2.x, r2.y);
|
|
}
|
|
function lu(e2, t2, n2) {
|
|
e2.beginPath && e2.beginPath();
|
|
for (var r2 = t2, i2 = 0; i2 < r2.length; i2++) {
|
|
var a2 = r2[i2];
|
|
e2.lineTo(a2.x, a2.y);
|
|
}
|
|
var o2 = n2, s2 = n2[0];
|
|
e2.moveTo(s2.x, s2.y);
|
|
for (i2 = 1; i2 < o2.length; i2++) {
|
|
a2 = o2[i2];
|
|
e2.lineTo(a2.x, a2.y);
|
|
}
|
|
e2.closePath && e2.closePath();
|
|
}
|
|
function uu(e2, t2, n2, r2, i2) {
|
|
e2.beginPath && e2.beginPath(), e2.arc(n2, r2, i2, 0, 2 * Math.PI, false);
|
|
var a2 = t2, o2 = a2[0];
|
|
e2.moveTo(o2.x, o2.y);
|
|
for (var s2 = 0; s2 < a2.length; s2++) {
|
|
var l2 = a2[s2];
|
|
e2.lineTo(l2.x, l2.y);
|
|
}
|
|
e2.closePath && e2.closePath();
|
|
}
|
|
function cu(e2, t2, n2, r2) {
|
|
e2.arc(t2, n2, r2, 0, 2 * Math.PI, false);
|
|
}
|
|
au.arrowShapeImpl = function(e2) {
|
|
return (iu || (iu = { polygon: ou, "triangle-backcurve": su, "triangle-tee": lu, "circle-triangle": uu, "triangle-cross": lu, circle: cu }))[e2];
|
|
};
|
|
var du = { drawElement: function(e2, t2, n2, r2, i2, a2) {
|
|
t2.isNode() ? this.drawNode(e2, t2, n2, r2, i2, a2) : this.drawEdge(e2, t2, n2, r2, i2, a2);
|
|
}, drawElementOverlay: function(e2, t2) {
|
|
t2.isNode() ? this.drawNodeOverlay(e2, t2) : this.drawEdgeOverlay(e2, t2);
|
|
}, drawElementUnderlay: function(e2, t2) {
|
|
t2.isNode() ? this.drawNodeUnderlay(e2, t2) : this.drawEdgeUnderlay(e2, t2);
|
|
}, drawCachedElementPortion: function(e2, t2, n2, r2, i2, a2, o2, s2) {
|
|
var l2 = this, u2 = n2.getBoundingBox(t2);
|
|
if (0 !== u2.w && 0 !== u2.h) {
|
|
var c2 = n2.getElement(t2, u2, r2, i2, a2);
|
|
if (null != c2) {
|
|
var d2 = s2(l2, t2);
|
|
if (0 === d2) return;
|
|
var h2, p2, f2, g2, v2, y2, m2 = o2(l2, t2), b2 = u2.x1, x2 = u2.y1, w2 = u2.w, E2 = u2.h;
|
|
if (0 !== m2) {
|
|
var k2 = n2.getRotationPoint(t2);
|
|
f2 = k2.x, g2 = k2.y, e2.translate(f2, g2), e2.rotate(m2), (v2 = l2.getImgSmoothing(e2)) || l2.setImgSmoothing(e2, true);
|
|
var C2 = n2.getRotationOffset(t2);
|
|
h2 = C2.x, p2 = C2.y;
|
|
} else h2 = b2, p2 = x2;
|
|
1 !== d2 && (y2 = e2.globalAlpha, e2.globalAlpha = y2 * d2), e2.drawImage(c2.texture.canvas, c2.x, 0, c2.width, c2.height, h2, p2, w2, E2), 1 !== d2 && (e2.globalAlpha = y2), 0 !== m2 && (e2.rotate(-m2), e2.translate(-f2, -g2), v2 || l2.setImgSmoothing(e2, false));
|
|
} else n2.drawElement(e2, t2);
|
|
}
|
|
} }, hu = function() {
|
|
return 0;
|
|
}, pu = function(e2, t2) {
|
|
return e2.getTextAngle(t2, null);
|
|
}, fu = function(e2, t2) {
|
|
return e2.getTextAngle(t2, "source");
|
|
}, gu = function(e2, t2) {
|
|
return e2.getTextAngle(t2, "target");
|
|
}, vu = function(e2, t2) {
|
|
return t2.effectiveOpacity();
|
|
}, yu = function(e2, t2) {
|
|
return t2.pstyle("text-opacity").pfValue * t2.effectiveOpacity();
|
|
};
|
|
du.drawCachedElement = function(e2, t2, n2, r2, i2, a2) {
|
|
var o2 = this, s2 = o2.data, l2 = s2.eleTxrCache, u2 = s2.lblTxrCache, c2 = s2.slbTxrCache, d2 = s2.tlbTxrCache, h2 = t2.boundingBox(), p2 = true === a2 ? l2.reasons.highQuality : null;
|
|
if (0 !== h2.w && 0 !== h2.h && t2.visible() && (!r2 || zt(h2, r2))) {
|
|
var f2 = t2.isEdge(), g2 = t2.element()._private.rscratch.badLine;
|
|
o2.drawElementUnderlay(e2, t2), o2.drawCachedElementPortion(e2, t2, l2, n2, i2, p2, hu, vu), f2 && g2 || o2.drawCachedElementPortion(e2, t2, u2, n2, i2, p2, pu, yu), f2 && !g2 && (o2.drawCachedElementPortion(e2, t2, c2, n2, i2, p2, fu, yu), o2.drawCachedElementPortion(e2, t2, d2, n2, i2, p2, gu, yu)), o2.drawElementOverlay(e2, t2);
|
|
}
|
|
}, du.drawElements = function(e2, t2) {
|
|
for (var n2 = 0; n2 < t2.length; n2++) {
|
|
var r2 = t2[n2];
|
|
this.drawElement(e2, r2);
|
|
}
|
|
}, du.drawCachedElements = function(e2, t2, n2, r2) {
|
|
for (var i2 = 0; i2 < t2.length; i2++) {
|
|
var a2 = t2[i2];
|
|
this.drawCachedElement(e2, a2, n2, r2);
|
|
}
|
|
}, du.drawCachedNodes = function(e2, t2, n2, r2) {
|
|
for (var i2 = 0; i2 < t2.length; i2++) {
|
|
var a2 = t2[i2];
|
|
a2.isNode() && this.drawCachedElement(e2, a2, n2, r2);
|
|
}
|
|
}, du.drawLayeredElements = function(e2, t2, n2, r2) {
|
|
var i2 = this.data.lyrTxrCache.getLayers(t2, n2);
|
|
if (i2) for (var a2 = 0; a2 < i2.length; a2++) {
|
|
var o2 = i2[a2], s2 = o2.bb;
|
|
0 !== s2.w && 0 !== s2.h && e2.drawImage(o2.canvas, s2.x1, s2.y1, s2.w, s2.h);
|
|
}
|
|
else this.drawCachedElements(e2, t2, n2, r2);
|
|
};
|
|
var mu = { drawEdge: function(e2, t2, n2) {
|
|
var r2 = !(arguments.length > 3 && void 0 !== arguments[3]) || arguments[3], i2 = !(arguments.length > 4 && void 0 !== arguments[4]) || arguments[4], a2 = !(arguments.length > 5 && void 0 !== arguments[5]) || arguments[5], o2 = this, s2 = t2._private.rscratch;
|
|
if ((!a2 || t2.visible()) && !s2.badLine && null != s2.allpts && !isNaN(s2.allpts[0])) {
|
|
var l2;
|
|
n2 && (l2 = n2, e2.translate(-l2.x1, -l2.y1));
|
|
var u2 = a2 ? t2.pstyle("opacity").value : 1, c2 = a2 ? t2.pstyle("line-opacity").value : 1, d2 = t2.pstyle("curve-style").value, h2 = t2.pstyle("line-style").value, p2 = t2.pstyle("width").pfValue, f2 = t2.pstyle("line-cap").value, g2 = u2 * c2, v2 = u2 * c2, y2 = function() {
|
|
var n3 = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : g2;
|
|
"straight-triangle" === d2 ? (o2.eleStrokeStyle(e2, t2, n3), o2.drawEdgeTrianglePath(t2, e2, s2.allpts)) : (e2.lineWidth = p2, e2.lineCap = f2, o2.eleStrokeStyle(e2, t2, n3), o2.drawEdgePath(t2, e2, s2.allpts, h2), e2.lineCap = "butt");
|
|
}, m2 = function() {
|
|
i2 && o2.drawEdgeOverlay(e2, t2);
|
|
}, b2 = function() {
|
|
i2 && o2.drawEdgeUnderlay(e2, t2);
|
|
}, x2 = function() {
|
|
var n3 = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : v2;
|
|
o2.drawArrowheads(e2, t2, n3);
|
|
}, w2 = function() {
|
|
o2.drawElementText(e2, t2, null, r2);
|
|
};
|
|
e2.lineJoin = "round";
|
|
var E2 = "yes" === t2.pstyle("ghost").value;
|
|
if (E2) {
|
|
var k2 = t2.pstyle("ghost-offset-x").pfValue, C2 = t2.pstyle("ghost-offset-y").pfValue, S2 = t2.pstyle("ghost-opacity").value, P2 = g2 * S2;
|
|
e2.translate(k2, C2), y2(P2), x2(P2), e2.translate(-k2, -C2);
|
|
}
|
|
b2(), y2(), x2(), m2(), w2(), n2 && e2.translate(l2.x1, l2.y1);
|
|
}
|
|
} }, bu = function(e2) {
|
|
if (!["overlay", "underlay"].includes(e2)) throw new Error("Invalid state");
|
|
return function(t2, n2) {
|
|
if (n2.visible()) {
|
|
var r2 = n2.pstyle("".concat(e2, "-opacity")).value;
|
|
if (0 !== r2) {
|
|
var i2 = this, a2 = i2.usePaths(), o2 = n2._private.rscratch, s2 = 2 * n2.pstyle("".concat(e2, "-padding")).pfValue, l2 = n2.pstyle("".concat(e2, "-color")).value;
|
|
t2.lineWidth = s2, "self" !== o2.edgeType || a2 ? t2.lineCap = "round" : t2.lineCap = "butt", i2.colorStrokeStyle(t2, l2[0], l2[1], l2[2], r2), i2.drawEdgePath(n2, t2, o2.allpts, "solid");
|
|
}
|
|
}
|
|
};
|
|
};
|
|
mu.drawEdgeOverlay = bu("overlay"), mu.drawEdgeUnderlay = bu("underlay"), mu.drawEdgePath = function(e2, t2, n2, r2) {
|
|
var i2, a2 = e2._private.rscratch, o2 = t2, s2 = false, l2 = this.usePaths(), u2 = e2.pstyle("line-dash-pattern").pfValue, c2 = e2.pstyle("line-dash-offset").pfValue;
|
|
if (l2) {
|
|
var d2 = n2.join("$");
|
|
a2.pathCacheKey && a2.pathCacheKey === d2 ? (i2 = t2 = a2.pathCache, s2 = true) : (i2 = t2 = new Path2D(), a2.pathCacheKey = d2, a2.pathCache = i2);
|
|
}
|
|
if (o2.setLineDash) switch (r2) {
|
|
case "dotted":
|
|
o2.setLineDash([1, 1]);
|
|
break;
|
|
case "dashed":
|
|
o2.setLineDash(u2), o2.lineDashOffset = c2;
|
|
break;
|
|
case "solid":
|
|
o2.setLineDash([]);
|
|
}
|
|
if (!s2 && !a2.badLine) switch (t2.beginPath && t2.beginPath(), t2.moveTo(n2[0], n2[1]), a2.edgeType) {
|
|
case "bezier":
|
|
case "self":
|
|
case "compound":
|
|
case "multibezier":
|
|
for (var h2 = 2; h2 + 3 < n2.length; h2 += 4) t2.quadraticCurveTo(n2[h2], n2[h2 + 1], n2[h2 + 2], n2[h2 + 3]);
|
|
break;
|
|
case "straight":
|
|
case "segments":
|
|
case "haystack":
|
|
for (var p2 = 2; p2 + 1 < n2.length; p2 += 2) t2.lineTo(n2[p2], n2[p2 + 1]);
|
|
}
|
|
t2 = o2, l2 ? t2.stroke(i2) : t2.stroke(), t2.setLineDash && t2.setLineDash([]);
|
|
}, mu.drawEdgeTrianglePath = function(e2, t2, n2) {
|
|
t2.fillStyle = t2.strokeStyle;
|
|
for (var r2 = e2.pstyle("width").pfValue, i2 = 0; i2 + 1 < n2.length; i2 += 2) {
|
|
var a2 = [n2[i2 + 2] - n2[i2], n2[i2 + 3] - n2[i2 + 1]], o2 = Math.sqrt(a2[0] * a2[0] + a2[1] * a2[1]), s2 = [a2[1] / o2, -a2[0] / o2], l2 = [s2[0] * r2 / 2, s2[1] * r2 / 2];
|
|
t2.beginPath(), t2.moveTo(n2[i2] - l2[0], n2[i2 + 1] - l2[1]), t2.lineTo(n2[i2] + l2[0], n2[i2 + 1] + l2[1]), t2.lineTo(n2[i2 + 2], n2[i2 + 3]), t2.closePath(), t2.fill();
|
|
}
|
|
}, mu.drawArrowheads = function(e2, t2, n2) {
|
|
var r2 = t2._private.rscratch, i2 = "haystack" === r2.edgeType;
|
|
i2 || this.drawArrowhead(e2, t2, "source", r2.arrowStartX, r2.arrowStartY, r2.srcArrowAngle, n2), this.drawArrowhead(e2, t2, "mid-target", r2.midX, r2.midY, r2.midtgtArrowAngle, n2), this.drawArrowhead(e2, t2, "mid-source", r2.midX, r2.midY, r2.midsrcArrowAngle, n2), i2 || this.drawArrowhead(e2, t2, "target", r2.arrowEndX, r2.arrowEndY, r2.tgtArrowAngle, n2);
|
|
}, mu.drawArrowhead = function(e2, t2, n2, r2, i2, a2, o2) {
|
|
if (!(isNaN(r2) || null == r2 || isNaN(i2) || null == i2 || isNaN(a2) || null == a2)) {
|
|
var s2 = t2.pstyle(n2 + "-arrow-shape").value;
|
|
if ("none" !== s2) {
|
|
var l2 = "hollow" === t2.pstyle(n2 + "-arrow-fill").value ? "both" : "filled", u2 = t2.pstyle(n2 + "-arrow-fill").value, c2 = t2.pstyle("width").pfValue, d2 = t2.pstyle(n2 + "-arrow-width"), h2 = "match-line" === d2.value ? c2 : d2.pfValue;
|
|
"%" === d2.units && (h2 *= c2);
|
|
var p2 = t2.pstyle("opacity").value;
|
|
void 0 === o2 && (o2 = p2);
|
|
var f2 = e2.globalCompositeOperation;
|
|
1 === o2 && "hollow" !== u2 || (e2.globalCompositeOperation = "destination-out", this.colorFillStyle(e2, 255, 255, 255, 1), this.colorStrokeStyle(e2, 255, 255, 255, 1), this.drawArrowShape(t2, e2, l2, c2, s2, h2, r2, i2, a2), e2.globalCompositeOperation = f2);
|
|
var g2 = t2.pstyle(n2 + "-arrow-color").value;
|
|
this.colorFillStyle(e2, g2[0], g2[1], g2[2], o2), this.colorStrokeStyle(e2, g2[0], g2[1], g2[2], o2), this.drawArrowShape(t2, e2, u2, c2, s2, h2, r2, i2, a2);
|
|
}
|
|
}
|
|
}, mu.drawArrowShape = function(e2, t2, n2, r2, i2, a2, o2, s2, l2) {
|
|
var u2, c2 = this, d2 = this.usePaths() && "triangle-cross" !== i2, h2 = false, p2 = t2, f2 = { x: o2, y: s2 }, g2 = e2.pstyle("arrow-scale").value, v2 = this.getArrowWidth(r2, g2), y2 = c2.arrowShapes[i2];
|
|
if (d2) {
|
|
var m2 = c2.arrowPathCache = c2.arrowPathCache || [], b2 = Pe(i2), x2 = m2[b2];
|
|
null != x2 ? (u2 = t2 = x2, h2 = true) : (u2 = t2 = new Path2D(), m2[b2] = u2);
|
|
}
|
|
h2 || (t2.beginPath && t2.beginPath(), d2 ? y2.draw(t2, 1, 0, { x: 0, y: 0 }, 1) : y2.draw(t2, v2, l2, f2, r2), t2.closePath && t2.closePath()), t2 = p2, d2 && (t2.translate(o2, s2), t2.rotate(l2), t2.scale(v2, v2)), "filled" !== n2 && "both" !== n2 || (d2 ? t2.fill(u2) : t2.fill()), "hollow" !== n2 && "both" !== n2 || (t2.lineWidth = a2 / (d2 ? v2 : 1), t2.lineJoin = "miter", d2 ? t2.stroke(u2) : t2.stroke()), d2 && (t2.scale(1 / v2, 1 / v2), t2.rotate(-l2), t2.translate(-o2, -s2));
|
|
};
|
|
var xu = { safeDrawImage: function(e2, t2, n2, r2, i2, a2, o2, s2, l2, u2) {
|
|
if (!(i2 <= 0 || a2 <= 0 || l2 <= 0 || u2 <= 0)) try {
|
|
e2.drawImage(t2, n2, r2, i2, a2, o2, s2, l2, u2);
|
|
} catch (e3) {
|
|
Ve(e3);
|
|
}
|
|
}, drawInscribedImage: function(e2, t2, n2, r2, i2) {
|
|
var a2 = this, o2 = n2.position(), s2 = o2.x, l2 = o2.y, u2 = n2.cy().style(), c2 = u2.getIndexedStyle.bind(u2), d2 = c2(n2, "background-fit", "value", r2), h2 = c2(n2, "background-repeat", "value", r2), p2 = n2.width(), f2 = n2.height(), g2 = 2 * n2.padding(), v2 = p2 + ("inner" === c2(n2, "background-width-relative-to", "value", r2) ? 0 : g2), y2 = f2 + ("inner" === c2(n2, "background-height-relative-to", "value", r2) ? 0 : g2), m2 = n2._private.rscratch, b2 = "node" === c2(n2, "background-clip", "value", r2), x2 = c2(n2, "background-image-opacity", "value", r2) * i2, w2 = c2(n2, "background-image-smoothing", "value", r2), E2 = t2.width || t2.cachedW, k2 = t2.height || t2.cachedH;
|
|
null != E2 && null != k2 || (document.body.appendChild(t2), E2 = t2.cachedW = t2.width || t2.offsetWidth, k2 = t2.cachedH = t2.height || t2.offsetHeight, document.body.removeChild(t2));
|
|
var C2 = E2, S2 = k2;
|
|
if ("auto" !== c2(n2, "background-width", "value", r2) && (C2 = "%" === c2(n2, "background-width", "units", r2) ? c2(n2, "background-width", "pfValue", r2) * v2 : c2(n2, "background-width", "pfValue", r2)), "auto" !== c2(n2, "background-height", "value", r2) && (S2 = "%" === c2(n2, "background-height", "units", r2) ? c2(n2, "background-height", "pfValue", r2) * y2 : c2(n2, "background-height", "pfValue", r2)), 0 !== C2 && 0 !== S2) {
|
|
if ("contain" === d2) C2 *= P2 = Math.min(v2 / C2, y2 / S2), S2 *= P2;
|
|
else if ("cover" === d2) {
|
|
var P2;
|
|
C2 *= P2 = Math.max(v2 / C2, y2 / S2), S2 *= P2;
|
|
}
|
|
var D2 = s2 - v2 / 2, T2 = c2(n2, "background-position-x", "units", r2), _2 = c2(n2, "background-position-x", "pfValue", r2);
|
|
D2 += "%" === T2 ? (v2 - C2) * _2 : _2;
|
|
var M2 = c2(n2, "background-offset-x", "units", r2), B2 = c2(n2, "background-offset-x", "pfValue", r2);
|
|
D2 += "%" === M2 ? (v2 - C2) * B2 : B2;
|
|
var N2 = l2 - y2 / 2, z2 = c2(n2, "background-position-y", "units", r2), I2 = c2(n2, "background-position-y", "pfValue", r2);
|
|
N2 += "%" === z2 ? (y2 - S2) * I2 : I2;
|
|
var L3 = c2(n2, "background-offset-y", "units", r2), A2 = c2(n2, "background-offset-y", "pfValue", r2);
|
|
N2 += "%" === L3 ? (y2 - S2) * A2 : A2, m2.pathCache && (D2 -= s2, N2 -= l2, s2 = 0, l2 = 0);
|
|
var O2 = e2.globalAlpha;
|
|
e2.globalAlpha = x2;
|
|
var R2 = a2.getImgSmoothing(e2), V2 = false;
|
|
if ("no" === w2 && R2 ? (a2.setImgSmoothing(e2, false), V2 = true) : "yes" !== w2 || R2 || (a2.setImgSmoothing(e2, true), V2 = true), "no-repeat" === h2) b2 && (e2.save(), m2.pathCache ? e2.clip(m2.pathCache) : (a2.nodeShapes[a2.getNodeShape(n2)].draw(e2, s2, l2, v2, y2), e2.clip())), a2.safeDrawImage(e2, t2, 0, 0, E2, k2, D2, N2, C2, S2), b2 && e2.restore();
|
|
else {
|
|
var F2 = e2.createPattern(t2, h2);
|
|
e2.fillStyle = F2, a2.nodeShapes[a2.getNodeShape(n2)].draw(e2, s2, l2, v2, y2), e2.translate(D2, N2), e2.fill(), e2.translate(-D2, -N2);
|
|
}
|
|
e2.globalAlpha = O2, V2 && a2.setImgSmoothing(e2, R2);
|
|
}
|
|
} }, wu = {};
|
|
function Eu(e2, t2, n2, r2, i2) {
|
|
var a2 = arguments.length > 5 && void 0 !== arguments[5] ? arguments[5] : 5, o2 = arguments.length > 6 ? arguments[6] : void 0;
|
|
e2.beginPath(), e2.moveTo(t2 + a2, n2), e2.lineTo(t2 + r2 - a2, n2), e2.quadraticCurveTo(t2 + r2, n2, t2 + r2, n2 + a2), e2.lineTo(t2 + r2, n2 + i2 - a2), e2.quadraticCurveTo(t2 + r2, n2 + i2, t2 + r2 - a2, n2 + i2), e2.lineTo(t2 + a2, n2 + i2), e2.quadraticCurveTo(t2, n2 + i2, t2, n2 + i2 - a2), e2.lineTo(t2, n2 + a2), e2.quadraticCurveTo(t2, n2, t2 + a2, n2), e2.closePath(), o2 ? e2.stroke() : e2.fill();
|
|
}
|
|
wu.eleTextBiggerThanMin = function(e2, t2) {
|
|
if (!t2) {
|
|
var n2 = e2.cy().zoom(), r2 = this.getPixelRatio(), i2 = Math.ceil(bt(n2 * r2));
|
|
t2 = Math.pow(2, i2);
|
|
}
|
|
return !(e2.pstyle("font-size").pfValue * t2 < e2.pstyle("min-zoomed-font-size").pfValue);
|
|
}, wu.drawElementText = function(e2, t2, n2, r2, i2) {
|
|
var a2 = !(arguments.length > 5 && void 0 !== arguments[5]) || arguments[5], o2 = this;
|
|
if (null == r2) {
|
|
if (a2 && !o2.eleTextBiggerThanMin(t2)) return;
|
|
} else if (false === r2) return;
|
|
if (t2.isNode()) {
|
|
var s2 = t2.pstyle("label");
|
|
if (!s2 || !s2.value) return;
|
|
var l2 = o2.getLabelJustification(t2);
|
|
e2.textAlign = l2, e2.textBaseline = "bottom";
|
|
} else {
|
|
var u2 = t2.element()._private.rscratch.badLine, c2 = t2.pstyle("label"), d2 = t2.pstyle("source-label"), h2 = t2.pstyle("target-label");
|
|
if (u2 || (!c2 || !c2.value) && (!d2 || !d2.value) && (!h2 || !h2.value)) return;
|
|
e2.textAlign = "center", e2.textBaseline = "bottom";
|
|
}
|
|
var p2, f2 = !n2;
|
|
n2 && (p2 = n2, e2.translate(-p2.x1, -p2.y1)), null == i2 ? (o2.drawText(e2, t2, null, f2, a2), t2.isEdge() && (o2.drawText(e2, t2, "source", f2, a2), o2.drawText(e2, t2, "target", f2, a2))) : o2.drawText(e2, t2, i2, f2, a2), n2 && e2.translate(p2.x1, p2.y1);
|
|
}, wu.getFontCache = function(e2) {
|
|
var t2;
|
|
this.fontCaches = this.fontCaches || [];
|
|
for (var n2 = 0; n2 < this.fontCaches.length; n2++) if ((t2 = this.fontCaches[n2]).context === e2) return t2;
|
|
return t2 = { context: e2 }, this.fontCaches.push(t2), t2;
|
|
}, wu.setupTextStyle = function(e2, t2) {
|
|
var n2 = !(arguments.length > 2 && void 0 !== arguments[2]) || arguments[2], r2 = t2.pstyle("font-style").strValue, i2 = t2.pstyle("font-size").pfValue + "px", a2 = t2.pstyle("font-family").strValue, o2 = t2.pstyle("font-weight").strValue, s2 = n2 ? t2.effectiveOpacity() * t2.pstyle("text-opacity").value : 1, l2 = t2.pstyle("text-outline-opacity").value * s2, u2 = t2.pstyle("color").value, c2 = t2.pstyle("text-outline-color").value;
|
|
e2.font = r2 + " " + o2 + " " + i2 + " " + a2, e2.lineJoin = "round", this.colorFillStyle(e2, u2[0], u2[1], u2[2], s2), this.colorStrokeStyle(e2, c2[0], c2[1], c2[2], l2);
|
|
}, wu.getTextAngle = function(e2, t2) {
|
|
var n2 = e2._private.rscratch, r2 = t2 ? t2 + "-" : "", i2 = e2.pstyle(r2 + "text-rotation"), a2 = Ke(n2, "labelAngle", t2);
|
|
return "autorotate" === i2.strValue ? e2.isEdge() ? a2 : 0 : "none" === i2.strValue ? 0 : i2.pfValue;
|
|
}, wu.drawText = function(e2, t2, n2) {
|
|
var r2 = !(arguments.length > 3 && void 0 !== arguments[3]) || arguments[3], i2 = !(arguments.length > 4 && void 0 !== arguments[4]) || arguments[4], a2 = t2._private, o2 = a2.rscratch, s2 = i2 ? t2.effectiveOpacity() : 1;
|
|
if (!i2 || 0 !== s2 && 0 !== t2.pstyle("text-opacity").value) {
|
|
"main" === n2 && (n2 = null);
|
|
var l2, u2, c2 = Ke(o2, "labelX", n2), d2 = Ke(o2, "labelY", n2), h2 = this.getLabelText(t2, n2);
|
|
if (null != h2 && "" !== h2 && !isNaN(c2) && !isNaN(d2)) {
|
|
this.setupTextStyle(e2, t2, i2);
|
|
var p2, f2 = n2 ? n2 + "-" : "", g2 = Ke(o2, "labelWidth", n2), v2 = Ke(o2, "labelHeight", n2), y2 = t2.pstyle(f2 + "text-margin-x").pfValue, m2 = t2.pstyle(f2 + "text-margin-y").pfValue, b2 = t2.isEdge(), x2 = t2.pstyle("text-halign").value, w2 = t2.pstyle("text-valign").value;
|
|
switch (b2 && (x2 = "center", w2 = "center"), c2 += y2, d2 += m2, 0 !== (p2 = r2 ? this.getTextAngle(t2, n2) : 0) && (l2 = c2, u2 = d2, e2.translate(l2, u2), e2.rotate(p2), c2 = 0, d2 = 0), w2) {
|
|
case "top":
|
|
break;
|
|
case "center":
|
|
d2 += v2 / 2;
|
|
break;
|
|
case "bottom":
|
|
d2 += v2;
|
|
}
|
|
var E2 = t2.pstyle("text-background-opacity").value, k2 = t2.pstyle("text-border-opacity").value, C2 = t2.pstyle("text-border-width").pfValue, S2 = t2.pstyle("text-background-padding").pfValue, P2 = t2.pstyle("text-background-shape").strValue, D2 = 0 === P2.indexOf("round"), T2 = 2;
|
|
if (E2 > 0 || C2 > 0 && k2 > 0) {
|
|
var _2 = c2 - S2;
|
|
switch (x2) {
|
|
case "left":
|
|
_2 -= g2;
|
|
break;
|
|
case "center":
|
|
_2 -= g2 / 2;
|
|
}
|
|
var M2 = d2 - v2 - S2, B2 = g2 + 2 * S2, N2 = v2 + 2 * S2;
|
|
if (E2 > 0) {
|
|
var z2 = e2.fillStyle, I2 = t2.pstyle("text-background-color").value;
|
|
e2.fillStyle = "rgba(" + I2[0] + "," + I2[1] + "," + I2[2] + "," + E2 * s2 + ")", D2 ? Eu(e2, _2, M2, B2, N2, T2) : e2.fillRect(_2, M2, B2, N2), e2.fillStyle = z2;
|
|
}
|
|
if (C2 > 0 && k2 > 0) {
|
|
var L3 = e2.strokeStyle, A2 = e2.lineWidth, O2 = t2.pstyle("text-border-color").value, R2 = t2.pstyle("text-border-style").value;
|
|
if (e2.strokeStyle = "rgba(" + O2[0] + "," + O2[1] + "," + O2[2] + "," + k2 * s2 + ")", e2.lineWidth = C2, e2.setLineDash) switch (R2) {
|
|
case "dotted":
|
|
e2.setLineDash([1, 1]);
|
|
break;
|
|
case "dashed":
|
|
e2.setLineDash([4, 2]);
|
|
break;
|
|
case "double":
|
|
e2.lineWidth = C2 / 4, e2.setLineDash([]);
|
|
break;
|
|
case "solid":
|
|
e2.setLineDash([]);
|
|
}
|
|
if (D2 ? Eu(e2, _2, M2, B2, N2, T2, "stroke") : e2.strokeRect(_2, M2, B2, N2), "double" === R2) {
|
|
var V2 = C2 / 2;
|
|
D2 ? Eu(e2, _2 + V2, M2 + V2, B2 - 2 * V2, N2 - 2 * V2, T2, "stroke") : e2.strokeRect(_2 + V2, M2 + V2, B2 - 2 * V2, N2 - 2 * V2);
|
|
}
|
|
e2.setLineDash && e2.setLineDash([]), e2.lineWidth = A2, e2.strokeStyle = L3;
|
|
}
|
|
}
|
|
var F2 = 2 * t2.pstyle("text-outline-width").pfValue;
|
|
if (F2 > 0 && (e2.lineWidth = F2), "wrap" === t2.pstyle("text-wrap").value) {
|
|
var j2 = Ke(o2, "labelWrapCachedLines", n2), q2 = Ke(o2, "labelLineHeight", n2), Y2 = g2 / 2, X2 = this.getLabelJustification(t2);
|
|
switch ("auto" === X2 || ("left" === x2 ? "left" === X2 ? c2 += -g2 : "center" === X2 && (c2 += -Y2) : "center" === x2 ? "left" === X2 ? c2 += -Y2 : "right" === X2 && (c2 += Y2) : "right" === x2 && ("center" === X2 ? c2 += Y2 : "right" === X2 && (c2 += g2))), w2) {
|
|
case "top":
|
|
d2 -= (j2.length - 1) * q2;
|
|
break;
|
|
case "center":
|
|
case "bottom":
|
|
d2 -= (j2.length - 1) * q2;
|
|
}
|
|
for (var W2 = 0; W2 < j2.length; W2++) F2 > 0 && e2.strokeText(j2[W2], c2, d2), e2.fillText(j2[W2], c2, d2), d2 += q2;
|
|
} else F2 > 0 && e2.strokeText(h2, c2, d2), e2.fillText(h2, c2, d2);
|
|
0 !== p2 && (e2.rotate(-p2), e2.translate(-l2, -u2));
|
|
}
|
|
}
|
|
};
|
|
var ku = { drawNode: function(e2, t2, n2) {
|
|
var r2, i2, a2 = !(arguments.length > 3 && void 0 !== arguments[3]) || arguments[3], o2 = !(arguments.length > 4 && void 0 !== arguments[4]) || arguments[4], s2 = !(arguments.length > 5 && void 0 !== arguments[5]) || arguments[5], l2 = this, u2 = t2._private, c2 = u2.rscratch, d2 = t2.position();
|
|
if (m(d2.x) && m(d2.y) && (!s2 || t2.visible())) {
|
|
var h2, p2, f2 = s2 ? t2.effectiveOpacity() : 1, g2 = l2.usePaths(), v2 = false, y2 = t2.padding();
|
|
r2 = t2.width() + 2 * y2, i2 = t2.height() + 2 * y2, n2 && (p2 = n2, e2.translate(-p2.x1, -p2.y1));
|
|
for (var b2 = t2.pstyle("background-image"), x2 = b2.value, w2 = new Array(x2.length), E2 = new Array(x2.length), k2 = 0, C2 = 0; C2 < x2.length; C2++) {
|
|
var S2 = x2[C2], P2 = w2[C2] = null != S2 && "none" !== S2;
|
|
if (P2) {
|
|
var D2 = t2.cy().style().getIndexedStyle(t2, "background-image-crossorigin", "value", C2);
|
|
k2++, E2[C2] = l2.getCachedImage(S2, D2, function() {
|
|
u2.backgroundTimestamp = Date.now(), t2.emitAndNotify("background");
|
|
});
|
|
}
|
|
}
|
|
var T2 = t2.pstyle("background-blacken").value, _2 = t2.pstyle("border-width").pfValue, M2 = t2.pstyle("background-opacity").value * f2, B2 = t2.pstyle("border-color").value, N2 = t2.pstyle("border-style").value, z2 = t2.pstyle("border-opacity").value * f2, I2 = t2.pstyle("outline-width").pfValue, L3 = t2.pstyle("outline-color").value, A2 = t2.pstyle("outline-style").value, O2 = t2.pstyle("outline-opacity").value * f2, R2 = t2.pstyle("outline-offset").value;
|
|
e2.lineJoin = "miter";
|
|
var V2 = function() {
|
|
var n3 = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : M2;
|
|
l2.eleFillStyle(e2, t2, n3);
|
|
}, F2 = function() {
|
|
var t3 = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : z2;
|
|
l2.colorStrokeStyle(e2, B2[0], B2[1], B2[2], t3);
|
|
}, j2 = function() {
|
|
var t3 = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : O2;
|
|
l2.colorStrokeStyle(e2, L3[0], L3[1], L3[2], t3);
|
|
}, q2 = function(e3, t3, n3, r3) {
|
|
var i3, a3 = l2.nodePathCache = l2.nodePathCache || [], o3 = De("polygon" === n3 ? n3 + "," + r3.join(",") : n3, "" + t3, "" + e3), s3 = a3[o3], u3 = false;
|
|
return null != s3 ? (i3 = s3, u3 = true, c2.pathCache = i3) : (i3 = new Path2D(), a3[o3] = c2.pathCache = i3), { path: i3, cacheHit: u3 };
|
|
}, Y2 = t2.pstyle("shape").strValue, X2 = t2.pstyle("shape-polygon-points").pfValue;
|
|
if (g2) {
|
|
e2.translate(d2.x, d2.y);
|
|
var W2 = q2(r2, i2, Y2, X2);
|
|
h2 = W2.path, v2 = W2.cacheHit;
|
|
}
|
|
var H2 = function() {
|
|
if (!v2) {
|
|
var n3 = d2;
|
|
g2 && (n3 = { x: 0, y: 0 }), l2.nodeShapes[l2.getNodeShape(t2)].draw(h2 || e2, n3.x, n3.y, r2, i2);
|
|
}
|
|
g2 ? e2.fill(h2) : e2.fill();
|
|
}, K2 = function() {
|
|
for (var n3 = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : f2, r3 = !(arguments.length > 1 && void 0 !== arguments[1]) || arguments[1], i3 = u2.backgrounding, a3 = 0, o3 = 0; o3 < E2.length; o3++) {
|
|
var s3 = t2.cy().style().getIndexedStyle(t2, "background-image-containment", "value", o3);
|
|
r3 && "over" === s3 || !r3 && "inside" === s3 ? a3++ : w2[o3] && E2[o3].complete && !E2[o3].error && (a3++, l2.drawInscribedImage(e2, E2[o3], t2, o3, n3));
|
|
}
|
|
u2.backgrounding = !(a3 === k2), i3 !== u2.backgrounding && t2.updateStyle(false);
|
|
}, G2 = function() {
|
|
var n3 = arguments.length > 0 && void 0 !== arguments[0] && arguments[0], a3 = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : f2;
|
|
l2.hasPie(t2) && (l2.drawPie(e2, t2, a3), n3 && (g2 || l2.nodeShapes[l2.getNodeShape(t2)].draw(e2, d2.x, d2.y, r2, i2)));
|
|
}, U2 = function() {
|
|
var t3 = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : f2, n3 = (T2 > 0 ? T2 : -T2) * t3, r3 = T2 > 0 ? 0 : 255;
|
|
0 !== T2 && (l2.colorFillStyle(e2, r3, r3, r3, n3), g2 ? e2.fill(h2) : e2.fill());
|
|
}, Z2 = function() {
|
|
if (_2 > 0) {
|
|
if (e2.lineWidth = _2, e2.lineCap = "butt", e2.setLineDash) switch (N2) {
|
|
case "dotted":
|
|
e2.setLineDash([1, 1]);
|
|
break;
|
|
case "dashed":
|
|
e2.setLineDash([4, 2]);
|
|
break;
|
|
case "solid":
|
|
case "double":
|
|
e2.setLineDash([]);
|
|
}
|
|
if (g2 ? e2.stroke(h2) : e2.stroke(), "double" === N2) {
|
|
e2.lineWidth = _2 / 3;
|
|
var t3 = e2.globalCompositeOperation;
|
|
e2.globalCompositeOperation = "destination-out", g2 ? e2.stroke(h2) : e2.stroke(), e2.globalCompositeOperation = t3;
|
|
}
|
|
e2.setLineDash && e2.setLineDash([]);
|
|
}
|
|
}, $2 = function() {
|
|
if (I2 > 0) {
|
|
if (e2.lineWidth = I2, e2.lineCap = "butt", e2.setLineDash) switch (A2) {
|
|
case "dotted":
|
|
e2.setLineDash([1, 1]);
|
|
break;
|
|
case "dashed":
|
|
e2.setLineDash([4, 2]);
|
|
break;
|
|
case "solid":
|
|
case "double":
|
|
e2.setLineDash([]);
|
|
}
|
|
var n3 = d2;
|
|
g2 && (n3 = { x: 0, y: 0 });
|
|
var a3, o3 = l2.getNodeShape(t2), s3 = (r2 + _2 + (I2 + R2)) / r2, u3 = (i2 + _2 + (I2 + R2)) / i2, c3 = r2 * s3, h3 = i2 * u3, p3 = l2.nodeShapes[o3].points;
|
|
if (g2) a3 = q2(c3, h3, o3, p3).path;
|
|
if ("ellipse" === o3) l2.drawEllipsePath(a3 || e2, n3.x, n3.y, c3, h3);
|
|
else if (["round-diamond", "round-heptagon", "round-hexagon", "round-octagon", "round-pentagon", "round-polygon", "round-triangle", "round-tag"].includes(o3)) {
|
|
var f3 = 0, v3 = 0, y3 = 0;
|
|
"round-diamond" === o3 ? f3 = 1.4 * (_2 + R2 + I2) : "round-heptagon" === o3 ? (f3 = 1.075 * (_2 + R2 + I2), y3 = -(_2 / 2 + R2 + I2) / 35) : "round-hexagon" === o3 ? f3 = 1.12 * (_2 + R2 + I2) : "round-pentagon" === o3 ? (f3 = 1.13 * (_2 + R2 + I2), y3 = -(_2 / 2 + R2 + I2) / 15) : "round-tag" === o3 ? (f3 = 1.12 * (_2 + R2 + I2), v3 = 0.07 * (_2 / 2 + I2 + R2)) : "round-triangle" === o3 && (f3 = (_2 + R2 + I2) * (Math.PI / 2), y3 = -(_2 + R2 / 2 + I2) / Math.PI), 0 !== f3 && (s3 = (r2 + f3) / r2, u3 = (i2 + f3) / i2), l2.drawRoundPolygonPath(a3 || e2, n3.x + v3, n3.y + y3, r2 * s3, i2 * u3, p3);
|
|
} else if (["roundrectangle", "round-rectangle"].includes(o3)) l2.drawRoundRectanglePath(a3 || e2, n3.x, n3.y, c3, h3);
|
|
else if (["cutrectangle", "cut-rectangle"].includes(o3)) l2.drawCutRectanglePath(a3 || e2, n3.x, n3.y, c3, h3);
|
|
else if (["bottomroundrectangle", "bottom-round-rectangle"].includes(o3)) l2.drawBottomRoundRectanglePath(a3 || e2, n3.x, n3.y, c3, h3);
|
|
else if ("barrel" === o3) l2.drawBarrelPath(a3 || e2, n3.x, n3.y, c3, h3);
|
|
else if (o3.startsWith("polygon") || ["rhomboid", "right-rhomboid", "round-tag", "tag", "vee"].includes(o3)) {
|
|
p3 = Yt(Xt(p3, (_2 + I2 + R2) / r2)), l2.drawPolygonPath(a3 || e2, n3.x, n3.y, r2, i2, p3);
|
|
} else {
|
|
p3 = Yt(Xt(p3, -((_2 + I2 + R2) / r2))), l2.drawPolygonPath(a3 || e2, n3.x, n3.y, r2, i2, p3);
|
|
}
|
|
if (g2 ? e2.stroke(a3) : e2.stroke(), "double" === A2) {
|
|
e2.lineWidth = _2 / 3;
|
|
var m2 = e2.globalCompositeOperation;
|
|
e2.globalCompositeOperation = "destination-out", g2 ? e2.stroke(a3) : e2.stroke(), e2.globalCompositeOperation = m2;
|
|
}
|
|
e2.setLineDash && e2.setLineDash([]);
|
|
}
|
|
}, Q2 = function() {
|
|
o2 && l2.drawNodeOverlay(e2, t2, d2, r2, i2);
|
|
}, J2 = function() {
|
|
o2 && l2.drawNodeUnderlay(e2, t2, d2, r2, i2);
|
|
}, ee2 = function() {
|
|
l2.drawElementText(e2, t2, null, a2);
|
|
}, te2 = "yes" === t2.pstyle("ghost").value;
|
|
if (te2) {
|
|
var ne2 = t2.pstyle("ghost-offset-x").pfValue, re2 = t2.pstyle("ghost-offset-y").pfValue, ie2 = t2.pstyle("ghost-opacity").value, ae2 = ie2 * f2;
|
|
e2.translate(ne2, re2), j2(), $2(), V2(ie2 * M2), H2(), K2(ae2, true), F2(ie2 * z2), Z2(), G2(0 !== T2 || 0 !== _2), K2(ae2, false), U2(ae2), e2.translate(-ne2, -re2);
|
|
}
|
|
g2 && e2.translate(-d2.x, -d2.y), J2(), g2 && e2.translate(d2.x, d2.y), j2(), $2(), V2(), H2(), K2(f2, true), F2(), Z2(), G2(0 !== T2 || 0 !== _2), K2(f2, false), U2(), g2 && e2.translate(-d2.x, -d2.y), ee2(), Q2(), n2 && e2.translate(p2.x1, p2.y1);
|
|
}
|
|
} }, Cu = function(e2) {
|
|
if (!["overlay", "underlay"].includes(e2)) throw new Error("Invalid state");
|
|
return function(t2, n2, r2, i2, a2) {
|
|
if (n2.visible()) {
|
|
var o2 = n2.pstyle("".concat(e2, "-padding")).pfValue, s2 = n2.pstyle("".concat(e2, "-opacity")).value, l2 = n2.pstyle("".concat(e2, "-color")).value, u2 = n2.pstyle("".concat(e2, "-shape")).value;
|
|
if (s2 > 0) {
|
|
if (r2 = r2 || n2.position(), null == i2 || null == a2) {
|
|
var c2 = n2.padding();
|
|
i2 = n2.width() + 2 * c2, a2 = n2.height() + 2 * c2;
|
|
}
|
|
this.colorFillStyle(t2, l2[0], l2[1], l2[2], s2), this.nodeShapes[u2].draw(t2, r2.x, r2.y, i2 + 2 * o2, a2 + 2 * o2), t2.fill();
|
|
}
|
|
}
|
|
};
|
|
};
|
|
ku.drawNodeOverlay = Cu("overlay"), ku.drawNodeUnderlay = Cu("underlay"), ku.hasPie = function(e2) {
|
|
return (e2 = e2[0])._private.hasPie;
|
|
}, ku.drawPie = function(e2, t2, n2, r2) {
|
|
t2 = t2[0], r2 = r2 || t2.position();
|
|
var i2 = t2.cy().style(), a2 = t2.pstyle("pie-size"), o2 = r2.x, s2 = r2.y, l2 = t2.width(), u2 = t2.height(), c2 = Math.min(l2, u2) / 2, d2 = 0;
|
|
this.usePaths() && (o2 = 0, s2 = 0), "%" === a2.units ? c2 *= a2.pfValue : void 0 !== a2.pfValue && (c2 = a2.pfValue / 2);
|
|
for (var h2 = 1; h2 <= i2.pieBackgroundN; h2++) {
|
|
var p2 = t2.pstyle("pie-" + h2 + "-background-size").value, f2 = t2.pstyle("pie-" + h2 + "-background-color").value, g2 = t2.pstyle("pie-" + h2 + "-background-opacity").value * n2, v2 = p2 / 100;
|
|
v2 + d2 > 1 && (v2 = 1 - d2);
|
|
var y2 = 1.5 * Math.PI + 2 * Math.PI * d2, m2 = y2 + 2 * Math.PI * v2;
|
|
0 === p2 || d2 >= 1 || d2 + v2 > 1 || (e2.beginPath(), e2.moveTo(o2, s2), e2.arc(o2, s2, c2, y2, m2), e2.closePath(), this.colorFillStyle(e2, f2[0], f2[1], f2[2], g2), e2.fill(), d2 += v2);
|
|
}
|
|
};
|
|
var Su = {};
|
|
Su.getPixelRatio = function() {
|
|
var e2 = this.data.contexts[0];
|
|
if (null != this.forcedPixelRatio) return this.forcedPixelRatio;
|
|
var t2 = e2.backingStorePixelRatio || e2.webkitBackingStorePixelRatio || e2.mozBackingStorePixelRatio || e2.msBackingStorePixelRatio || e2.oBackingStorePixelRatio || e2.backingStorePixelRatio || 1;
|
|
return (window.devicePixelRatio || 1) / t2;
|
|
}, Su.paintCache = function(e2) {
|
|
for (var t2, n2 = this.paintCaches = this.paintCaches || [], r2 = true, i2 = 0; i2 < n2.length; i2++) if ((t2 = n2[i2]).context === e2) {
|
|
r2 = false;
|
|
break;
|
|
}
|
|
return r2 && (t2 = { context: e2 }, n2.push(t2)), t2;
|
|
}, Su.createGradientStyleFor = function(e2, t2, n2, r2, i2) {
|
|
var a2, o2 = this.usePaths(), s2 = n2.pstyle(t2 + "-gradient-stop-colors").value, l2 = n2.pstyle(t2 + "-gradient-stop-positions").pfValue;
|
|
if ("radial-gradient" === r2) if (n2.isEdge()) {
|
|
var u2 = n2.sourceEndpoint(), c2 = n2.targetEndpoint(), d2 = n2.midpoint(), h2 = wt(u2, d2), p2 = wt(c2, d2);
|
|
a2 = e2.createRadialGradient(d2.x, d2.y, 0, d2.x, d2.y, Math.max(h2, p2));
|
|
} else {
|
|
var f2 = o2 ? { x: 0, y: 0 } : n2.position(), g2 = n2.paddedWidth(), v2 = n2.paddedHeight();
|
|
a2 = e2.createRadialGradient(f2.x, f2.y, 0, f2.x, f2.y, Math.max(g2, v2));
|
|
}
|
|
else if (n2.isEdge()) {
|
|
var y2 = n2.sourceEndpoint(), m2 = n2.targetEndpoint();
|
|
a2 = e2.createLinearGradient(y2.x, y2.y, m2.x, m2.y);
|
|
} else {
|
|
var b2 = o2 ? { x: 0, y: 0 } : n2.position(), x2 = n2.paddedWidth() / 2, w2 = n2.paddedHeight() / 2;
|
|
switch (n2.pstyle("background-gradient-direction").value) {
|
|
case "to-bottom":
|
|
a2 = e2.createLinearGradient(b2.x, b2.y - w2, b2.x, b2.y + w2);
|
|
break;
|
|
case "to-top":
|
|
a2 = e2.createLinearGradient(b2.x, b2.y + w2, b2.x, b2.y - w2);
|
|
break;
|
|
case "to-left":
|
|
a2 = e2.createLinearGradient(b2.x + x2, b2.y, b2.x - x2, b2.y);
|
|
break;
|
|
case "to-right":
|
|
a2 = e2.createLinearGradient(b2.x - x2, b2.y, b2.x + x2, b2.y);
|
|
break;
|
|
case "to-bottom-right":
|
|
case "to-right-bottom":
|
|
a2 = e2.createLinearGradient(b2.x - x2, b2.y - w2, b2.x + x2, b2.y + w2);
|
|
break;
|
|
case "to-top-right":
|
|
case "to-right-top":
|
|
a2 = e2.createLinearGradient(b2.x - x2, b2.y + w2, b2.x + x2, b2.y - w2);
|
|
break;
|
|
case "to-bottom-left":
|
|
case "to-left-bottom":
|
|
a2 = e2.createLinearGradient(b2.x + x2, b2.y - w2, b2.x - x2, b2.y + w2);
|
|
break;
|
|
case "to-top-left":
|
|
case "to-left-top":
|
|
a2 = e2.createLinearGradient(b2.x + x2, b2.y + w2, b2.x - x2, b2.y - w2);
|
|
}
|
|
}
|
|
if (!a2) return null;
|
|
for (var E2 = l2.length === s2.length, k2 = s2.length, C2 = 0; C2 < k2; C2++) a2.addColorStop(E2 ? l2[C2] : C2 / (k2 - 1), "rgba(" + s2[C2][0] + "," + s2[C2][1] + "," + s2[C2][2] + "," + i2 + ")");
|
|
return a2;
|
|
}, Su.gradientFillStyle = function(e2, t2, n2, r2) {
|
|
var i2 = this.createGradientStyleFor(e2, "background", t2, n2, r2);
|
|
if (!i2) return null;
|
|
e2.fillStyle = i2;
|
|
}, Su.colorFillStyle = function(e2, t2, n2, r2, i2) {
|
|
e2.fillStyle = "rgba(" + t2 + "," + n2 + "," + r2 + "," + i2 + ")";
|
|
}, Su.eleFillStyle = function(e2, t2, n2) {
|
|
var r2 = t2.pstyle("background-fill").value;
|
|
if ("linear-gradient" === r2 || "radial-gradient" === r2) this.gradientFillStyle(e2, t2, r2, n2);
|
|
else {
|
|
var i2 = t2.pstyle("background-color").value;
|
|
this.colorFillStyle(e2, i2[0], i2[1], i2[2], n2);
|
|
}
|
|
}, Su.gradientStrokeStyle = function(e2, t2, n2, r2) {
|
|
var i2 = this.createGradientStyleFor(e2, "line", t2, n2, r2);
|
|
if (!i2) return null;
|
|
e2.strokeStyle = i2;
|
|
}, Su.colorStrokeStyle = function(e2, t2, n2, r2, i2) {
|
|
e2.strokeStyle = "rgba(" + t2 + "," + n2 + "," + r2 + "," + i2 + ")";
|
|
}, Su.eleStrokeStyle = function(e2, t2, n2) {
|
|
var r2 = t2.pstyle("line-fill").value;
|
|
if ("linear-gradient" === r2 || "radial-gradient" === r2) this.gradientStrokeStyle(e2, t2, r2, n2);
|
|
else {
|
|
var i2 = t2.pstyle("line-color").value;
|
|
this.colorStrokeStyle(e2, i2[0], i2[1], i2[2], n2);
|
|
}
|
|
}, Su.matchCanvasSize = function(e2) {
|
|
var t2 = this, n2 = t2.data, r2 = t2.findContainerClientCoords(), i2 = r2[2], a2 = r2[3], o2 = t2.getPixelRatio(), s2 = t2.motionBlurPxRatio;
|
|
e2 !== t2.data.bufferCanvases[t2.MOTIONBLUR_BUFFER_NODE] && e2 !== t2.data.bufferCanvases[t2.MOTIONBLUR_BUFFER_DRAG] || (o2 = s2);
|
|
var l2, u2 = i2 * o2, c2 = a2 * o2;
|
|
if (u2 !== t2.canvasWidth || c2 !== t2.canvasHeight) {
|
|
t2.fontCaches = null;
|
|
var d2 = n2.canvasContainer;
|
|
d2.style.width = i2 + "px", d2.style.height = a2 + "px";
|
|
for (var h2 = 0; h2 < t2.CANVAS_LAYERS; h2++) (l2 = n2.canvases[h2]).width = u2, l2.height = c2, l2.style.width = i2 + "px", l2.style.height = a2 + "px";
|
|
for (h2 = 0; h2 < t2.BUFFER_COUNT; h2++) (l2 = n2.bufferCanvases[h2]).width = u2, l2.height = c2, l2.style.width = i2 + "px", l2.style.height = a2 + "px";
|
|
t2.textureMult = 1, o2 <= 1 && (l2 = n2.bufferCanvases[t2.TEXTURE_BUFFER], t2.textureMult = 2, l2.width = u2 * t2.textureMult, l2.height = c2 * t2.textureMult), t2.canvasWidth = u2, t2.canvasHeight = c2;
|
|
}
|
|
}, Su.renderTo = function(e2, t2, n2, r2) {
|
|
this.render({ forcedContext: e2, forcedZoom: t2, forcedPan: n2, drawAllLayers: true, forcedPxRatio: r2 });
|
|
}, Su.render = function(e2) {
|
|
var t2 = (e2 = e2 || Ye()).forcedContext, n2 = e2.drawAllLayers, r2 = e2.drawOnlyNodeLayer, i2 = e2.forcedZoom, a2 = e2.forcedPan, o2 = this, s2 = void 0 === e2.forcedPxRatio ? this.getPixelRatio() : e2.forcedPxRatio, l2 = o2.cy, u2 = o2.data, c2 = u2.canvasNeedsRedraw, d2 = o2.textureOnViewport && !t2 && (o2.pinching || o2.hoverData.dragging || o2.swipePanning || o2.data.wheelZooming), h2 = void 0 !== e2.motionBlur ? e2.motionBlur : o2.motionBlur, p2 = o2.motionBlurPxRatio, f2 = l2.hasCompoundNodes(), g2 = o2.hoverData.draggingEles, v2 = !(!o2.hoverData.selecting && !o2.touchData.selecting), y2 = h2 = h2 && !t2 && o2.motionBlurEnabled && !v2;
|
|
t2 || (o2.prevPxRatio !== s2 && (o2.invalidateContainerClientCoordsCache(), o2.matchCanvasSize(o2.container), o2.redrawHint("eles", true), o2.redrawHint("drag", true)), o2.prevPxRatio = s2), !t2 && o2.motionBlurTimeout && clearTimeout(o2.motionBlurTimeout), h2 && (null == o2.mbFrames && (o2.mbFrames = 0), o2.mbFrames++, o2.mbFrames < 3 && (y2 = false), o2.mbFrames > o2.minMbLowQualFrames && (o2.motionBlurPxRatio = o2.mbPxRBlurry)), o2.clearingMotionBlur && (o2.motionBlurPxRatio = 1), o2.textureDrawLastFrame && !d2 && (c2[o2.NODE] = true, c2[o2.SELECT_BOX] = true);
|
|
var m2 = l2.style(), b2 = l2.zoom(), x2 = void 0 !== i2 ? i2 : b2, w2 = l2.pan(), E2 = { x: w2.x, y: w2.y }, k2 = { zoom: b2, pan: { x: w2.x, y: w2.y } }, C2 = o2.prevViewport;
|
|
void 0 === C2 || k2.zoom !== C2.zoom || k2.pan.x !== C2.pan.x || k2.pan.y !== C2.pan.y || g2 && !f2 || (o2.motionBlurPxRatio = 1), a2 && (E2 = a2), x2 *= s2, E2.x *= s2, E2.y *= s2;
|
|
var S2 = o2.getCachedZSortedEles();
|
|
function P2(e3, t3, n3, r3, i3) {
|
|
var a3 = e3.globalCompositeOperation;
|
|
e3.globalCompositeOperation = "destination-out", o2.colorFillStyle(e3, 255, 255, 255, o2.motionBlurTransparency), e3.fillRect(t3, n3, r3, i3), e3.globalCompositeOperation = a3;
|
|
}
|
|
function D2(e3, r3) {
|
|
var s3, l3, c3, d3;
|
|
o2.clearingMotionBlur || e3 !== u2.bufferContexts[o2.MOTIONBLUR_BUFFER_NODE] && e3 !== u2.bufferContexts[o2.MOTIONBLUR_BUFFER_DRAG] ? (s3 = E2, l3 = x2, c3 = o2.canvasWidth, d3 = o2.canvasHeight) : (s3 = { x: w2.x * p2, y: w2.y * p2 }, l3 = b2 * p2, c3 = o2.canvasWidth * p2, d3 = o2.canvasHeight * p2), e3.setTransform(1, 0, 0, 1, 0, 0), "motionBlur" === r3 ? P2(e3, 0, 0, c3, d3) : t2 || void 0 !== r3 && !r3 || e3.clearRect(0, 0, c3, d3), n2 || (e3.translate(s3.x, s3.y), e3.scale(l3, l3)), a2 && e3.translate(a2.x, a2.y), i2 && e3.scale(i2, i2);
|
|
}
|
|
if (d2 || (o2.textureDrawLastFrame = false), d2) {
|
|
if (o2.textureDrawLastFrame = true, !o2.textureCache) {
|
|
o2.textureCache = {}, o2.textureCache.bb = l2.mutableElements().boundingBox(), o2.textureCache.texture = o2.data.bufferCanvases[o2.TEXTURE_BUFFER];
|
|
var T2 = o2.data.bufferContexts[o2.TEXTURE_BUFFER];
|
|
T2.setTransform(1, 0, 0, 1, 0, 0), T2.clearRect(0, 0, o2.canvasWidth * o2.textureMult, o2.canvasHeight * o2.textureMult), o2.render({ forcedContext: T2, drawOnlyNodeLayer: true, forcedPxRatio: s2 * o2.textureMult }), (k2 = o2.textureCache.viewport = { zoom: l2.zoom(), pan: l2.pan(), width: o2.canvasWidth, height: o2.canvasHeight }).mpan = { x: (0 - k2.pan.x) / k2.zoom, y: (0 - k2.pan.y) / k2.zoom };
|
|
}
|
|
c2[o2.DRAG] = false, c2[o2.NODE] = false;
|
|
var _2 = u2.contexts[o2.NODE], M2 = o2.textureCache.texture;
|
|
k2 = o2.textureCache.viewport;
|
|
_2.setTransform(1, 0, 0, 1, 0, 0), h2 ? P2(_2, 0, 0, k2.width, k2.height) : _2.clearRect(0, 0, k2.width, k2.height);
|
|
var B2 = m2.core("outside-texture-bg-color").value, N2 = m2.core("outside-texture-bg-opacity").value;
|
|
o2.colorFillStyle(_2, B2[0], B2[1], B2[2], N2), _2.fillRect(0, 0, k2.width, k2.height);
|
|
b2 = l2.zoom();
|
|
D2(_2, false), _2.clearRect(k2.mpan.x, k2.mpan.y, k2.width / k2.zoom / s2, k2.height / k2.zoom / s2), _2.drawImage(M2, k2.mpan.x, k2.mpan.y, k2.width / k2.zoom / s2, k2.height / k2.zoom / s2);
|
|
} else o2.textureOnViewport && !t2 && (o2.textureCache = null);
|
|
var z2 = l2.extent(), I2 = o2.pinching || o2.hoverData.dragging || o2.swipePanning || o2.data.wheelZooming || o2.hoverData.draggingEles || o2.cy.animated(), L3 = o2.hideEdgesOnViewport && I2, A2 = [];
|
|
if (A2[o2.NODE] = !c2[o2.NODE] && h2 && !o2.clearedForMotionBlur[o2.NODE] || o2.clearingMotionBlur, A2[o2.NODE] && (o2.clearedForMotionBlur[o2.NODE] = true), A2[o2.DRAG] = !c2[o2.DRAG] && h2 && !o2.clearedForMotionBlur[o2.DRAG] || o2.clearingMotionBlur, A2[o2.DRAG] && (o2.clearedForMotionBlur[o2.DRAG] = true), c2[o2.NODE] || n2 || r2 || A2[o2.NODE]) {
|
|
var O2 = h2 && !A2[o2.NODE] && 1 !== p2;
|
|
D2(_2 = t2 || (O2 ? o2.data.bufferContexts[o2.MOTIONBLUR_BUFFER_NODE] : u2.contexts[o2.NODE]), h2 && !O2 ? "motionBlur" : void 0), L3 ? o2.drawCachedNodes(_2, S2.nondrag, s2, z2) : o2.drawLayeredElements(_2, S2.nondrag, s2, z2), o2.debug && o2.drawDebugPoints(_2, S2.nondrag), n2 || h2 || (c2[o2.NODE] = false);
|
|
}
|
|
if (!r2 && (c2[o2.DRAG] || n2 || A2[o2.DRAG])) {
|
|
O2 = h2 && !A2[o2.DRAG] && 1 !== p2;
|
|
D2(_2 = t2 || (O2 ? o2.data.bufferContexts[o2.MOTIONBLUR_BUFFER_DRAG] : u2.contexts[o2.DRAG]), h2 && !O2 ? "motionBlur" : void 0), L3 ? o2.drawCachedNodes(_2, S2.drag, s2, z2) : o2.drawCachedElements(_2, S2.drag, s2, z2), o2.debug && o2.drawDebugPoints(_2, S2.drag), n2 || h2 || (c2[o2.DRAG] = false);
|
|
}
|
|
if (o2.showFps || !r2 && c2[o2.SELECT_BOX] && !n2) {
|
|
if (D2(_2 = t2 || u2.contexts[o2.SELECT_BOX]), 1 == o2.selection[4] && (o2.hoverData.selecting || o2.touchData.selecting)) {
|
|
b2 = o2.cy.zoom();
|
|
var R2 = m2.core("selection-box-border-width").value / b2;
|
|
_2.lineWidth = R2, _2.fillStyle = "rgba(" + m2.core("selection-box-color").value[0] + "," + m2.core("selection-box-color").value[1] + "," + m2.core("selection-box-color").value[2] + "," + m2.core("selection-box-opacity").value + ")", _2.fillRect(o2.selection[0], o2.selection[1], o2.selection[2] - o2.selection[0], o2.selection[3] - o2.selection[1]), R2 > 0 && (_2.strokeStyle = "rgba(" + m2.core("selection-box-border-color").value[0] + "," + m2.core("selection-box-border-color").value[1] + "," + m2.core("selection-box-border-color").value[2] + "," + m2.core("selection-box-opacity").value + ")", _2.strokeRect(o2.selection[0], o2.selection[1], o2.selection[2] - o2.selection[0], o2.selection[3] - o2.selection[1]));
|
|
}
|
|
if (u2.bgActivePosistion && !o2.hoverData.selecting) {
|
|
b2 = o2.cy.zoom();
|
|
var V2 = u2.bgActivePosistion;
|
|
_2.fillStyle = "rgba(" + m2.core("active-bg-color").value[0] + "," + m2.core("active-bg-color").value[1] + "," + m2.core("active-bg-color").value[2] + "," + m2.core("active-bg-opacity").value + ")", _2.beginPath(), _2.arc(V2.x, V2.y, m2.core("active-bg-size").pfValue / b2, 0, 2 * Math.PI), _2.fill();
|
|
}
|
|
var F2 = o2.lastRedrawTime;
|
|
if (o2.showFps && F2) {
|
|
F2 = Math.round(F2);
|
|
var j2 = Math.round(1e3 / F2);
|
|
_2.setTransform(1, 0, 0, 1, 0, 0), _2.fillStyle = "rgba(255, 0, 0, 0.75)", _2.strokeStyle = "rgba(255, 0, 0, 0.75)", _2.lineWidth = 1, _2.fillText("1 frame = " + F2 + " ms = " + j2 + " fps", 0, 20);
|
|
_2.strokeRect(0, 30, 250, 20), _2.fillRect(0, 30, 250 * Math.min(j2 / 60, 1), 20);
|
|
}
|
|
n2 || (c2[o2.SELECT_BOX] = false);
|
|
}
|
|
if (h2 && 1 !== p2) {
|
|
var q2 = u2.contexts[o2.NODE], Y2 = o2.data.bufferCanvases[o2.MOTIONBLUR_BUFFER_NODE], X2 = u2.contexts[o2.DRAG], W2 = o2.data.bufferCanvases[o2.MOTIONBLUR_BUFFER_DRAG], H2 = function(e3, t3, n3) {
|
|
e3.setTransform(1, 0, 0, 1, 0, 0), n3 || !y2 ? e3.clearRect(0, 0, o2.canvasWidth, o2.canvasHeight) : P2(e3, 0, 0, o2.canvasWidth, o2.canvasHeight);
|
|
var r3 = p2;
|
|
e3.drawImage(t3, 0, 0, o2.canvasWidth * r3, o2.canvasHeight * r3, 0, 0, o2.canvasWidth, o2.canvasHeight);
|
|
};
|
|
(c2[o2.NODE] || A2[o2.NODE]) && (H2(q2, Y2, A2[o2.NODE]), c2[o2.NODE] = false), (c2[o2.DRAG] || A2[o2.DRAG]) && (H2(X2, W2, A2[o2.DRAG]), c2[o2.DRAG] = false);
|
|
}
|
|
o2.prevViewport = k2, o2.clearingMotionBlur && (o2.clearingMotionBlur = false, o2.motionBlurCleared = true, o2.motionBlur = true), h2 && (o2.motionBlurTimeout = setTimeout(function() {
|
|
o2.motionBlurTimeout = null, o2.clearedForMotionBlur[o2.NODE] = false, o2.clearedForMotionBlur[o2.DRAG] = false, o2.motionBlur = false, o2.clearingMotionBlur = !d2, o2.mbFrames = 0, c2[o2.NODE] = true, c2[o2.DRAG] = true, o2.redraw();
|
|
}, 100)), t2 || l2.emit("render");
|
|
};
|
|
for (var Pu = { drawPolygonPath: function(e2, t2, n2, r2, i2, a2) {
|
|
var o2 = r2 / 2, s2 = i2 / 2;
|
|
e2.beginPath && e2.beginPath(), e2.moveTo(t2 + o2 * a2[0], n2 + s2 * a2[1]);
|
|
for (var l2 = 1; l2 < a2.length / 2; l2++) e2.lineTo(t2 + o2 * a2[2 * l2], n2 + s2 * a2[2 * l2 + 1]);
|
|
e2.closePath();
|
|
}, drawRoundPolygonPath: function(e2, t2, n2, r2, i2, a2) {
|
|
var o2 = r2 / 2, s2 = i2 / 2, l2 = tn(r2, i2);
|
|
e2.beginPath && e2.beginPath();
|
|
for (var u2 = 0; u2 < a2.length / 4; u2++) {
|
|
var c2, d2 = void 0;
|
|
d2 = 0 === u2 ? a2.length - 2 : 4 * u2 - 2, c2 = 4 * u2 + 2;
|
|
var h2 = t2 + o2 * a2[4 * u2], p2 = n2 + s2 * a2[4 * u2 + 1], f2 = -a2[d2] * a2[c2] - a2[d2 + 1] * a2[c2 + 1], g2 = l2 / Math.tan(Math.acos(f2) / 2), v2 = h2 - g2 * a2[d2], y2 = p2 - g2 * a2[d2 + 1], m2 = h2 + g2 * a2[c2], b2 = p2 + g2 * a2[c2 + 1];
|
|
0 === u2 ? e2.moveTo(v2, y2) : e2.lineTo(v2, y2), e2.arcTo(h2, p2, m2, b2, l2);
|
|
}
|
|
e2.closePath();
|
|
}, drawRoundRectanglePath: function(e2, t2, n2, r2, i2) {
|
|
var a2 = r2 / 2, o2 = i2 / 2, s2 = en(r2, i2);
|
|
e2.beginPath && e2.beginPath(), e2.moveTo(t2, n2 - o2), e2.arcTo(t2 + a2, n2 - o2, t2 + a2, n2, s2), e2.arcTo(t2 + a2, n2 + o2, t2, n2 + o2, s2), e2.arcTo(t2 - a2, n2 + o2, t2 - a2, n2, s2), e2.arcTo(t2 - a2, n2 - o2, t2, n2 - o2, s2), e2.lineTo(t2, n2 - o2), e2.closePath();
|
|
}, drawBottomRoundRectanglePath: function(e2, t2, n2, r2, i2) {
|
|
var a2 = r2 / 2, o2 = i2 / 2, s2 = en(r2, i2);
|
|
e2.beginPath && e2.beginPath(), e2.moveTo(t2, n2 - o2), e2.lineTo(t2 + a2, n2 - o2), e2.lineTo(t2 + a2, n2), e2.arcTo(t2 + a2, n2 + o2, t2, n2 + o2, s2), e2.arcTo(t2 - a2, n2 + o2, t2 - a2, n2, s2), e2.lineTo(t2 - a2, n2 - o2), e2.lineTo(t2, n2 - o2), e2.closePath();
|
|
}, drawCutRectanglePath: function(e2, t2, n2, r2, i2) {
|
|
var a2 = r2 / 2, o2 = i2 / 2;
|
|
e2.beginPath && e2.beginPath(), e2.moveTo(t2 - a2 + 8, n2 - o2), e2.lineTo(t2 + a2 - 8, n2 - o2), e2.lineTo(t2 + a2, n2 - o2 + 8), e2.lineTo(t2 + a2, n2 + o2 - 8), e2.lineTo(t2 + a2 - 8, n2 + o2), e2.lineTo(t2 - a2 + 8, n2 + o2), e2.lineTo(t2 - a2, n2 + o2 - 8), e2.lineTo(t2 - a2, n2 - o2 + 8), e2.closePath();
|
|
}, drawBarrelPath: function(e2, t2, n2, r2, i2) {
|
|
var a2 = r2 / 2, o2 = i2 / 2, s2 = t2 - a2, l2 = t2 + a2, u2 = n2 - o2, c2 = n2 + o2, d2 = nn(r2, i2), h2 = d2.widthOffset, p2 = d2.heightOffset, f2 = d2.ctrlPtOffsetPct * h2;
|
|
e2.beginPath && e2.beginPath(), e2.moveTo(s2, u2 + p2), e2.lineTo(s2, c2 - p2), e2.quadraticCurveTo(s2 + f2, c2, s2 + h2, c2), e2.lineTo(l2 - h2, c2), e2.quadraticCurveTo(l2 - f2, c2, l2, c2 - p2), e2.lineTo(l2, u2 + p2), e2.quadraticCurveTo(l2 - f2, u2, l2 - h2, u2), e2.lineTo(s2 + h2, u2), e2.quadraticCurveTo(s2 + f2, u2, s2, u2 + p2), e2.closePath();
|
|
} }, Du = Math.sin(0), Tu = Math.cos(0), _u = {}, Mu = {}, Bu = Math.PI / 40, Nu = 0 * Math.PI; Nu < 2 * Math.PI; Nu += Bu) _u[Nu] = Math.sin(Nu), Mu[Nu] = Math.cos(Nu);
|
|
Pu.drawEllipsePath = function(e2, t2, n2, r2, i2) {
|
|
if (e2.beginPath && e2.beginPath(), e2.ellipse) e2.ellipse(t2, n2, r2 / 2, i2 / 2, 0, 0, 2 * Math.PI);
|
|
else for (var a2, o2, s2 = r2 / 2, l2 = i2 / 2, u2 = 0 * Math.PI; u2 < 2 * Math.PI; u2 += Bu) a2 = t2 - s2 * _u[u2] * Du + s2 * Mu[u2] * Tu, o2 = n2 + l2 * Mu[u2] * Du + l2 * _u[u2] * Tu, 0 === u2 ? e2.moveTo(a2, o2) : e2.lineTo(a2, o2);
|
|
e2.closePath();
|
|
};
|
|
var zu = {};
|
|
function Iu(e2) {
|
|
var t2 = e2.indexOf(",");
|
|
return e2.substr(t2 + 1);
|
|
}
|
|
function Lu(e2, t2, n2) {
|
|
var r2 = function() {
|
|
return t2.toDataURL(n2, e2.quality);
|
|
};
|
|
switch (e2.output) {
|
|
case "blob-promise":
|
|
return new pr(function(r3, i2) {
|
|
try {
|
|
t2.toBlob(function(e3) {
|
|
null != e3 ? r3(e3) : i2(new Error("`canvas.toBlob()` sent a null value in its callback"));
|
|
}, n2, e2.quality);
|
|
} catch (e3) {
|
|
i2(e3);
|
|
}
|
|
});
|
|
case "blob":
|
|
return function(e3, t3) {
|
|
for (var n3 = atob(e3), r3 = new ArrayBuffer(n3.length), i2 = new Uint8Array(r3), a2 = 0; a2 < n3.length; a2++) i2[a2] = n3.charCodeAt(a2);
|
|
return new Blob([r3], { type: t3 });
|
|
}(Iu(r2()), n2);
|
|
case "base64":
|
|
return Iu(r2());
|
|
case "base64uri":
|
|
default:
|
|
return r2();
|
|
}
|
|
}
|
|
zu.createBuffer = function(e2, t2) {
|
|
var n2 = document.createElement("canvas");
|
|
return n2.width = e2, n2.height = t2, [n2, n2.getContext("2d")];
|
|
}, zu.bufferCanvasImage = function(e2) {
|
|
var t2 = this.cy, n2 = t2.mutableElements().boundingBox(), r2 = this.findContainerClientCoords(), i2 = e2.full ? Math.ceil(n2.w) : r2[2], a2 = e2.full ? Math.ceil(n2.h) : r2[3], o2 = m(e2.maxWidth) || m(e2.maxHeight), s2 = this.getPixelRatio(), l2 = 1;
|
|
if (void 0 !== e2.scale) i2 *= e2.scale, a2 *= e2.scale, l2 = e2.scale;
|
|
else if (o2) {
|
|
var u2 = 1 / 0, c2 = 1 / 0;
|
|
m(e2.maxWidth) && (u2 = l2 * e2.maxWidth / i2), m(e2.maxHeight) && (c2 = l2 * e2.maxHeight / a2), i2 *= l2 = Math.min(u2, c2), a2 *= l2;
|
|
}
|
|
o2 || (i2 *= s2, a2 *= s2, l2 *= s2);
|
|
var d2 = document.createElement("canvas");
|
|
d2.width = i2, d2.height = a2, d2.style.width = i2 + "px", d2.style.height = a2 + "px";
|
|
var h2 = d2.getContext("2d");
|
|
if (i2 > 0 && a2 > 0) {
|
|
h2.clearRect(0, 0, i2, a2), h2.globalCompositeOperation = "source-over";
|
|
var p2 = this.getCachedZSortedEles();
|
|
if (e2.full) h2.translate(-n2.x1 * l2, -n2.y1 * l2), h2.scale(l2, l2), this.drawElements(h2, p2), h2.scale(1 / l2, 1 / l2), h2.translate(n2.x1 * l2, n2.y1 * l2);
|
|
else {
|
|
var f2 = t2.pan(), g2 = { x: f2.x * l2, y: f2.y * l2 };
|
|
l2 *= t2.zoom(), h2.translate(g2.x, g2.y), h2.scale(l2, l2), this.drawElements(h2, p2), h2.scale(1 / l2, 1 / l2), h2.translate(-g2.x, -g2.y);
|
|
}
|
|
e2.bg && (h2.globalCompositeOperation = "destination-over", h2.fillStyle = e2.bg, h2.rect(0, 0, i2, a2), h2.fill());
|
|
}
|
|
return d2;
|
|
}, zu.png = function(e2) {
|
|
return Lu(e2, this.bufferCanvasImage(e2), "image/png");
|
|
}, zu.jpg = function(e2) {
|
|
return Lu(e2, this.bufferCanvasImage(e2), "image/jpeg");
|
|
};
|
|
var Au = { nodeShapeImpl: function(e2, t2, n2, r2, i2, a2, o2) {
|
|
switch (e2) {
|
|
case "ellipse":
|
|
return this.drawEllipsePath(t2, n2, r2, i2, a2);
|
|
case "polygon":
|
|
return this.drawPolygonPath(t2, n2, r2, i2, a2, o2);
|
|
case "round-polygon":
|
|
return this.drawRoundPolygonPath(t2, n2, r2, i2, a2, o2);
|
|
case "roundrectangle":
|
|
case "round-rectangle":
|
|
return this.drawRoundRectanglePath(t2, n2, r2, i2, a2);
|
|
case "cutrectangle":
|
|
case "cut-rectangle":
|
|
return this.drawCutRectanglePath(t2, n2, r2, i2, a2);
|
|
case "bottomroundrectangle":
|
|
case "bottom-round-rectangle":
|
|
return this.drawBottomRoundRectanglePath(t2, n2, r2, i2, a2);
|
|
case "barrel":
|
|
return this.drawBarrelPath(t2, n2, r2, i2, a2);
|
|
}
|
|
} }, Ou = Vu, Ru = Vu.prototype;
|
|
function Vu(e2) {
|
|
var t2 = this;
|
|
t2.data = { canvases: new Array(Ru.CANVAS_LAYERS), contexts: new Array(Ru.CANVAS_LAYERS), canvasNeedsRedraw: new Array(Ru.CANVAS_LAYERS), bufferCanvases: new Array(Ru.BUFFER_COUNT), bufferContexts: new Array(Ru.CANVAS_LAYERS) };
|
|
t2.data.canvasContainer = document.createElement("div");
|
|
var n2 = t2.data.canvasContainer.style;
|
|
t2.data.canvasContainer.style["-webkit-tap-highlight-color"] = "rgba(0,0,0,0)", n2.position = "relative", n2.zIndex = "0", n2.overflow = "hidden";
|
|
var r2 = e2.cy.container();
|
|
r2.appendChild(t2.data.canvasContainer), r2.style["-webkit-tap-highlight-color"] = "rgba(0,0,0,0)";
|
|
var i2 = { "-webkit-user-select": "none", "-moz-user-select": "-moz-none", "user-select": "none", "-webkit-tap-highlight-color": "rgba(0,0,0,0)", "outline-style": "none" };
|
|
l && l.userAgent.match(/msie|trident|edge/i) && (i2["-ms-touch-action"] = "none", i2["touch-action"] = "none");
|
|
for (var a2 = 0; a2 < Ru.CANVAS_LAYERS; a2++) {
|
|
var o2 = t2.data.canvases[a2] = document.createElement("canvas");
|
|
t2.data.contexts[a2] = o2.getContext("2d"), Object.keys(i2).forEach(function(e3) {
|
|
o2.style[e3] = i2[e3];
|
|
}), o2.style.position = "absolute", o2.setAttribute("data-id", "layer" + a2), o2.style.zIndex = String(Ru.CANVAS_LAYERS - a2), t2.data.canvasContainer.appendChild(o2), t2.data.canvasNeedsRedraw[a2] = false;
|
|
}
|
|
t2.data.topCanvas = t2.data.canvases[0], t2.data.canvases[Ru.NODE].setAttribute("data-id", "layer" + Ru.NODE + "-node"), t2.data.canvases[Ru.SELECT_BOX].setAttribute("data-id", "layer" + Ru.SELECT_BOX + "-selectbox"), t2.data.canvases[Ru.DRAG].setAttribute("data-id", "layer" + Ru.DRAG + "-drag");
|
|
for (a2 = 0; a2 < Ru.BUFFER_COUNT; a2++) t2.data.bufferCanvases[a2] = document.createElement("canvas"), t2.data.bufferContexts[a2] = t2.data.bufferCanvases[a2].getContext("2d"), t2.data.bufferCanvases[a2].style.position = "absolute", t2.data.bufferCanvases[a2].setAttribute("data-id", "buffer" + a2), t2.data.bufferCanvases[a2].style.zIndex = String(-a2 - 1), t2.data.bufferCanvases[a2].style.visibility = "hidden";
|
|
t2.pathsEnabled = true;
|
|
var s2 = Dt(), u2 = function(e3) {
|
|
return { x: -e3.w / 2, y: -e3.h / 2 };
|
|
}, c2 = function(e3) {
|
|
return e3.boundingBox(), e3[0]._private.bodyBounds;
|
|
}, d2 = function(e3) {
|
|
return e3.boundingBox(), e3[0]._private.labelBounds.main || s2;
|
|
}, h2 = function(e3) {
|
|
return e3.boundingBox(), e3[0]._private.labelBounds.source || s2;
|
|
}, p2 = function(e3) {
|
|
return e3.boundingBox(), e3[0]._private.labelBounds.target || s2;
|
|
}, f2 = function(e3, t3) {
|
|
return t3;
|
|
}, g2 = function(e3, t3, n3) {
|
|
var r3 = e3 ? e3 + "-" : "";
|
|
return { x: t3.x + n3.pstyle(r3 + "text-margin-x").pfValue, y: t3.y + n3.pstyle(r3 + "text-margin-y").pfValue };
|
|
}, v2 = function(e3, t3, n3) {
|
|
var r3 = e3[0]._private.rscratch;
|
|
return { x: r3[t3], y: r3[n3] };
|
|
}, y2 = t2.data.eleTxrCache = new Ql(t2, { getKey: function(e3) {
|
|
return e3[0]._private.nodeKey;
|
|
}, doesEleInvalidateKey: function(e3) {
|
|
var t3 = e3[0]._private;
|
|
return !(t3.oldBackgroundTimestamp === t3.backgroundTimestamp);
|
|
}, drawElement: function(e3, n3, r3, i3, a3) {
|
|
return t2.drawElement(e3, n3, r3, false, false, a3);
|
|
}, getBoundingBox: c2, getRotationPoint: function(e3) {
|
|
return { x: ((t3 = c2(e3)).x1 + t3.x2) / 2, y: (t3.y1 + t3.y2) / 2 };
|
|
var t3;
|
|
}, getRotationOffset: function(e3) {
|
|
return u2(c2(e3));
|
|
}, allowEdgeTxrCaching: false, allowParentTxrCaching: false }), m2 = t2.data.lblTxrCache = new Ql(t2, { getKey: function(e3) {
|
|
return e3[0]._private.labelStyleKey;
|
|
}, drawElement: function(e3, n3, r3, i3, a3) {
|
|
return t2.drawElementText(e3, n3, r3, i3, "main", a3);
|
|
}, getBoundingBox: d2, getRotationPoint: function(e3) {
|
|
return g2("", v2(e3, "labelX", "labelY"), e3);
|
|
}, getRotationOffset: function(e3) {
|
|
var t3 = d2(e3), n3 = u2(d2(e3));
|
|
if (e3.isNode()) {
|
|
switch (e3.pstyle("text-halign").value) {
|
|
case "left":
|
|
n3.x = -t3.w;
|
|
break;
|
|
case "right":
|
|
n3.x = 0;
|
|
}
|
|
switch (e3.pstyle("text-valign").value) {
|
|
case "top":
|
|
n3.y = -t3.h;
|
|
break;
|
|
case "bottom":
|
|
n3.y = 0;
|
|
}
|
|
}
|
|
return n3;
|
|
}, isVisible: f2 }), b2 = t2.data.slbTxrCache = new Ql(t2, { getKey: function(e3) {
|
|
return e3[0]._private.sourceLabelStyleKey;
|
|
}, drawElement: function(e3, n3, r3, i3, a3) {
|
|
return t2.drawElementText(e3, n3, r3, i3, "source", a3);
|
|
}, getBoundingBox: h2, getRotationPoint: function(e3) {
|
|
return g2("source", v2(e3, "sourceLabelX", "sourceLabelY"), e3);
|
|
}, getRotationOffset: function(e3) {
|
|
return u2(h2(e3));
|
|
}, isVisible: f2 }), x2 = t2.data.tlbTxrCache = new Ql(t2, { getKey: function(e3) {
|
|
return e3[0]._private.targetLabelStyleKey;
|
|
}, drawElement: function(e3, n3, r3, i3, a3) {
|
|
return t2.drawElementText(e3, n3, r3, i3, "target", a3);
|
|
}, getBoundingBox: p2, getRotationPoint: function(e3) {
|
|
return g2("target", v2(e3, "targetLabelX", "targetLabelY"), e3);
|
|
}, getRotationOffset: function(e3) {
|
|
return u2(p2(e3));
|
|
}, isVisible: f2 }), w2 = t2.data.lyrTxrCache = new eu(t2);
|
|
t2.onUpdateEleCalcs(function(e3, t3) {
|
|
y2.invalidateElements(t3), m2.invalidateElements(t3), b2.invalidateElements(t3), x2.invalidateElements(t3), w2.invalidateElements(t3);
|
|
for (var n3 = 0; n3 < t3.length; n3++) {
|
|
var r3 = t3[n3]._private;
|
|
r3.oldBackgroundTimestamp = r3.backgroundTimestamp;
|
|
}
|
|
});
|
|
var E2 = function(e3) {
|
|
for (var t3 = 0; t3 < e3.length; t3++) w2.enqueueElementRefinement(e3[t3].ele);
|
|
};
|
|
y2.onDequeue(E2), m2.onDequeue(E2), b2.onDequeue(E2), x2.onDequeue(E2);
|
|
}
|
|
Ru.CANVAS_LAYERS = 3, Ru.SELECT_BOX = 0, Ru.DRAG = 1, Ru.NODE = 2, Ru.BUFFER_COUNT = 3, Ru.TEXTURE_BUFFER = 0, Ru.MOTIONBLUR_BUFFER_NODE = 1, Ru.MOTIONBLUR_BUFFER_DRAG = 2, Ru.redrawHint = function(e2, t2) {
|
|
var n2 = this;
|
|
switch (e2) {
|
|
case "eles":
|
|
n2.data.canvasNeedsRedraw[Ru.NODE] = t2;
|
|
break;
|
|
case "drag":
|
|
n2.data.canvasNeedsRedraw[Ru.DRAG] = t2;
|
|
break;
|
|
case "select":
|
|
n2.data.canvasNeedsRedraw[Ru.SELECT_BOX] = t2;
|
|
}
|
|
};
|
|
var Fu = "undefined" != typeof Path2D;
|
|
Ru.path2dEnabled = function(e2) {
|
|
if (void 0 === e2) return this.pathsEnabled;
|
|
this.pathsEnabled = !!e2;
|
|
}, Ru.usePaths = function() {
|
|
return Fu && this.pathsEnabled;
|
|
}, Ru.setImgSmoothing = function(e2, t2) {
|
|
null != e2.imageSmoothingEnabled ? e2.imageSmoothingEnabled = t2 : (e2.webkitImageSmoothingEnabled = t2, e2.mozImageSmoothingEnabled = t2, e2.msImageSmoothingEnabled = t2);
|
|
}, Ru.getImgSmoothing = function(e2) {
|
|
return null != e2.imageSmoothingEnabled ? e2.imageSmoothingEnabled : e2.webkitImageSmoothingEnabled || e2.mozImageSmoothingEnabled || e2.msImageSmoothingEnabled;
|
|
}, Ru.makeOffscreenCanvas = function(t2, n2) {
|
|
var r2;
|
|
return "undefined" !== ("undefined" == typeof OffscreenCanvas ? "undefined" : e(OffscreenCanvas)) ? r2 = new OffscreenCanvas(t2, n2) : ((r2 = document.createElement("canvas")).width = t2, r2.height = n2), r2;
|
|
}, [au, du, mu, xu, wu, ku, Su, Pu, zu, Au].forEach(function(e2) {
|
|
I(Ru, e2);
|
|
});
|
|
var ju = [{ type: "layout", extensions: wl }, { type: "renderer", extensions: [{ name: "null", impl: El }, { name: "base", impl: Hl }, { name: "canvas", impl: Ou }] }], qu = {}, Yu = {};
|
|
function Xu(e2, t2, n2) {
|
|
var r2 = n2, i2 = function(n3) {
|
|
Ve("Can not register `" + t2 + "` for `" + e2 + "` since `" + n3 + "` already exists in the prototype and can not be overridden");
|
|
};
|
|
if ("core" === e2) {
|
|
if (Is.prototype[t2]) return i2(t2);
|
|
Is.prototype[t2] = n2;
|
|
} else if ("collection" === e2) {
|
|
if (Qo.prototype[t2]) return i2(t2);
|
|
Qo.prototype[t2] = n2;
|
|
} else if ("layout" === e2) {
|
|
for (var a2 = function(e3) {
|
|
this.options = e3, n2.call(this, e3), y(this._private) || (this._private = {}), this._private.cy = e3.cy, this._private.listeners = [], this.createEmitter();
|
|
}, o2 = a2.prototype = Object.create(n2.prototype), s2 = [], l2 = 0; l2 < s2.length; l2++) {
|
|
var u2 = s2[l2];
|
|
o2[u2] = o2[u2] || function() {
|
|
return this;
|
|
};
|
|
}
|
|
o2.start && !o2.run ? o2.run = function() {
|
|
return this.start(), this;
|
|
} : !o2.start && o2.run && (o2.start = function() {
|
|
return this.run(), this;
|
|
});
|
|
var c2 = n2.prototype.stop;
|
|
o2.stop = function() {
|
|
var e3 = this.options;
|
|
if (e3 && e3.animate) {
|
|
var t3 = this.animations;
|
|
if (t3) for (var n3 = 0; n3 < t3.length; n3++) t3[n3].stop();
|
|
}
|
|
return c2 ? c2.call(this) : this.emit("layoutstop"), this;
|
|
}, o2.destroy || (o2.destroy = function() {
|
|
return this;
|
|
}), o2.cy = function() {
|
|
return this._private.cy;
|
|
};
|
|
var d2 = function(e3) {
|
|
return e3._private.cy;
|
|
}, h2 = { addEventFields: function(e3, t3) {
|
|
t3.layout = e3, t3.cy = d2(e3), t3.target = e3;
|
|
}, bubble: function() {
|
|
return true;
|
|
}, parent: function(e3) {
|
|
return d2(e3);
|
|
} };
|
|
I(o2, { createEmitter: function() {
|
|
return this._private.emitter = new yo(h2, this), this;
|
|
}, emitter: function() {
|
|
return this._private.emitter;
|
|
}, on: function(e3, t3) {
|
|
return this.emitter().on(e3, t3), this;
|
|
}, one: function(e3, t3) {
|
|
return this.emitter().one(e3, t3), this;
|
|
}, once: function(e3, t3) {
|
|
return this.emitter().one(e3, t3), this;
|
|
}, removeListener: function(e3, t3) {
|
|
return this.emitter().removeListener(e3, t3), this;
|
|
}, removeAllListeners: function() {
|
|
return this.emitter().removeAllListeners(), this;
|
|
}, emit: function(e3, t3) {
|
|
return this.emitter().emit(e3, t3), this;
|
|
} }), Oi.eventAliasesOn(o2), r2 = a2;
|
|
} else if ("renderer" === e2 && "null" !== t2 && "base" !== t2) {
|
|
var p2 = Wu("renderer", "base"), f2 = p2.prototype, g2 = n2, v2 = n2.prototype, m2 = function() {
|
|
p2.apply(this, arguments), g2.apply(this, arguments);
|
|
}, b2 = m2.prototype;
|
|
for (var x2 in f2) {
|
|
var w2 = f2[x2];
|
|
if (null != v2[x2]) return i2(x2);
|
|
b2[x2] = w2;
|
|
}
|
|
for (var E2 in v2) b2[E2] = v2[E2];
|
|
f2.clientFunctions.forEach(function(e3) {
|
|
b2[e3] = b2[e3] || function() {
|
|
Oe("Renderer does not implement `renderer." + e3 + "()` on its prototype");
|
|
};
|
|
}), r2 = m2;
|
|
} else if ("__proto__" === e2 || "constructor" === e2 || "prototype" === e2) return Oe(e2 + " is an illegal type to be registered, possibly lead to prototype pollutions");
|
|
return O({ map: qu, keys: [e2, t2], value: r2 });
|
|
}
|
|
function Wu(e2, t2) {
|
|
return R({ map: qu, keys: [e2, t2] });
|
|
}
|
|
function Hu(e2, t2, n2, r2, i2) {
|
|
return O({ map: Yu, keys: [e2, t2, n2, r2], value: i2 });
|
|
}
|
|
function Ku(e2, t2, n2, r2) {
|
|
return R({ map: Yu, keys: [e2, t2, n2, r2] });
|
|
}
|
|
var Gu = function() {
|
|
return 2 === arguments.length ? Wu.apply(null, arguments) : 3 === arguments.length ? Xu.apply(null, arguments) : 4 === arguments.length ? Ku.apply(null, arguments) : 5 === arguments.length ? Hu.apply(null, arguments) : void Oe("Invalid extension access syntax");
|
|
};
|
|
Is.prototype.extension = Gu, ju.forEach(function(e2) {
|
|
e2.extensions.forEach(function(t2) {
|
|
Xu(e2.type, t2.name, t2.impl);
|
|
});
|
|
});
|
|
var Uu = function e2() {
|
|
if (!(this instanceof e2)) return new e2();
|
|
this.length = 0;
|
|
}, Zu = Uu.prototype;
|
|
Zu.instanceString = function() {
|
|
return "stylesheet";
|
|
}, Zu.selector = function(e2) {
|
|
return this[this.length++] = { selector: e2, properties: [] }, this;
|
|
}, Zu.css = function(e2, t2) {
|
|
var n2 = this.length - 1;
|
|
if (f(e2)) this[n2].properties.push({ name: e2, value: t2 });
|
|
else if (y(e2)) for (var r2 = e2, i2 = Object.keys(r2), a2 = 0; a2 < i2.length; a2++) {
|
|
var o2 = i2[a2], s2 = r2[o2];
|
|
if (null != s2) {
|
|
var l2 = _s.properties[o2] || _s.properties[_(o2)];
|
|
if (null != l2) {
|
|
var u2 = l2.name, c2 = s2;
|
|
this[n2].properties.push({ name: u2, value: c2 });
|
|
}
|
|
}
|
|
}
|
|
return this;
|
|
}, Zu.style = Zu.css, Zu.generateStyle = function(e2) {
|
|
var t2 = new _s(e2);
|
|
return this.appendToStyle(t2);
|
|
}, Zu.appendToStyle = function(e2) {
|
|
for (var t2 = 0; t2 < this.length; t2++) {
|
|
var n2 = this[t2], r2 = n2.selector, i2 = n2.properties;
|
|
e2.selector(r2);
|
|
for (var a2 = 0; a2 < i2.length; a2++) {
|
|
var o2 = i2[a2];
|
|
e2.css(o2.name, o2.value);
|
|
}
|
|
}
|
|
return e2;
|
|
};
|
|
var $u = function(e2) {
|
|
return void 0 === e2 && (e2 = {}), y(e2) ? new Is(e2) : f(e2) ? Gu.apply(Gu, arguments) : void 0;
|
|
};
|
|
return $u.use = function(e2) {
|
|
var t2 = Array.prototype.slice.call(arguments, 1);
|
|
return t2.unshift($u), e2.apply(null, t2), this;
|
|
}, $u.warnings = function(e2) {
|
|
return Re(e2);
|
|
}, $u.version = "3.28.1", $u.stylesheet = $u.Stylesheet = Uu, $u;
|
|
});
|
|
}
|
|
});
|
|
|
|
// ../deps/phoenix_html/priv/static/phoenix_html.js
|
|
(function() {
|
|
var PolyfillEvent = eventConstructor();
|
|
function eventConstructor() {
|
|
if (typeof window.CustomEvent === "function") return window.CustomEvent;
|
|
function CustomEvent2(event, params) {
|
|
params = params || { bubbles: false, cancelable: false, detail: void 0 };
|
|
var evt = document.createEvent("CustomEvent");
|
|
evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
|
|
return evt;
|
|
}
|
|
CustomEvent2.prototype = window.Event.prototype;
|
|
return CustomEvent2;
|
|
}
|
|
function buildHiddenInput(name, value) {
|
|
var input = document.createElement("input");
|
|
input.type = "hidden";
|
|
input.name = name;
|
|
input.value = value;
|
|
return input;
|
|
}
|
|
function handleClick(element, targetModifierKey) {
|
|
var to = element.getAttribute("data-to"), method = buildHiddenInput("_method", element.getAttribute("data-method")), csrf = buildHiddenInput("_csrf_token", element.getAttribute("data-csrf")), form = document.createElement("form"), submit = document.createElement("input"), target = element.getAttribute("target");
|
|
form.method = element.getAttribute("data-method") === "get" ? "get" : "post";
|
|
form.action = to;
|
|
form.style.display = "none";
|
|
if (target) form.target = target;
|
|
else if (targetModifierKey) form.target = "_blank";
|
|
form.appendChild(csrf);
|
|
form.appendChild(method);
|
|
document.body.appendChild(form);
|
|
submit.type = "submit";
|
|
form.appendChild(submit);
|
|
submit.click();
|
|
}
|
|
window.addEventListener("click", function(e) {
|
|
var element = e.target;
|
|
if (e.defaultPrevented) return;
|
|
while (element && element.getAttribute) {
|
|
var phoenixLinkEvent = new PolyfillEvent("phoenix.link.click", {
|
|
"bubbles": true,
|
|
"cancelable": true
|
|
});
|
|
if (!element.dispatchEvent(phoenixLinkEvent)) {
|
|
e.preventDefault();
|
|
e.stopImmediatePropagation();
|
|
return false;
|
|
}
|
|
if (element.getAttribute("data-method") && element.getAttribute("data-to")) {
|
|
handleClick(element, e.metaKey || e.shiftKey);
|
|
e.preventDefault();
|
|
return false;
|
|
} else {
|
|
element = element.parentNode;
|
|
}
|
|
}
|
|
}, false);
|
|
window.addEventListener("phoenix.link.click", function(e) {
|
|
var message = e.target.getAttribute("data-confirm");
|
|
if (message && !window.confirm(message)) {
|
|
e.preventDefault();
|
|
}
|
|
}, false);
|
|
})();
|
|
|
|
// ../deps/phoenix/priv/static/phoenix.mjs
|
|
var closure = (value) => {
|
|
if (typeof value === "function") {
|
|
return value;
|
|
} else {
|
|
let closure22 = function() {
|
|
return value;
|
|
};
|
|
return closure22;
|
|
}
|
|
};
|
|
var globalSelf = typeof self !== "undefined" ? self : null;
|
|
var phxWindow = typeof window !== "undefined" ? window : null;
|
|
var global2 = globalSelf || phxWindow || globalThis;
|
|
var DEFAULT_VSN = "2.0.0";
|
|
var SOCKET_STATES = { connecting: 0, open: 1, closing: 2, closed: 3 };
|
|
var MAX_LONGPOLL_BATCH_SIZE = 100;
|
|
var DEFAULT_TIMEOUT = 1e4;
|
|
var WS_CLOSE_NORMAL = 1e3;
|
|
var CHANNEL_STATES = {
|
|
closed: "closed",
|
|
errored: "errored",
|
|
joined: "joined",
|
|
joining: "joining",
|
|
leaving: "leaving"
|
|
};
|
|
var CHANNEL_EVENTS = {
|
|
close: "phx_close",
|
|
error: "phx_error",
|
|
join: "phx_join",
|
|
reply: "phx_reply",
|
|
leave: "phx_leave"
|
|
};
|
|
var TRANSPORTS = {
|
|
longpoll: "longpoll",
|
|
websocket: "websocket"
|
|
};
|
|
var XHR_STATES = {
|
|
complete: 4
|
|
};
|
|
var AUTH_TOKEN_PREFIX = "base64url.bearer.phx.";
|
|
var Push = class {
|
|
constructor(channel, event, payload, timeout) {
|
|
this.channel = channel;
|
|
this.event = event;
|
|
this.payload = payload || function() {
|
|
return {};
|
|
};
|
|
this.receivedResp = null;
|
|
this.timeout = timeout;
|
|
this.timeoutTimer = null;
|
|
this.recHooks = [];
|
|
this.sent = false;
|
|
}
|
|
/**
|
|
*
|
|
* @param {number} timeout
|
|
*/
|
|
resend(timeout) {
|
|
this.timeout = timeout;
|
|
this.reset();
|
|
this.send();
|
|
}
|
|
/**
|
|
*
|
|
*/
|
|
send() {
|
|
if (this.hasReceived("timeout")) {
|
|
return;
|
|
}
|
|
this.startTimeout();
|
|
this.sent = true;
|
|
this.channel.socket.push({
|
|
topic: this.channel.topic,
|
|
event: this.event,
|
|
payload: this.payload(),
|
|
ref: this.ref,
|
|
join_ref: this.channel.joinRef()
|
|
});
|
|
}
|
|
/**
|
|
*
|
|
* @param {*} status
|
|
* @param {*} callback
|
|
*/
|
|
receive(status, callback) {
|
|
if (this.hasReceived(status)) {
|
|
callback(this.receivedResp.response);
|
|
}
|
|
this.recHooks.push({ status, callback });
|
|
return this;
|
|
}
|
|
/**
|
|
* @private
|
|
*/
|
|
reset() {
|
|
this.cancelRefEvent();
|
|
this.ref = null;
|
|
this.refEvent = null;
|
|
this.receivedResp = null;
|
|
this.sent = false;
|
|
}
|
|
/**
|
|
* @private
|
|
*/
|
|
matchReceive({ status, response, _ref }) {
|
|
this.recHooks.filter((h) => h.status === status).forEach((h) => h.callback(response));
|
|
}
|
|
/**
|
|
* @private
|
|
*/
|
|
cancelRefEvent() {
|
|
if (!this.refEvent) {
|
|
return;
|
|
}
|
|
this.channel.off(this.refEvent);
|
|
}
|
|
/**
|
|
* @private
|
|
*/
|
|
cancelTimeout() {
|
|
clearTimeout(this.timeoutTimer);
|
|
this.timeoutTimer = null;
|
|
}
|
|
/**
|
|
* @private
|
|
*/
|
|
startTimeout() {
|
|
if (this.timeoutTimer) {
|
|
this.cancelTimeout();
|
|
}
|
|
this.ref = this.channel.socket.makeRef();
|
|
this.refEvent = this.channel.replyEventName(this.ref);
|
|
this.channel.on(this.refEvent, (payload) => {
|
|
this.cancelRefEvent();
|
|
this.cancelTimeout();
|
|
this.receivedResp = payload;
|
|
this.matchReceive(payload);
|
|
});
|
|
this.timeoutTimer = setTimeout(() => {
|
|
this.trigger("timeout", {});
|
|
}, this.timeout);
|
|
}
|
|
/**
|
|
* @private
|
|
*/
|
|
hasReceived(status) {
|
|
return this.receivedResp && this.receivedResp.status === status;
|
|
}
|
|
/**
|
|
* @private
|
|
*/
|
|
trigger(status, response) {
|
|
this.channel.trigger(this.refEvent, { status, response });
|
|
}
|
|
};
|
|
var Timer = class {
|
|
constructor(callback, timerCalc) {
|
|
this.callback = callback;
|
|
this.timerCalc = timerCalc;
|
|
this.timer = null;
|
|
this.tries = 0;
|
|
}
|
|
reset() {
|
|
this.tries = 0;
|
|
clearTimeout(this.timer);
|
|
}
|
|
/**
|
|
* Cancels any previous scheduleTimeout and schedules callback
|
|
*/
|
|
scheduleTimeout() {
|
|
clearTimeout(this.timer);
|
|
this.timer = setTimeout(() => {
|
|
this.tries = this.tries + 1;
|
|
this.callback();
|
|
}, this.timerCalc(this.tries + 1));
|
|
}
|
|
};
|
|
var Channel = class {
|
|
constructor(topic, params, socket) {
|
|
this.state = CHANNEL_STATES.closed;
|
|
this.topic = topic;
|
|
this.params = closure(params || {});
|
|
this.socket = socket;
|
|
this.bindings = [];
|
|
this.bindingRef = 0;
|
|
this.timeout = this.socket.timeout;
|
|
this.joinedOnce = false;
|
|
this.joinPush = new Push(this, CHANNEL_EVENTS.join, this.params, this.timeout);
|
|
this.pushBuffer = [];
|
|
this.stateChangeRefs = [];
|
|
this.rejoinTimer = new Timer(() => {
|
|
if (this.socket.isConnected()) {
|
|
this.rejoin();
|
|
}
|
|
}, this.socket.rejoinAfterMs);
|
|
this.stateChangeRefs.push(this.socket.onError(() => this.rejoinTimer.reset()));
|
|
this.stateChangeRefs.push(
|
|
this.socket.onOpen(() => {
|
|
this.rejoinTimer.reset();
|
|
if (this.isErrored()) {
|
|
this.rejoin();
|
|
}
|
|
})
|
|
);
|
|
this.joinPush.receive("ok", () => {
|
|
this.state = CHANNEL_STATES.joined;
|
|
this.rejoinTimer.reset();
|
|
this.pushBuffer.forEach((pushEvent) => pushEvent.send());
|
|
this.pushBuffer = [];
|
|
});
|
|
this.joinPush.receive("error", () => {
|
|
this.state = CHANNEL_STATES.errored;
|
|
if (this.socket.isConnected()) {
|
|
this.rejoinTimer.scheduleTimeout();
|
|
}
|
|
});
|
|
this.onClose(() => {
|
|
this.rejoinTimer.reset();
|
|
if (this.socket.hasLogger()) this.socket.log("channel", `close ${this.topic} ${this.joinRef()}`);
|
|
this.state = CHANNEL_STATES.closed;
|
|
this.socket.remove(this);
|
|
});
|
|
this.onError((reason) => {
|
|
if (this.socket.hasLogger()) this.socket.log("channel", `error ${this.topic}`, reason);
|
|
if (this.isJoining()) {
|
|
this.joinPush.reset();
|
|
}
|
|
this.state = CHANNEL_STATES.errored;
|
|
if (this.socket.isConnected()) {
|
|
this.rejoinTimer.scheduleTimeout();
|
|
}
|
|
});
|
|
this.joinPush.receive("timeout", () => {
|
|
if (this.socket.hasLogger()) this.socket.log("channel", `timeout ${this.topic} (${this.joinRef()})`, this.joinPush.timeout);
|
|
let leavePush = new Push(this, CHANNEL_EVENTS.leave, closure({}), this.timeout);
|
|
leavePush.send();
|
|
this.state = CHANNEL_STATES.errored;
|
|
this.joinPush.reset();
|
|
if (this.socket.isConnected()) {
|
|
this.rejoinTimer.scheduleTimeout();
|
|
}
|
|
});
|
|
this.on(CHANNEL_EVENTS.reply, (payload, ref) => {
|
|
this.trigger(this.replyEventName(ref), payload);
|
|
});
|
|
}
|
|
/**
|
|
* Join the channel
|
|
* @param {integer} timeout
|
|
* @returns {Push}
|
|
*/
|
|
join(timeout = this.timeout) {
|
|
if (this.joinedOnce) {
|
|
throw new Error("tried to join multiple times. 'join' can only be called a single time per channel instance");
|
|
} else {
|
|
this.timeout = timeout;
|
|
this.joinedOnce = true;
|
|
this.rejoin();
|
|
return this.joinPush;
|
|
}
|
|
}
|
|
/**
|
|
* Hook into channel close
|
|
* @param {Function} callback
|
|
*/
|
|
onClose(callback) {
|
|
this.on(CHANNEL_EVENTS.close, callback);
|
|
}
|
|
/**
|
|
* Hook into channel errors
|
|
* @param {Function} callback
|
|
*/
|
|
onError(callback) {
|
|
return this.on(CHANNEL_EVENTS.error, (reason) => callback(reason));
|
|
}
|
|
/**
|
|
* Subscribes on channel events
|
|
*
|
|
* Subscription returns a ref counter, which can be used later to
|
|
* unsubscribe the exact event listener
|
|
*
|
|
* @example
|
|
* const ref1 = channel.on("event", do_stuff)
|
|
* const ref2 = channel.on("event", do_other_stuff)
|
|
* channel.off("event", ref1)
|
|
* // Since unsubscription, do_stuff won't fire,
|
|
* // while do_other_stuff will keep firing on the "event"
|
|
*
|
|
* @param {string} event
|
|
* @param {Function} callback
|
|
* @returns {integer} ref
|
|
*/
|
|
on(event, callback) {
|
|
let ref = this.bindingRef++;
|
|
this.bindings.push({ event, ref, callback });
|
|
return ref;
|
|
}
|
|
/**
|
|
* Unsubscribes off of channel events
|
|
*
|
|
* Use the ref returned from a channel.on() to unsubscribe one
|
|
* handler, or pass nothing for the ref to unsubscribe all
|
|
* handlers for the given event.
|
|
*
|
|
* @example
|
|
* // Unsubscribe the do_stuff handler
|
|
* const ref1 = channel.on("event", do_stuff)
|
|
* channel.off("event", ref1)
|
|
*
|
|
* // Unsubscribe all handlers from event
|
|
* channel.off("event")
|
|
*
|
|
* @param {string} event
|
|
* @param {integer} ref
|
|
*/
|
|
off(event, ref) {
|
|
this.bindings = this.bindings.filter((bind) => {
|
|
return !(bind.event === event && (typeof ref === "undefined" || ref === bind.ref));
|
|
});
|
|
}
|
|
/**
|
|
* @private
|
|
*/
|
|
canPush() {
|
|
return this.socket.isConnected() && this.isJoined();
|
|
}
|
|
/**
|
|
* Sends a message `event` to phoenix with the payload `payload`.
|
|
* Phoenix receives this in the `handle_in(event, payload, socket)`
|
|
* function. if phoenix replies or it times out (default 10000ms),
|
|
* then optionally the reply can be received.
|
|
*
|
|
* @example
|
|
* channel.push("event")
|
|
* .receive("ok", payload => console.log("phoenix replied:", payload))
|
|
* .receive("error", err => console.log("phoenix errored", err))
|
|
* .receive("timeout", () => console.log("timed out pushing"))
|
|
* @param {string} event
|
|
* @param {Object} payload
|
|
* @param {number} [timeout]
|
|
* @returns {Push}
|
|
*/
|
|
push(event, payload, timeout = this.timeout) {
|
|
payload = payload || {};
|
|
if (!this.joinedOnce) {
|
|
throw new Error(`tried to push '${event}' to '${this.topic}' before joining. Use channel.join() before pushing events`);
|
|
}
|
|
let pushEvent = new Push(this, event, function() {
|
|
return payload;
|
|
}, timeout);
|
|
if (this.canPush()) {
|
|
pushEvent.send();
|
|
} else {
|
|
pushEvent.startTimeout();
|
|
this.pushBuffer.push(pushEvent);
|
|
}
|
|
return pushEvent;
|
|
}
|
|
/** Leaves the channel
|
|
*
|
|
* Unsubscribes from server events, and
|
|
* instructs channel to terminate on server
|
|
*
|
|
* Triggers onClose() hooks
|
|
*
|
|
* To receive leave acknowledgements, use the `receive`
|
|
* hook to bind to the server ack, ie:
|
|
*
|
|
* @example
|
|
* channel.leave().receive("ok", () => alert("left!") )
|
|
*
|
|
* @param {integer} timeout
|
|
* @returns {Push}
|
|
*/
|
|
leave(timeout = this.timeout) {
|
|
this.rejoinTimer.reset();
|
|
this.joinPush.cancelTimeout();
|
|
this.state = CHANNEL_STATES.leaving;
|
|
let onClose = () => {
|
|
if (this.socket.hasLogger()) this.socket.log("channel", `leave ${this.topic}`);
|
|
this.trigger(CHANNEL_EVENTS.close, "leave");
|
|
};
|
|
let leavePush = new Push(this, CHANNEL_EVENTS.leave, closure({}), timeout);
|
|
leavePush.receive("ok", () => onClose()).receive("timeout", () => onClose());
|
|
leavePush.send();
|
|
if (!this.canPush()) {
|
|
leavePush.trigger("ok", {});
|
|
}
|
|
return leavePush;
|
|
}
|
|
/**
|
|
* Overridable message hook
|
|
*
|
|
* Receives all events for specialized message handling
|
|
* before dispatching to the channel callbacks.
|
|
*
|
|
* Must return the payload, modified or unmodified
|
|
* @param {string} event
|
|
* @param {Object} payload
|
|
* @param {integer} ref
|
|
* @returns {Object}
|
|
*/
|
|
onMessage(_event, payload, _ref) {
|
|
return payload;
|
|
}
|
|
/**
|
|
* @private
|
|
*/
|
|
isMember(topic, event, payload, joinRef) {
|
|
if (this.topic !== topic) {
|
|
return false;
|
|
}
|
|
if (joinRef && joinRef !== this.joinRef()) {
|
|
if (this.socket.hasLogger()) this.socket.log("channel", "dropping outdated message", { topic, event, payload, joinRef });
|
|
return false;
|
|
} else {
|
|
return true;
|
|
}
|
|
}
|
|
/**
|
|
* @private
|
|
*/
|
|
joinRef() {
|
|
return this.joinPush.ref;
|
|
}
|
|
/**
|
|
* @private
|
|
*/
|
|
rejoin(timeout = this.timeout) {
|
|
if (this.isLeaving()) {
|
|
return;
|
|
}
|
|
this.socket.leaveOpenTopic(this.topic);
|
|
this.state = CHANNEL_STATES.joining;
|
|
this.joinPush.resend(timeout);
|
|
}
|
|
/**
|
|
* @private
|
|
*/
|
|
trigger(event, payload, ref, joinRef) {
|
|
let handledPayload = this.onMessage(event, payload, ref, joinRef);
|
|
if (payload && !handledPayload) {
|
|
throw new Error("channel onMessage callbacks must return the payload, modified or unmodified");
|
|
}
|
|
let eventBindings = this.bindings.filter((bind) => bind.event === event);
|
|
for (let i = 0; i < eventBindings.length; i++) {
|
|
let bind = eventBindings[i];
|
|
bind.callback(handledPayload, ref, joinRef || this.joinRef());
|
|
}
|
|
}
|
|
/**
|
|
* @private
|
|
*/
|
|
replyEventName(ref) {
|
|
return `chan_reply_${ref}`;
|
|
}
|
|
/**
|
|
* @private
|
|
*/
|
|
isClosed() {
|
|
return this.state === CHANNEL_STATES.closed;
|
|
}
|
|
/**
|
|
* @private
|
|
*/
|
|
isErrored() {
|
|
return this.state === CHANNEL_STATES.errored;
|
|
}
|
|
/**
|
|
* @private
|
|
*/
|
|
isJoined() {
|
|
return this.state === CHANNEL_STATES.joined;
|
|
}
|
|
/**
|
|
* @private
|
|
*/
|
|
isJoining() {
|
|
return this.state === CHANNEL_STATES.joining;
|
|
}
|
|
/**
|
|
* @private
|
|
*/
|
|
isLeaving() {
|
|
return this.state === CHANNEL_STATES.leaving;
|
|
}
|
|
};
|
|
var Ajax = class {
|
|
static request(method, endPoint, headers, body, timeout, ontimeout, callback) {
|
|
if (global2.XDomainRequest) {
|
|
let req = new global2.XDomainRequest();
|
|
return this.xdomainRequest(req, method, endPoint, body, timeout, ontimeout, callback);
|
|
} else if (global2.XMLHttpRequest) {
|
|
let req = new global2.XMLHttpRequest();
|
|
return this.xhrRequest(req, method, endPoint, headers, body, timeout, ontimeout, callback);
|
|
} else if (global2.fetch && global2.AbortController) {
|
|
return this.fetchRequest(method, endPoint, headers, body, timeout, ontimeout, callback);
|
|
} else {
|
|
throw new Error("No suitable XMLHttpRequest implementation found");
|
|
}
|
|
}
|
|
static fetchRequest(method, endPoint, headers, body, timeout, ontimeout, callback) {
|
|
let options = {
|
|
method,
|
|
headers,
|
|
body
|
|
};
|
|
let controller = null;
|
|
if (timeout) {
|
|
controller = new AbortController();
|
|
const _timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
options.signal = controller.signal;
|
|
}
|
|
global2.fetch(endPoint, options).then((response) => response.text()).then((data) => this.parseJSON(data)).then((data) => callback && callback(data)).catch((err) => {
|
|
if (err.name === "AbortError" && ontimeout) {
|
|
ontimeout();
|
|
} else {
|
|
callback && callback(null);
|
|
}
|
|
});
|
|
return controller;
|
|
}
|
|
static xdomainRequest(req, method, endPoint, body, timeout, ontimeout, callback) {
|
|
req.timeout = timeout;
|
|
req.open(method, endPoint);
|
|
req.onload = () => {
|
|
let response = this.parseJSON(req.responseText);
|
|
callback && callback(response);
|
|
};
|
|
if (ontimeout) {
|
|
req.ontimeout = ontimeout;
|
|
}
|
|
req.onprogress = () => {
|
|
};
|
|
req.send(body);
|
|
return req;
|
|
}
|
|
static xhrRequest(req, method, endPoint, headers, body, timeout, ontimeout, callback) {
|
|
req.open(method, endPoint, true);
|
|
req.timeout = timeout;
|
|
for (let [key, value] of Object.entries(headers)) {
|
|
req.setRequestHeader(key, value);
|
|
}
|
|
req.onerror = () => callback && callback(null);
|
|
req.onreadystatechange = () => {
|
|
if (req.readyState === XHR_STATES.complete && callback) {
|
|
let response = this.parseJSON(req.responseText);
|
|
callback(response);
|
|
}
|
|
};
|
|
if (ontimeout) {
|
|
req.ontimeout = ontimeout;
|
|
}
|
|
req.send(body);
|
|
return req;
|
|
}
|
|
static parseJSON(resp) {
|
|
if (!resp || resp === "") {
|
|
return null;
|
|
}
|
|
try {
|
|
return JSON.parse(resp);
|
|
} catch (e) {
|
|
console && console.log("failed to parse JSON response", resp);
|
|
return null;
|
|
}
|
|
}
|
|
static serialize(obj, parentKey) {
|
|
let queryStr = [];
|
|
for (var key in obj) {
|
|
if (!Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
continue;
|
|
}
|
|
let paramKey = parentKey ? `${parentKey}[${key}]` : key;
|
|
let paramVal = obj[key];
|
|
if (typeof paramVal === "object") {
|
|
queryStr.push(this.serialize(paramVal, paramKey));
|
|
} else {
|
|
queryStr.push(encodeURIComponent(paramKey) + "=" + encodeURIComponent(paramVal));
|
|
}
|
|
}
|
|
return queryStr.join("&");
|
|
}
|
|
static appendParams(url, params) {
|
|
if (Object.keys(params).length === 0) {
|
|
return url;
|
|
}
|
|
let prefix = url.match(/\?/) ? "&" : "?";
|
|
return `${url}${prefix}${this.serialize(params)}`;
|
|
}
|
|
};
|
|
var arrayBufferToBase64 = (buffer) => {
|
|
let binary = "";
|
|
let bytes = new Uint8Array(buffer);
|
|
let len = bytes.byteLength;
|
|
for (let i = 0; i < len; i++) {
|
|
binary += String.fromCharCode(bytes[i]);
|
|
}
|
|
return btoa(binary);
|
|
};
|
|
var LongPoll = class {
|
|
constructor(endPoint, protocols) {
|
|
if (protocols && protocols.length === 2 && protocols[1].startsWith(AUTH_TOKEN_PREFIX)) {
|
|
this.authToken = atob(protocols[1].slice(AUTH_TOKEN_PREFIX.length));
|
|
}
|
|
this.endPoint = null;
|
|
this.token = null;
|
|
this.skipHeartbeat = true;
|
|
this.reqs = /* @__PURE__ */ new Set();
|
|
this.awaitingBatchAck = false;
|
|
this.currentBatch = null;
|
|
this.currentBatchTimer = null;
|
|
this.batchBuffer = [];
|
|
this.onopen = function() {
|
|
};
|
|
this.onerror = function() {
|
|
};
|
|
this.onmessage = function() {
|
|
};
|
|
this.onclose = function() {
|
|
};
|
|
this.pollEndpoint = this.normalizeEndpoint(endPoint);
|
|
this.readyState = SOCKET_STATES.connecting;
|
|
setTimeout(() => this.poll(), 0);
|
|
}
|
|
normalizeEndpoint(endPoint) {
|
|
return endPoint.replace("ws://", "http://").replace("wss://", "https://").replace(new RegExp("(.*)/" + TRANSPORTS.websocket), "$1/" + TRANSPORTS.longpoll);
|
|
}
|
|
endpointURL() {
|
|
return Ajax.appendParams(this.pollEndpoint, { token: this.token });
|
|
}
|
|
closeAndRetry(code, reason, wasClean) {
|
|
this.close(code, reason, wasClean);
|
|
this.readyState = SOCKET_STATES.connecting;
|
|
}
|
|
ontimeout() {
|
|
this.onerror("timeout");
|
|
this.closeAndRetry(1005, "timeout", false);
|
|
}
|
|
isActive() {
|
|
return this.readyState === SOCKET_STATES.open || this.readyState === SOCKET_STATES.connecting;
|
|
}
|
|
poll() {
|
|
const headers = { "Accept": "application/json" };
|
|
if (this.authToken) {
|
|
headers["X-Phoenix-AuthToken"] = this.authToken;
|
|
}
|
|
this.ajax("GET", headers, null, () => this.ontimeout(), (resp) => {
|
|
if (resp) {
|
|
var { status, token, messages } = resp;
|
|
if (status === 410 && this.token !== null) {
|
|
this.onerror(410);
|
|
this.closeAndRetry(3410, "session_gone", false);
|
|
return;
|
|
}
|
|
this.token = token;
|
|
} else {
|
|
status = 0;
|
|
}
|
|
switch (status) {
|
|
case 200:
|
|
messages.forEach((msg) => {
|
|
setTimeout(() => this.onmessage({ data: msg }), 0);
|
|
});
|
|
this.poll();
|
|
break;
|
|
case 204:
|
|
this.poll();
|
|
break;
|
|
case 410:
|
|
this.readyState = SOCKET_STATES.open;
|
|
this.onopen({});
|
|
this.poll();
|
|
break;
|
|
case 403:
|
|
this.onerror(403);
|
|
this.close(1008, "forbidden", false);
|
|
break;
|
|
case 0:
|
|
case 500:
|
|
this.onerror(500);
|
|
this.closeAndRetry(1011, "internal server error", 500);
|
|
break;
|
|
default:
|
|
throw new Error(`unhandled poll status ${status}`);
|
|
}
|
|
});
|
|
}
|
|
// we collect all pushes within the current event loop by
|
|
// setTimeout 0, which optimizes back-to-back procedural
|
|
// pushes against an empty buffer
|
|
send(body) {
|
|
if (typeof body !== "string") {
|
|
body = arrayBufferToBase64(body);
|
|
}
|
|
if (this.currentBatch) {
|
|
this.currentBatch.push(body);
|
|
} else if (this.awaitingBatchAck) {
|
|
this.batchBuffer.push(body);
|
|
} else {
|
|
this.currentBatch = [body];
|
|
this.currentBatchTimer = setTimeout(() => {
|
|
this.batchSend(this.currentBatch);
|
|
this.currentBatch = null;
|
|
}, 0);
|
|
}
|
|
}
|
|
batchSend(messages, offset = 0) {
|
|
this.awaitingBatchAck = true;
|
|
const next = offset + MAX_LONGPOLL_BATCH_SIZE;
|
|
const batch = messages.slice(offset, next);
|
|
this.ajax("POST", { "Content-Type": "application/x-ndjson" }, batch.join("\n"), () => this.onerror("timeout"), (resp) => {
|
|
if (!resp || resp.status !== 200) {
|
|
this.awaitingBatchAck = false;
|
|
this.onerror(resp && resp.status);
|
|
this.closeAndRetry(1011, "internal server error", false);
|
|
} else if (next < messages.length) {
|
|
this.batchSend(messages, next);
|
|
} else if (this.batchBuffer.length > 0) {
|
|
this.batchSend(this.batchBuffer);
|
|
this.batchBuffer = [];
|
|
} else {
|
|
this.awaitingBatchAck = false;
|
|
}
|
|
});
|
|
}
|
|
close(code, reason, wasClean) {
|
|
for (let req of this.reqs) {
|
|
req.abort();
|
|
}
|
|
this.readyState = SOCKET_STATES.closed;
|
|
let opts = Object.assign({ code: 1e3, reason: void 0, wasClean: true }, { code, reason, wasClean });
|
|
this.batchBuffer = [];
|
|
clearTimeout(this.currentBatchTimer);
|
|
this.currentBatchTimer = null;
|
|
if (typeof CloseEvent !== "undefined") {
|
|
this.onclose(new CloseEvent("close", opts));
|
|
} else {
|
|
this.onclose(opts);
|
|
}
|
|
}
|
|
ajax(method, headers, body, onCallerTimeout, callback) {
|
|
let req;
|
|
let ontimeout = () => {
|
|
this.reqs.delete(req);
|
|
onCallerTimeout();
|
|
};
|
|
req = Ajax.request(method, this.endpointURL(), headers, body, this.timeout, ontimeout, (resp) => {
|
|
this.reqs.delete(req);
|
|
if (this.isActive()) {
|
|
callback(resp);
|
|
}
|
|
});
|
|
this.reqs.add(req);
|
|
}
|
|
};
|
|
var serializer_default = {
|
|
HEADER_LENGTH: 1,
|
|
META_LENGTH: 4,
|
|
KINDS: { push: 0, reply: 1, broadcast: 2 },
|
|
encode(msg, callback) {
|
|
if (msg.payload.constructor === ArrayBuffer) {
|
|
return callback(this.binaryEncode(msg));
|
|
} else {
|
|
let payload = [msg.join_ref, msg.ref, msg.topic, msg.event, msg.payload];
|
|
return callback(JSON.stringify(payload));
|
|
}
|
|
},
|
|
decode(rawPayload, callback) {
|
|
if (rawPayload.constructor === ArrayBuffer) {
|
|
return callback(this.binaryDecode(rawPayload));
|
|
} else {
|
|
let [join_ref, ref, topic, event, payload] = JSON.parse(rawPayload);
|
|
return callback({ join_ref, ref, topic, event, payload });
|
|
}
|
|
},
|
|
// private
|
|
binaryEncode(message) {
|
|
let { join_ref, ref, event, topic, payload } = message;
|
|
let metaLength = this.META_LENGTH + join_ref.length + ref.length + topic.length + event.length;
|
|
let header = new ArrayBuffer(this.HEADER_LENGTH + metaLength);
|
|
let view = new DataView(header);
|
|
let offset = 0;
|
|
view.setUint8(offset++, this.KINDS.push);
|
|
view.setUint8(offset++, join_ref.length);
|
|
view.setUint8(offset++, ref.length);
|
|
view.setUint8(offset++, topic.length);
|
|
view.setUint8(offset++, event.length);
|
|
Array.from(join_ref, (char) => view.setUint8(offset++, char.charCodeAt(0)));
|
|
Array.from(ref, (char) => view.setUint8(offset++, char.charCodeAt(0)));
|
|
Array.from(topic, (char) => view.setUint8(offset++, char.charCodeAt(0)));
|
|
Array.from(event, (char) => view.setUint8(offset++, char.charCodeAt(0)));
|
|
var combined = new Uint8Array(header.byteLength + payload.byteLength);
|
|
combined.set(new Uint8Array(header), 0);
|
|
combined.set(new Uint8Array(payload), header.byteLength);
|
|
return combined.buffer;
|
|
},
|
|
binaryDecode(buffer) {
|
|
let view = new DataView(buffer);
|
|
let kind = view.getUint8(0);
|
|
let decoder = new TextDecoder();
|
|
switch (kind) {
|
|
case this.KINDS.push:
|
|
return this.decodePush(buffer, view, decoder);
|
|
case this.KINDS.reply:
|
|
return this.decodeReply(buffer, view, decoder);
|
|
case this.KINDS.broadcast:
|
|
return this.decodeBroadcast(buffer, view, decoder);
|
|
}
|
|
},
|
|
decodePush(buffer, view, decoder) {
|
|
let joinRefSize = view.getUint8(1);
|
|
let topicSize = view.getUint8(2);
|
|
let eventSize = view.getUint8(3);
|
|
let offset = this.HEADER_LENGTH + this.META_LENGTH - 1;
|
|
let joinRef = decoder.decode(buffer.slice(offset, offset + joinRefSize));
|
|
offset = offset + joinRefSize;
|
|
let topic = decoder.decode(buffer.slice(offset, offset + topicSize));
|
|
offset = offset + topicSize;
|
|
let event = decoder.decode(buffer.slice(offset, offset + eventSize));
|
|
offset = offset + eventSize;
|
|
let data = buffer.slice(offset, buffer.byteLength);
|
|
return { join_ref: joinRef, ref: null, topic, event, payload: data };
|
|
},
|
|
decodeReply(buffer, view, decoder) {
|
|
let joinRefSize = view.getUint8(1);
|
|
let refSize = view.getUint8(2);
|
|
let topicSize = view.getUint8(3);
|
|
let eventSize = view.getUint8(4);
|
|
let offset = this.HEADER_LENGTH + this.META_LENGTH;
|
|
let joinRef = decoder.decode(buffer.slice(offset, offset + joinRefSize));
|
|
offset = offset + joinRefSize;
|
|
let ref = decoder.decode(buffer.slice(offset, offset + refSize));
|
|
offset = offset + refSize;
|
|
let topic = decoder.decode(buffer.slice(offset, offset + topicSize));
|
|
offset = offset + topicSize;
|
|
let event = decoder.decode(buffer.slice(offset, offset + eventSize));
|
|
offset = offset + eventSize;
|
|
let data = buffer.slice(offset, buffer.byteLength);
|
|
let payload = { status: event, response: data };
|
|
return { join_ref: joinRef, ref, topic, event: CHANNEL_EVENTS.reply, payload };
|
|
},
|
|
decodeBroadcast(buffer, view, decoder) {
|
|
let topicSize = view.getUint8(1);
|
|
let eventSize = view.getUint8(2);
|
|
let offset = this.HEADER_LENGTH + 2;
|
|
let topic = decoder.decode(buffer.slice(offset, offset + topicSize));
|
|
offset = offset + topicSize;
|
|
let event = decoder.decode(buffer.slice(offset, offset + eventSize));
|
|
offset = offset + eventSize;
|
|
let data = buffer.slice(offset, buffer.byteLength);
|
|
return { join_ref: null, ref: null, topic, event, payload: data };
|
|
}
|
|
};
|
|
var Socket = class {
|
|
constructor(endPoint, opts = {}) {
|
|
this.stateChangeCallbacks = { open: [], close: [], error: [], message: [] };
|
|
this.channels = [];
|
|
this.sendBuffer = [];
|
|
this.ref = 0;
|
|
this.fallbackRef = null;
|
|
this.timeout = opts.timeout || DEFAULT_TIMEOUT;
|
|
this.transport = opts.transport || global2.WebSocket || LongPoll;
|
|
this.primaryPassedHealthCheck = false;
|
|
this.longPollFallbackMs = opts.longPollFallbackMs;
|
|
this.fallbackTimer = null;
|
|
this.sessionStore = opts.sessionStorage || global2 && global2.sessionStorage;
|
|
this.establishedConnections = 0;
|
|
this.defaultEncoder = serializer_default.encode.bind(serializer_default);
|
|
this.defaultDecoder = serializer_default.decode.bind(serializer_default);
|
|
this.closeWasClean = true;
|
|
this.disconnecting = false;
|
|
this.binaryType = opts.binaryType || "arraybuffer";
|
|
this.connectClock = 1;
|
|
this.pageHidden = false;
|
|
if (this.transport !== LongPoll) {
|
|
this.encode = opts.encode || this.defaultEncoder;
|
|
this.decode = opts.decode || this.defaultDecoder;
|
|
} else {
|
|
this.encode = this.defaultEncoder;
|
|
this.decode = this.defaultDecoder;
|
|
}
|
|
let awaitingConnectionOnPageShow = null;
|
|
if (phxWindow && phxWindow.addEventListener) {
|
|
phxWindow.addEventListener("pagehide", (_e) => {
|
|
if (this.conn) {
|
|
this.disconnect();
|
|
awaitingConnectionOnPageShow = this.connectClock;
|
|
}
|
|
});
|
|
phxWindow.addEventListener("pageshow", (_e) => {
|
|
if (awaitingConnectionOnPageShow === this.connectClock) {
|
|
awaitingConnectionOnPageShow = null;
|
|
this.connect();
|
|
}
|
|
});
|
|
phxWindow.addEventListener("visibilitychange", () => {
|
|
if (document.visibilityState === "hidden") {
|
|
this.pageHidden = true;
|
|
} else {
|
|
this.pageHidden = false;
|
|
if (!this.isConnected() && !this.closeWasClean) {
|
|
this.teardown(() => this.connect());
|
|
}
|
|
}
|
|
});
|
|
}
|
|
this.heartbeatIntervalMs = opts.heartbeatIntervalMs || 3e4;
|
|
this.rejoinAfterMs = (tries) => {
|
|
if (opts.rejoinAfterMs) {
|
|
return opts.rejoinAfterMs(tries);
|
|
} else {
|
|
return [1e3, 2e3, 5e3][tries - 1] || 1e4;
|
|
}
|
|
};
|
|
this.reconnectAfterMs = (tries) => {
|
|
if (opts.reconnectAfterMs) {
|
|
return opts.reconnectAfterMs(tries);
|
|
} else {
|
|
return [10, 50, 100, 150, 200, 250, 500, 1e3, 2e3][tries - 1] || 5e3;
|
|
}
|
|
};
|
|
this.logger = opts.logger || null;
|
|
if (!this.logger && opts.debug) {
|
|
this.logger = (kind, msg, data) => {
|
|
console.log(`${kind}: ${msg}`, data);
|
|
};
|
|
}
|
|
this.longpollerTimeout = opts.longpollerTimeout || 2e4;
|
|
this.params = closure(opts.params || {});
|
|
this.endPoint = `${endPoint}/${TRANSPORTS.websocket}`;
|
|
this.vsn = opts.vsn || DEFAULT_VSN;
|
|
this.heartbeatTimeoutTimer = null;
|
|
this.heartbeatTimer = null;
|
|
this.pendingHeartbeatRef = null;
|
|
this.reconnectTimer = new Timer(() => {
|
|
if (this.pageHidden) {
|
|
this.log("Not reconnecting as page is hidden!");
|
|
this.teardown();
|
|
return;
|
|
}
|
|
this.teardown(() => this.connect());
|
|
}, this.reconnectAfterMs);
|
|
this.authToken = opts.authToken;
|
|
}
|
|
/**
|
|
* Returns the LongPoll transport reference
|
|
*/
|
|
getLongPollTransport() {
|
|
return LongPoll;
|
|
}
|
|
/**
|
|
* Disconnects and replaces the active transport
|
|
*
|
|
* @param {Function} newTransport - The new transport class to instantiate
|
|
*
|
|
*/
|
|
replaceTransport(newTransport) {
|
|
this.connectClock++;
|
|
this.closeWasClean = true;
|
|
clearTimeout(this.fallbackTimer);
|
|
this.reconnectTimer.reset();
|
|
if (this.conn) {
|
|
this.conn.close();
|
|
this.conn = null;
|
|
}
|
|
this.transport = newTransport;
|
|
}
|
|
/**
|
|
* Returns the socket protocol
|
|
*
|
|
* @returns {string}
|
|
*/
|
|
protocol() {
|
|
return location.protocol.match(/^https/) ? "wss" : "ws";
|
|
}
|
|
/**
|
|
* The fully qualified socket url
|
|
*
|
|
* @returns {string}
|
|
*/
|
|
endPointURL() {
|
|
let uri = Ajax.appendParams(
|
|
Ajax.appendParams(this.endPoint, this.params()),
|
|
{ vsn: this.vsn }
|
|
);
|
|
if (uri.charAt(0) !== "/") {
|
|
return uri;
|
|
}
|
|
if (uri.charAt(1) === "/") {
|
|
return `${this.protocol()}:${uri}`;
|
|
}
|
|
return `${this.protocol()}://${location.host}${uri}`;
|
|
}
|
|
/**
|
|
* Disconnects the socket
|
|
*
|
|
* See https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes for valid status codes.
|
|
*
|
|
* @param {Function} callback - Optional callback which is called after socket is disconnected.
|
|
* @param {integer} code - A status code for disconnection (Optional).
|
|
* @param {string} reason - A textual description of the reason to disconnect. (Optional)
|
|
*/
|
|
disconnect(callback, code, reason) {
|
|
this.connectClock++;
|
|
this.disconnecting = true;
|
|
this.closeWasClean = true;
|
|
clearTimeout(this.fallbackTimer);
|
|
this.reconnectTimer.reset();
|
|
this.teardown(() => {
|
|
this.disconnecting = false;
|
|
callback && callback();
|
|
}, code, reason);
|
|
}
|
|
/**
|
|
*
|
|
* @param {Object} params - The params to send when connecting, for example `{user_id: userToken}`
|
|
*
|
|
* Passing params to connect is deprecated; pass them in the Socket constructor instead:
|
|
* `new Socket("/socket", {params: {user_id: userToken}})`.
|
|
*/
|
|
connect(params) {
|
|
if (params) {
|
|
console && console.log("passing params to connect is deprecated. Instead pass :params to the Socket constructor");
|
|
this.params = closure(params);
|
|
}
|
|
if (this.conn && !this.disconnecting) {
|
|
return;
|
|
}
|
|
if (this.longPollFallbackMs && this.transport !== LongPoll) {
|
|
this.connectWithFallback(LongPoll, this.longPollFallbackMs);
|
|
} else {
|
|
this.transportConnect();
|
|
}
|
|
}
|
|
/**
|
|
* Logs the message. Override `this.logger` for specialized logging. noops by default
|
|
* @param {string} kind
|
|
* @param {string} msg
|
|
* @param {Object} data
|
|
*/
|
|
log(kind, msg, data) {
|
|
this.logger && this.logger(kind, msg, data);
|
|
}
|
|
/**
|
|
* Returns true if a logger has been set on this socket.
|
|
*/
|
|
hasLogger() {
|
|
return this.logger !== null;
|
|
}
|
|
/**
|
|
* Registers callbacks for connection open events
|
|
*
|
|
* @example socket.onOpen(function(){ console.info("the socket was opened") })
|
|
*
|
|
* @param {Function} callback
|
|
*/
|
|
onOpen(callback) {
|
|
let ref = this.makeRef();
|
|
this.stateChangeCallbacks.open.push([ref, callback]);
|
|
return ref;
|
|
}
|
|
/**
|
|
* Registers callbacks for connection close events
|
|
* @param {Function} callback
|
|
*/
|
|
onClose(callback) {
|
|
let ref = this.makeRef();
|
|
this.stateChangeCallbacks.close.push([ref, callback]);
|
|
return ref;
|
|
}
|
|
/**
|
|
* Registers callbacks for connection error events
|
|
*
|
|
* @example socket.onError(function(error){ alert("An error occurred") })
|
|
*
|
|
* @param {Function} callback
|
|
*/
|
|
onError(callback) {
|
|
let ref = this.makeRef();
|
|
this.stateChangeCallbacks.error.push([ref, callback]);
|
|
return ref;
|
|
}
|
|
/**
|
|
* Registers callbacks for connection message events
|
|
* @param {Function} callback
|
|
*/
|
|
onMessage(callback) {
|
|
let ref = this.makeRef();
|
|
this.stateChangeCallbacks.message.push([ref, callback]);
|
|
return ref;
|
|
}
|
|
/**
|
|
* Pings the server and invokes the callback with the RTT in milliseconds
|
|
* @param {Function} callback
|
|
*
|
|
* Returns true if the ping was pushed or false if unable to be pushed.
|
|
*/
|
|
ping(callback) {
|
|
if (!this.isConnected()) {
|
|
return false;
|
|
}
|
|
let ref = this.makeRef();
|
|
let startTime = Date.now();
|
|
this.push({ topic: "phoenix", event: "heartbeat", payload: {}, ref });
|
|
let onMsgRef = this.onMessage((msg) => {
|
|
if (msg.ref === ref) {
|
|
this.off([onMsgRef]);
|
|
callback(Date.now() - startTime);
|
|
}
|
|
});
|
|
return true;
|
|
}
|
|
/**
|
|
* @private
|
|
*
|
|
* @param {Function}
|
|
*/
|
|
transportName(transport) {
|
|
switch (transport) {
|
|
case LongPoll:
|
|
return "LongPoll";
|
|
default:
|
|
return transport.name;
|
|
}
|
|
}
|
|
/**
|
|
* @private
|
|
*/
|
|
transportConnect() {
|
|
this.connectClock++;
|
|
this.closeWasClean = false;
|
|
let protocols = void 0;
|
|
if (this.authToken) {
|
|
protocols = ["phoenix", `${AUTH_TOKEN_PREFIX}${btoa(this.authToken).replace(/=/g, "")}`];
|
|
}
|
|
this.conn = new this.transport(this.endPointURL(), protocols);
|
|
this.conn.binaryType = this.binaryType;
|
|
this.conn.timeout = this.longpollerTimeout;
|
|
this.conn.onopen = () => this.onConnOpen();
|
|
this.conn.onerror = (error) => this.onConnError(error);
|
|
this.conn.onmessage = (event) => this.onConnMessage(event);
|
|
this.conn.onclose = (event) => this.onConnClose(event);
|
|
}
|
|
getSession(key) {
|
|
return this.sessionStore && this.sessionStore.getItem(key);
|
|
}
|
|
storeSession(key, val) {
|
|
this.sessionStore && this.sessionStore.setItem(key, val);
|
|
}
|
|
connectWithFallback(fallbackTransport, fallbackThreshold = 2500) {
|
|
clearTimeout(this.fallbackTimer);
|
|
let established = false;
|
|
let primaryTransport = true;
|
|
let openRef, errorRef;
|
|
let fallbackTransportName = this.transportName(fallbackTransport);
|
|
let fallback = (reason) => {
|
|
this.log("transport", `falling back to ${fallbackTransportName}...`, reason);
|
|
this.off([openRef, errorRef]);
|
|
primaryTransport = false;
|
|
this.replaceTransport(fallbackTransport);
|
|
this.transportConnect();
|
|
};
|
|
if (this.getSession(`phx:fallback:${fallbackTransportName}`)) {
|
|
return fallback("memorized");
|
|
}
|
|
this.fallbackTimer = setTimeout(fallback, fallbackThreshold);
|
|
errorRef = this.onError((reason) => {
|
|
this.log("transport", "error", reason);
|
|
if (primaryTransport && !established) {
|
|
clearTimeout(this.fallbackTimer);
|
|
fallback(reason);
|
|
}
|
|
});
|
|
if (this.fallbackRef) {
|
|
this.off([this.fallbackRef]);
|
|
}
|
|
this.fallbackRef = this.onOpen(() => {
|
|
established = true;
|
|
if (!primaryTransport) {
|
|
let fallbackTransportName2 = this.transportName(fallbackTransport);
|
|
if (!this.primaryPassedHealthCheck) {
|
|
this.storeSession(`phx:fallback:${fallbackTransportName2}`, "true");
|
|
}
|
|
return this.log("transport", `established ${fallbackTransportName2} fallback`);
|
|
}
|
|
clearTimeout(this.fallbackTimer);
|
|
this.fallbackTimer = setTimeout(fallback, fallbackThreshold);
|
|
this.ping((rtt) => {
|
|
this.log("transport", "connected to primary after", rtt);
|
|
this.primaryPassedHealthCheck = true;
|
|
clearTimeout(this.fallbackTimer);
|
|
});
|
|
});
|
|
this.transportConnect();
|
|
}
|
|
clearHeartbeats() {
|
|
clearTimeout(this.heartbeatTimer);
|
|
clearTimeout(this.heartbeatTimeoutTimer);
|
|
}
|
|
onConnOpen() {
|
|
if (this.hasLogger()) this.log("transport", `${this.transportName(this.transport)} connected to ${this.endPointURL()}`);
|
|
this.closeWasClean = false;
|
|
this.disconnecting = false;
|
|
this.establishedConnections++;
|
|
this.flushSendBuffer();
|
|
this.reconnectTimer.reset();
|
|
this.resetHeartbeat();
|
|
this.stateChangeCallbacks.open.forEach(([, callback]) => callback());
|
|
}
|
|
/**
|
|
* @private
|
|
*/
|
|
heartbeatTimeout() {
|
|
if (this.pendingHeartbeatRef) {
|
|
this.pendingHeartbeatRef = null;
|
|
if (this.hasLogger()) {
|
|
this.log("transport", "heartbeat timeout. Attempting to re-establish connection");
|
|
}
|
|
this.triggerChanError();
|
|
this.closeWasClean = false;
|
|
this.teardown(() => this.reconnectTimer.scheduleTimeout(), WS_CLOSE_NORMAL, "heartbeat timeout");
|
|
}
|
|
}
|
|
resetHeartbeat() {
|
|
if (this.conn && this.conn.skipHeartbeat) {
|
|
return;
|
|
}
|
|
this.pendingHeartbeatRef = null;
|
|
this.clearHeartbeats();
|
|
this.heartbeatTimer = setTimeout(() => this.sendHeartbeat(), this.heartbeatIntervalMs);
|
|
}
|
|
teardown(callback, code, reason) {
|
|
if (!this.conn) {
|
|
return callback && callback();
|
|
}
|
|
const connToClose = this.conn;
|
|
this.waitForBufferDone(connToClose, () => {
|
|
if (code) {
|
|
connToClose.close(code, reason || "");
|
|
} else {
|
|
connToClose.close();
|
|
}
|
|
this.waitForSocketClosed(connToClose, () => {
|
|
if (this.conn === connToClose) {
|
|
this.conn.onopen = function() {
|
|
};
|
|
this.conn.onerror = function() {
|
|
};
|
|
this.conn.onmessage = function() {
|
|
};
|
|
this.conn.onclose = function() {
|
|
};
|
|
this.conn = null;
|
|
}
|
|
callback && callback();
|
|
});
|
|
});
|
|
}
|
|
waitForBufferDone(conn, callback, tries = 1) {
|
|
if (tries === 5 || !conn.bufferedAmount) {
|
|
callback();
|
|
return;
|
|
}
|
|
setTimeout(() => {
|
|
this.waitForBufferDone(conn, callback, tries + 1);
|
|
}, 150 * tries);
|
|
}
|
|
waitForSocketClosed(conn, callback, tries = 1) {
|
|
if (tries === 5 || conn.readyState === SOCKET_STATES.closed) {
|
|
callback();
|
|
return;
|
|
}
|
|
setTimeout(() => {
|
|
this.waitForSocketClosed(conn, callback, tries + 1);
|
|
}, 150 * tries);
|
|
}
|
|
onConnClose(event) {
|
|
if (this.conn) this.conn.onclose = () => {
|
|
};
|
|
let closeCode = event && event.code;
|
|
if (this.hasLogger()) this.log("transport", "close", event);
|
|
this.triggerChanError();
|
|
this.clearHeartbeats();
|
|
if (!this.closeWasClean && closeCode !== 1e3) {
|
|
this.reconnectTimer.scheduleTimeout();
|
|
}
|
|
this.stateChangeCallbacks.close.forEach(([, callback]) => callback(event));
|
|
}
|
|
/**
|
|
* @private
|
|
*/
|
|
onConnError(error) {
|
|
if (this.hasLogger()) this.log("transport", "error", error);
|
|
let transportBefore = this.transport;
|
|
let establishedBefore = this.establishedConnections;
|
|
this.stateChangeCallbacks.error.forEach(([, callback]) => {
|
|
callback(error, transportBefore, establishedBefore);
|
|
});
|
|
if (transportBefore === this.transport || establishedBefore > 0) {
|
|
this.triggerChanError();
|
|
}
|
|
}
|
|
/**
|
|
* @private
|
|
*/
|
|
triggerChanError() {
|
|
this.channels.forEach((channel) => {
|
|
if (!(channel.isErrored() || channel.isLeaving() || channel.isClosed())) {
|
|
channel.trigger(CHANNEL_EVENTS.error);
|
|
}
|
|
});
|
|
}
|
|
/**
|
|
* @returns {string}
|
|
*/
|
|
connectionState() {
|
|
switch (this.conn && this.conn.readyState) {
|
|
case SOCKET_STATES.connecting:
|
|
return "connecting";
|
|
case SOCKET_STATES.open:
|
|
return "open";
|
|
case SOCKET_STATES.closing:
|
|
return "closing";
|
|
default:
|
|
return "closed";
|
|
}
|
|
}
|
|
/**
|
|
* @returns {boolean}
|
|
*/
|
|
isConnected() {
|
|
return this.connectionState() === "open";
|
|
}
|
|
/**
|
|
* @private
|
|
*
|
|
* @param {Channel}
|
|
*/
|
|
remove(channel) {
|
|
this.off(channel.stateChangeRefs);
|
|
this.channels = this.channels.filter((c) => c !== channel);
|
|
}
|
|
/**
|
|
* Removes `onOpen`, `onClose`, `onError,` and `onMessage` registrations.
|
|
*
|
|
* @param {refs} - list of refs returned by calls to
|
|
* `onOpen`, `onClose`, `onError,` and `onMessage`
|
|
*/
|
|
off(refs) {
|
|
for (let key in this.stateChangeCallbacks) {
|
|
this.stateChangeCallbacks[key] = this.stateChangeCallbacks[key].filter(([ref]) => {
|
|
return refs.indexOf(ref) === -1;
|
|
});
|
|
}
|
|
}
|
|
/**
|
|
* Initiates a new channel for the given topic
|
|
*
|
|
* @param {string} topic
|
|
* @param {Object} chanParams - Parameters for the channel
|
|
* @returns {Channel}
|
|
*/
|
|
channel(topic, chanParams = {}) {
|
|
let chan = new Channel(topic, chanParams, this);
|
|
this.channels.push(chan);
|
|
return chan;
|
|
}
|
|
/**
|
|
* @param {Object} data
|
|
*/
|
|
push(data) {
|
|
if (this.hasLogger()) {
|
|
let { topic, event, payload, ref, join_ref } = data;
|
|
this.log("push", `${topic} ${event} (${join_ref}, ${ref})`, payload);
|
|
}
|
|
if (this.isConnected()) {
|
|
this.encode(data, (result) => this.conn.send(result));
|
|
} else {
|
|
this.sendBuffer.push(() => this.encode(data, (result) => this.conn.send(result)));
|
|
}
|
|
}
|
|
/**
|
|
* Return the next message ref, accounting for overflows
|
|
* @returns {string}
|
|
*/
|
|
makeRef() {
|
|
let newRef = this.ref + 1;
|
|
if (newRef === this.ref) {
|
|
this.ref = 0;
|
|
} else {
|
|
this.ref = newRef;
|
|
}
|
|
return this.ref.toString();
|
|
}
|
|
sendHeartbeat() {
|
|
if (this.pendingHeartbeatRef && !this.isConnected()) {
|
|
return;
|
|
}
|
|
this.pendingHeartbeatRef = this.makeRef();
|
|
this.push({ topic: "phoenix", event: "heartbeat", payload: {}, ref: this.pendingHeartbeatRef });
|
|
this.heartbeatTimeoutTimer = setTimeout(() => this.heartbeatTimeout(), this.heartbeatIntervalMs);
|
|
}
|
|
flushSendBuffer() {
|
|
if (this.isConnected() && this.sendBuffer.length > 0) {
|
|
this.sendBuffer.forEach((callback) => callback());
|
|
this.sendBuffer = [];
|
|
}
|
|
}
|
|
onConnMessage(rawMessage) {
|
|
this.decode(rawMessage.data, (msg) => {
|
|
let { topic, event, payload, ref, join_ref } = msg;
|
|
if (ref && ref === this.pendingHeartbeatRef) {
|
|
this.clearHeartbeats();
|
|
this.pendingHeartbeatRef = null;
|
|
this.heartbeatTimer = setTimeout(() => this.sendHeartbeat(), this.heartbeatIntervalMs);
|
|
}
|
|
if (this.hasLogger()) this.log("receive", `${payload.status || ""} ${topic} ${event} ${ref && "(" + ref + ")" || ""}`, payload);
|
|
for (let i = 0; i < this.channels.length; i++) {
|
|
const channel = this.channels[i];
|
|
if (!channel.isMember(topic, event, payload, join_ref)) {
|
|
continue;
|
|
}
|
|
channel.trigger(event, payload, ref, join_ref);
|
|
}
|
|
for (let i = 0; i < this.stateChangeCallbacks.message.length; i++) {
|
|
let [, callback] = this.stateChangeCallbacks.message[i];
|
|
callback(msg);
|
|
}
|
|
});
|
|
}
|
|
leaveOpenTopic(topic) {
|
|
let dupChannel = this.channels.find((c) => c.topic === topic && (c.isJoined() || c.isJoining()));
|
|
if (dupChannel) {
|
|
if (this.hasLogger()) this.log("transport", `leaving duplicate topic "${topic}"`);
|
|
dupChannel.leave();
|
|
}
|
|
}
|
|
};
|
|
|
|
// ../deps/phoenix_live_view/priv/static/phoenix_live_view.esm.js
|
|
var CONSECUTIVE_RELOADS = "consecutive-reloads";
|
|
var MAX_RELOADS = 10;
|
|
var RELOAD_JITTER_MIN = 5e3;
|
|
var RELOAD_JITTER_MAX = 1e4;
|
|
var FAILSAFE_JITTER = 3e4;
|
|
var PHX_EVENT_CLASSES = [
|
|
"phx-click-loading",
|
|
"phx-change-loading",
|
|
"phx-submit-loading",
|
|
"phx-keydown-loading",
|
|
"phx-keyup-loading",
|
|
"phx-blur-loading",
|
|
"phx-focus-loading",
|
|
"phx-hook-loading"
|
|
];
|
|
var PHX_DROP_TARGET_ACTIVE_CLASS = "phx-drop-target-active";
|
|
var PHX_COMPONENT = "data-phx-component";
|
|
var PHX_VIEW_REF = "data-phx-view";
|
|
var PHX_LIVE_LINK = "data-phx-link";
|
|
var PHX_TRACK_STATIC = "track-static";
|
|
var PHX_LINK_STATE = "data-phx-link-state";
|
|
var PHX_REF_LOADING = "data-phx-ref-loading";
|
|
var PHX_REF_SRC = "data-phx-ref-src";
|
|
var PHX_REF_LOCK = "data-phx-ref-lock";
|
|
var PHX_PENDING_REFS = "phx-pending-refs";
|
|
var PHX_TRACK_UPLOADS = "track-uploads";
|
|
var PHX_UPLOAD_REF = "data-phx-upload-ref";
|
|
var PHX_PREFLIGHTED_REFS = "data-phx-preflighted-refs";
|
|
var PHX_DONE_REFS = "data-phx-done-refs";
|
|
var PHX_DROP_TARGET = "drop-target";
|
|
var PHX_ACTIVE_ENTRY_REFS = "data-phx-active-refs";
|
|
var PHX_LIVE_FILE_UPDATED = "phx:live-file:updated";
|
|
var PHX_SKIP = "data-phx-skip";
|
|
var PHX_MAGIC_ID = "data-phx-id";
|
|
var PHX_PRUNE = "data-phx-prune";
|
|
var PHX_CONNECTED_CLASS = "phx-connected";
|
|
var PHX_LOADING_CLASS = "phx-loading";
|
|
var PHX_ERROR_CLASS = "phx-error";
|
|
var PHX_CLIENT_ERROR_CLASS = "phx-client-error";
|
|
var PHX_SERVER_ERROR_CLASS = "phx-server-error";
|
|
var PHX_PARENT_ID = "data-phx-parent-id";
|
|
var PHX_MAIN = "data-phx-main";
|
|
var PHX_ROOT_ID = "data-phx-root-id";
|
|
var PHX_VIEWPORT_TOP = "viewport-top";
|
|
var PHX_VIEWPORT_BOTTOM = "viewport-bottom";
|
|
var PHX_VIEWPORT_OVERRUN_TARGET = "viewport-overrun-target";
|
|
var PHX_TRIGGER_ACTION = "trigger-action";
|
|
var PHX_HAS_FOCUSED = "phx-has-focused";
|
|
var FOCUSABLE_INPUTS = [
|
|
"text",
|
|
"textarea",
|
|
"number",
|
|
"email",
|
|
"password",
|
|
"search",
|
|
"tel",
|
|
"url",
|
|
"date",
|
|
"time",
|
|
"datetime-local",
|
|
"color",
|
|
"range"
|
|
];
|
|
var CHECKABLE_INPUTS = ["checkbox", "radio"];
|
|
var PHX_HAS_SUBMITTED = "phx-has-submitted";
|
|
var PHX_SESSION = "data-phx-session";
|
|
var PHX_VIEW_SELECTOR = `[${PHX_SESSION}]`;
|
|
var PHX_STICKY = "data-phx-sticky";
|
|
var PHX_STATIC = "data-phx-static";
|
|
var PHX_READONLY = "data-phx-readonly";
|
|
var PHX_DISABLED = "data-phx-disabled";
|
|
var PHX_DISABLE_WITH = "disable-with";
|
|
var PHX_DISABLE_WITH_RESTORE = "data-phx-disable-with-restore";
|
|
var PHX_HOOK = "hook";
|
|
var PHX_DEBOUNCE = "debounce";
|
|
var PHX_THROTTLE = "throttle";
|
|
var PHX_UPDATE = "update";
|
|
var PHX_STREAM = "stream";
|
|
var PHX_STREAM_REF = "data-phx-stream";
|
|
var PHX_PORTAL = "data-phx-portal";
|
|
var PHX_TELEPORTED_REF = "data-phx-teleported";
|
|
var PHX_TELEPORTED_SRC = "data-phx-teleported-src";
|
|
var PHX_RUNTIME_HOOK = "data-phx-runtime-hook";
|
|
var PHX_LV_PID = "data-phx-pid";
|
|
var PHX_KEY = "key";
|
|
var PHX_PRIVATE = "phxPrivate";
|
|
var PHX_AUTO_RECOVER = "auto-recover";
|
|
var PHX_LV_DEBUG = "phx:live-socket:debug";
|
|
var PHX_LV_PROFILE = "phx:live-socket:profiling";
|
|
var PHX_LV_LATENCY_SIM = "phx:live-socket:latency-sim";
|
|
var PHX_LV_HISTORY_POSITION = "phx:nav-history-position";
|
|
var PHX_PROGRESS = "progress";
|
|
var PHX_MOUNTED = "mounted";
|
|
var PHX_RELOAD_STATUS = "__phoenix_reload_status__";
|
|
var LOADER_TIMEOUT = 1;
|
|
var MAX_CHILD_JOIN_ATTEMPTS = 3;
|
|
var BEFORE_UNLOAD_LOADER_TIMEOUT = 200;
|
|
var DISCONNECTED_TIMEOUT = 500;
|
|
var BINDING_PREFIX = "phx-";
|
|
var PUSH_TIMEOUT = 3e4;
|
|
var DEBOUNCE_TRIGGER = "debounce-trigger";
|
|
var THROTTLED = "throttled";
|
|
var DEBOUNCE_PREV_KEY = "debounce-prev-key";
|
|
var DEFAULTS = {
|
|
debounce: 300,
|
|
throttle: 300
|
|
};
|
|
var PHX_PENDING_ATTRS = [PHX_REF_LOADING, PHX_REF_SRC, PHX_REF_LOCK];
|
|
var STATIC = "s";
|
|
var ROOT = "r";
|
|
var COMPONENTS = "c";
|
|
var KEYED = "k";
|
|
var KEYED_COUNT = "kc";
|
|
var EVENTS = "e";
|
|
var REPLY = "r";
|
|
var TITLE = "t";
|
|
var TEMPLATES = "p";
|
|
var STREAM = "stream";
|
|
var EntryUploader = class {
|
|
constructor(entry, config, liveSocket2) {
|
|
const { chunk_size, chunk_timeout } = config;
|
|
this.liveSocket = liveSocket2;
|
|
this.entry = entry;
|
|
this.offset = 0;
|
|
this.chunkSize = chunk_size;
|
|
this.chunkTimeout = chunk_timeout;
|
|
this.chunkTimer = null;
|
|
this.errored = false;
|
|
this.uploadChannel = liveSocket2.channel(`lvu:${entry.ref}`, {
|
|
token: entry.metadata()
|
|
});
|
|
}
|
|
error(reason) {
|
|
if (this.errored) {
|
|
return;
|
|
}
|
|
this.uploadChannel.leave();
|
|
this.errored = true;
|
|
clearTimeout(this.chunkTimer);
|
|
this.entry.error(reason);
|
|
}
|
|
upload() {
|
|
this.uploadChannel.onError((reason) => this.error(reason));
|
|
this.uploadChannel.join().receive("ok", (_data) => this.readNextChunk()).receive("error", (reason) => this.error(reason));
|
|
}
|
|
isDone() {
|
|
return this.offset >= this.entry.file.size;
|
|
}
|
|
readNextChunk() {
|
|
const reader = new window.FileReader();
|
|
const blob = this.entry.file.slice(
|
|
this.offset,
|
|
this.chunkSize + this.offset
|
|
);
|
|
reader.onload = (e) => {
|
|
if (e.target.error === null) {
|
|
this.offset += /** @type {ArrayBuffer} */
|
|
e.target.result.byteLength;
|
|
this.pushChunk(
|
|
/** @type {ArrayBuffer} */
|
|
e.target.result
|
|
);
|
|
} else {
|
|
return logError("Read error: " + e.target.error);
|
|
}
|
|
};
|
|
reader.readAsArrayBuffer(blob);
|
|
}
|
|
pushChunk(chunk) {
|
|
if (!this.uploadChannel.isJoined()) {
|
|
return;
|
|
}
|
|
this.uploadChannel.push("chunk", chunk, this.chunkTimeout).receive("ok", () => {
|
|
this.entry.progress(this.offset / this.entry.file.size * 100);
|
|
if (!this.isDone()) {
|
|
this.chunkTimer = setTimeout(
|
|
() => this.readNextChunk(),
|
|
this.liveSocket.getLatencySim() || 0
|
|
);
|
|
}
|
|
}).receive("error", ({ reason }) => this.error(reason));
|
|
}
|
|
};
|
|
var logError = (msg, obj) => console.error && console.error(msg, obj);
|
|
var isCid = (cid) => {
|
|
const type = typeof cid;
|
|
return type === "number" || type === "string" && /^(0|[1-9]\d*)$/.test(cid);
|
|
};
|
|
function detectDuplicateIds() {
|
|
const ids = /* @__PURE__ */ new Set();
|
|
const elems = document.querySelectorAll("*[id]");
|
|
for (let i = 0, len = elems.length; i < len; i++) {
|
|
if (ids.has(elems[i].id)) {
|
|
console.error(
|
|
`Multiple IDs detected: ${elems[i].id}. Ensure unique element ids.`
|
|
);
|
|
} else {
|
|
ids.add(elems[i].id);
|
|
}
|
|
}
|
|
}
|
|
function detectInvalidStreamInserts(inserts) {
|
|
const errors = /* @__PURE__ */ new Set();
|
|
Object.keys(inserts).forEach((id) => {
|
|
const streamEl = document.getElementById(id);
|
|
if (streamEl && streamEl.parentElement && streamEl.parentElement.getAttribute("phx-update") !== "stream") {
|
|
errors.add(
|
|
`The stream container with id "${streamEl.parentElement.id}" is missing the phx-update="stream" attribute. Ensure it is set for streams to work properly.`
|
|
);
|
|
}
|
|
});
|
|
errors.forEach((error) => console.error(error));
|
|
}
|
|
var debug = (view, kind, msg, obj) => {
|
|
if (view.liveSocket.isDebugEnabled()) {
|
|
console.log(`${view.id} ${kind}: ${msg} - `, obj);
|
|
}
|
|
};
|
|
var closure2 = (val) => typeof val === "function" ? val : function() {
|
|
return val;
|
|
};
|
|
var clone = (obj) => {
|
|
return JSON.parse(JSON.stringify(obj));
|
|
};
|
|
var closestPhxBinding = (el, binding, borderEl) => {
|
|
do {
|
|
if (el.matches(`[${binding}]`) && !el.disabled) {
|
|
return el;
|
|
}
|
|
el = el.parentElement || el.parentNode;
|
|
} while (el !== null && el.nodeType === 1 && !(borderEl && borderEl.isSameNode(el) || el.matches(PHX_VIEW_SELECTOR)));
|
|
return null;
|
|
};
|
|
var isObject = (obj) => {
|
|
return obj !== null && typeof obj === "object" && !(obj instanceof Array);
|
|
};
|
|
var isEqualObj = (obj1, obj2) => JSON.stringify(obj1) === JSON.stringify(obj2);
|
|
var isEmpty = (obj) => {
|
|
for (const x in obj) {
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
var maybe = (el, callback) => el && callback(el);
|
|
var channelUploader = function(entries, onError, resp, liveSocket2) {
|
|
entries.forEach((entry) => {
|
|
const entryUploader = new EntryUploader(entry, resp.config, liveSocket2);
|
|
entryUploader.upload();
|
|
});
|
|
};
|
|
var eventContainsFiles = (e) => {
|
|
if (e.dataTransfer.types) {
|
|
for (let i = 0; i < e.dataTransfer.types.length; i++) {
|
|
if (e.dataTransfer.types[i] === "Files") {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
var Browser = {
|
|
canPushState() {
|
|
return typeof history.pushState !== "undefined";
|
|
},
|
|
dropLocal(localStorage2, namespace, subkey) {
|
|
return localStorage2.removeItem(this.localKey(namespace, subkey));
|
|
},
|
|
updateLocal(localStorage2, namespace, subkey, initial, func) {
|
|
const current = this.getLocal(localStorage2, namespace, subkey);
|
|
const key = this.localKey(namespace, subkey);
|
|
const newVal = current === null ? initial : func(current);
|
|
localStorage2.setItem(key, JSON.stringify(newVal));
|
|
return newVal;
|
|
},
|
|
getLocal(localStorage2, namespace, subkey) {
|
|
return JSON.parse(localStorage2.getItem(this.localKey(namespace, subkey)));
|
|
},
|
|
updateCurrentState(callback) {
|
|
if (!this.canPushState()) {
|
|
return;
|
|
}
|
|
history.replaceState(
|
|
callback(history.state || {}),
|
|
"",
|
|
window.location.href
|
|
);
|
|
},
|
|
pushState(kind, meta, to) {
|
|
if (this.canPushState()) {
|
|
if (to !== window.location.href) {
|
|
if (meta.type == "redirect" && meta.scroll) {
|
|
const currentState = history.state || {};
|
|
currentState.scroll = meta.scroll;
|
|
history.replaceState(currentState, "", window.location.href);
|
|
}
|
|
delete meta.scroll;
|
|
history[kind + "State"](meta, "", to || null);
|
|
window.requestAnimationFrame(() => {
|
|
const hashEl = this.getHashTargetEl(window.location.hash);
|
|
if (hashEl) {
|
|
hashEl.scrollIntoView();
|
|
} else if (meta.type === "redirect") {
|
|
window.scroll(0, 0);
|
|
}
|
|
});
|
|
}
|
|
} else {
|
|
this.redirect(to);
|
|
}
|
|
},
|
|
setCookie(name, value, maxAgeSeconds) {
|
|
const expires = typeof maxAgeSeconds === "number" ? ` max-age=${maxAgeSeconds};` : "";
|
|
document.cookie = `${name}=${value};${expires} path=/`;
|
|
},
|
|
getCookie(name) {
|
|
return document.cookie.replace(
|
|
new RegExp(`(?:(?:^|.*;s*)${name}s*=s*([^;]*).*$)|^.*$`),
|
|
"$1"
|
|
);
|
|
},
|
|
deleteCookie(name) {
|
|
document.cookie = `${name}=; max-age=-1; path=/`;
|
|
},
|
|
redirect(toURL, flash, navigate = (url) => {
|
|
window.location.href = url;
|
|
}) {
|
|
if (flash) {
|
|
this.setCookie("__phoenix_flash__", flash, 60);
|
|
}
|
|
navigate(toURL);
|
|
},
|
|
localKey(namespace, subkey) {
|
|
return `${namespace}-${subkey}`;
|
|
},
|
|
getHashTargetEl(maybeHash) {
|
|
const hash = maybeHash.toString().substring(1);
|
|
if (hash === "") {
|
|
return;
|
|
}
|
|
return document.getElementById(hash) || document.querySelector(`a[name="${hash}"]`);
|
|
}
|
|
};
|
|
var browser_default = Browser;
|
|
var DOM = {
|
|
byId(id) {
|
|
return document.getElementById(id) || logError(`no id found for ${id}`);
|
|
},
|
|
removeClass(el, className) {
|
|
el.classList.remove(className);
|
|
if (el.classList.length === 0) {
|
|
el.removeAttribute("class");
|
|
}
|
|
},
|
|
all(node, query, callback) {
|
|
if (!node) {
|
|
return [];
|
|
}
|
|
const array = Array.from(node.querySelectorAll(query));
|
|
if (callback) {
|
|
array.forEach(callback);
|
|
}
|
|
return array;
|
|
},
|
|
childNodeLength(html) {
|
|
const template = document.createElement("template");
|
|
template.innerHTML = html;
|
|
return template.content.childElementCount;
|
|
},
|
|
isUploadInput(el) {
|
|
return el.type === "file" && el.getAttribute(PHX_UPLOAD_REF) !== null;
|
|
},
|
|
isAutoUpload(inputEl) {
|
|
return inputEl.hasAttribute("data-phx-auto-upload");
|
|
},
|
|
findUploadInputs(node) {
|
|
const formId = node.id;
|
|
const inputsOutsideForm = this.all(
|
|
document,
|
|
`input[type="file"][${PHX_UPLOAD_REF}][form="${formId}"]`
|
|
);
|
|
return this.all(node, `input[type="file"][${PHX_UPLOAD_REF}]`).concat(
|
|
inputsOutsideForm
|
|
);
|
|
},
|
|
findComponentNodeList(viewId, cid, doc2 = document) {
|
|
return this.all(
|
|
doc2,
|
|
`[${PHX_VIEW_REF}="${viewId}"][${PHX_COMPONENT}="${cid}"]`
|
|
);
|
|
},
|
|
isPhxDestroyed(node) {
|
|
return node.id && DOM.private(node, "destroyed") ? true : false;
|
|
},
|
|
wantsNewTab(e) {
|
|
const wantsNewTab = e.ctrlKey || e.shiftKey || e.metaKey || e.button && e.button === 1;
|
|
const isDownload = e.target instanceof HTMLAnchorElement && e.target.hasAttribute("download");
|
|
const isTargetBlank = e.target.hasAttribute("target") && e.target.getAttribute("target").toLowerCase() === "_blank";
|
|
const isTargetNamedTab = e.target.hasAttribute("target") && !e.target.getAttribute("target").startsWith("_");
|
|
return wantsNewTab || isTargetBlank || isDownload || isTargetNamedTab;
|
|
},
|
|
isUnloadableFormSubmit(e) {
|
|
const isDialogSubmit = e.target && e.target.getAttribute("method") === "dialog" || e.submitter && e.submitter.getAttribute("formmethod") === "dialog";
|
|
if (isDialogSubmit) {
|
|
return false;
|
|
} else {
|
|
return !e.defaultPrevented && !this.wantsNewTab(e);
|
|
}
|
|
},
|
|
isNewPageClick(e, currentLocation) {
|
|
const href = e.target instanceof HTMLAnchorElement ? e.target.getAttribute("href") : null;
|
|
let url;
|
|
if (e.defaultPrevented || href === null || this.wantsNewTab(e)) {
|
|
return false;
|
|
}
|
|
if (href.startsWith("mailto:") || href.startsWith("tel:")) {
|
|
return false;
|
|
}
|
|
if (e.target.isContentEditable) {
|
|
return false;
|
|
}
|
|
try {
|
|
url = new URL(href);
|
|
} catch (e2) {
|
|
try {
|
|
url = new URL(href, currentLocation);
|
|
} catch (e3) {
|
|
return true;
|
|
}
|
|
}
|
|
if (url.host === currentLocation.host && url.protocol === currentLocation.protocol) {
|
|
if (url.pathname === currentLocation.pathname && url.search === currentLocation.search) {
|
|
return url.hash === "" && !url.href.endsWith("#");
|
|
}
|
|
}
|
|
return url.protocol.startsWith("http");
|
|
},
|
|
markPhxChildDestroyed(el) {
|
|
if (this.isPhxChild(el)) {
|
|
el.setAttribute(PHX_SESSION, "");
|
|
}
|
|
this.putPrivate(el, "destroyed", true);
|
|
},
|
|
findPhxChildrenInFragment(html, parentId) {
|
|
const template = document.createElement("template");
|
|
template.innerHTML = html;
|
|
return this.findPhxChildren(template.content, parentId);
|
|
},
|
|
isIgnored(el, phxUpdate) {
|
|
return (el.getAttribute(phxUpdate) || el.getAttribute("data-phx-update")) === "ignore";
|
|
},
|
|
isPhxUpdate(el, phxUpdate, updateTypes) {
|
|
return el.getAttribute && updateTypes.indexOf(el.getAttribute(phxUpdate)) >= 0;
|
|
},
|
|
findPhxSticky(el) {
|
|
return this.all(el, `[${PHX_STICKY}]`);
|
|
},
|
|
findPhxChildren(el, parentId) {
|
|
return this.all(el, `${PHX_VIEW_SELECTOR}[${PHX_PARENT_ID}="${parentId}"]`);
|
|
},
|
|
findExistingParentCIDs(viewId, cids) {
|
|
const parentCids = /* @__PURE__ */ new Set();
|
|
const childrenCids = /* @__PURE__ */ new Set();
|
|
cids.forEach((cid) => {
|
|
this.all(
|
|
document,
|
|
`[${PHX_VIEW_REF}="${viewId}"][${PHX_COMPONENT}="${cid}"]`
|
|
).forEach((parent) => {
|
|
parentCids.add(cid);
|
|
this.all(parent, `[${PHX_VIEW_REF}="${viewId}"][${PHX_COMPONENT}]`).map((el) => parseInt(el.getAttribute(PHX_COMPONENT))).forEach((childCID) => childrenCids.add(childCID));
|
|
});
|
|
});
|
|
childrenCids.forEach((childCid) => parentCids.delete(childCid));
|
|
return parentCids;
|
|
},
|
|
private(el, key) {
|
|
return el[PHX_PRIVATE] && el[PHX_PRIVATE][key];
|
|
},
|
|
deletePrivate(el, key) {
|
|
el[PHX_PRIVATE] && delete el[PHX_PRIVATE][key];
|
|
},
|
|
putPrivate(el, key, value) {
|
|
if (!el[PHX_PRIVATE]) {
|
|
el[PHX_PRIVATE] = {};
|
|
}
|
|
el[PHX_PRIVATE][key] = value;
|
|
},
|
|
updatePrivate(el, key, defaultVal, updateFunc) {
|
|
const existing = this.private(el, key);
|
|
if (existing === void 0) {
|
|
this.putPrivate(el, key, updateFunc(defaultVal));
|
|
} else {
|
|
this.putPrivate(el, key, updateFunc(existing));
|
|
}
|
|
},
|
|
syncPendingAttrs(fromEl, toEl) {
|
|
if (!fromEl.hasAttribute(PHX_REF_SRC)) {
|
|
return;
|
|
}
|
|
PHX_EVENT_CLASSES.forEach((className) => {
|
|
fromEl.classList.contains(className) && toEl.classList.add(className);
|
|
});
|
|
PHX_PENDING_ATTRS.filter((attr) => fromEl.hasAttribute(attr)).forEach(
|
|
(attr) => {
|
|
toEl.setAttribute(attr, fromEl.getAttribute(attr));
|
|
}
|
|
);
|
|
},
|
|
copyPrivates(target, source) {
|
|
if (source[PHX_PRIVATE]) {
|
|
target[PHX_PRIVATE] = source[PHX_PRIVATE];
|
|
}
|
|
},
|
|
putTitle(str) {
|
|
const titleEl = document.querySelector("title");
|
|
if (titleEl) {
|
|
const { prefix, suffix, default: defaultTitle } = titleEl.dataset;
|
|
const isEmpty2 = typeof str !== "string" || str.trim() === "";
|
|
if (isEmpty2 && typeof defaultTitle !== "string") {
|
|
return;
|
|
}
|
|
const inner = isEmpty2 ? defaultTitle : str;
|
|
document.title = `${prefix || ""}${inner || ""}${suffix || ""}`;
|
|
} else {
|
|
document.title = str;
|
|
}
|
|
},
|
|
debounce(el, event, phxDebounce, defaultDebounce, phxThrottle, defaultThrottle, asyncFilter, callback) {
|
|
let debounce = el.getAttribute(phxDebounce);
|
|
let throttle = el.getAttribute(phxThrottle);
|
|
if (debounce === "") {
|
|
debounce = defaultDebounce;
|
|
}
|
|
if (throttle === "") {
|
|
throttle = defaultThrottle;
|
|
}
|
|
const value = debounce || throttle;
|
|
switch (value) {
|
|
case null:
|
|
return callback();
|
|
case "blur":
|
|
this.incCycle(el, "debounce-blur-cycle", () => {
|
|
if (asyncFilter()) {
|
|
callback();
|
|
}
|
|
});
|
|
if (this.once(el, "debounce-blur")) {
|
|
el.addEventListener(
|
|
"blur",
|
|
() => this.triggerCycle(el, "debounce-blur-cycle")
|
|
);
|
|
}
|
|
return;
|
|
default:
|
|
const timeout = parseInt(value);
|
|
const trigger = () => throttle ? this.deletePrivate(el, THROTTLED) : callback();
|
|
const currentCycle = this.incCycle(el, DEBOUNCE_TRIGGER, trigger);
|
|
if (isNaN(timeout)) {
|
|
return logError(`invalid throttle/debounce value: ${value}`);
|
|
}
|
|
if (throttle) {
|
|
let newKeyDown = false;
|
|
if (event.type === "keydown") {
|
|
const prevKey = this.private(el, DEBOUNCE_PREV_KEY);
|
|
this.putPrivate(el, DEBOUNCE_PREV_KEY, event.key);
|
|
newKeyDown = prevKey !== event.key;
|
|
}
|
|
if (!newKeyDown && this.private(el, THROTTLED)) {
|
|
return false;
|
|
} else {
|
|
callback();
|
|
const t = setTimeout(() => {
|
|
if (asyncFilter()) {
|
|
this.triggerCycle(el, DEBOUNCE_TRIGGER);
|
|
}
|
|
}, timeout);
|
|
this.putPrivate(el, THROTTLED, t);
|
|
}
|
|
} else {
|
|
setTimeout(() => {
|
|
if (asyncFilter()) {
|
|
this.triggerCycle(el, DEBOUNCE_TRIGGER, currentCycle);
|
|
}
|
|
}, timeout);
|
|
}
|
|
const form = el.form;
|
|
if (form && this.once(form, "bind-debounce")) {
|
|
form.addEventListener("submit", () => {
|
|
Array.from(new FormData(form).entries(), ([name]) => {
|
|
const namedItem = form.elements.namedItem(name);
|
|
const input = namedItem instanceof RadioNodeList ? namedItem[0] : namedItem;
|
|
if (input) {
|
|
this.incCycle(input, DEBOUNCE_TRIGGER);
|
|
this.deletePrivate(input, THROTTLED);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
if (this.once(el, "bind-debounce")) {
|
|
el.addEventListener("blur", () => {
|
|
clearTimeout(this.private(el, THROTTLED));
|
|
this.triggerCycle(el, DEBOUNCE_TRIGGER);
|
|
});
|
|
}
|
|
}
|
|
},
|
|
triggerCycle(el, key, currentCycle) {
|
|
const [cycle, trigger] = this.private(el, key);
|
|
if (!currentCycle) {
|
|
currentCycle = cycle;
|
|
}
|
|
if (currentCycle === cycle) {
|
|
this.incCycle(el, key);
|
|
trigger();
|
|
}
|
|
},
|
|
once(el, key) {
|
|
if (this.private(el, key) === true) {
|
|
return false;
|
|
}
|
|
this.putPrivate(el, key, true);
|
|
return true;
|
|
},
|
|
incCycle(el, key, trigger = function() {
|
|
}) {
|
|
let [currentCycle] = this.private(el, key) || [0, trigger];
|
|
currentCycle++;
|
|
this.putPrivate(el, key, [currentCycle, trigger]);
|
|
return currentCycle;
|
|
},
|
|
// maintains or adds privately used hook information
|
|
// fromEl and toEl can be the same element in the case of a newly added node
|
|
// fromEl and toEl can be any HTML node type, so we need to check if it's an element node
|
|
maintainPrivateHooks(fromEl, toEl, phxViewportTop, phxViewportBottom) {
|
|
if (fromEl.hasAttribute && fromEl.hasAttribute("data-phx-hook") && !toEl.hasAttribute("data-phx-hook")) {
|
|
toEl.setAttribute("data-phx-hook", fromEl.getAttribute("data-phx-hook"));
|
|
}
|
|
if (toEl.hasAttribute && (toEl.hasAttribute(phxViewportTop) || toEl.hasAttribute(phxViewportBottom))) {
|
|
toEl.setAttribute("data-phx-hook", "Phoenix.InfiniteScroll");
|
|
}
|
|
},
|
|
putCustomElHook(el, hook) {
|
|
if (el.isConnected) {
|
|
el.setAttribute("data-phx-hook", "");
|
|
} else {
|
|
console.error(`
|
|
hook attached to non-connected DOM element
|
|
ensure you are calling createHook within your connectedCallback. ${el.outerHTML}
|
|
`);
|
|
}
|
|
this.putPrivate(el, "custom-el-hook", hook);
|
|
},
|
|
getCustomElHook(el) {
|
|
return this.private(el, "custom-el-hook");
|
|
},
|
|
isUsedInput(el) {
|
|
return el.nodeType === Node.ELEMENT_NODE && (this.private(el, PHX_HAS_FOCUSED) || this.private(el, PHX_HAS_SUBMITTED));
|
|
},
|
|
resetForm(form) {
|
|
Array.from(form.elements).forEach((input) => {
|
|
this.deletePrivate(input, PHX_HAS_FOCUSED);
|
|
this.deletePrivate(input, PHX_HAS_SUBMITTED);
|
|
});
|
|
},
|
|
isPhxChild(node) {
|
|
return node.getAttribute && node.getAttribute(PHX_PARENT_ID);
|
|
},
|
|
isPhxSticky(node) {
|
|
return node.getAttribute && node.getAttribute(PHX_STICKY) !== null;
|
|
},
|
|
isChildOfAny(el, parents) {
|
|
return !!parents.find((parent) => parent.contains(el));
|
|
},
|
|
firstPhxChild(el) {
|
|
return this.isPhxChild(el) ? el : this.all(el, `[${PHX_PARENT_ID}]`)[0];
|
|
},
|
|
isPortalTemplate(el) {
|
|
return el.tagName === "TEMPLATE" && el.hasAttribute(PHX_PORTAL);
|
|
},
|
|
closestViewEl(el) {
|
|
const portalOrViewEl = el.closest(
|
|
`[${PHX_TELEPORTED_REF}],${PHX_VIEW_SELECTOR}`
|
|
);
|
|
if (!portalOrViewEl) {
|
|
return null;
|
|
}
|
|
if (portalOrViewEl.hasAttribute(PHX_TELEPORTED_REF)) {
|
|
return this.byId(portalOrViewEl.getAttribute(PHX_TELEPORTED_REF));
|
|
} else if (portalOrViewEl.hasAttribute(PHX_SESSION)) {
|
|
return portalOrViewEl;
|
|
}
|
|
return null;
|
|
},
|
|
dispatchEvent(target, name, opts = {}) {
|
|
let defaultBubble = true;
|
|
const isUploadTarget = target.nodeName === "INPUT" && target.type === "file";
|
|
if (isUploadTarget && name === "click") {
|
|
defaultBubble = false;
|
|
}
|
|
const bubbles = opts.bubbles === void 0 ? defaultBubble : !!opts.bubbles;
|
|
const eventOpts = {
|
|
bubbles,
|
|
cancelable: true,
|
|
detail: opts.detail || {}
|
|
};
|
|
const event = name === "click" ? new MouseEvent("click", eventOpts) : new CustomEvent(name, eventOpts);
|
|
target.dispatchEvent(event);
|
|
},
|
|
cloneNode(node, html) {
|
|
if (typeof html === "undefined") {
|
|
return node.cloneNode(true);
|
|
} else {
|
|
const cloned = node.cloneNode(false);
|
|
cloned.innerHTML = html;
|
|
return cloned;
|
|
}
|
|
},
|
|
// merge attributes from source to target
|
|
// if an element is ignored, we only merge data attributes
|
|
// including removing data attributes that are no longer in the source
|
|
mergeAttrs(target, source, opts = {}) {
|
|
var _a2;
|
|
const exclude = new Set(opts.exclude || []);
|
|
const isIgnored = opts.isIgnored;
|
|
const sourceAttrs = source.attributes;
|
|
for (let i = sourceAttrs.length - 1; i >= 0; i--) {
|
|
const name = sourceAttrs[i].name;
|
|
if (!exclude.has(name)) {
|
|
const sourceValue = source.getAttribute(name);
|
|
if (target.getAttribute(name) !== sourceValue && (!isIgnored || isIgnored && name.startsWith("data-"))) {
|
|
target.setAttribute(name, sourceValue);
|
|
}
|
|
} else {
|
|
if (name === "value") {
|
|
const sourceValue = (_a2 = source.value) != null ? _a2 : source.getAttribute(name);
|
|
if (target.value === sourceValue) {
|
|
target.setAttribute("value", source.getAttribute(name));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
const targetAttrs = target.attributes;
|
|
for (let i = targetAttrs.length - 1; i >= 0; i--) {
|
|
const name = targetAttrs[i].name;
|
|
if (isIgnored) {
|
|
if (name.startsWith("data-") && !source.hasAttribute(name) && !PHX_PENDING_ATTRS.includes(name)) {
|
|
target.removeAttribute(name);
|
|
}
|
|
} else {
|
|
if (!source.hasAttribute(name)) {
|
|
target.removeAttribute(name);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
mergeFocusedInput(target, source) {
|
|
if (!(target instanceof HTMLSelectElement)) {
|
|
DOM.mergeAttrs(target, source, { exclude: ["value"] });
|
|
}
|
|
if (source.readOnly) {
|
|
target.setAttribute("readonly", true);
|
|
} else {
|
|
target.removeAttribute("readonly");
|
|
}
|
|
},
|
|
hasSelectionRange(el) {
|
|
return el.setSelectionRange && (el.type === "text" || el.type === "textarea");
|
|
},
|
|
restoreFocus(focused, selectionStart, selectionEnd) {
|
|
if (focused instanceof HTMLSelectElement) {
|
|
focused.focus();
|
|
}
|
|
if (!DOM.isTextualInput(focused)) {
|
|
return;
|
|
}
|
|
const wasFocused = focused.matches(":focus");
|
|
if (!wasFocused) {
|
|
focused.focus();
|
|
}
|
|
if (this.hasSelectionRange(focused)) {
|
|
focused.setSelectionRange(selectionStart, selectionEnd);
|
|
}
|
|
},
|
|
isFormInput(el) {
|
|
if (el.localName && customElements.get(el.localName)) {
|
|
return customElements.get(el.localName)[`formAssociated`];
|
|
}
|
|
return /^(?:input|select|textarea)$/i.test(el.tagName) && el.type !== "button";
|
|
},
|
|
syncAttrsToProps(el) {
|
|
if (el instanceof HTMLInputElement && CHECKABLE_INPUTS.indexOf(el.type.toLocaleLowerCase()) >= 0) {
|
|
el.checked = el.getAttribute("checked") !== null;
|
|
}
|
|
},
|
|
isTextualInput(el) {
|
|
return FOCUSABLE_INPUTS.indexOf(el.type) >= 0;
|
|
},
|
|
isNowTriggerFormExternal(el, phxTriggerExternal) {
|
|
return el.getAttribute && el.getAttribute(phxTriggerExternal) !== null && document.body.contains(el);
|
|
},
|
|
cleanChildNodes(container, phxUpdate) {
|
|
if (DOM.isPhxUpdate(container, phxUpdate, ["append", "prepend", PHX_STREAM])) {
|
|
const toRemove = [];
|
|
container.childNodes.forEach((childNode) => {
|
|
if (!childNode.id) {
|
|
const isEmptyTextNode = childNode.nodeType === Node.TEXT_NODE && childNode.nodeValue.trim() === "";
|
|
if (!isEmptyTextNode && childNode.nodeType !== Node.COMMENT_NODE) {
|
|
logError(
|
|
`only HTML element tags with an id are allowed inside containers with phx-update.
|
|
|
|
removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
|
|
|
|
`
|
|
);
|
|
}
|
|
toRemove.push(childNode);
|
|
}
|
|
});
|
|
toRemove.forEach((childNode) => childNode.remove());
|
|
}
|
|
},
|
|
replaceRootContainer(container, tagName, attrs) {
|
|
const retainedAttrs = /* @__PURE__ */ new Set([
|
|
"id",
|
|
PHX_SESSION,
|
|
PHX_STATIC,
|
|
PHX_MAIN,
|
|
PHX_ROOT_ID
|
|
]);
|
|
if (container.tagName.toLowerCase() === tagName.toLowerCase()) {
|
|
Array.from(container.attributes).filter((attr) => !retainedAttrs.has(attr.name.toLowerCase())).forEach((attr) => container.removeAttribute(attr.name));
|
|
Object.keys(attrs).filter((name) => !retainedAttrs.has(name.toLowerCase())).forEach((attr) => container.setAttribute(attr, attrs[attr]));
|
|
return container;
|
|
} else {
|
|
const newContainer = document.createElement(tagName);
|
|
Object.keys(attrs).forEach(
|
|
(attr) => newContainer.setAttribute(attr, attrs[attr])
|
|
);
|
|
retainedAttrs.forEach(
|
|
(attr) => newContainer.setAttribute(attr, container.getAttribute(attr))
|
|
);
|
|
newContainer.innerHTML = container.innerHTML;
|
|
container.replaceWith(newContainer);
|
|
return newContainer;
|
|
}
|
|
},
|
|
getSticky(el, name, defaultVal) {
|
|
const op = (DOM.private(el, "sticky") || []).find(
|
|
([existingName]) => name === existingName
|
|
);
|
|
if (op) {
|
|
const [_name, _op, stashedResult] = op;
|
|
return stashedResult;
|
|
} else {
|
|
return typeof defaultVal === "function" ? defaultVal() : defaultVal;
|
|
}
|
|
},
|
|
deleteSticky(el, name) {
|
|
this.updatePrivate(el, "sticky", [], (ops) => {
|
|
return ops.filter(([existingName, _]) => existingName !== name);
|
|
});
|
|
},
|
|
putSticky(el, name, op) {
|
|
const stashedResult = op(el);
|
|
this.updatePrivate(el, "sticky", [], (ops) => {
|
|
const existingIndex = ops.findIndex(
|
|
([existingName]) => name === existingName
|
|
);
|
|
if (existingIndex >= 0) {
|
|
ops[existingIndex] = [name, op, stashedResult];
|
|
} else {
|
|
ops.push([name, op, stashedResult]);
|
|
}
|
|
return ops;
|
|
});
|
|
},
|
|
applyStickyOperations(el) {
|
|
const ops = DOM.private(el, "sticky");
|
|
if (!ops) {
|
|
return;
|
|
}
|
|
ops.forEach(([name, op, _stashed]) => this.putSticky(el, name, op));
|
|
},
|
|
isLocked(el) {
|
|
return el.hasAttribute && el.hasAttribute(PHX_REF_LOCK);
|
|
},
|
|
attributeIgnored(attribute, ignoredAttributes) {
|
|
return ignoredAttributes.some(
|
|
(toIgnore) => attribute.name == toIgnore || toIgnore === "*" || toIgnore.includes("*") && attribute.name.match(toIgnore) != null
|
|
);
|
|
}
|
|
};
|
|
var dom_default = DOM;
|
|
var UploadEntry = class {
|
|
static isActive(fileEl, file) {
|
|
const isNew = file._phxRef === void 0;
|
|
const activeRefs = fileEl.getAttribute(PHX_ACTIVE_ENTRY_REFS).split(",");
|
|
const isActive = activeRefs.indexOf(LiveUploader.genFileRef(file)) >= 0;
|
|
return file.size > 0 && (isNew || isActive);
|
|
}
|
|
static isPreflighted(fileEl, file) {
|
|
const preflightedRefs = fileEl.getAttribute(PHX_PREFLIGHTED_REFS).split(",");
|
|
const isPreflighted = preflightedRefs.indexOf(LiveUploader.genFileRef(file)) >= 0;
|
|
return isPreflighted && this.isActive(fileEl, file);
|
|
}
|
|
static isPreflightInProgress(file) {
|
|
return file._preflightInProgress === true;
|
|
}
|
|
static markPreflightInProgress(file) {
|
|
file._preflightInProgress = true;
|
|
}
|
|
constructor(fileEl, file, view, autoUpload) {
|
|
this.ref = LiveUploader.genFileRef(file);
|
|
this.fileEl = fileEl;
|
|
this.file = file;
|
|
this.view = view;
|
|
this.meta = null;
|
|
this._isCancelled = false;
|
|
this._isDone = false;
|
|
this._progress = 0;
|
|
this._lastProgressSent = -1;
|
|
this._onDone = function() {
|
|
};
|
|
this._onElUpdated = this.onElUpdated.bind(this);
|
|
this.fileEl.addEventListener(PHX_LIVE_FILE_UPDATED, this._onElUpdated);
|
|
this.autoUpload = autoUpload;
|
|
}
|
|
metadata() {
|
|
return this.meta;
|
|
}
|
|
progress(progress) {
|
|
this._progress = Math.floor(progress);
|
|
if (this._progress > this._lastProgressSent) {
|
|
if (this._progress >= 100) {
|
|
this._progress = 100;
|
|
this._lastProgressSent = 100;
|
|
this._isDone = true;
|
|
this.view.pushFileProgress(this.fileEl, this.ref, 100, () => {
|
|
LiveUploader.untrackFile(this.fileEl, this.file);
|
|
this._onDone();
|
|
});
|
|
} else {
|
|
this._lastProgressSent = this._progress;
|
|
this.view.pushFileProgress(this.fileEl, this.ref, this._progress);
|
|
}
|
|
}
|
|
}
|
|
isCancelled() {
|
|
return this._isCancelled;
|
|
}
|
|
cancel() {
|
|
this.file._preflightInProgress = false;
|
|
this._isCancelled = true;
|
|
this._isDone = true;
|
|
this._onDone();
|
|
}
|
|
isDone() {
|
|
return this._isDone;
|
|
}
|
|
error(reason = "failed") {
|
|
this.fileEl.removeEventListener(PHX_LIVE_FILE_UPDATED, this._onElUpdated);
|
|
this.view.pushFileProgress(this.fileEl, this.ref, { error: reason });
|
|
if (!this.isAutoUpload()) {
|
|
LiveUploader.clearFiles(this.fileEl);
|
|
}
|
|
}
|
|
isAutoUpload() {
|
|
return this.autoUpload;
|
|
}
|
|
//private
|
|
onDone(callback) {
|
|
this._onDone = () => {
|
|
this.fileEl.removeEventListener(PHX_LIVE_FILE_UPDATED, this._onElUpdated);
|
|
callback();
|
|
};
|
|
}
|
|
onElUpdated() {
|
|
const activeRefs = this.fileEl.getAttribute(PHX_ACTIVE_ENTRY_REFS).split(",");
|
|
if (activeRefs.indexOf(this.ref) === -1) {
|
|
LiveUploader.untrackFile(this.fileEl, this.file);
|
|
this.cancel();
|
|
}
|
|
}
|
|
toPreflightPayload() {
|
|
return {
|
|
last_modified: this.file.lastModified,
|
|
name: this.file.name,
|
|
relative_path: this.file.webkitRelativePath,
|
|
size: this.file.size,
|
|
type: this.file.type,
|
|
ref: this.ref,
|
|
meta: typeof this.file.meta === "function" ? this.file.meta() : void 0
|
|
};
|
|
}
|
|
uploader(uploaders) {
|
|
if (this.meta.uploader) {
|
|
const callback = uploaders[this.meta.uploader] || logError(`no uploader configured for ${this.meta.uploader}`);
|
|
return { name: this.meta.uploader, callback };
|
|
} else {
|
|
return { name: "channel", callback: channelUploader };
|
|
}
|
|
}
|
|
zipPostFlight(resp) {
|
|
this.meta = resp.entries[this.ref];
|
|
if (!this.meta) {
|
|
logError(`no preflight upload response returned with ref ${this.ref}`, {
|
|
input: this.fileEl,
|
|
response: resp
|
|
});
|
|
}
|
|
}
|
|
};
|
|
var liveUploaderFileRef = 0;
|
|
var LiveUploader = class _LiveUploader {
|
|
static genFileRef(file) {
|
|
const ref = file._phxRef;
|
|
if (ref !== void 0) {
|
|
return ref;
|
|
} else {
|
|
file._phxRef = (liveUploaderFileRef++).toString();
|
|
return file._phxRef;
|
|
}
|
|
}
|
|
static getEntryDataURL(inputEl, ref, callback) {
|
|
const file = this.activeFiles(inputEl).find(
|
|
(file2) => this.genFileRef(file2) === ref
|
|
);
|
|
callback(URL.createObjectURL(file));
|
|
}
|
|
static hasUploadsInProgress(formEl) {
|
|
let active = 0;
|
|
dom_default.findUploadInputs(formEl).forEach((input) => {
|
|
if (input.getAttribute(PHX_PREFLIGHTED_REFS) !== input.getAttribute(PHX_DONE_REFS)) {
|
|
active++;
|
|
}
|
|
});
|
|
return active > 0;
|
|
}
|
|
static serializeUploads(inputEl) {
|
|
const files = this.activeFiles(inputEl);
|
|
const fileData = {};
|
|
files.forEach((file) => {
|
|
const entry = { path: inputEl.name };
|
|
const uploadRef = inputEl.getAttribute(PHX_UPLOAD_REF);
|
|
fileData[uploadRef] = fileData[uploadRef] || [];
|
|
entry.ref = this.genFileRef(file);
|
|
entry.last_modified = file.lastModified;
|
|
entry.name = file.name || entry.ref;
|
|
entry.relative_path = file.webkitRelativePath;
|
|
entry.type = file.type;
|
|
entry.size = file.size;
|
|
if (typeof file.meta === "function") {
|
|
entry.meta = file.meta();
|
|
}
|
|
fileData[uploadRef].push(entry);
|
|
});
|
|
return fileData;
|
|
}
|
|
static clearFiles(inputEl) {
|
|
inputEl.value = null;
|
|
inputEl.removeAttribute(PHX_UPLOAD_REF);
|
|
dom_default.putPrivate(inputEl, "files", []);
|
|
}
|
|
static untrackFile(inputEl, file) {
|
|
dom_default.putPrivate(
|
|
inputEl,
|
|
"files",
|
|
dom_default.private(inputEl, "files").filter((f) => !Object.is(f, file))
|
|
);
|
|
}
|
|
/**
|
|
* @param {HTMLInputElement} inputEl
|
|
* @param {Array<File|Blob>} files
|
|
* @param {DataTransfer} [dataTransfer]
|
|
*/
|
|
static trackFiles(inputEl, files, dataTransfer) {
|
|
if (inputEl.getAttribute("multiple") !== null) {
|
|
const newFiles = files.filter(
|
|
(file) => !this.activeFiles(inputEl).find((f) => Object.is(f, file))
|
|
);
|
|
dom_default.updatePrivate(
|
|
inputEl,
|
|
"files",
|
|
[],
|
|
(existing) => existing.concat(newFiles)
|
|
);
|
|
inputEl.value = null;
|
|
} else {
|
|
if (dataTransfer && dataTransfer.files.length > 0) {
|
|
inputEl.files = dataTransfer.files;
|
|
}
|
|
dom_default.putPrivate(inputEl, "files", files);
|
|
}
|
|
}
|
|
static activeFileInputs(formEl) {
|
|
const fileInputs = dom_default.findUploadInputs(formEl);
|
|
return Array.from(fileInputs).filter(
|
|
(el) => el.files && this.activeFiles(el).length > 0
|
|
);
|
|
}
|
|
static activeFiles(input) {
|
|
return (dom_default.private(input, "files") || []).filter(
|
|
(f) => UploadEntry.isActive(input, f)
|
|
);
|
|
}
|
|
static inputsAwaitingPreflight(formEl) {
|
|
const fileInputs = dom_default.findUploadInputs(formEl);
|
|
return Array.from(fileInputs).filter(
|
|
(input) => this.filesAwaitingPreflight(input).length > 0
|
|
);
|
|
}
|
|
static filesAwaitingPreflight(input) {
|
|
return this.activeFiles(input).filter(
|
|
(f) => !UploadEntry.isPreflighted(input, f) && !UploadEntry.isPreflightInProgress(f)
|
|
);
|
|
}
|
|
static markPreflightInProgress(entries) {
|
|
entries.forEach((entry) => UploadEntry.markPreflightInProgress(entry.file));
|
|
}
|
|
constructor(inputEl, view, onComplete) {
|
|
this.autoUpload = dom_default.isAutoUpload(inputEl);
|
|
this.view = view;
|
|
this.onComplete = onComplete;
|
|
this._entries = Array.from(
|
|
_LiveUploader.filesAwaitingPreflight(inputEl) || []
|
|
).map((file) => new UploadEntry(inputEl, file, view, this.autoUpload));
|
|
_LiveUploader.markPreflightInProgress(this._entries);
|
|
this.numEntriesInProgress = this._entries.length;
|
|
}
|
|
isAutoUpload() {
|
|
return this.autoUpload;
|
|
}
|
|
entries() {
|
|
return this._entries;
|
|
}
|
|
initAdapterUpload(resp, onError, liveSocket2) {
|
|
this._entries = this._entries.map((entry) => {
|
|
if (entry.isCancelled()) {
|
|
this.numEntriesInProgress--;
|
|
if (this.numEntriesInProgress === 0) {
|
|
this.onComplete();
|
|
}
|
|
} else {
|
|
entry.zipPostFlight(resp);
|
|
entry.onDone(() => {
|
|
this.numEntriesInProgress--;
|
|
if (this.numEntriesInProgress === 0) {
|
|
this.onComplete();
|
|
}
|
|
});
|
|
}
|
|
return entry;
|
|
});
|
|
const groupedEntries = this._entries.reduce((acc, entry) => {
|
|
if (!entry.meta) {
|
|
return acc;
|
|
}
|
|
const { name, callback } = entry.uploader(liveSocket2.uploaders);
|
|
acc[name] = acc[name] || { callback, entries: [] };
|
|
acc[name].entries.push(entry);
|
|
return acc;
|
|
}, {});
|
|
for (const name in groupedEntries) {
|
|
const { callback, entries } = groupedEntries[name];
|
|
callback(entries, onError, resp, liveSocket2);
|
|
}
|
|
}
|
|
};
|
|
var ARIA = {
|
|
anyOf(instance, classes) {
|
|
return classes.find((name) => instance instanceof name);
|
|
},
|
|
isFocusable(el, interactiveOnly) {
|
|
return el instanceof HTMLAnchorElement && el.rel !== "ignore" || el instanceof HTMLAreaElement && el.href !== void 0 || !el.disabled && this.anyOf(el, [
|
|
HTMLInputElement,
|
|
HTMLSelectElement,
|
|
HTMLTextAreaElement,
|
|
HTMLButtonElement
|
|
]) || el instanceof HTMLIFrameElement || el.tabIndex >= 0 && el.getAttribute("aria-hidden") !== "true" || !interactiveOnly && el.getAttribute("tabindex") !== null && el.getAttribute("aria-hidden") !== "true";
|
|
},
|
|
attemptFocus(el, interactiveOnly) {
|
|
if (this.isFocusable(el, interactiveOnly)) {
|
|
try {
|
|
el.focus();
|
|
} catch (e) {
|
|
}
|
|
}
|
|
return !!document.activeElement && document.activeElement.isSameNode(el);
|
|
},
|
|
focusFirstInteractive(el) {
|
|
let child = el.firstElementChild;
|
|
while (child) {
|
|
if (this.attemptFocus(child, true) || this.focusFirstInteractive(child)) {
|
|
return true;
|
|
}
|
|
child = child.nextElementSibling;
|
|
}
|
|
},
|
|
focusFirst(el) {
|
|
let child = el.firstElementChild;
|
|
while (child) {
|
|
if (this.attemptFocus(child) || this.focusFirst(child)) {
|
|
return true;
|
|
}
|
|
child = child.nextElementSibling;
|
|
}
|
|
},
|
|
focusLast(el) {
|
|
let child = el.lastElementChild;
|
|
while (child) {
|
|
if (this.attemptFocus(child) || this.focusLast(child)) {
|
|
return true;
|
|
}
|
|
child = child.previousElementSibling;
|
|
}
|
|
}
|
|
};
|
|
var aria_default = ARIA;
|
|
var Hooks = {
|
|
LiveFileUpload: {
|
|
activeRefs() {
|
|
return this.el.getAttribute(PHX_ACTIVE_ENTRY_REFS);
|
|
},
|
|
preflightedRefs() {
|
|
return this.el.getAttribute(PHX_PREFLIGHTED_REFS);
|
|
},
|
|
mounted() {
|
|
this.js().ignoreAttributes(this.el, ["value"]);
|
|
this.preflightedWas = this.preflightedRefs();
|
|
},
|
|
updated() {
|
|
const newPreflights = this.preflightedRefs();
|
|
if (this.preflightedWas !== newPreflights) {
|
|
this.preflightedWas = newPreflights;
|
|
if (newPreflights === "") {
|
|
this.__view().cancelSubmit(this.el.form);
|
|
}
|
|
}
|
|
if (this.activeRefs() === "") {
|
|
this.el.value = null;
|
|
}
|
|
this.el.dispatchEvent(new CustomEvent(PHX_LIVE_FILE_UPDATED));
|
|
}
|
|
},
|
|
LiveImgPreview: {
|
|
mounted() {
|
|
this.ref = this.el.getAttribute("data-phx-entry-ref");
|
|
this.inputEl = document.getElementById(
|
|
this.el.getAttribute(PHX_UPLOAD_REF)
|
|
);
|
|
LiveUploader.getEntryDataURL(this.inputEl, this.ref, (url) => {
|
|
this.url = url;
|
|
this.el.src = url;
|
|
});
|
|
},
|
|
destroyed() {
|
|
URL.revokeObjectURL(this.url);
|
|
}
|
|
},
|
|
FocusWrap: {
|
|
mounted() {
|
|
this.focusStart = this.el.firstElementChild;
|
|
this.focusEnd = this.el.lastElementChild;
|
|
this.focusStart.addEventListener("focus", (e) => {
|
|
if (!e.relatedTarget || !this.el.contains(e.relatedTarget)) {
|
|
const nextFocus = e.target.nextElementSibling;
|
|
aria_default.attemptFocus(nextFocus) || aria_default.focusFirst(nextFocus);
|
|
} else {
|
|
aria_default.focusLast(this.el);
|
|
}
|
|
});
|
|
this.focusEnd.addEventListener("focus", (e) => {
|
|
if (!e.relatedTarget || !this.el.contains(e.relatedTarget)) {
|
|
const nextFocus = e.target.previousElementSibling;
|
|
aria_default.attemptFocus(nextFocus) || aria_default.focusLast(nextFocus);
|
|
} else {
|
|
aria_default.focusFirst(this.el);
|
|
}
|
|
});
|
|
if (!this.el.contains(document.activeElement)) {
|
|
this.el.addEventListener("phx:show-end", () => this.el.focus());
|
|
if (window.getComputedStyle(this.el).display !== "none") {
|
|
aria_default.focusFirst(this.el);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
var findScrollContainer = (el) => {
|
|
if (["HTML", "BODY"].indexOf(el.nodeName.toUpperCase()) >= 0)
|
|
return null;
|
|
if (["scroll", "auto"].indexOf(getComputedStyle(el).overflowY) >= 0)
|
|
return el;
|
|
return findScrollContainer(el.parentElement);
|
|
};
|
|
var scrollTop = (scrollContainer) => {
|
|
if (scrollContainer) {
|
|
return scrollContainer.scrollTop;
|
|
} else {
|
|
return document.documentElement.scrollTop || document.body.scrollTop;
|
|
}
|
|
};
|
|
var bottom = (scrollContainer) => {
|
|
if (scrollContainer) {
|
|
return scrollContainer.getBoundingClientRect().bottom;
|
|
} else {
|
|
return window.innerHeight || document.documentElement.clientHeight;
|
|
}
|
|
};
|
|
var top = (scrollContainer) => {
|
|
if (scrollContainer) {
|
|
return scrollContainer.getBoundingClientRect().top;
|
|
} else {
|
|
return 0;
|
|
}
|
|
};
|
|
var isAtViewportTop = (el, scrollContainer) => {
|
|
const rect = el.getBoundingClientRect();
|
|
return Math.ceil(rect.top) >= top(scrollContainer) && Math.floor(rect.top) <= bottom(scrollContainer);
|
|
};
|
|
var isAtViewportBottom = (el, scrollContainer) => {
|
|
const rect = el.getBoundingClientRect();
|
|
return Math.ceil(rect.bottom) >= top(scrollContainer) && Math.floor(rect.bottom) <= bottom(scrollContainer);
|
|
};
|
|
var isWithinViewport = (el, scrollContainer) => {
|
|
const rect = el.getBoundingClientRect();
|
|
return Math.ceil(rect.top) >= top(scrollContainer) && Math.floor(rect.top) <= bottom(scrollContainer);
|
|
};
|
|
Hooks.InfiniteScroll = {
|
|
mounted() {
|
|
this.scrollContainer = findScrollContainer(this.el);
|
|
let scrollBefore = scrollTop(this.scrollContainer);
|
|
let topOverran = false;
|
|
const throttleInterval = 500;
|
|
let pendingOp = null;
|
|
const onTopOverrun = this.throttle(
|
|
throttleInterval,
|
|
(topEvent, firstChild) => {
|
|
pendingOp = () => true;
|
|
this.liveSocket.js().push(this.el, topEvent, {
|
|
value: { id: firstChild.id, _overran: true },
|
|
callback: () => {
|
|
pendingOp = null;
|
|
}
|
|
});
|
|
}
|
|
);
|
|
const onFirstChildAtTop = this.throttle(
|
|
throttleInterval,
|
|
(topEvent, firstChild) => {
|
|
pendingOp = () => firstChild.scrollIntoView({ block: "start" });
|
|
this.liveSocket.js().push(this.el, topEvent, {
|
|
value: { id: firstChild.id },
|
|
callback: () => {
|
|
pendingOp = null;
|
|
window.requestAnimationFrame(() => {
|
|
if (!isWithinViewport(firstChild, this.scrollContainer)) {
|
|
firstChild.scrollIntoView({ block: "start" });
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
);
|
|
const onLastChildAtBottom = this.throttle(
|
|
throttleInterval,
|
|
(bottomEvent, lastChild) => {
|
|
pendingOp = () => lastChild.scrollIntoView({ block: "end" });
|
|
this.liveSocket.js().push(this.el, bottomEvent, {
|
|
value: { id: lastChild.id },
|
|
callback: () => {
|
|
pendingOp = null;
|
|
window.requestAnimationFrame(() => {
|
|
if (!isWithinViewport(lastChild, this.scrollContainer)) {
|
|
lastChild.scrollIntoView({ block: "end" });
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
);
|
|
this.onScroll = (_e) => {
|
|
const scrollNow = scrollTop(this.scrollContainer);
|
|
if (pendingOp) {
|
|
scrollBefore = scrollNow;
|
|
return pendingOp();
|
|
}
|
|
const rect = this.findOverrunTarget();
|
|
const topEvent = this.el.getAttribute(
|
|
this.liveSocket.binding("viewport-top")
|
|
);
|
|
const bottomEvent = this.el.getAttribute(
|
|
this.liveSocket.binding("viewport-bottom")
|
|
);
|
|
const lastChild = this.el.lastElementChild;
|
|
const firstChild = this.el.firstElementChild;
|
|
const isScrollingUp = scrollNow < scrollBefore;
|
|
const isScrollingDown = scrollNow > scrollBefore;
|
|
if (isScrollingUp && topEvent && !topOverran && rect.top >= 0) {
|
|
topOverran = true;
|
|
onTopOverrun(topEvent, firstChild);
|
|
} else if (isScrollingDown && topOverran && rect.top <= 0) {
|
|
topOverran = false;
|
|
}
|
|
if (topEvent && isScrollingUp && isAtViewportTop(firstChild, this.scrollContainer)) {
|
|
onFirstChildAtTop(topEvent, firstChild);
|
|
} else if (bottomEvent && isScrollingDown && isAtViewportBottom(lastChild, this.scrollContainer)) {
|
|
onLastChildAtBottom(bottomEvent, lastChild);
|
|
}
|
|
scrollBefore = scrollNow;
|
|
};
|
|
if (this.scrollContainer) {
|
|
this.scrollContainer.addEventListener("scroll", this.onScroll);
|
|
} else {
|
|
window.addEventListener("scroll", this.onScroll);
|
|
}
|
|
},
|
|
updated() {
|
|
if (this.scrollContainer && !this.scrollContainer.isConnected) {
|
|
this.destroyed();
|
|
this.mounted();
|
|
}
|
|
},
|
|
destroyed() {
|
|
if (this.scrollContainer) {
|
|
this.scrollContainer.removeEventListener("scroll", this.onScroll);
|
|
} else {
|
|
window.removeEventListener("scroll", this.onScroll);
|
|
}
|
|
},
|
|
throttle(interval, callback) {
|
|
let lastCallAt = 0;
|
|
let timer;
|
|
return (...args) => {
|
|
const now = Date.now();
|
|
const remainingTime = interval - (now - lastCallAt);
|
|
if (remainingTime <= 0 || remainingTime > interval) {
|
|
if (timer) {
|
|
clearTimeout(timer);
|
|
timer = null;
|
|
}
|
|
lastCallAt = now;
|
|
callback(...args);
|
|
} else if (!timer) {
|
|
timer = setTimeout(() => {
|
|
lastCallAt = Date.now();
|
|
timer = null;
|
|
callback(...args);
|
|
}, remainingTime);
|
|
}
|
|
};
|
|
},
|
|
findOverrunTarget() {
|
|
let rect;
|
|
const overrunTarget = this.el.getAttribute(
|
|
this.liveSocket.binding(PHX_VIEWPORT_OVERRUN_TARGET)
|
|
);
|
|
if (overrunTarget) {
|
|
const overrunEl = document.getElementById(overrunTarget);
|
|
if (overrunEl) {
|
|
rect = overrunEl.getBoundingClientRect();
|
|
} else {
|
|
throw new Error("did not find element with id " + overrunTarget);
|
|
}
|
|
} else {
|
|
rect = this.el.getBoundingClientRect();
|
|
}
|
|
return rect;
|
|
}
|
|
};
|
|
var hooks_default = Hooks;
|
|
var ElementRef = class {
|
|
static onUnlock(el, callback) {
|
|
if (!dom_default.isLocked(el) && !el.closest(`[${PHX_REF_LOCK}]`)) {
|
|
return callback();
|
|
}
|
|
const closestLock = el.closest(`[${PHX_REF_LOCK}]`);
|
|
const ref = closestLock.closest(`[${PHX_REF_LOCK}]`).getAttribute(PHX_REF_LOCK);
|
|
closestLock.addEventListener(
|
|
`phx:undo-lock:${ref}`,
|
|
() => {
|
|
callback();
|
|
},
|
|
{ once: true }
|
|
);
|
|
}
|
|
constructor(el) {
|
|
this.el = el;
|
|
this.loadingRef = el.hasAttribute(PHX_REF_LOADING) ? parseInt(el.getAttribute(PHX_REF_LOADING), 10) : null;
|
|
this.lockRef = el.hasAttribute(PHX_REF_LOCK) ? parseInt(el.getAttribute(PHX_REF_LOCK), 10) : null;
|
|
}
|
|
// public
|
|
maybeUndo(ref, phxEvent, eachCloneCallback) {
|
|
if (!this.isWithin(ref)) {
|
|
dom_default.updatePrivate(this.el, PHX_PENDING_REFS, [], (pendingRefs) => {
|
|
pendingRefs.push(ref);
|
|
return pendingRefs;
|
|
});
|
|
return;
|
|
}
|
|
this.undoLocks(ref, phxEvent, eachCloneCallback);
|
|
this.undoLoading(ref, phxEvent);
|
|
dom_default.updatePrivate(this.el, PHX_PENDING_REFS, [], (pendingRefs) => {
|
|
return pendingRefs.filter((pendingRef) => {
|
|
let opts = {
|
|
detail: { ref: pendingRef, event: phxEvent },
|
|
bubbles: true,
|
|
cancelable: false
|
|
};
|
|
if (this.loadingRef && this.loadingRef > pendingRef) {
|
|
this.el.dispatchEvent(
|
|
new CustomEvent(`phx:undo-loading:${pendingRef}`, opts)
|
|
);
|
|
}
|
|
if (this.lockRef && this.lockRef > pendingRef) {
|
|
this.el.dispatchEvent(
|
|
new CustomEvent(`phx:undo-lock:${pendingRef}`, opts)
|
|
);
|
|
}
|
|
return pendingRef > ref;
|
|
});
|
|
});
|
|
if (this.isFullyResolvedBy(ref)) {
|
|
this.el.removeAttribute(PHX_REF_SRC);
|
|
}
|
|
}
|
|
// private
|
|
isWithin(ref) {
|
|
return !(this.loadingRef !== null && this.loadingRef > ref && this.lockRef !== null && this.lockRef > ref);
|
|
}
|
|
// Check for cloned PHX_REF_LOCK element that has been morphed behind
|
|
// the scenes while this element was locked in the DOM.
|
|
// When we apply the cloned tree to the active DOM element, we must
|
|
//
|
|
// 1. execute pending mounted hooks for nodes now in the DOM
|
|
// 2. undo any ref inside the cloned tree that has since been ack'd
|
|
undoLocks(ref, phxEvent, eachCloneCallback) {
|
|
if (!this.isLockUndoneBy(ref)) {
|
|
return;
|
|
}
|
|
const clonedTree = dom_default.private(this.el, PHX_REF_LOCK);
|
|
if (clonedTree) {
|
|
eachCloneCallback(clonedTree);
|
|
dom_default.deletePrivate(this.el, PHX_REF_LOCK);
|
|
}
|
|
this.el.removeAttribute(PHX_REF_LOCK);
|
|
const opts = {
|
|
detail: { ref, event: phxEvent },
|
|
bubbles: true,
|
|
cancelable: false
|
|
};
|
|
this.el.dispatchEvent(
|
|
new CustomEvent(`phx:undo-lock:${this.lockRef}`, opts)
|
|
);
|
|
}
|
|
undoLoading(ref, phxEvent) {
|
|
if (!this.isLoadingUndoneBy(ref)) {
|
|
if (this.canUndoLoading(ref) && this.el.classList.contains("phx-submit-loading")) {
|
|
this.el.classList.remove("phx-change-loading");
|
|
}
|
|
return;
|
|
}
|
|
if (this.canUndoLoading(ref)) {
|
|
this.el.removeAttribute(PHX_REF_LOADING);
|
|
const disabledVal = this.el.getAttribute(PHX_DISABLED);
|
|
const readOnlyVal = this.el.getAttribute(PHX_READONLY);
|
|
if (readOnlyVal !== null) {
|
|
this.el.readOnly = readOnlyVal === "true" ? true : false;
|
|
this.el.removeAttribute(PHX_READONLY);
|
|
}
|
|
if (disabledVal !== null) {
|
|
this.el.disabled = disabledVal === "true" ? true : false;
|
|
this.el.removeAttribute(PHX_DISABLED);
|
|
}
|
|
const disableRestore = this.el.getAttribute(PHX_DISABLE_WITH_RESTORE);
|
|
if (disableRestore !== null) {
|
|
this.el.textContent = disableRestore;
|
|
this.el.removeAttribute(PHX_DISABLE_WITH_RESTORE);
|
|
}
|
|
const opts = {
|
|
detail: { ref, event: phxEvent },
|
|
bubbles: true,
|
|
cancelable: false
|
|
};
|
|
this.el.dispatchEvent(
|
|
new CustomEvent(`phx:undo-loading:${this.loadingRef}`, opts)
|
|
);
|
|
}
|
|
PHX_EVENT_CLASSES.forEach((name) => {
|
|
if (name !== "phx-submit-loading" || this.canUndoLoading(ref)) {
|
|
dom_default.removeClass(this.el, name);
|
|
}
|
|
});
|
|
}
|
|
isLoadingUndoneBy(ref) {
|
|
return this.loadingRef === null ? false : this.loadingRef <= ref;
|
|
}
|
|
isLockUndoneBy(ref) {
|
|
return this.lockRef === null ? false : this.lockRef <= ref;
|
|
}
|
|
isFullyResolvedBy(ref) {
|
|
return (this.loadingRef === null || this.loadingRef <= ref) && (this.lockRef === null || this.lockRef <= ref);
|
|
}
|
|
// only remove the phx-submit-loading class if we are not locked
|
|
canUndoLoading(ref) {
|
|
return this.lockRef === null || this.lockRef <= ref;
|
|
}
|
|
};
|
|
var DOMPostMorphRestorer = class {
|
|
constructor(containerBefore, containerAfter, updateType) {
|
|
const idsBefore = /* @__PURE__ */ new Set();
|
|
const idsAfter = new Set(
|
|
[...containerAfter.children].map((child) => child.id)
|
|
);
|
|
const elementsToModify = [];
|
|
Array.from(containerBefore.children).forEach((child) => {
|
|
if (child.id) {
|
|
idsBefore.add(child.id);
|
|
if (idsAfter.has(child.id)) {
|
|
const previousElementId = child.previousElementSibling && child.previousElementSibling.id;
|
|
elementsToModify.push({
|
|
elementId: child.id,
|
|
previousElementId
|
|
});
|
|
}
|
|
}
|
|
});
|
|
this.containerId = containerAfter.id;
|
|
this.updateType = updateType;
|
|
this.elementsToModify = elementsToModify;
|
|
this.elementIdsToAdd = [...idsAfter].filter((id) => !idsBefore.has(id));
|
|
}
|
|
// We do the following to optimize append/prepend operations:
|
|
// 1) Track ids of modified elements & of new elements
|
|
// 2) All the modified elements are put back in the correct position in the DOM tree
|
|
// by storing the id of their previous sibling
|
|
// 3) New elements are going to be put in the right place by morphdom during append.
|
|
// For prepend, we move them to the first position in the container
|
|
perform() {
|
|
const container = dom_default.byId(this.containerId);
|
|
if (!container) {
|
|
return;
|
|
}
|
|
this.elementsToModify.forEach((elementToModify) => {
|
|
if (elementToModify.previousElementId) {
|
|
maybe(
|
|
document.getElementById(elementToModify.previousElementId),
|
|
(previousElem) => {
|
|
maybe(
|
|
document.getElementById(elementToModify.elementId),
|
|
(elem) => {
|
|
const isInRightPlace = elem.previousElementSibling && elem.previousElementSibling.id == previousElem.id;
|
|
if (!isInRightPlace) {
|
|
previousElem.insertAdjacentElement("afterend", elem);
|
|
}
|
|
}
|
|
);
|
|
}
|
|
);
|
|
} else {
|
|
maybe(document.getElementById(elementToModify.elementId), (elem) => {
|
|
const isInRightPlace = elem.previousElementSibling == null;
|
|
if (!isInRightPlace) {
|
|
container.insertAdjacentElement("afterbegin", elem);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
if (this.updateType == "prepend") {
|
|
this.elementIdsToAdd.reverse().forEach((elemId) => {
|
|
maybe(
|
|
document.getElementById(elemId),
|
|
(elem) => container.insertAdjacentElement("afterbegin", elem)
|
|
);
|
|
});
|
|
}
|
|
}
|
|
};
|
|
var DOCUMENT_FRAGMENT_NODE = 11;
|
|
function morphAttrs(fromNode, toNode) {
|
|
var toNodeAttrs = toNode.attributes;
|
|
var attr;
|
|
var attrName;
|
|
var attrNamespaceURI;
|
|
var attrValue;
|
|
var fromValue;
|
|
if (toNode.nodeType === DOCUMENT_FRAGMENT_NODE || fromNode.nodeType === DOCUMENT_FRAGMENT_NODE) {
|
|
return;
|
|
}
|
|
for (var i = toNodeAttrs.length - 1; i >= 0; i--) {
|
|
attr = toNodeAttrs[i];
|
|
attrName = attr.name;
|
|
attrNamespaceURI = attr.namespaceURI;
|
|
attrValue = attr.value;
|
|
if (attrNamespaceURI) {
|
|
attrName = attr.localName || attrName;
|
|
fromValue = fromNode.getAttributeNS(attrNamespaceURI, attrName);
|
|
if (fromValue !== attrValue) {
|
|
if (attr.prefix === "xmlns") {
|
|
attrName = attr.name;
|
|
}
|
|
fromNode.setAttributeNS(attrNamespaceURI, attrName, attrValue);
|
|
}
|
|
} else {
|
|
fromValue = fromNode.getAttribute(attrName);
|
|
if (fromValue !== attrValue) {
|
|
fromNode.setAttribute(attrName, attrValue);
|
|
}
|
|
}
|
|
}
|
|
var fromNodeAttrs = fromNode.attributes;
|
|
for (var d = fromNodeAttrs.length - 1; d >= 0; d--) {
|
|
attr = fromNodeAttrs[d];
|
|
attrName = attr.name;
|
|
attrNamespaceURI = attr.namespaceURI;
|
|
if (attrNamespaceURI) {
|
|
attrName = attr.localName || attrName;
|
|
if (!toNode.hasAttributeNS(attrNamespaceURI, attrName)) {
|
|
fromNode.removeAttributeNS(attrNamespaceURI, attrName);
|
|
}
|
|
} else {
|
|
if (!toNode.hasAttribute(attrName)) {
|
|
fromNode.removeAttribute(attrName);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var range;
|
|
var NS_XHTML = "http://www.w3.org/1999/xhtml";
|
|
var doc = typeof document === "undefined" ? void 0 : document;
|
|
var HAS_TEMPLATE_SUPPORT = !!doc && "content" in doc.createElement("template");
|
|
var HAS_RANGE_SUPPORT = !!doc && doc.createRange && "createContextualFragment" in doc.createRange();
|
|
function createFragmentFromTemplate(str) {
|
|
var template = doc.createElement("template");
|
|
template.innerHTML = str;
|
|
return template.content.childNodes[0];
|
|
}
|
|
function createFragmentFromRange(str) {
|
|
if (!range) {
|
|
range = doc.createRange();
|
|
range.selectNode(doc.body);
|
|
}
|
|
var fragment = range.createContextualFragment(str);
|
|
return fragment.childNodes[0];
|
|
}
|
|
function createFragmentFromWrap(str) {
|
|
var fragment = doc.createElement("body");
|
|
fragment.innerHTML = str;
|
|
return fragment.childNodes[0];
|
|
}
|
|
function toElement(str) {
|
|
str = str.trim();
|
|
if (HAS_TEMPLATE_SUPPORT) {
|
|
return createFragmentFromTemplate(str);
|
|
} else if (HAS_RANGE_SUPPORT) {
|
|
return createFragmentFromRange(str);
|
|
}
|
|
return createFragmentFromWrap(str);
|
|
}
|
|
function compareNodeNames(fromEl, toEl) {
|
|
var fromNodeName = fromEl.nodeName;
|
|
var toNodeName = toEl.nodeName;
|
|
var fromCodeStart, toCodeStart;
|
|
if (fromNodeName === toNodeName) {
|
|
return true;
|
|
}
|
|
fromCodeStart = fromNodeName.charCodeAt(0);
|
|
toCodeStart = toNodeName.charCodeAt(0);
|
|
if (fromCodeStart <= 90 && toCodeStart >= 97) {
|
|
return fromNodeName === toNodeName.toUpperCase();
|
|
} else if (toCodeStart <= 90 && fromCodeStart >= 97) {
|
|
return toNodeName === fromNodeName.toUpperCase();
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
function createElementNS(name, namespaceURI) {
|
|
return !namespaceURI || namespaceURI === NS_XHTML ? doc.createElement(name) : doc.createElementNS(namespaceURI, name);
|
|
}
|
|
function moveChildren(fromEl, toEl) {
|
|
var curChild = fromEl.firstChild;
|
|
while (curChild) {
|
|
var nextChild = curChild.nextSibling;
|
|
toEl.appendChild(curChild);
|
|
curChild = nextChild;
|
|
}
|
|
return toEl;
|
|
}
|
|
function syncBooleanAttrProp(fromEl, toEl, name) {
|
|
if (fromEl[name] !== toEl[name]) {
|
|
fromEl[name] = toEl[name];
|
|
if (fromEl[name]) {
|
|
fromEl.setAttribute(name, "");
|
|
} else {
|
|
fromEl.removeAttribute(name);
|
|
}
|
|
}
|
|
}
|
|
var specialElHandlers = {
|
|
OPTION: function(fromEl, toEl) {
|
|
var parentNode = fromEl.parentNode;
|
|
if (parentNode) {
|
|
var parentName = parentNode.nodeName.toUpperCase();
|
|
if (parentName === "OPTGROUP") {
|
|
parentNode = parentNode.parentNode;
|
|
parentName = parentNode && parentNode.nodeName.toUpperCase();
|
|
}
|
|
if (parentName === "SELECT" && !parentNode.hasAttribute("multiple")) {
|
|
if (fromEl.hasAttribute("selected") && !toEl.selected) {
|
|
fromEl.setAttribute("selected", "selected");
|
|
fromEl.removeAttribute("selected");
|
|
}
|
|
parentNode.selectedIndex = -1;
|
|
}
|
|
}
|
|
syncBooleanAttrProp(fromEl, toEl, "selected");
|
|
},
|
|
/**
|
|
* The "value" attribute is special for the <input> element since it sets
|
|
* the initial value. Changing the "value" attribute without changing the
|
|
* "value" property will have no effect since it is only used to the set the
|
|
* initial value. Similar for the "checked" attribute, and "disabled".
|
|
*/
|
|
INPUT: function(fromEl, toEl) {
|
|
syncBooleanAttrProp(fromEl, toEl, "checked");
|
|
syncBooleanAttrProp(fromEl, toEl, "disabled");
|
|
if (fromEl.value !== toEl.value) {
|
|
fromEl.value = toEl.value;
|
|
}
|
|
if (!toEl.hasAttribute("value")) {
|
|
fromEl.removeAttribute("value");
|
|
}
|
|
},
|
|
TEXTAREA: function(fromEl, toEl) {
|
|
var newValue = toEl.value;
|
|
if (fromEl.value !== newValue) {
|
|
fromEl.value = newValue;
|
|
}
|
|
var firstChild = fromEl.firstChild;
|
|
if (firstChild) {
|
|
var oldValue = firstChild.nodeValue;
|
|
if (oldValue == newValue || !newValue && oldValue == fromEl.placeholder) {
|
|
return;
|
|
}
|
|
firstChild.nodeValue = newValue;
|
|
}
|
|
},
|
|
SELECT: function(fromEl, toEl) {
|
|
if (!toEl.hasAttribute("multiple")) {
|
|
var selectedIndex = -1;
|
|
var i = 0;
|
|
var curChild = fromEl.firstChild;
|
|
var optgroup;
|
|
var nodeName;
|
|
while (curChild) {
|
|
nodeName = curChild.nodeName && curChild.nodeName.toUpperCase();
|
|
if (nodeName === "OPTGROUP") {
|
|
optgroup = curChild;
|
|
curChild = optgroup.firstChild;
|
|
if (!curChild) {
|
|
curChild = optgroup.nextSibling;
|
|
optgroup = null;
|
|
}
|
|
} else {
|
|
if (nodeName === "OPTION") {
|
|
if (curChild.hasAttribute("selected")) {
|
|
selectedIndex = i;
|
|
break;
|
|
}
|
|
i++;
|
|
}
|
|
curChild = curChild.nextSibling;
|
|
if (!curChild && optgroup) {
|
|
curChild = optgroup.nextSibling;
|
|
optgroup = null;
|
|
}
|
|
}
|
|
}
|
|
fromEl.selectedIndex = selectedIndex;
|
|
}
|
|
}
|
|
};
|
|
var ELEMENT_NODE = 1;
|
|
var DOCUMENT_FRAGMENT_NODE$1 = 11;
|
|
var TEXT_NODE = 3;
|
|
var COMMENT_NODE = 8;
|
|
function noop() {
|
|
}
|
|
function defaultGetNodeKey(node) {
|
|
if (node) {
|
|
return node.getAttribute && node.getAttribute("id") || node.id;
|
|
}
|
|
}
|
|
function morphdomFactory(morphAttrs2) {
|
|
return function morphdom2(fromNode, toNode, options) {
|
|
if (!options) {
|
|
options = {};
|
|
}
|
|
if (typeof toNode === "string") {
|
|
if (fromNode.nodeName === "#document" || fromNode.nodeName === "HTML") {
|
|
var toNodeHtml = toNode;
|
|
toNode = doc.createElement("html");
|
|
toNode.innerHTML = toNodeHtml;
|
|
} else if (fromNode.nodeName === "BODY") {
|
|
var toNodeBody = toNode;
|
|
toNode = doc.createElement("html");
|
|
toNode.innerHTML = toNodeBody;
|
|
var bodyElement = toNode.querySelector("body");
|
|
if (bodyElement) {
|
|
toNode = bodyElement;
|
|
}
|
|
} else {
|
|
toNode = toElement(toNode);
|
|
}
|
|
} else if (toNode.nodeType === DOCUMENT_FRAGMENT_NODE$1) {
|
|
toNode = toNode.firstElementChild;
|
|
}
|
|
var getNodeKey = options.getNodeKey || defaultGetNodeKey;
|
|
var onBeforeNodeAdded = options.onBeforeNodeAdded || noop;
|
|
var onNodeAdded = options.onNodeAdded || noop;
|
|
var onBeforeElUpdated = options.onBeforeElUpdated || noop;
|
|
var onElUpdated = options.onElUpdated || noop;
|
|
var onBeforeNodeDiscarded = options.onBeforeNodeDiscarded || noop;
|
|
var onNodeDiscarded = options.onNodeDiscarded || noop;
|
|
var onBeforeElChildrenUpdated = options.onBeforeElChildrenUpdated || noop;
|
|
var skipFromChildren = options.skipFromChildren || noop;
|
|
var addChild = options.addChild || function(parent, child) {
|
|
return parent.appendChild(child);
|
|
};
|
|
var childrenOnly = options.childrenOnly === true;
|
|
var fromNodesLookup = /* @__PURE__ */ Object.create(null);
|
|
var keyedRemovalList = [];
|
|
function addKeyedRemoval(key) {
|
|
keyedRemovalList.push(key);
|
|
}
|
|
function walkDiscardedChildNodes(node, skipKeyedNodes) {
|
|
if (node.nodeType === ELEMENT_NODE) {
|
|
var curChild = node.firstChild;
|
|
while (curChild) {
|
|
var key = void 0;
|
|
if (skipKeyedNodes && (key = getNodeKey(curChild))) {
|
|
addKeyedRemoval(key);
|
|
} else {
|
|
onNodeDiscarded(curChild);
|
|
if (curChild.firstChild) {
|
|
walkDiscardedChildNodes(curChild, skipKeyedNodes);
|
|
}
|
|
}
|
|
curChild = curChild.nextSibling;
|
|
}
|
|
}
|
|
}
|
|
function removeNode(node, parentNode, skipKeyedNodes) {
|
|
if (onBeforeNodeDiscarded(node) === false) {
|
|
return;
|
|
}
|
|
if (parentNode) {
|
|
parentNode.removeChild(node);
|
|
}
|
|
onNodeDiscarded(node);
|
|
walkDiscardedChildNodes(node, skipKeyedNodes);
|
|
}
|
|
function indexTree(node) {
|
|
if (node.nodeType === ELEMENT_NODE || node.nodeType === DOCUMENT_FRAGMENT_NODE$1) {
|
|
var curChild = node.firstChild;
|
|
while (curChild) {
|
|
var key = getNodeKey(curChild);
|
|
if (key) {
|
|
fromNodesLookup[key] = curChild;
|
|
}
|
|
indexTree(curChild);
|
|
curChild = curChild.nextSibling;
|
|
}
|
|
}
|
|
}
|
|
indexTree(fromNode);
|
|
function handleNodeAdded(el) {
|
|
onNodeAdded(el);
|
|
var curChild = el.firstChild;
|
|
while (curChild) {
|
|
var nextSibling = curChild.nextSibling;
|
|
var key = getNodeKey(curChild);
|
|
if (key) {
|
|
var unmatchedFromEl = fromNodesLookup[key];
|
|
if (unmatchedFromEl && compareNodeNames(curChild, unmatchedFromEl)) {
|
|
curChild.parentNode.replaceChild(unmatchedFromEl, curChild);
|
|
morphEl(unmatchedFromEl, curChild);
|
|
} else {
|
|
handleNodeAdded(curChild);
|
|
}
|
|
} else {
|
|
handleNodeAdded(curChild);
|
|
}
|
|
curChild = nextSibling;
|
|
}
|
|
}
|
|
function cleanupFromEl(fromEl, curFromNodeChild, curFromNodeKey) {
|
|
while (curFromNodeChild) {
|
|
var fromNextSibling = curFromNodeChild.nextSibling;
|
|
if (curFromNodeKey = getNodeKey(curFromNodeChild)) {
|
|
addKeyedRemoval(curFromNodeKey);
|
|
} else {
|
|
removeNode(
|
|
curFromNodeChild,
|
|
fromEl,
|
|
true
|
|
/* skip keyed nodes */
|
|
);
|
|
}
|
|
curFromNodeChild = fromNextSibling;
|
|
}
|
|
}
|
|
function morphEl(fromEl, toEl, childrenOnly2) {
|
|
var toElKey = getNodeKey(toEl);
|
|
if (toElKey) {
|
|
delete fromNodesLookup[toElKey];
|
|
}
|
|
if (!childrenOnly2) {
|
|
var beforeUpdateResult = onBeforeElUpdated(fromEl, toEl);
|
|
if (beforeUpdateResult === false) {
|
|
return;
|
|
} else if (beforeUpdateResult instanceof HTMLElement) {
|
|
fromEl = beforeUpdateResult;
|
|
indexTree(fromEl);
|
|
}
|
|
morphAttrs2(fromEl, toEl);
|
|
onElUpdated(fromEl);
|
|
if (onBeforeElChildrenUpdated(fromEl, toEl) === false) {
|
|
return;
|
|
}
|
|
}
|
|
if (fromEl.nodeName !== "TEXTAREA") {
|
|
morphChildren(fromEl, toEl);
|
|
} else {
|
|
specialElHandlers.TEXTAREA(fromEl, toEl);
|
|
}
|
|
}
|
|
function morphChildren(fromEl, toEl) {
|
|
var skipFrom = skipFromChildren(fromEl, toEl);
|
|
var curToNodeChild = toEl.firstChild;
|
|
var curFromNodeChild = fromEl.firstChild;
|
|
var curToNodeKey;
|
|
var curFromNodeKey;
|
|
var fromNextSibling;
|
|
var toNextSibling;
|
|
var matchingFromEl;
|
|
outer:
|
|
while (curToNodeChild) {
|
|
toNextSibling = curToNodeChild.nextSibling;
|
|
curToNodeKey = getNodeKey(curToNodeChild);
|
|
while (!skipFrom && curFromNodeChild) {
|
|
fromNextSibling = curFromNodeChild.nextSibling;
|
|
if (curToNodeChild.isSameNode && curToNodeChild.isSameNode(curFromNodeChild)) {
|
|
curToNodeChild = toNextSibling;
|
|
curFromNodeChild = fromNextSibling;
|
|
continue outer;
|
|
}
|
|
curFromNodeKey = getNodeKey(curFromNodeChild);
|
|
var curFromNodeType = curFromNodeChild.nodeType;
|
|
var isCompatible = void 0;
|
|
if (curFromNodeType === curToNodeChild.nodeType) {
|
|
if (curFromNodeType === ELEMENT_NODE) {
|
|
if (curToNodeKey) {
|
|
if (curToNodeKey !== curFromNodeKey) {
|
|
if (matchingFromEl = fromNodesLookup[curToNodeKey]) {
|
|
if (fromNextSibling === matchingFromEl) {
|
|
isCompatible = false;
|
|
} else {
|
|
fromEl.insertBefore(matchingFromEl, curFromNodeChild);
|
|
if (curFromNodeKey) {
|
|
addKeyedRemoval(curFromNodeKey);
|
|
} else {
|
|
removeNode(
|
|
curFromNodeChild,
|
|
fromEl,
|
|
true
|
|
/* skip keyed nodes */
|
|
);
|
|
}
|
|
curFromNodeChild = matchingFromEl;
|
|
curFromNodeKey = getNodeKey(curFromNodeChild);
|
|
}
|
|
} else {
|
|
isCompatible = false;
|
|
}
|
|
}
|
|
} else if (curFromNodeKey) {
|
|
isCompatible = false;
|
|
}
|
|
isCompatible = isCompatible !== false && compareNodeNames(curFromNodeChild, curToNodeChild);
|
|
if (isCompatible) {
|
|
morphEl(curFromNodeChild, curToNodeChild);
|
|
}
|
|
} else if (curFromNodeType === TEXT_NODE || curFromNodeType == COMMENT_NODE) {
|
|
isCompatible = true;
|
|
if (curFromNodeChild.nodeValue !== curToNodeChild.nodeValue) {
|
|
curFromNodeChild.nodeValue = curToNodeChild.nodeValue;
|
|
}
|
|
}
|
|
}
|
|
if (isCompatible) {
|
|
curToNodeChild = toNextSibling;
|
|
curFromNodeChild = fromNextSibling;
|
|
continue outer;
|
|
}
|
|
if (curFromNodeKey) {
|
|
addKeyedRemoval(curFromNodeKey);
|
|
} else {
|
|
removeNode(
|
|
curFromNodeChild,
|
|
fromEl,
|
|
true
|
|
/* skip keyed nodes */
|
|
);
|
|
}
|
|
curFromNodeChild = fromNextSibling;
|
|
}
|
|
if (curToNodeKey && (matchingFromEl = fromNodesLookup[curToNodeKey]) && compareNodeNames(matchingFromEl, curToNodeChild)) {
|
|
if (!skipFrom) {
|
|
addChild(fromEl, matchingFromEl);
|
|
}
|
|
morphEl(matchingFromEl, curToNodeChild);
|
|
} else {
|
|
var onBeforeNodeAddedResult = onBeforeNodeAdded(curToNodeChild);
|
|
if (onBeforeNodeAddedResult !== false) {
|
|
if (onBeforeNodeAddedResult) {
|
|
curToNodeChild = onBeforeNodeAddedResult;
|
|
}
|
|
if (curToNodeChild.actualize) {
|
|
curToNodeChild = curToNodeChild.actualize(fromEl.ownerDocument || doc);
|
|
}
|
|
addChild(fromEl, curToNodeChild);
|
|
handleNodeAdded(curToNodeChild);
|
|
}
|
|
}
|
|
curToNodeChild = toNextSibling;
|
|
curFromNodeChild = fromNextSibling;
|
|
}
|
|
cleanupFromEl(fromEl, curFromNodeChild, curFromNodeKey);
|
|
var specialElHandler = specialElHandlers[fromEl.nodeName];
|
|
if (specialElHandler) {
|
|
specialElHandler(fromEl, toEl);
|
|
}
|
|
}
|
|
var morphedNode = fromNode;
|
|
var morphedNodeType = morphedNode.nodeType;
|
|
var toNodeType = toNode.nodeType;
|
|
if (!childrenOnly) {
|
|
if (morphedNodeType === ELEMENT_NODE) {
|
|
if (toNodeType === ELEMENT_NODE) {
|
|
if (!compareNodeNames(fromNode, toNode)) {
|
|
onNodeDiscarded(fromNode);
|
|
morphedNode = moveChildren(fromNode, createElementNS(toNode.nodeName, toNode.namespaceURI));
|
|
}
|
|
} else {
|
|
morphedNode = toNode;
|
|
}
|
|
} else if (morphedNodeType === TEXT_NODE || morphedNodeType === COMMENT_NODE) {
|
|
if (toNodeType === morphedNodeType) {
|
|
if (morphedNode.nodeValue !== toNode.nodeValue) {
|
|
morphedNode.nodeValue = toNode.nodeValue;
|
|
}
|
|
return morphedNode;
|
|
} else {
|
|
morphedNode = toNode;
|
|
}
|
|
}
|
|
}
|
|
if (morphedNode === toNode) {
|
|
onNodeDiscarded(fromNode);
|
|
} else {
|
|
if (toNode.isSameNode && toNode.isSameNode(morphedNode)) {
|
|
return;
|
|
}
|
|
morphEl(morphedNode, toNode, childrenOnly);
|
|
if (keyedRemovalList) {
|
|
for (var i = 0, len = keyedRemovalList.length; i < len; i++) {
|
|
var elToRemove = fromNodesLookup[keyedRemovalList[i]];
|
|
if (elToRemove) {
|
|
removeNode(elToRemove, elToRemove.parentNode, false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!childrenOnly && morphedNode !== fromNode && fromNode.parentNode) {
|
|
if (morphedNode.actualize) {
|
|
morphedNode = morphedNode.actualize(fromNode.ownerDocument || doc);
|
|
}
|
|
fromNode.parentNode.replaceChild(morphedNode, fromNode);
|
|
}
|
|
return morphedNode;
|
|
};
|
|
}
|
|
var morphdom = morphdomFactory(morphAttrs);
|
|
var morphdom_esm_default = morphdom;
|
|
var DOMPatch = class {
|
|
constructor(view, container, id, html, streams, targetCID, opts = {}) {
|
|
this.view = view;
|
|
this.liveSocket = view.liveSocket;
|
|
this.container = container;
|
|
this.id = id;
|
|
this.rootID = view.root.id;
|
|
this.html = html;
|
|
this.streams = streams;
|
|
this.streamInserts = {};
|
|
this.streamComponentRestore = {};
|
|
this.targetCID = targetCID;
|
|
this.cidPatch = isCid(this.targetCID);
|
|
this.pendingRemoves = [];
|
|
this.phxRemove = this.liveSocket.binding("remove");
|
|
this.targetContainer = this.isCIDPatch() ? this.targetCIDContainer(html) : container;
|
|
this.callbacks = {
|
|
beforeadded: [],
|
|
beforeupdated: [],
|
|
beforephxChildAdded: [],
|
|
afteradded: [],
|
|
afterupdated: [],
|
|
afterdiscarded: [],
|
|
afterphxChildAdded: [],
|
|
aftertransitionsDiscarded: []
|
|
};
|
|
this.withChildren = opts.withChildren || opts.undoRef !== void 0 || false;
|
|
this.undoRef = opts.undoRef;
|
|
}
|
|
before(kind, callback) {
|
|
this.callbacks[`before${kind}`].push(callback);
|
|
}
|
|
after(kind, callback) {
|
|
this.callbacks[`after${kind}`].push(callback);
|
|
}
|
|
trackBefore(kind, ...args) {
|
|
this.callbacks[`before${kind}`].forEach((callback) => callback(...args));
|
|
}
|
|
trackAfter(kind, ...args) {
|
|
this.callbacks[`after${kind}`].forEach((callback) => callback(...args));
|
|
}
|
|
markPrunableContentForRemoval() {
|
|
const phxUpdate = this.liveSocket.binding(PHX_UPDATE);
|
|
dom_default.all(
|
|
this.container,
|
|
`[${phxUpdate}=append] > *, [${phxUpdate}=prepend] > *`,
|
|
(el) => {
|
|
el.setAttribute(PHX_PRUNE, "");
|
|
}
|
|
);
|
|
}
|
|
perform(isJoinPatch) {
|
|
const { view, liveSocket: liveSocket2, html, container } = this;
|
|
let targetContainer = this.targetContainer;
|
|
if (this.isCIDPatch() && !this.targetContainer) {
|
|
return;
|
|
}
|
|
if (this.isCIDPatch()) {
|
|
const closestLock = targetContainer.closest(`[${PHX_REF_LOCK}]`);
|
|
if (closestLock && !closestLock.isSameNode(targetContainer)) {
|
|
const clonedTree = dom_default.private(closestLock, PHX_REF_LOCK);
|
|
if (clonedTree) {
|
|
targetContainer = clonedTree.querySelector(
|
|
`[data-phx-component="${this.targetCID}"]`
|
|
);
|
|
if (!targetContainer)
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
const focused = liveSocket2.getActiveElement();
|
|
const { selectionStart, selectionEnd } = focused && dom_default.hasSelectionRange(focused) ? focused : {};
|
|
const phxUpdate = liveSocket2.binding(PHX_UPDATE);
|
|
const phxViewportTop = liveSocket2.binding(PHX_VIEWPORT_TOP);
|
|
const phxViewportBottom = liveSocket2.binding(PHX_VIEWPORT_BOTTOM);
|
|
const phxTriggerExternal = liveSocket2.binding(PHX_TRIGGER_ACTION);
|
|
const added = [];
|
|
const updates = [];
|
|
const appendPrependUpdates = [];
|
|
let portalCallbacks = [];
|
|
let externalFormTriggered = null;
|
|
const morph = (targetContainer2, source, withChildren = this.withChildren) => {
|
|
const morphCallbacks = {
|
|
// normally, we are running with childrenOnly, as the patch HTML for a LV
|
|
// does not include the LV attrs (data-phx-session, etc.)
|
|
// when we are patching a live component, we do want to patch the root element as well;
|
|
// another case is the recursive patch of a stream item that was kept on reset (-> onBeforeNodeAdded)
|
|
childrenOnly: targetContainer2.getAttribute(PHX_COMPONENT) === null && !withChildren,
|
|
getNodeKey: (node) => {
|
|
if (dom_default.isPhxDestroyed(node)) {
|
|
return null;
|
|
}
|
|
if (isJoinPatch) {
|
|
return node.id;
|
|
}
|
|
if (dom_default.private(node, "clientsideIdAttribute")) {
|
|
return node.getAttribute && node.getAttribute(PHX_MAGIC_ID);
|
|
}
|
|
return node.id || node.getAttribute && node.getAttribute(PHX_MAGIC_ID);
|
|
},
|
|
// skip indexing from children when container is stream
|
|
skipFromChildren: (from) => {
|
|
return from.getAttribute(phxUpdate) === PHX_STREAM;
|
|
},
|
|
// tell morphdom how to add a child
|
|
addChild: (parent, child) => {
|
|
const { ref, streamAt } = this.getStreamInsert(child);
|
|
if (ref === void 0) {
|
|
return parent.appendChild(child);
|
|
}
|
|
this.setStreamRef(child, ref);
|
|
if (streamAt === 0) {
|
|
parent.insertAdjacentElement("afterbegin", child);
|
|
} else if (streamAt === -1) {
|
|
const lastChild = parent.lastElementChild;
|
|
if (lastChild && !lastChild.hasAttribute(PHX_STREAM_REF)) {
|
|
const nonStreamChild = Array.from(parent.children).find(
|
|
(c) => !c.hasAttribute(PHX_STREAM_REF)
|
|
);
|
|
parent.insertBefore(child, nonStreamChild);
|
|
} else {
|
|
parent.appendChild(child);
|
|
}
|
|
} else if (streamAt > 0) {
|
|
const sibling = Array.from(parent.children)[streamAt];
|
|
parent.insertBefore(child, sibling);
|
|
}
|
|
},
|
|
onBeforeNodeAdded: (el) => {
|
|
var _a2;
|
|
if (((_a2 = this.getStreamInsert(el)) == null ? void 0 : _a2.updateOnly) && !this.streamComponentRestore[el.id]) {
|
|
return false;
|
|
}
|
|
dom_default.maintainPrivateHooks(el, el, phxViewportTop, phxViewportBottom);
|
|
this.trackBefore("added", el);
|
|
let morphedEl = el;
|
|
if (this.streamComponentRestore[el.id]) {
|
|
morphedEl = this.streamComponentRestore[el.id];
|
|
delete this.streamComponentRestore[el.id];
|
|
morph(morphedEl, el, true);
|
|
}
|
|
return morphedEl;
|
|
},
|
|
onNodeAdded: (el) => {
|
|
if (el.getAttribute) {
|
|
this.maybeReOrderStream(el, true);
|
|
}
|
|
if (dom_default.isPortalTemplate(el)) {
|
|
portalCallbacks.push(() => this.teleport(el, morph));
|
|
}
|
|
if (el instanceof HTMLImageElement && el.srcset) {
|
|
el.srcset = el.srcset;
|
|
} else if (el instanceof HTMLVideoElement && el.autoplay) {
|
|
el.play();
|
|
}
|
|
if (dom_default.isNowTriggerFormExternal(el, phxTriggerExternal)) {
|
|
externalFormTriggered = el;
|
|
}
|
|
if (dom_default.isPhxChild(el) && view.ownsElement(el) || dom_default.isPhxSticky(el) && view.ownsElement(el.parentNode)) {
|
|
this.trackAfter("phxChildAdded", el);
|
|
}
|
|
if (el.nodeName === "SCRIPT" && el.hasAttribute(PHX_RUNTIME_HOOK)) {
|
|
this.handleRuntimeHook(el, source);
|
|
}
|
|
added.push(el);
|
|
},
|
|
onNodeDiscarded: (el) => this.onNodeDiscarded(el),
|
|
onBeforeNodeDiscarded: (el) => {
|
|
if (el.getAttribute && el.getAttribute(PHX_PRUNE) !== null) {
|
|
return true;
|
|
}
|
|
if (el.parentElement !== null && el.id && dom_default.isPhxUpdate(el.parentElement, phxUpdate, [
|
|
PHX_STREAM,
|
|
"append",
|
|
"prepend"
|
|
])) {
|
|
return false;
|
|
}
|
|
if (el.getAttribute && el.getAttribute(PHX_TELEPORTED_REF)) {
|
|
return false;
|
|
}
|
|
if (this.maybePendingRemove(el)) {
|
|
return false;
|
|
}
|
|
if (this.skipCIDSibling(el)) {
|
|
return false;
|
|
}
|
|
if (dom_default.isPortalTemplate(el)) {
|
|
const teleportedEl = document.getElementById(
|
|
el.content.firstElementChild.id
|
|
);
|
|
if (teleportedEl) {
|
|
teleportedEl.remove();
|
|
morphCallbacks.onNodeDiscarded(teleportedEl);
|
|
this.view.dropPortalElementId(teleportedEl.id);
|
|
}
|
|
}
|
|
return true;
|
|
},
|
|
onElUpdated: (el) => {
|
|
if (dom_default.isNowTriggerFormExternal(el, phxTriggerExternal)) {
|
|
externalFormTriggered = el;
|
|
}
|
|
updates.push(el);
|
|
this.maybeReOrderStream(el, false);
|
|
},
|
|
onBeforeElUpdated: (fromEl, toEl) => {
|
|
if (fromEl.id && fromEl.isSameNode(targetContainer2) && fromEl.id !== toEl.id) {
|
|
morphCallbacks.onNodeDiscarded(fromEl);
|
|
fromEl.replaceWith(toEl);
|
|
return morphCallbacks.onNodeAdded(toEl);
|
|
}
|
|
dom_default.syncPendingAttrs(fromEl, toEl);
|
|
dom_default.maintainPrivateHooks(
|
|
fromEl,
|
|
toEl,
|
|
phxViewportTop,
|
|
phxViewportBottom
|
|
);
|
|
dom_default.cleanChildNodes(toEl, phxUpdate);
|
|
const isFocusedFormEl = focused && fromEl.isSameNode(focused) && dom_default.isFormInput(fromEl);
|
|
const focusedSelectChanged = isFocusedFormEl && this.isChangedSelect(fromEl, toEl);
|
|
if (this.skipCIDSibling(toEl)) {
|
|
this.maybeCloneLockedElement(fromEl, isFocusedFormEl);
|
|
this.copyNestedPrivateLock(fromEl, toEl);
|
|
this.maybeReOrderStream(fromEl);
|
|
return false;
|
|
}
|
|
if (dom_default.isPhxSticky(fromEl)) {
|
|
[PHX_SESSION, PHX_STATIC, PHX_ROOT_ID].map((attr) => [
|
|
attr,
|
|
fromEl.getAttribute(attr),
|
|
toEl.getAttribute(attr)
|
|
]).forEach(([attr, fromVal, toVal]) => {
|
|
if (toVal && fromVal !== toVal) {
|
|
fromEl.setAttribute(attr, toVal);
|
|
}
|
|
});
|
|
return false;
|
|
}
|
|
if (dom_default.isIgnored(fromEl, phxUpdate) || fromEl.form && fromEl.form.isSameNode(externalFormTriggered)) {
|
|
this.trackBefore("updated", fromEl, toEl);
|
|
dom_default.mergeAttrs(fromEl, toEl, {
|
|
isIgnored: dom_default.isIgnored(fromEl, phxUpdate)
|
|
});
|
|
updates.push(fromEl);
|
|
dom_default.applyStickyOperations(fromEl);
|
|
return false;
|
|
}
|
|
if (fromEl.type === "number" && fromEl.validity && fromEl.validity.badInput) {
|
|
return false;
|
|
}
|
|
fromEl = this.maybeCloneLockedElement(fromEl, isFocusedFormEl);
|
|
if (dom_default.isPhxChild(toEl)) {
|
|
const prevSession = fromEl.getAttribute(PHX_SESSION);
|
|
dom_default.mergeAttrs(fromEl, toEl, { exclude: [PHX_STATIC] });
|
|
if (prevSession !== "") {
|
|
fromEl.setAttribute(PHX_SESSION, prevSession);
|
|
}
|
|
fromEl.setAttribute(PHX_ROOT_ID, this.rootID);
|
|
dom_default.applyStickyOperations(fromEl);
|
|
return false;
|
|
}
|
|
this.copyNestedPrivateLock(fromEl, toEl);
|
|
dom_default.copyPrivates(toEl, fromEl);
|
|
if (dom_default.isPortalTemplate(toEl)) {
|
|
portalCallbacks.push(() => this.teleport(toEl, morph));
|
|
fromEl.content.replaceChildren(toEl.content.cloneNode(true));
|
|
return false;
|
|
}
|
|
if (isFocusedFormEl && fromEl.type !== "hidden" && !focusedSelectChanged) {
|
|
this.trackBefore("updated", fromEl, toEl);
|
|
dom_default.mergeFocusedInput(fromEl, toEl);
|
|
dom_default.syncAttrsToProps(fromEl);
|
|
updates.push(fromEl);
|
|
dom_default.applyStickyOperations(fromEl);
|
|
return false;
|
|
} else {
|
|
if (focusedSelectChanged) {
|
|
fromEl.blur();
|
|
}
|
|
if (dom_default.isPhxUpdate(toEl, phxUpdate, ["append", "prepend"])) {
|
|
appendPrependUpdates.push(
|
|
new DOMPostMorphRestorer(
|
|
fromEl,
|
|
toEl,
|
|
toEl.getAttribute(phxUpdate)
|
|
)
|
|
);
|
|
}
|
|
dom_default.syncAttrsToProps(toEl);
|
|
dom_default.applyStickyOperations(toEl);
|
|
this.trackBefore("updated", fromEl, toEl);
|
|
return fromEl;
|
|
}
|
|
}
|
|
};
|
|
morphdom_esm_default(targetContainer2, source, morphCallbacks);
|
|
};
|
|
this.trackBefore("added", container);
|
|
this.trackBefore("updated", container, container);
|
|
liveSocket2.time("morphdom", () => {
|
|
this.streams.forEach(([ref, inserts, deleteIds, reset]) => {
|
|
inserts.forEach(([key, streamAt, limit, updateOnly]) => {
|
|
this.streamInserts[key] = { ref, streamAt, limit, reset, updateOnly };
|
|
});
|
|
if (reset !== void 0) {
|
|
dom_default.all(document, `[${PHX_STREAM_REF}="${ref}"]`, (child) => {
|
|
this.removeStreamChildElement(child);
|
|
});
|
|
}
|
|
deleteIds.forEach((id) => {
|
|
const child = document.getElementById(id);
|
|
if (child) {
|
|
this.removeStreamChildElement(child);
|
|
}
|
|
});
|
|
});
|
|
if (isJoinPatch) {
|
|
dom_default.all(this.container, `[${phxUpdate}=${PHX_STREAM}]`).filter((el) => this.view.ownsElement(el)).forEach((el) => {
|
|
Array.from(el.children).forEach((child) => {
|
|
this.removeStreamChildElement(child, true);
|
|
});
|
|
});
|
|
}
|
|
morph(targetContainer, html);
|
|
let teleportCount = 0;
|
|
while (portalCallbacks.length > 0 && teleportCount < 5) {
|
|
const copy = portalCallbacks.slice();
|
|
portalCallbacks = [];
|
|
copy.forEach((callback) => callback());
|
|
teleportCount++;
|
|
}
|
|
this.view.portalElementIds.forEach((id) => {
|
|
const el = document.getElementById(id);
|
|
if (el) {
|
|
const source = document.getElementById(
|
|
el.getAttribute(PHX_TELEPORTED_SRC)
|
|
);
|
|
if (!source) {
|
|
el.remove();
|
|
this.onNodeDiscarded(el);
|
|
this.view.dropPortalElementId(id);
|
|
}
|
|
}
|
|
});
|
|
});
|
|
if (liveSocket2.isDebugEnabled()) {
|
|
detectDuplicateIds();
|
|
detectInvalidStreamInserts(this.streamInserts);
|
|
Array.from(document.querySelectorAll("input[name=id]")).forEach(
|
|
(node) => {
|
|
if (node instanceof HTMLInputElement && node.form) {
|
|
console.error(
|
|
'Detected an input with name="id" inside a form! This will cause problems when patching the DOM.\n',
|
|
node
|
|
);
|
|
}
|
|
}
|
|
);
|
|
}
|
|
if (appendPrependUpdates.length > 0) {
|
|
liveSocket2.time("post-morph append/prepend restoration", () => {
|
|
appendPrependUpdates.forEach((update) => update.perform());
|
|
});
|
|
}
|
|
liveSocket2.silenceEvents(
|
|
() => dom_default.restoreFocus(focused, selectionStart, selectionEnd)
|
|
);
|
|
dom_default.dispatchEvent(document, "phx:update");
|
|
added.forEach((el) => this.trackAfter("added", el));
|
|
updates.forEach((el) => this.trackAfter("updated", el));
|
|
this.transitionPendingRemoves();
|
|
if (externalFormTriggered) {
|
|
liveSocket2.unload();
|
|
const submitter = dom_default.private(externalFormTriggered, "submitter");
|
|
if (submitter && submitter.name && targetContainer.contains(submitter)) {
|
|
const input = document.createElement("input");
|
|
input.type = "hidden";
|
|
const formId = submitter.getAttribute("form");
|
|
if (formId) {
|
|
input.setAttribute("form", formId);
|
|
}
|
|
input.name = submitter.name;
|
|
input.value = submitter.value;
|
|
submitter.parentElement.insertBefore(input, submitter);
|
|
}
|
|
Object.getPrototypeOf(externalFormTriggered).submit.call(
|
|
externalFormTriggered
|
|
);
|
|
}
|
|
return true;
|
|
}
|
|
onNodeDiscarded(el) {
|
|
if (dom_default.isPhxChild(el) || dom_default.isPhxSticky(el)) {
|
|
this.liveSocket.destroyViewByEl(el);
|
|
}
|
|
this.trackAfter("discarded", el);
|
|
}
|
|
maybePendingRemove(node) {
|
|
if (node.getAttribute && node.getAttribute(this.phxRemove) !== null) {
|
|
this.pendingRemoves.push(node);
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
removeStreamChildElement(child, force = false) {
|
|
if (!force && !this.view.ownsElement(child)) {
|
|
return;
|
|
}
|
|
if (this.streamInserts[child.id]) {
|
|
this.streamComponentRestore[child.id] = child;
|
|
child.remove();
|
|
} else {
|
|
if (!this.maybePendingRemove(child)) {
|
|
child.remove();
|
|
this.onNodeDiscarded(child);
|
|
}
|
|
}
|
|
}
|
|
getStreamInsert(el) {
|
|
const insert = el.id ? this.streamInserts[el.id] : {};
|
|
return insert || {};
|
|
}
|
|
setStreamRef(el, ref) {
|
|
dom_default.putSticky(
|
|
el,
|
|
PHX_STREAM_REF,
|
|
(el2) => el2.setAttribute(PHX_STREAM_REF, ref)
|
|
);
|
|
}
|
|
maybeReOrderStream(el, isNew) {
|
|
const { ref, streamAt, reset } = this.getStreamInsert(el);
|
|
if (streamAt === void 0) {
|
|
return;
|
|
}
|
|
this.setStreamRef(el, ref);
|
|
if (!reset && !isNew) {
|
|
return;
|
|
}
|
|
if (!el.parentElement) {
|
|
return;
|
|
}
|
|
if (streamAt === 0) {
|
|
this.moveOrInsertBefore(
|
|
el.parentElement,
|
|
el,
|
|
el.parentElement.firstElementChild
|
|
);
|
|
} else if (streamAt > 0) {
|
|
const children = Array.from(el.parentElement.children);
|
|
const oldIndex = children.indexOf(el);
|
|
if (streamAt >= children.length - 1) {
|
|
this.moveOrInsertBefore(el.parentElement, el, null);
|
|
} else {
|
|
const sibling = children[streamAt];
|
|
if (oldIndex > streamAt) {
|
|
this.moveOrInsertBefore(el.parentElement, el, sibling);
|
|
} else {
|
|
this.moveOrInsertBefore(
|
|
el.parentElement,
|
|
el,
|
|
sibling.nextElementSibling
|
|
);
|
|
}
|
|
}
|
|
}
|
|
this.maybeLimitStream(el);
|
|
}
|
|
// Reorder a child within its parent. When supported, use the atomic
|
|
// moveBefore (https://developer.mozilla.org/en-US/docs/Web/API/Node/moveBefore)
|
|
// so connected custom elements (and other state-bearing nodes like iframes)
|
|
// are not disconnected and reconnected by the move. Falls back to
|
|
// insertBefore otherwise. Passing `ref === null` moves to the end.
|
|
// See also https://github.com/phoenixframework/phoenix_live_view/issues/4212.
|
|
moveOrInsertBefore(parent, child, ref) {
|
|
if (typeof parent.moveBefore === "function") {
|
|
try {
|
|
parent.moveBefore(child, ref);
|
|
return;
|
|
} catch (e) {
|
|
}
|
|
}
|
|
parent.insertBefore(child, ref);
|
|
}
|
|
maybeLimitStream(el) {
|
|
const { limit } = this.getStreamInsert(el);
|
|
const children = limit !== null && Array.from(el.parentElement.children);
|
|
if (limit && limit < 0 && children.length > limit * -1) {
|
|
children.slice(0, children.length + limit).forEach((child) => this.removeStreamChildElement(child));
|
|
} else if (limit && limit >= 0 && children.length > limit) {
|
|
children.slice(limit).forEach((child) => this.removeStreamChildElement(child));
|
|
}
|
|
}
|
|
transitionPendingRemoves() {
|
|
const { pendingRemoves, liveSocket: liveSocket2 } = this;
|
|
if (pendingRemoves.length > 0) {
|
|
liveSocket2.transitionRemoves(pendingRemoves, () => {
|
|
pendingRemoves.forEach((el) => {
|
|
const child = dom_default.firstPhxChild(el);
|
|
if (child) {
|
|
liveSocket2.destroyViewByEl(child);
|
|
}
|
|
el.remove();
|
|
});
|
|
this.trackAfter("transitionsDiscarded", pendingRemoves);
|
|
});
|
|
}
|
|
}
|
|
isChangedSelect(fromEl, toEl) {
|
|
if (!(fromEl instanceof HTMLSelectElement) || fromEl.multiple) {
|
|
return false;
|
|
}
|
|
if (fromEl.options.length !== toEl.options.length) {
|
|
return true;
|
|
}
|
|
toEl.value = fromEl.value;
|
|
return !fromEl.isEqualNode(toEl);
|
|
}
|
|
isCIDPatch() {
|
|
return this.cidPatch;
|
|
}
|
|
skipCIDSibling(el) {
|
|
return el.nodeType === Node.ELEMENT_NODE && el.hasAttribute(PHX_SKIP);
|
|
}
|
|
maybeCloneLockedElement(fromEl, isFocusedFormEl) {
|
|
if (!fromEl.hasAttribute(PHX_REF_SRC))
|
|
return fromEl;
|
|
const ref = new ElementRef(fromEl);
|
|
if (ref.lockRef === null || this.undoRef !== void 0 && ref.isLockUndoneBy(this.undoRef)) {
|
|
return fromEl;
|
|
}
|
|
dom_default.applyStickyOperations(fromEl);
|
|
const clone2 = fromEl.hasAttribute(PHX_REF_LOCK) ? dom_default.private(fromEl, PHX_REF_LOCK) || fromEl.cloneNode(true) : null;
|
|
if (!clone2)
|
|
return fromEl;
|
|
dom_default.putPrivate(fromEl, PHX_REF_LOCK, clone2);
|
|
return isFocusedFormEl ? fromEl : clone2;
|
|
}
|
|
copyNestedPrivateLock(fromEl, toEl) {
|
|
if (this.undoRef === void 0 || !dom_default.private(toEl, PHX_REF_LOCK))
|
|
return;
|
|
dom_default.putPrivate(fromEl, PHX_REF_LOCK, dom_default.private(toEl, PHX_REF_LOCK));
|
|
}
|
|
targetCIDContainer(html) {
|
|
if (!this.isCIDPatch()) {
|
|
return;
|
|
}
|
|
const [first, ...rest] = dom_default.findComponentNodeList(
|
|
this.view.id,
|
|
this.targetCID
|
|
);
|
|
if (rest.length === 0 && dom_default.childNodeLength(html) === 1) {
|
|
return first;
|
|
} else {
|
|
return first && first.parentNode;
|
|
}
|
|
}
|
|
indexOf(parent, child) {
|
|
return Array.from(parent.children).indexOf(child);
|
|
}
|
|
teleport(el, morph) {
|
|
const targetSelector = el.getAttribute(PHX_PORTAL);
|
|
const portalContainer = document.querySelector(targetSelector);
|
|
if (!portalContainer) {
|
|
throw new Error(
|
|
"portal target with selector " + targetSelector + " not found"
|
|
);
|
|
}
|
|
const toTeleport = el.content.firstElementChild;
|
|
if (this.skipCIDSibling(toTeleport)) {
|
|
return;
|
|
}
|
|
if (!(toTeleport == null ? void 0 : toTeleport.id)) {
|
|
throw new Error(
|
|
"phx-portal template must have a single root element with ID!"
|
|
);
|
|
}
|
|
const existing = document.getElementById(toTeleport.id);
|
|
let portalTarget;
|
|
if (existing) {
|
|
if (!portalContainer.contains(existing)) {
|
|
portalContainer.appendChild(existing);
|
|
}
|
|
portalTarget = existing;
|
|
} else {
|
|
portalTarget = document.createElement(toTeleport.tagName);
|
|
portalContainer.appendChild(portalTarget);
|
|
}
|
|
toTeleport.setAttribute(PHX_TELEPORTED_REF, this.view.id);
|
|
toTeleport.setAttribute(PHX_TELEPORTED_SRC, el.id);
|
|
morph(portalTarget, toTeleport, true);
|
|
toTeleport.removeAttribute(PHX_TELEPORTED_REF);
|
|
toTeleport.removeAttribute(PHX_TELEPORTED_SRC);
|
|
this.view.pushPortalElementId(toTeleport.id);
|
|
}
|
|
handleRuntimeHook(el, source) {
|
|
const name = el.getAttribute(PHX_RUNTIME_HOOK);
|
|
let nonce = el.hasAttribute("nonce") ? el.getAttribute("nonce") : null;
|
|
if (el.hasAttribute("nonce")) {
|
|
const template = document.createElement("template");
|
|
template.innerHTML = source;
|
|
nonce = template.content.querySelector(`script[${PHX_RUNTIME_HOOK}="${CSS.escape(name)}"]`).getAttribute("nonce");
|
|
}
|
|
const script = document.createElement("script");
|
|
script.textContent = el.textContent;
|
|
dom_default.mergeAttrs(script, el, { isIgnored: false });
|
|
if (nonce) {
|
|
script.nonce = nonce;
|
|
}
|
|
el.replaceWith(script);
|
|
el = script;
|
|
}
|
|
};
|
|
var VOID_TAGS = /* @__PURE__ */ new Set([
|
|
"area",
|
|
"base",
|
|
"br",
|
|
"col",
|
|
"command",
|
|
"embed",
|
|
"hr",
|
|
"img",
|
|
"input",
|
|
"keygen",
|
|
"link",
|
|
"meta",
|
|
"param",
|
|
"source",
|
|
"track",
|
|
"wbr"
|
|
]);
|
|
var quoteChars = /* @__PURE__ */ new Set(["'", '"']);
|
|
var modifyRoot = (html, attrs, clearInnerHTML) => {
|
|
let i = 0;
|
|
let insideComment = false;
|
|
let beforeTag, afterTag, tag, tagNameEndsAt, id, newHTML;
|
|
const lookahead = html.match(/^(\s*(?:<!--.*?-->\s*)*)<([^\s\/>]+)/);
|
|
if (lookahead === null) {
|
|
throw new Error(`malformed html ${html}`);
|
|
}
|
|
i = lookahead[0].length;
|
|
beforeTag = lookahead[1];
|
|
tag = lookahead[2];
|
|
tagNameEndsAt = i;
|
|
for (i; i < html.length; i++) {
|
|
if (html.charAt(i) === ">") {
|
|
break;
|
|
}
|
|
if (html.charAt(i) === "=") {
|
|
const isId = html.slice(i - 3, i) === " id";
|
|
i++;
|
|
const char = html.charAt(i);
|
|
if (quoteChars.has(char)) {
|
|
const attrStartsAt = i;
|
|
i++;
|
|
for (i; i < html.length; i++) {
|
|
if (html.charAt(i) === char) {
|
|
break;
|
|
}
|
|
}
|
|
if (isId) {
|
|
id = html.slice(attrStartsAt + 1, i);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
let closeAt = html.length - 1;
|
|
insideComment = false;
|
|
while (closeAt >= beforeTag.length + tag.length) {
|
|
const char = html.charAt(closeAt);
|
|
if (insideComment) {
|
|
if (char === "-" && html.slice(closeAt - 3, closeAt) === "<!-") {
|
|
insideComment = false;
|
|
closeAt -= 4;
|
|
} else {
|
|
closeAt -= 1;
|
|
}
|
|
} else if (char === ">" && html.slice(closeAt - 2, closeAt) === "--") {
|
|
insideComment = true;
|
|
closeAt -= 3;
|
|
} else if (char === ">") {
|
|
break;
|
|
} else {
|
|
closeAt -= 1;
|
|
}
|
|
}
|
|
afterTag = html.slice(closeAt + 1, html.length);
|
|
const attrsStr = Object.keys(attrs).map((attr) => attrs[attr] === true ? attr : `${attr}="${attrs[attr]}"`).join(" ");
|
|
if (clearInnerHTML) {
|
|
const idAttrStr = id ? ` id="${id}"` : "";
|
|
if (VOID_TAGS.has(tag)) {
|
|
newHTML = `<${tag}${idAttrStr}${attrsStr === "" ? "" : " "}${attrsStr}/>`;
|
|
} else {
|
|
newHTML = `<${tag}${idAttrStr}${attrsStr === "" ? "" : " "}${attrsStr}></${tag}>`;
|
|
}
|
|
} else {
|
|
const rest = html.slice(tagNameEndsAt, closeAt + 1);
|
|
newHTML = `<${tag}${attrsStr === "" ? "" : " "}${attrsStr}${rest}`;
|
|
}
|
|
return [newHTML, beforeTag, afterTag];
|
|
};
|
|
var Rendered = class {
|
|
static extract(diff) {
|
|
const { [REPLY]: reply, [EVENTS]: events, [TITLE]: title } = diff;
|
|
delete diff[REPLY];
|
|
delete diff[EVENTS];
|
|
delete diff[TITLE];
|
|
return { diff, title, reply: reply || null, events: events || [] };
|
|
}
|
|
constructor(viewId, rendered) {
|
|
this.viewId = viewId;
|
|
this.rendered = {};
|
|
this.magicId = 0;
|
|
this.mergeDiff(rendered);
|
|
}
|
|
parentViewId() {
|
|
return this.viewId;
|
|
}
|
|
toString(onlyCids) {
|
|
const { buffer: str, streams } = this.recursiveToString(
|
|
this.rendered,
|
|
this.rendered[COMPONENTS],
|
|
onlyCids,
|
|
true,
|
|
{}
|
|
);
|
|
return { buffer: str, streams };
|
|
}
|
|
recursiveToString(rendered, components = rendered[COMPONENTS], onlyCids, changeTracking, rootAttrs) {
|
|
onlyCids = onlyCids ? new Set(onlyCids) : null;
|
|
const output = {
|
|
buffer: "",
|
|
components,
|
|
onlyCids,
|
|
streams: /* @__PURE__ */ new Set()
|
|
};
|
|
this.toOutputBuffer(rendered, null, output, changeTracking, rootAttrs);
|
|
return { buffer: output.buffer, streams: output.streams };
|
|
}
|
|
componentCIDs(diff) {
|
|
return Object.keys(diff[COMPONENTS] || {}).map((i) => parseInt(i));
|
|
}
|
|
isComponentOnlyDiff(diff) {
|
|
if (!diff[COMPONENTS]) {
|
|
return false;
|
|
}
|
|
return Object.keys(diff).length === 1;
|
|
}
|
|
getComponent(diff, cid) {
|
|
return diff[COMPONENTS][cid];
|
|
}
|
|
resetRender(cid) {
|
|
if (this.rendered[COMPONENTS][cid]) {
|
|
this.rendered[COMPONENTS][cid].reset = true;
|
|
}
|
|
}
|
|
mergeDiff(diff) {
|
|
const newc = diff[COMPONENTS];
|
|
const cache = {};
|
|
delete diff[COMPONENTS];
|
|
this.rendered = this.mutableMerge(this.rendered, diff);
|
|
this.rendered[COMPONENTS] = this.rendered[COMPONENTS] || {};
|
|
if (newc) {
|
|
const oldc = this.rendered[COMPONENTS];
|
|
for (const cid in newc) {
|
|
newc[cid] = this.cachedFindComponent(cid, newc[cid], oldc, newc, cache);
|
|
}
|
|
for (const cid in newc) {
|
|
oldc[cid] = newc[cid];
|
|
}
|
|
diff[COMPONENTS] = newc;
|
|
}
|
|
}
|
|
cachedFindComponent(cid, cdiff, oldc, newc, cache) {
|
|
if (cache[cid]) {
|
|
return cache[cid];
|
|
} else {
|
|
let ndiff, stat, scid = cdiff[STATIC];
|
|
if (isCid(scid)) {
|
|
let tdiff;
|
|
if (scid > 0) {
|
|
tdiff = this.cachedFindComponent(scid, newc[scid], oldc, newc, cache);
|
|
} else {
|
|
tdiff = oldc[-scid];
|
|
}
|
|
stat = tdiff[STATIC];
|
|
ndiff = this.cloneMerge(tdiff, cdiff, true);
|
|
ndiff[STATIC] = stat;
|
|
} else {
|
|
ndiff = cdiff[STATIC] !== void 0 || oldc[cid] === void 0 ? cdiff : this.cloneMerge(oldc[cid], cdiff, false);
|
|
}
|
|
cache[cid] = ndiff;
|
|
return ndiff;
|
|
}
|
|
}
|
|
mutableMerge(target, source) {
|
|
if (source[STATIC] !== void 0) {
|
|
return source;
|
|
} else {
|
|
this.doMutableMerge(target, source);
|
|
return target;
|
|
}
|
|
}
|
|
doMutableMerge(target, source) {
|
|
if (source[KEYED]) {
|
|
this.mergeKeyed(target, source);
|
|
} else {
|
|
for (const key in source) {
|
|
const val = source[key];
|
|
const targetVal = target[key];
|
|
const isObjVal = isObject(val);
|
|
if (isObjVal && val[STATIC] === void 0 && isObject(targetVal)) {
|
|
this.doMutableMerge(targetVal, val);
|
|
} else {
|
|
target[key] = val;
|
|
}
|
|
}
|
|
}
|
|
if (target[ROOT]) {
|
|
target.newRender = true;
|
|
}
|
|
}
|
|
clone(diff) {
|
|
if ("structuredClone" in window) {
|
|
return structuredClone(diff);
|
|
} else {
|
|
return JSON.parse(JSON.stringify(diff));
|
|
}
|
|
}
|
|
// keyed comprehensions
|
|
mergeKeyed(target, source) {
|
|
const clonedTarget = this.clone(target);
|
|
Object.entries(source[KEYED]).forEach(([i, entry]) => {
|
|
if (i === KEYED_COUNT) {
|
|
return;
|
|
}
|
|
if (Array.isArray(entry)) {
|
|
const [old_idx, diff] = entry;
|
|
target[KEYED][i] = clonedTarget[KEYED][old_idx];
|
|
this.doMutableMerge(target[KEYED][i], diff);
|
|
} else if (typeof entry === "number") {
|
|
const old_idx = entry;
|
|
target[KEYED][i] = clonedTarget[KEYED][old_idx];
|
|
} else if (typeof entry === "object") {
|
|
if (!target[KEYED][i]) {
|
|
target[KEYED][i] = {};
|
|
}
|
|
this.doMutableMerge(target[KEYED][i], entry);
|
|
}
|
|
});
|
|
if (source[KEYED][KEYED_COUNT] < target[KEYED][KEYED_COUNT]) {
|
|
for (let i = source[KEYED][KEYED_COUNT]; i < target[KEYED][KEYED_COUNT]; i++) {
|
|
delete target[KEYED][i];
|
|
}
|
|
}
|
|
target[KEYED][KEYED_COUNT] = source[KEYED][KEYED_COUNT];
|
|
if (source[STREAM]) {
|
|
target[STREAM] = source[STREAM];
|
|
}
|
|
if (source[TEMPLATES]) {
|
|
target[TEMPLATES] = source[TEMPLATES];
|
|
}
|
|
}
|
|
// Merges cid trees together, copying statics from source tree.
|
|
//
|
|
// The `pruneMagicId` is passed to control pruning the magicId of the
|
|
// target. We must always prune the magicId when we are sharing statics
|
|
// from another component. If not pruning, we replicate the logic from
|
|
// mutableMerge, where we set newRender to true if there is a root
|
|
// (effectively forcing the new version to be rendered instead of skipped)
|
|
//
|
|
cloneMerge(target, source, pruneMagicId) {
|
|
let merged;
|
|
if (source[KEYED]) {
|
|
merged = this.clone(target);
|
|
this.mergeKeyed(merged, source);
|
|
} else {
|
|
merged = __spreadValues(__spreadValues({}, target), source);
|
|
for (const key in merged) {
|
|
const val = source[key];
|
|
const targetVal = target[key];
|
|
if (isObject(val) && val[STATIC] === void 0 && isObject(targetVal)) {
|
|
merged[key] = this.cloneMerge(targetVal, val, pruneMagicId);
|
|
} else if (val === void 0 && isObject(targetVal)) {
|
|
merged[key] = this.cloneMerge(targetVal, {}, pruneMagicId);
|
|
}
|
|
}
|
|
}
|
|
if (pruneMagicId) {
|
|
delete merged.magicId;
|
|
delete merged.newRender;
|
|
} else if (target[ROOT]) {
|
|
merged.newRender = true;
|
|
}
|
|
return merged;
|
|
}
|
|
componentToString(cid) {
|
|
const { buffer: str, streams } = this.recursiveCIDToString(
|
|
this.rendered[COMPONENTS],
|
|
cid,
|
|
null
|
|
);
|
|
const [strippedHTML, _before, _after] = modifyRoot(str, {});
|
|
return { buffer: strippedHTML, streams };
|
|
}
|
|
pruneCIDs(cids) {
|
|
cids.forEach((cid) => delete this.rendered[COMPONENTS][cid]);
|
|
}
|
|
// private
|
|
get() {
|
|
return this.rendered;
|
|
}
|
|
isNewFingerprint(diff = {}) {
|
|
return !!diff[STATIC];
|
|
}
|
|
templateStatic(part, templates) {
|
|
if (typeof part === "number") {
|
|
return templates[part];
|
|
} else {
|
|
return part;
|
|
}
|
|
}
|
|
nextMagicID() {
|
|
this.magicId++;
|
|
return `m${this.magicId}-${this.parentViewId()}`;
|
|
}
|
|
// Converts rendered tree to output buffer.
|
|
//
|
|
// changeTracking controls if we can apply the PHX_SKIP optimization.
|
|
toOutputBuffer(rendered, templates, output, changeTracking, rootAttrs = {}) {
|
|
if (rendered[KEYED]) {
|
|
return this.comprehensionToBuffer(
|
|
rendered,
|
|
templates,
|
|
output,
|
|
changeTracking
|
|
);
|
|
}
|
|
if (rendered[TEMPLATES]) {
|
|
templates = rendered[TEMPLATES];
|
|
delete rendered[TEMPLATES];
|
|
}
|
|
let { [STATIC]: statics } = rendered;
|
|
statics = this.templateStatic(statics, templates);
|
|
rendered[STATIC] = statics;
|
|
const isRoot = rendered[ROOT];
|
|
const prevBuffer = output.buffer;
|
|
if (isRoot) {
|
|
output.buffer = "";
|
|
}
|
|
if (changeTracking && isRoot && !rendered.magicId) {
|
|
rendered.newRender = true;
|
|
rendered.magicId = this.nextMagicID();
|
|
}
|
|
output.buffer += statics[0];
|
|
for (let i = 1; i < statics.length; i++) {
|
|
this.dynamicToBuffer(rendered[i - 1], templates, output, changeTracking);
|
|
output.buffer += statics[i];
|
|
}
|
|
if (isRoot) {
|
|
let skip = false;
|
|
let attrs;
|
|
if (changeTracking || rendered.magicId) {
|
|
skip = changeTracking && !rendered.newRender;
|
|
attrs = __spreadValues({ [PHX_MAGIC_ID]: rendered.magicId }, rootAttrs);
|
|
} else {
|
|
attrs = rootAttrs;
|
|
}
|
|
if (skip) {
|
|
attrs[PHX_SKIP] = true;
|
|
}
|
|
const [newRoot, commentBefore, commentAfter] = modifyRoot(
|
|
output.buffer,
|
|
attrs,
|
|
skip
|
|
);
|
|
rendered.newRender = false;
|
|
output.buffer = prevBuffer + commentBefore + newRoot + commentAfter;
|
|
}
|
|
}
|
|
comprehensionToBuffer(rendered, templates, output, changeTracking) {
|
|
const keyedTemplates = templates || rendered[TEMPLATES];
|
|
const statics = this.templateStatic(rendered[STATIC], templates);
|
|
rendered[STATIC] = statics;
|
|
delete rendered[TEMPLATES];
|
|
for (let i = 0; i < rendered[KEYED][KEYED_COUNT]; i++) {
|
|
output.buffer += statics[0];
|
|
for (let j = 1; j < statics.length; j++) {
|
|
this.dynamicToBuffer(
|
|
rendered[KEYED][i][j - 1],
|
|
keyedTemplates,
|
|
output,
|
|
changeTracking
|
|
);
|
|
output.buffer += statics[j];
|
|
}
|
|
}
|
|
if (rendered[STREAM]) {
|
|
const stream = rendered[STREAM];
|
|
const [_ref, _inserts, deleteIds, reset] = stream || [null, {}, [], null];
|
|
if (stream !== void 0 && (rendered[KEYED][KEYED_COUNT] > 0 || deleteIds.length > 0 || reset)) {
|
|
delete rendered[STREAM];
|
|
rendered[KEYED] = {
|
|
[KEYED_COUNT]: 0
|
|
};
|
|
output.streams.add(stream);
|
|
}
|
|
}
|
|
}
|
|
dynamicToBuffer(rendered, templates, output, changeTracking) {
|
|
if (typeof rendered === "number") {
|
|
const { buffer: str, streams } = this.recursiveCIDToString(
|
|
output.components,
|
|
rendered,
|
|
output.onlyCids
|
|
);
|
|
output.buffer += str;
|
|
output.streams = /* @__PURE__ */ new Set([...output.streams, ...streams]);
|
|
} else if (isObject(rendered)) {
|
|
this.toOutputBuffer(rendered, templates, output, changeTracking, {});
|
|
} else {
|
|
output.buffer += rendered;
|
|
}
|
|
}
|
|
recursiveCIDToString(components, cid, onlyCids) {
|
|
const component = components[cid] || logError(`no component for CID ${cid}`, components);
|
|
const attrs = { [PHX_COMPONENT]: cid, [PHX_VIEW_REF]: this.viewId };
|
|
const skip = onlyCids && !onlyCids.has(cid);
|
|
component.newRender = !skip;
|
|
component.magicId = `c${cid}-${this.parentViewId()}`;
|
|
const changeTracking = !component.reset;
|
|
const { buffer: html, streams } = this.recursiveToString(
|
|
component,
|
|
components,
|
|
onlyCids,
|
|
changeTracking,
|
|
attrs
|
|
);
|
|
delete component.reset;
|
|
return { buffer: html, streams };
|
|
}
|
|
};
|
|
var focusStack = [];
|
|
var default_transition_time = 200;
|
|
var JS = {
|
|
// private
|
|
exec(e, eventType, phxEvent, view, sourceEl, defaults) {
|
|
const [defaultKind, defaultArgs] = defaults || [
|
|
null,
|
|
{ callback: defaults && defaults.callback }
|
|
];
|
|
const commands = phxEvent.charAt(0) === "[" ? JSON.parse(phxEvent) : [[defaultKind, defaultArgs]];
|
|
commands.forEach(([kind, args]) => {
|
|
if (kind === defaultKind) {
|
|
args = __spreadValues(__spreadValues({}, defaultArgs), args);
|
|
args.callback = args.callback || defaultArgs.callback;
|
|
}
|
|
this.filterToEls(view.liveSocket, sourceEl, args).forEach((el) => {
|
|
this[`exec_${kind}`](e, eventType, phxEvent, view, sourceEl, el, args);
|
|
});
|
|
});
|
|
},
|
|
isVisible(el) {
|
|
return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length > 0);
|
|
},
|
|
// returns true if any part of the element is inside the viewport
|
|
isInViewport(el) {
|
|
const rect = el.getBoundingClientRect();
|
|
const windowHeight = window.innerHeight || document.documentElement.clientHeight;
|
|
const windowWidth = window.innerWidth || document.documentElement.clientWidth;
|
|
return rect.right > 0 && rect.bottom > 0 && rect.left < windowWidth && rect.top < windowHeight;
|
|
},
|
|
// private
|
|
// commands
|
|
exec_exec(e, eventType, phxEvent, view, sourceEl, el, { attr, to }) {
|
|
const encodedJS = el.getAttribute(attr);
|
|
if (!encodedJS) {
|
|
throw new Error(`expected ${attr} to contain JS command on "${to}"`);
|
|
}
|
|
view.liveSocket.execJS(el, encodedJS, eventType);
|
|
},
|
|
exec_dispatch(e, eventType, phxEvent, view, sourceEl, el, { event, detail, bubbles, blocking }) {
|
|
detail = detail || {};
|
|
detail.dispatcher = sourceEl;
|
|
if (blocking) {
|
|
const promise = new Promise((resolve, _reject) => {
|
|
detail.done = resolve;
|
|
});
|
|
view.liveSocket.asyncTransition(promise);
|
|
}
|
|
dom_default.dispatchEvent(el, event, { detail, bubbles });
|
|
},
|
|
exec_push(e, eventType, phxEvent, view, sourceEl, el, args) {
|
|
const {
|
|
event,
|
|
data,
|
|
target,
|
|
page_loading,
|
|
loading,
|
|
value,
|
|
dispatcher,
|
|
callback
|
|
} = args;
|
|
const pushOpts = {
|
|
loading,
|
|
value,
|
|
target,
|
|
page_loading: !!page_loading,
|
|
originalEvent: e
|
|
};
|
|
const targetSrc = eventType === "change" && dispatcher ? dispatcher : sourceEl;
|
|
const phxTarget = target || targetSrc.getAttribute(view.binding("target")) || targetSrc;
|
|
const handler = (targetView, targetCtx) => {
|
|
if (!targetView.isConnected()) {
|
|
return;
|
|
}
|
|
if (eventType === "change") {
|
|
let { newCid, _target } = args;
|
|
_target = _target || (dom_default.isFormInput(sourceEl) ? sourceEl.name : void 0);
|
|
if (_target) {
|
|
pushOpts._target = _target;
|
|
}
|
|
targetView.pushInput(
|
|
sourceEl,
|
|
targetCtx,
|
|
newCid,
|
|
event || phxEvent,
|
|
pushOpts,
|
|
callback
|
|
);
|
|
} else if (eventType === "submit") {
|
|
const { submitter } = args;
|
|
targetView.submitForm(
|
|
sourceEl,
|
|
targetCtx,
|
|
event || phxEvent,
|
|
submitter,
|
|
pushOpts,
|
|
callback
|
|
);
|
|
} else {
|
|
targetView.pushEvent(
|
|
eventType,
|
|
sourceEl,
|
|
targetCtx,
|
|
event || phxEvent,
|
|
data,
|
|
pushOpts,
|
|
callback
|
|
);
|
|
}
|
|
};
|
|
if (args.targetView && args.targetCtx) {
|
|
handler(args.targetView, args.targetCtx);
|
|
} else {
|
|
view.withinTargets(phxTarget, handler);
|
|
}
|
|
},
|
|
exec_navigate(e, eventType, phxEvent, view, sourceEl, el, { href, replace }) {
|
|
view.liveSocket.historyRedirect(
|
|
e,
|
|
href,
|
|
replace ? "replace" : "push",
|
|
null,
|
|
sourceEl
|
|
);
|
|
},
|
|
exec_patch(e, eventType, phxEvent, view, sourceEl, el, { href, replace }) {
|
|
view.liveSocket.pushHistoryPatch(
|
|
e,
|
|
href,
|
|
replace ? "replace" : "push",
|
|
sourceEl
|
|
);
|
|
},
|
|
exec_focus(e, eventType, phxEvent, view, sourceEl, el) {
|
|
aria_default.attemptFocus(el);
|
|
window.requestAnimationFrame(() => {
|
|
window.requestAnimationFrame(() => aria_default.attemptFocus(el));
|
|
});
|
|
},
|
|
exec_focus_first(e, eventType, phxEvent, view, sourceEl, el) {
|
|
aria_default.focusFirstInteractive(el) || aria_default.focusFirst(el);
|
|
window.requestAnimationFrame(() => {
|
|
window.requestAnimationFrame(
|
|
() => aria_default.focusFirstInteractive(el) || aria_default.focusFirst(el)
|
|
);
|
|
});
|
|
},
|
|
exec_push_focus(e, eventType, phxEvent, view, sourceEl, el) {
|
|
focusStack.push(el || sourceEl);
|
|
},
|
|
exec_pop_focus(_e, _eventType, _phxEvent, _view, _sourceEl, _el) {
|
|
const el = focusStack.pop();
|
|
if (el) {
|
|
el.focus();
|
|
window.requestAnimationFrame(() => {
|
|
window.requestAnimationFrame(() => el.focus());
|
|
});
|
|
}
|
|
},
|
|
exec_add_class(e, eventType, phxEvent, view, sourceEl, el, { names, transition, time, blocking }) {
|
|
this.addOrRemoveClasses(el, names, [], transition, time, view, blocking);
|
|
},
|
|
exec_remove_class(e, eventType, phxEvent, view, sourceEl, el, { names, transition, time, blocking }) {
|
|
this.addOrRemoveClasses(el, [], names, transition, time, view, blocking);
|
|
},
|
|
exec_toggle_class(e, eventType, phxEvent, view, sourceEl, el, { names, transition, time, blocking }) {
|
|
this.toggleClasses(el, names, transition, time, view, blocking);
|
|
},
|
|
exec_toggle_attr(e, eventType, phxEvent, view, sourceEl, el, { attr: [attr, val1, val2] }) {
|
|
this.toggleAttr(el, attr, val1, val2);
|
|
},
|
|
exec_ignore_attrs(e, eventType, phxEvent, view, sourceEl, el, { attrs }) {
|
|
this.ignoreAttrs(el, attrs);
|
|
},
|
|
exec_transition(e, eventType, phxEvent, view, sourceEl, el, { time, transition, blocking }) {
|
|
this.addOrRemoveClasses(el, [], [], transition, time, view, blocking);
|
|
},
|
|
exec_toggle(e, eventType, phxEvent, view, sourceEl, el, { display, ins, outs, time, blocking }) {
|
|
this.toggle(eventType, view, el, display, ins, outs, time, blocking);
|
|
},
|
|
exec_show(e, eventType, phxEvent, view, sourceEl, el, { display, transition, time, blocking }) {
|
|
this.show(eventType, view, el, display, transition, time, blocking);
|
|
},
|
|
exec_hide(e, eventType, phxEvent, view, sourceEl, el, { display, transition, time, blocking }) {
|
|
this.hide(eventType, view, el, display, transition, time, blocking);
|
|
},
|
|
exec_set_attr(e, eventType, phxEvent, view, sourceEl, el, { attr: [attr, val] }) {
|
|
this.setOrRemoveAttrs(el, [[attr, val]], []);
|
|
},
|
|
exec_remove_attr(e, eventType, phxEvent, view, sourceEl, el, { attr }) {
|
|
this.setOrRemoveAttrs(el, [], [attr]);
|
|
},
|
|
ignoreAttrs(el, attrs) {
|
|
dom_default.putPrivate(el, "JS:ignore_attrs", {
|
|
apply: (fromEl, toEl) => {
|
|
let fromAttributes = Array.from(fromEl.attributes);
|
|
let fromAttributeNames = fromAttributes.map((attr) => attr.name);
|
|
Array.from(toEl.attributes).filter((attr) => {
|
|
return !fromAttributeNames.includes(attr.name);
|
|
}).forEach((attr) => {
|
|
if (dom_default.attributeIgnored(attr, attrs)) {
|
|
toEl.removeAttribute(attr.name);
|
|
}
|
|
});
|
|
fromAttributes.forEach((attr) => {
|
|
if (dom_default.attributeIgnored(attr, attrs)) {
|
|
toEl.setAttribute(attr.name, attr.value);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
},
|
|
onBeforeElUpdated(fromEl, toEl) {
|
|
const ignoreAttrs = dom_default.private(fromEl, "JS:ignore_attrs");
|
|
if (ignoreAttrs) {
|
|
ignoreAttrs.apply(fromEl, toEl);
|
|
}
|
|
},
|
|
// utils for commands
|
|
show(eventType, view, el, display, transition, time, blocking) {
|
|
if (!this.isVisible(el)) {
|
|
this.toggle(
|
|
eventType,
|
|
view,
|
|
el,
|
|
display,
|
|
transition,
|
|
null,
|
|
time,
|
|
blocking
|
|
);
|
|
}
|
|
},
|
|
hide(eventType, view, el, display, transition, time, blocking) {
|
|
if (this.isVisible(el)) {
|
|
this.toggle(
|
|
eventType,
|
|
view,
|
|
el,
|
|
display,
|
|
null,
|
|
transition,
|
|
time,
|
|
blocking
|
|
);
|
|
}
|
|
},
|
|
toggle(eventType, view, el, display, ins, outs, time, blocking) {
|
|
time = time || default_transition_time;
|
|
const [inClasses, inStartClasses, inEndClasses] = ins || [[], [], []];
|
|
const [outClasses, outStartClasses, outEndClasses] = outs || [[], [], []];
|
|
if (inClasses.length > 0 || outClasses.length > 0) {
|
|
if (this.isVisible(el)) {
|
|
const onStart = () => {
|
|
this.addOrRemoveClasses(
|
|
el,
|
|
outStartClasses,
|
|
inClasses.concat(inStartClasses).concat(inEndClasses)
|
|
);
|
|
window.requestAnimationFrame(() => {
|
|
this.addOrRemoveClasses(el, outClasses, []);
|
|
window.requestAnimationFrame(
|
|
() => this.addOrRemoveClasses(el, outEndClasses, outStartClasses)
|
|
);
|
|
});
|
|
};
|
|
const onEnd = () => {
|
|
this.addOrRemoveClasses(el, [], outClasses.concat(outEndClasses));
|
|
dom_default.putSticky(
|
|
el,
|
|
"toggle",
|
|
(currentEl) => currentEl.style.display = "none"
|
|
);
|
|
el.dispatchEvent(new Event("phx:hide-end"));
|
|
};
|
|
el.dispatchEvent(new Event("phx:hide-start"));
|
|
if (blocking === false) {
|
|
onStart();
|
|
setTimeout(onEnd, time);
|
|
} else {
|
|
view.transition(time, onStart, onEnd);
|
|
}
|
|
} else {
|
|
if (eventType === "remove") {
|
|
return;
|
|
}
|
|
const onStart = () => {
|
|
this.addOrRemoveClasses(
|
|
el,
|
|
inStartClasses,
|
|
outClasses.concat(outStartClasses).concat(outEndClasses)
|
|
);
|
|
const stickyDisplay = display || this.defaultDisplay(el);
|
|
window.requestAnimationFrame(() => {
|
|
this.addOrRemoveClasses(el, inClasses, []);
|
|
window.requestAnimationFrame(() => {
|
|
dom_default.putSticky(
|
|
el,
|
|
"toggle",
|
|
(currentEl) => currentEl.style.display = stickyDisplay
|
|
);
|
|
this.addOrRemoveClasses(el, inEndClasses, inStartClasses);
|
|
});
|
|
});
|
|
};
|
|
const onEnd = () => {
|
|
this.addOrRemoveClasses(el, [], inClasses.concat(inEndClasses));
|
|
el.dispatchEvent(new Event("phx:show-end"));
|
|
};
|
|
el.dispatchEvent(new Event("phx:show-start"));
|
|
if (blocking === false) {
|
|
onStart();
|
|
setTimeout(onEnd, time);
|
|
} else {
|
|
view.transition(time, onStart, onEnd);
|
|
}
|
|
}
|
|
} else {
|
|
if (this.isVisible(el)) {
|
|
window.requestAnimationFrame(() => {
|
|
el.dispatchEvent(new Event("phx:hide-start"));
|
|
dom_default.putSticky(
|
|
el,
|
|
"toggle",
|
|
(currentEl) => currentEl.style.display = "none"
|
|
);
|
|
el.dispatchEvent(new Event("phx:hide-end"));
|
|
});
|
|
} else {
|
|
window.requestAnimationFrame(() => {
|
|
el.dispatchEvent(new Event("phx:show-start"));
|
|
const stickyDisplay = display || this.defaultDisplay(el);
|
|
dom_default.putSticky(
|
|
el,
|
|
"toggle",
|
|
(currentEl) => currentEl.style.display = stickyDisplay
|
|
);
|
|
el.dispatchEvent(new Event("phx:show-end"));
|
|
});
|
|
}
|
|
}
|
|
},
|
|
toggleClasses(el, classes, transition, time, view, blocking) {
|
|
window.requestAnimationFrame(() => {
|
|
const [prevAdds, prevRemoves] = dom_default.getSticky(el, "classes", [[], []]);
|
|
const newAdds = classes.filter(
|
|
(name) => prevAdds.indexOf(name) < 0 && !el.classList.contains(name)
|
|
);
|
|
const newRemoves = classes.filter(
|
|
(name) => prevRemoves.indexOf(name) < 0 && el.classList.contains(name)
|
|
);
|
|
this.addOrRemoveClasses(
|
|
el,
|
|
newAdds,
|
|
newRemoves,
|
|
transition,
|
|
time,
|
|
view,
|
|
blocking
|
|
);
|
|
});
|
|
},
|
|
toggleAttr(el, attr, val1, val2) {
|
|
if (el.hasAttribute(attr)) {
|
|
if (val2 !== void 0) {
|
|
if (el.getAttribute(attr) === val1) {
|
|
this.setOrRemoveAttrs(el, [[attr, val2]], []);
|
|
} else {
|
|
this.setOrRemoveAttrs(el, [[attr, val1]], []);
|
|
}
|
|
} else {
|
|
this.setOrRemoveAttrs(el, [], [attr]);
|
|
}
|
|
} else {
|
|
this.setOrRemoveAttrs(el, [[attr, val1]], []);
|
|
}
|
|
},
|
|
addOrRemoveClasses(el, adds, removes, transition, time, view, blocking) {
|
|
time = time || default_transition_time;
|
|
const [transitionRun, transitionStart, transitionEnd] = transition || [
|
|
[],
|
|
[],
|
|
[]
|
|
];
|
|
if (transitionRun.length > 0) {
|
|
const onStart = () => {
|
|
this.addOrRemoveClasses(
|
|
el,
|
|
transitionStart,
|
|
[].concat(transitionRun).concat(transitionEnd)
|
|
);
|
|
window.requestAnimationFrame(() => {
|
|
this.addOrRemoveClasses(el, transitionRun, []);
|
|
window.requestAnimationFrame(
|
|
() => this.addOrRemoveClasses(el, transitionEnd, transitionStart)
|
|
);
|
|
});
|
|
};
|
|
const onDone = () => this.addOrRemoveClasses(
|
|
el,
|
|
adds.concat(transitionEnd),
|
|
removes.concat(transitionRun).concat(transitionStart)
|
|
);
|
|
if (blocking === false) {
|
|
onStart();
|
|
setTimeout(onDone, time);
|
|
} else {
|
|
view.transition(time, onStart, onDone);
|
|
}
|
|
return;
|
|
}
|
|
window.requestAnimationFrame(() => {
|
|
const [prevAdds, prevRemoves] = dom_default.getSticky(el, "classes", [[], []]);
|
|
const keepAdds = adds.filter(
|
|
(name) => prevAdds.indexOf(name) < 0 && !el.classList.contains(name)
|
|
);
|
|
const keepRemoves = removes.filter(
|
|
(name) => prevRemoves.indexOf(name) < 0 && el.classList.contains(name)
|
|
);
|
|
const newAdds = prevAdds.filter((name) => removes.indexOf(name) < 0).concat(keepAdds);
|
|
const newRemoves = prevRemoves.filter((name) => adds.indexOf(name) < 0).concat(keepRemoves);
|
|
dom_default.putSticky(el, "classes", (currentEl) => {
|
|
currentEl.classList.remove(...newRemoves);
|
|
currentEl.classList.add(...newAdds);
|
|
return [newAdds, newRemoves];
|
|
});
|
|
});
|
|
},
|
|
setOrRemoveAttrs(el, sets, removes) {
|
|
const [prevSets, prevRemoves] = dom_default.getSticky(el, "attrs", [[], []]);
|
|
const alteredAttrs = sets.map(([attr, _val]) => attr).concat(removes);
|
|
const newSets = prevSets.filter(([attr, _val]) => !alteredAttrs.includes(attr)).concat(sets);
|
|
const newRemoves = prevRemoves.filter((attr) => !alteredAttrs.includes(attr)).concat(removes);
|
|
if (sets.some(([attr, _val]) => attr === "id")) {
|
|
dom_default.putPrivate(el, "clientsideIdAttribute", true);
|
|
}
|
|
dom_default.putSticky(el, "attrs", (currentEl) => {
|
|
newRemoves.forEach((attr) => currentEl.removeAttribute(attr));
|
|
newSets.forEach(([attr, val]) => currentEl.setAttribute(attr, val));
|
|
return [newSets, newRemoves];
|
|
});
|
|
},
|
|
hasAllClasses(el, classes) {
|
|
return classes.every((name) => el.classList.contains(name));
|
|
},
|
|
isToggledOut(el, outClasses) {
|
|
return !this.isVisible(el) || this.hasAllClasses(el, outClasses);
|
|
},
|
|
filterToEls(liveSocket2, sourceEl, { to }) {
|
|
const defaultQuery = () => {
|
|
if (typeof to === "string") {
|
|
return document.querySelectorAll(to);
|
|
} else if (to.closest) {
|
|
const toEl = sourceEl.closest(to.closest);
|
|
return toEl ? [toEl] : [];
|
|
} else if (to.inner) {
|
|
return sourceEl.querySelectorAll(to.inner);
|
|
}
|
|
};
|
|
return to ? liveSocket2.jsQuerySelectorAll(sourceEl, to, defaultQuery) : [sourceEl];
|
|
},
|
|
defaultDisplay(el) {
|
|
return { tr: "table-row", td: "table-cell" }[el.tagName.toLowerCase()] || "block";
|
|
},
|
|
transitionClasses(val) {
|
|
if (!val) {
|
|
return null;
|
|
}
|
|
let [trans, tStart, tEnd] = Array.isArray(val) ? val : [val.split(" "), [], []];
|
|
trans = Array.isArray(trans) ? trans : trans.split(" ");
|
|
tStart = Array.isArray(tStart) ? tStart : tStart.split(" ");
|
|
tEnd = Array.isArray(tEnd) ? tEnd : tEnd.split(" ");
|
|
return [trans, tStart, tEnd];
|
|
}
|
|
};
|
|
var js_default = JS;
|
|
var js_commands_default = (liveSocket2, eventType) => {
|
|
return {
|
|
exec(el, encodedJS) {
|
|
liveSocket2.execJS(el, encodedJS, eventType);
|
|
},
|
|
show(el, opts = {}) {
|
|
const owner = liveSocket2.owner(el);
|
|
js_default.show(
|
|
eventType,
|
|
owner,
|
|
el,
|
|
opts.display,
|
|
js_default.transitionClasses(opts.transition),
|
|
opts.time,
|
|
opts.blocking
|
|
);
|
|
},
|
|
hide(el, opts = {}) {
|
|
const owner = liveSocket2.owner(el);
|
|
js_default.hide(
|
|
eventType,
|
|
owner,
|
|
el,
|
|
null,
|
|
js_default.transitionClasses(opts.transition),
|
|
opts.time,
|
|
opts.blocking
|
|
);
|
|
},
|
|
toggle(el, opts = {}) {
|
|
const owner = liveSocket2.owner(el);
|
|
const inTransition = js_default.transitionClasses(opts.in);
|
|
const outTransition = js_default.transitionClasses(opts.out);
|
|
js_default.toggle(
|
|
eventType,
|
|
owner,
|
|
el,
|
|
opts.display,
|
|
inTransition,
|
|
outTransition,
|
|
opts.time,
|
|
opts.blocking
|
|
);
|
|
},
|
|
addClass(el, names, opts = {}) {
|
|
const classNames = Array.isArray(names) ? names : names.split(" ");
|
|
const owner = liveSocket2.owner(el);
|
|
js_default.addOrRemoveClasses(
|
|
el,
|
|
classNames,
|
|
[],
|
|
js_default.transitionClasses(opts.transition),
|
|
opts.time,
|
|
owner,
|
|
opts.blocking
|
|
);
|
|
},
|
|
removeClass(el, names, opts = {}) {
|
|
const classNames = Array.isArray(names) ? names : names.split(" ");
|
|
const owner = liveSocket2.owner(el);
|
|
js_default.addOrRemoveClasses(
|
|
el,
|
|
[],
|
|
classNames,
|
|
js_default.transitionClasses(opts.transition),
|
|
opts.time,
|
|
owner,
|
|
opts.blocking
|
|
);
|
|
},
|
|
toggleClass(el, names, opts = {}) {
|
|
const classNames = Array.isArray(names) ? names : names.split(" ");
|
|
const owner = liveSocket2.owner(el);
|
|
js_default.toggleClasses(
|
|
el,
|
|
classNames,
|
|
js_default.transitionClasses(opts.transition),
|
|
opts.time,
|
|
owner,
|
|
opts.blocking
|
|
);
|
|
},
|
|
transition(el, transition, opts = {}) {
|
|
const owner = liveSocket2.owner(el);
|
|
js_default.addOrRemoveClasses(
|
|
el,
|
|
[],
|
|
[],
|
|
js_default.transitionClasses(transition),
|
|
opts.time,
|
|
owner,
|
|
opts.blocking
|
|
);
|
|
},
|
|
setAttribute(el, attr, val) {
|
|
js_default.setOrRemoveAttrs(el, [[attr, val]], []);
|
|
},
|
|
removeAttribute(el, attr) {
|
|
js_default.setOrRemoveAttrs(el, [], [attr]);
|
|
},
|
|
toggleAttribute(el, attr, val1, val2) {
|
|
js_default.toggleAttr(el, attr, val1, val2);
|
|
},
|
|
push(el, type, opts = {}) {
|
|
liveSocket2.withinOwners(el, (view) => {
|
|
const data = opts.value || {};
|
|
delete opts.value;
|
|
let e = new CustomEvent("phx:exec", { detail: { sourceElement: el } });
|
|
js_default.exec(e, eventType, type, view, el, ["push", __spreadValues({ data }, opts)]);
|
|
});
|
|
},
|
|
navigate(href, opts = {}) {
|
|
const customEvent = new CustomEvent("phx:exec");
|
|
liveSocket2.historyRedirect(
|
|
customEvent,
|
|
href,
|
|
opts.replace ? "replace" : "push",
|
|
null,
|
|
null
|
|
);
|
|
},
|
|
patch(href, opts = {}) {
|
|
const customEvent = new CustomEvent("phx:exec");
|
|
liveSocket2.pushHistoryPatch(
|
|
customEvent,
|
|
href,
|
|
opts.replace ? "replace" : "push",
|
|
null
|
|
);
|
|
},
|
|
ignoreAttributes(el, attrs) {
|
|
js_default.ignoreAttrs(el, Array.isArray(attrs) ? attrs : [attrs]);
|
|
}
|
|
};
|
|
};
|
|
var HOOK_ID = "hookId";
|
|
var DEAD_HOOK = "deadHook";
|
|
var viewHookID = 1;
|
|
var ViewHook = class _ViewHook {
|
|
get liveSocket() {
|
|
return this.__liveSocket();
|
|
}
|
|
static makeID() {
|
|
return viewHookID++;
|
|
}
|
|
static elementID(el) {
|
|
return dom_default.private(el, HOOK_ID);
|
|
}
|
|
static deadHook(el) {
|
|
return dom_default.private(el, DEAD_HOOK) === true;
|
|
}
|
|
constructor(view, el, callbacks) {
|
|
this.el = el;
|
|
this.__attachView(view);
|
|
this.__listeners = /* @__PURE__ */ new Set();
|
|
this.__isDisconnected = false;
|
|
dom_default.putPrivate(this.el, HOOK_ID, _ViewHook.makeID());
|
|
if (view && view.isDead) {
|
|
dom_default.putPrivate(this.el, DEAD_HOOK, true);
|
|
}
|
|
if (callbacks) {
|
|
const protectedProps = /* @__PURE__ */ new Set([
|
|
"el",
|
|
"liveSocket",
|
|
"__view",
|
|
"__listeners",
|
|
"__isDisconnected",
|
|
"constructor",
|
|
// Standard object properties
|
|
// Core ViewHook API methods
|
|
"js",
|
|
"pushEvent",
|
|
"pushEventTo",
|
|
"handleEvent",
|
|
"removeHandleEvent",
|
|
"upload",
|
|
"uploadTo",
|
|
// Internal lifecycle callers
|
|
"__mounted",
|
|
"__updated",
|
|
"__beforeUpdate",
|
|
"__destroyed",
|
|
"__reconnected",
|
|
"__disconnected",
|
|
"__cleanup__"
|
|
]);
|
|
for (const key in callbacks) {
|
|
if (Object.prototype.hasOwnProperty.call(callbacks, key)) {
|
|
this[key] = callbacks[key];
|
|
if (protectedProps.has(key)) {
|
|
console.warn(
|
|
`Hook object for element #${el.id} overwrites core property '${key}'!`
|
|
);
|
|
}
|
|
}
|
|
}
|
|
const lifecycleMethods = [
|
|
"mounted",
|
|
"beforeUpdate",
|
|
"updated",
|
|
"destroyed",
|
|
"disconnected",
|
|
"reconnected"
|
|
];
|
|
lifecycleMethods.forEach((methodName) => {
|
|
if (callbacks[methodName] && typeof callbacks[methodName] === "function") {
|
|
this[methodName] = callbacks[methodName];
|
|
}
|
|
});
|
|
}
|
|
}
|
|
/** @internal */
|
|
__attachView(view) {
|
|
if (view) {
|
|
this.__view = () => view;
|
|
this.__liveSocket = () => view.liveSocket;
|
|
} else {
|
|
this.__view = () => {
|
|
throw new Error(
|
|
`hook not yet attached to a live view: ${this.el.outerHTML}`
|
|
);
|
|
};
|
|
this.__liveSocket = () => {
|
|
throw new Error(
|
|
`hook not yet attached to a live view: ${this.el.outerHTML}`
|
|
);
|
|
};
|
|
}
|
|
}
|
|
// Default lifecycle methods
|
|
mounted() {
|
|
}
|
|
beforeUpdate() {
|
|
}
|
|
updated() {
|
|
}
|
|
destroyed() {
|
|
}
|
|
disconnected() {
|
|
}
|
|
reconnected() {
|
|
}
|
|
// Internal lifecycle callers - called by the View
|
|
/** @internal */
|
|
__mounted() {
|
|
this.mounted();
|
|
}
|
|
/** @internal */
|
|
__updated() {
|
|
this.updated();
|
|
}
|
|
/** @internal */
|
|
__beforeUpdate() {
|
|
this.beforeUpdate();
|
|
}
|
|
/** @internal */
|
|
__destroyed() {
|
|
this.destroyed();
|
|
dom_default.deletePrivate(this.el, HOOK_ID);
|
|
}
|
|
/** @internal */
|
|
__reconnected() {
|
|
if (this.__isDisconnected) {
|
|
this.__isDisconnected = false;
|
|
this.reconnected();
|
|
}
|
|
}
|
|
/** @internal */
|
|
__disconnected() {
|
|
this.__isDisconnected = true;
|
|
this.disconnected();
|
|
}
|
|
js() {
|
|
return __spreadProps(__spreadValues({}, js_commands_default(this.__view().liveSocket, "hook")), {
|
|
exec: (encodedJS) => {
|
|
this.__view().liveSocket.execJS(this.el, encodedJS, "hook");
|
|
}
|
|
});
|
|
}
|
|
pushEvent(event, payload, onReply) {
|
|
const promise = this.__view().pushHookEvent(
|
|
this.el,
|
|
null,
|
|
event,
|
|
payload || {}
|
|
);
|
|
if (onReply === void 0) {
|
|
return promise.then(({ reply }) => reply);
|
|
}
|
|
promise.then(
|
|
({ reply, ref }) => onReply(reply, ref)
|
|
).catch(() => {
|
|
});
|
|
}
|
|
pushEventTo(selectorOrTarget, event, payload, onReply) {
|
|
if (onReply === void 0) {
|
|
const targetPair = [];
|
|
this.__view().withinTargets(
|
|
selectorOrTarget,
|
|
(view, targetCtx) => {
|
|
targetPair.push({ view, targetCtx });
|
|
}
|
|
);
|
|
const promises = targetPair.map(({ view, targetCtx }) => {
|
|
return view.pushHookEvent(this.el, targetCtx, event, payload || {});
|
|
});
|
|
return Promise.allSettled(promises);
|
|
}
|
|
this.__view().withinTargets(
|
|
selectorOrTarget,
|
|
(view, targetCtx) => {
|
|
view.pushHookEvent(this.el, targetCtx, event, payload || {}).then(
|
|
({ reply, ref }) => onReply(reply, ref)
|
|
).catch(() => {
|
|
});
|
|
}
|
|
);
|
|
}
|
|
handleEvent(event, callback) {
|
|
const callbackRef = {
|
|
event,
|
|
callback: (customEvent) => callback(customEvent.detail)
|
|
};
|
|
window.addEventListener(
|
|
`phx:${event}`,
|
|
callbackRef.callback
|
|
);
|
|
this.__listeners.add(callbackRef);
|
|
return callbackRef;
|
|
}
|
|
removeHandleEvent(ref) {
|
|
window.removeEventListener(
|
|
`phx:${ref.event}`,
|
|
ref.callback
|
|
);
|
|
this.__listeners.delete(ref);
|
|
}
|
|
upload(name, files) {
|
|
return this.__view().dispatchUploads(null, name, files);
|
|
}
|
|
uploadTo(selectorOrTarget, name, files) {
|
|
return this.__view().withinTargets(
|
|
selectorOrTarget,
|
|
(view, targetCtx) => {
|
|
view.dispatchUploads(targetCtx, name, files);
|
|
}
|
|
);
|
|
}
|
|
/** @internal */
|
|
__cleanup__() {
|
|
this.__listeners.forEach(
|
|
(callbackRef) => this.removeHandleEvent(callbackRef)
|
|
);
|
|
}
|
|
};
|
|
var prependFormDataKey = (key, prefix) => {
|
|
const isArray = key.endsWith("[]");
|
|
let baseKey = isArray ? key.slice(0, -2) : key;
|
|
baseKey = baseKey.replace(/([^\[\]]+)(\]?$)/, `${prefix}$1$2`);
|
|
if (isArray) {
|
|
baseKey += "[]";
|
|
}
|
|
return baseKey;
|
|
};
|
|
var serializeForm = (form, opts, onlyNames = []) => {
|
|
const { submitter } = opts;
|
|
let injectedElement;
|
|
if (submitter && submitter.name) {
|
|
const input = document.createElement("input");
|
|
input.type = "hidden";
|
|
const formId = submitter.getAttribute("form");
|
|
if (formId) {
|
|
input.setAttribute("form", formId);
|
|
}
|
|
input.name = submitter.name;
|
|
input.value = submitter.value;
|
|
submitter.parentElement.insertBefore(input, submitter);
|
|
injectedElement = input;
|
|
}
|
|
const formData = new FormData(form);
|
|
const toRemove = [];
|
|
formData.forEach((val, key, _index) => {
|
|
if (val instanceof File) {
|
|
toRemove.push(key);
|
|
}
|
|
});
|
|
toRemove.forEach((key) => formData.delete(key));
|
|
const params = new URLSearchParams();
|
|
const { inputsUnused, onlyHiddenInputs } = Array.from(form.elements).reduce(
|
|
(acc, input) => {
|
|
const { inputsUnused: inputsUnused2, onlyHiddenInputs: onlyHiddenInputs2 } = acc;
|
|
const key = input.name;
|
|
if (!key) {
|
|
return acc;
|
|
}
|
|
if (inputsUnused2[key] === void 0) {
|
|
inputsUnused2[key] = true;
|
|
}
|
|
if (onlyHiddenInputs2[key] === void 0) {
|
|
onlyHiddenInputs2[key] = true;
|
|
}
|
|
const isUsed = dom_default.private(input, PHX_HAS_FOCUSED) || dom_default.private(input, PHX_HAS_SUBMITTED);
|
|
const isHidden = input.type === "hidden";
|
|
inputsUnused2[key] = inputsUnused2[key] && !isUsed;
|
|
onlyHiddenInputs2[key] = onlyHiddenInputs2[key] && isHidden;
|
|
return acc;
|
|
},
|
|
{ inputsUnused: {}, onlyHiddenInputs: {} }
|
|
);
|
|
for (const [key, val] of formData.entries()) {
|
|
if (onlyNames.length === 0 || onlyNames.indexOf(key) >= 0) {
|
|
const isUnused = inputsUnused[key];
|
|
const hidden = onlyHiddenInputs[key];
|
|
if (isUnused && !(submitter && submitter.name == key) && !hidden) {
|
|
params.append(prependFormDataKey(key, "_unused_"), "");
|
|
}
|
|
if (typeof val === "string") {
|
|
params.append(key, val);
|
|
}
|
|
}
|
|
}
|
|
if (submitter && injectedElement) {
|
|
submitter.parentElement.removeChild(injectedElement);
|
|
}
|
|
return params.toString();
|
|
};
|
|
var View = class _View {
|
|
static closestView(el) {
|
|
const liveViewEl = el.closest(PHX_VIEW_SELECTOR);
|
|
return liveViewEl ? dom_default.private(liveViewEl, "view") : null;
|
|
}
|
|
constructor(el, liveSocket2, parentView, flash, liveReferer) {
|
|
this.isDead = false;
|
|
this.liveSocket = liveSocket2;
|
|
this.flash = flash;
|
|
this.parent = parentView;
|
|
this.root = parentView ? parentView.root : this;
|
|
this.el = el;
|
|
const boundView = dom_default.private(this.el, "view");
|
|
if (boundView !== void 0 && boundView.isDead !== true) {
|
|
logError(
|
|
`The DOM element for this view has already been bound to a view.
|
|
|
|
An element can only ever be associated with a single view!
|
|
Please ensure that you are not trying to initialize multiple LiveSockets on the same page.
|
|
This could happen if you're accidentally trying to render your root layout more than once.
|
|
Ensure that the template set on the LiveView is different than the root layout.
|
|
`,
|
|
{ view: boundView }
|
|
);
|
|
throw new Error("Cannot bind multiple views to the same DOM element.");
|
|
}
|
|
dom_default.putPrivate(this.el, "view", this);
|
|
this.id = this.el.id;
|
|
this.el.setAttribute(PHX_ROOT_ID, this.root.id);
|
|
this.ref = 0;
|
|
this.lastAckRef = null;
|
|
this.childJoins = 0;
|
|
this.loaderTimer = null;
|
|
this.disconnectedTimer = null;
|
|
this.pendingDiffs = [];
|
|
this.pendingForms = /* @__PURE__ */ new Set();
|
|
this.redirect = false;
|
|
this.href = null;
|
|
this.joinCount = this.parent ? this.parent.joinCount - 1 : 0;
|
|
this.joinAttempts = 0;
|
|
this.joinPending = true;
|
|
this.destroyed = false;
|
|
this.joinCallback = function(onDone) {
|
|
onDone && onDone();
|
|
};
|
|
this.stopCallback = function() {
|
|
};
|
|
this.pendingJoinOps = [];
|
|
this.viewHooks = {};
|
|
this.formSubmits = [];
|
|
this.children = this.parent ? null : {};
|
|
this.root.children[this.id] = {};
|
|
this.formsForRecovery = {};
|
|
this.channel = this.liveSocket.channel(`lv:${this.id}`, () => {
|
|
const url = this.href && this.expandURL(this.href);
|
|
return {
|
|
redirect: this.redirect ? url : void 0,
|
|
url: this.redirect ? void 0 : url || void 0,
|
|
params: this.connectParams(liveReferer),
|
|
session: this.getSession(),
|
|
static: this.getStatic(),
|
|
flash: this.flash,
|
|
sticky: this.el.hasAttribute(PHX_STICKY)
|
|
};
|
|
});
|
|
this.portalElementIds = /* @__PURE__ */ new Set();
|
|
}
|
|
setHref(href) {
|
|
this.href = href;
|
|
}
|
|
setRedirect(href) {
|
|
this.redirect = true;
|
|
this.href = href;
|
|
}
|
|
isMain() {
|
|
return this.el.hasAttribute(PHX_MAIN);
|
|
}
|
|
connectParams(liveReferer) {
|
|
const params = this.liveSocket.params(this.el);
|
|
const manifest = dom_default.all(document, `[${this.binding(PHX_TRACK_STATIC)}]`).map((node) => node.src || node.href).filter((url) => typeof url === "string");
|
|
if (manifest.length > 0) {
|
|
params["_track_static"] = manifest;
|
|
}
|
|
params["_mounts"] = this.joinCount;
|
|
params["_mount_attempts"] = this.joinAttempts;
|
|
params["_live_referer"] = liveReferer;
|
|
this.joinAttempts++;
|
|
return params;
|
|
}
|
|
isConnected() {
|
|
return this.channel.canPush();
|
|
}
|
|
getSession() {
|
|
return this.el.getAttribute(PHX_SESSION);
|
|
}
|
|
getStatic() {
|
|
const val = this.el.getAttribute(PHX_STATIC);
|
|
return val === "" ? null : val;
|
|
}
|
|
destroy(callback = function() {
|
|
}) {
|
|
this.destroyAllChildren();
|
|
this.destroyPortalElements();
|
|
this.destroyed = true;
|
|
dom_default.deletePrivate(this.el, "view");
|
|
delete this.root.children[this.id];
|
|
if (this.parent) {
|
|
delete this.root.children[this.parent.id][this.id];
|
|
}
|
|
clearTimeout(this.loaderTimer);
|
|
const onFinished = () => {
|
|
callback();
|
|
for (const id in this.viewHooks) {
|
|
this.destroyHook(this.viewHooks[id]);
|
|
}
|
|
};
|
|
dom_default.markPhxChildDestroyed(this.el);
|
|
this.log("destroyed", () => ["the child has been removed from the parent"]);
|
|
this.channel.leave().receive("ok", onFinished).receive("error", onFinished).receive("timeout", onFinished);
|
|
}
|
|
setContainerClasses(...classes) {
|
|
this.el.classList.remove(
|
|
PHX_CONNECTED_CLASS,
|
|
PHX_LOADING_CLASS,
|
|
PHX_ERROR_CLASS,
|
|
PHX_CLIENT_ERROR_CLASS,
|
|
PHX_SERVER_ERROR_CLASS
|
|
);
|
|
this.el.classList.add(...classes);
|
|
}
|
|
showLoader(timeout) {
|
|
clearTimeout(this.loaderTimer);
|
|
if (timeout) {
|
|
this.loaderTimer = setTimeout(() => this.showLoader(), timeout);
|
|
} else {
|
|
for (const id in this.viewHooks) {
|
|
this.viewHooks[id].__disconnected();
|
|
}
|
|
this.setContainerClasses(PHX_LOADING_CLASS);
|
|
}
|
|
}
|
|
execAll(binding) {
|
|
dom_default.all(
|
|
this.el,
|
|
`[${binding}]`,
|
|
(el) => this.liveSocket.execJS(el, el.getAttribute(binding))
|
|
);
|
|
}
|
|
hideLoader() {
|
|
clearTimeout(this.loaderTimer);
|
|
clearTimeout(this.disconnectedTimer);
|
|
this.setContainerClasses(PHX_CONNECTED_CLASS);
|
|
this.execAll(this.binding("connected"));
|
|
}
|
|
triggerReconnected() {
|
|
for (const id in this.viewHooks) {
|
|
this.viewHooks[id].__reconnected();
|
|
}
|
|
}
|
|
log(kind, msgCallback) {
|
|
this.liveSocket.log(this, kind, msgCallback);
|
|
}
|
|
transition(time, onStart, onDone = function() {
|
|
}) {
|
|
this.liveSocket.transition(time, onStart, onDone);
|
|
}
|
|
// calls the callback with the view and target element for the given phxTarget
|
|
// targets can be:
|
|
// * an element itself, then it is simply passed to liveSocket.owner;
|
|
// * a CID (Component ID), then we first search the component's element in the DOM
|
|
// * a selector, then we search the selector in the DOM and call the callback
|
|
// for each element found with the corresponding owner view
|
|
withinTargets(phxTarget, callback, dom = document) {
|
|
if (phxTarget instanceof HTMLElement || phxTarget instanceof SVGElement) {
|
|
return this.liveSocket.owner(
|
|
phxTarget,
|
|
(view) => callback(view, phxTarget)
|
|
);
|
|
}
|
|
if (isCid(phxTarget)) {
|
|
const targets = dom_default.findComponentNodeList(this.id, phxTarget, dom);
|
|
if (targets.length === 0) {
|
|
logError(`no component found matching phx-target of ${phxTarget}`);
|
|
} else {
|
|
callback(this, parseInt(phxTarget));
|
|
}
|
|
} else {
|
|
const targets = Array.from(dom.querySelectorAll(phxTarget));
|
|
if (targets.length === 0) {
|
|
logError(
|
|
`nothing found matching the phx-target selector "${phxTarget}"`
|
|
);
|
|
}
|
|
targets.forEach(
|
|
(target) => this.liveSocket.owner(target, (view) => callback(view, target))
|
|
);
|
|
}
|
|
}
|
|
applyDiff(type, rawDiff, callback) {
|
|
this.log(type, () => ["", clone(rawDiff)]);
|
|
const { diff, reply, events, title } = Rendered.extract(rawDiff);
|
|
const ev = events.reduce(
|
|
(acc, args) => {
|
|
if (args.length === 3 && args[2] == true) {
|
|
acc.pre.push(args.slice(0, -1));
|
|
} else {
|
|
acc.post.push(args);
|
|
}
|
|
return acc;
|
|
},
|
|
{ pre: [], post: [] }
|
|
);
|
|
this.liveSocket.dispatchEvents(ev.pre);
|
|
const update = () => {
|
|
callback({ diff, reply, events: ev.post });
|
|
if (typeof title === "string" || type == "mount" && this.isMain()) {
|
|
window.requestAnimationFrame(() => dom_default.putTitle(title));
|
|
}
|
|
};
|
|
if ("onDocumentPatch" in this.liveSocket.domCallbacks) {
|
|
this.liveSocket.triggerDOM("onDocumentPatch", [update]);
|
|
} else {
|
|
update();
|
|
}
|
|
}
|
|
onJoin(resp) {
|
|
const { rendered, container, liveview_version, pid } = resp;
|
|
if (container) {
|
|
const [tag, attrs] = container;
|
|
this.el = dom_default.replaceRootContainer(this.el, tag, attrs);
|
|
}
|
|
this.childJoins = 0;
|
|
this.joinPending = true;
|
|
this.flash = null;
|
|
if (this.root === this) {
|
|
this.formsForRecovery = this.getFormsForRecovery();
|
|
}
|
|
if (this.isMain() && window.history.state === null) {
|
|
browser_default.pushState("replace", {
|
|
type: "patch",
|
|
id: this.id,
|
|
position: this.liveSocket.currentHistoryPosition
|
|
});
|
|
}
|
|
if (liveview_version !== this.liveSocket.version()) {
|
|
console.warn(
|
|
`LiveView asset version mismatch. JavaScript version ${this.liveSocket.version()} vs. server ${liveview_version}. To avoid issues, please ensure that your assets use the same version as the server.`
|
|
);
|
|
}
|
|
if (pid) {
|
|
this.el.setAttribute(PHX_LV_PID, pid);
|
|
}
|
|
browser_default.dropLocal(
|
|
this.liveSocket.localStorage,
|
|
window.location.pathname,
|
|
CONSECUTIVE_RELOADS
|
|
);
|
|
this.applyDiff("mount", rendered, ({ diff, events }) => {
|
|
this.rendered = new Rendered(this.id, diff);
|
|
const [html, streams] = this.renderContainer(null, "join");
|
|
this.dropPendingRefs();
|
|
this.joinCount++;
|
|
this.joinAttempts = 0;
|
|
this.maybeRecoverForms(html, () => {
|
|
this.onJoinComplete(resp, html, streams, events);
|
|
});
|
|
});
|
|
}
|
|
dropPendingRefs() {
|
|
dom_default.all(document, `[${PHX_REF_SRC}="${this.refSrc()}"]`, (el) => {
|
|
el.removeAttribute(PHX_REF_LOADING);
|
|
el.removeAttribute(PHX_REF_SRC);
|
|
el.removeAttribute(PHX_REF_LOCK);
|
|
});
|
|
}
|
|
onJoinComplete({ live_patch }, html, streams, events) {
|
|
if (this.joinCount > 1 || this.parent && !this.parent.isJoinPending()) {
|
|
return this.applyJoinPatch(live_patch, html, streams, events);
|
|
}
|
|
const newChildren = dom_default.findPhxChildrenInFragment(html, this.id).filter(
|
|
(toEl) => {
|
|
const fromEl = toEl.id && this.el.querySelector(`[id="${toEl.id}"]`);
|
|
const phxStatic = fromEl && fromEl.getAttribute(PHX_STATIC);
|
|
if (phxStatic) {
|
|
toEl.setAttribute(PHX_STATIC, phxStatic);
|
|
}
|
|
if (fromEl) {
|
|
fromEl.setAttribute(PHX_ROOT_ID, this.root.id);
|
|
}
|
|
return this.joinChild(toEl);
|
|
}
|
|
);
|
|
if (newChildren.length === 0) {
|
|
if (this.parent) {
|
|
this.root.pendingJoinOps.push([
|
|
this,
|
|
() => this.applyJoinPatch(live_patch, html, streams, events)
|
|
]);
|
|
this.parent.ackJoin(this);
|
|
} else {
|
|
this.onAllChildJoinsComplete();
|
|
this.applyJoinPatch(live_patch, html, streams, events);
|
|
}
|
|
} else {
|
|
this.root.pendingJoinOps.push([
|
|
this,
|
|
() => this.applyJoinPatch(live_patch, html, streams, events)
|
|
]);
|
|
}
|
|
}
|
|
attachTrueDocEl() {
|
|
this.el = dom_default.byId(this.id);
|
|
this.el.setAttribute(PHX_ROOT_ID, this.root.id);
|
|
}
|
|
// this is invoked for dead and live views, so we must filter by
|
|
// by owner to ensure we aren't duplicating hooks across disconnect
|
|
// and connected states. This also handles cases where hooks exist
|
|
// in a root layout with a LV in the body
|
|
execNewMounted(parent = document) {
|
|
let phxViewportTop = this.binding(PHX_VIEWPORT_TOP);
|
|
let phxViewportBottom = this.binding(PHX_VIEWPORT_BOTTOM);
|
|
this.all(
|
|
parent,
|
|
`[${phxViewportTop}], [${phxViewportBottom}]`,
|
|
(hookEl) => {
|
|
dom_default.maintainPrivateHooks(
|
|
hookEl,
|
|
hookEl,
|
|
phxViewportTop,
|
|
phxViewportBottom
|
|
);
|
|
this.maybeAddNewHook(hookEl);
|
|
}
|
|
);
|
|
this.all(
|
|
parent,
|
|
`[${this.binding(PHX_HOOK)}], [data-phx-${PHX_HOOK}]`,
|
|
(hookEl) => {
|
|
this.maybeAddNewHook(hookEl);
|
|
}
|
|
);
|
|
this.all(parent, `[${this.binding(PHX_MOUNTED)}]`, (el) => {
|
|
this.maybeMounted(el);
|
|
});
|
|
}
|
|
all(parent, selector, callback) {
|
|
dom_default.all(parent, selector, (el) => {
|
|
if (this.ownsElement(el)) {
|
|
callback(el);
|
|
}
|
|
});
|
|
}
|
|
applyJoinPatch(live_patch, html, streams, events) {
|
|
if (this.joinCount > 1) {
|
|
if (this.pendingJoinOps.length) {
|
|
this.pendingJoinOps.forEach((cb) => typeof cb === "function" && cb());
|
|
this.pendingJoinOps = [];
|
|
}
|
|
}
|
|
this.attachTrueDocEl();
|
|
const patch = new DOMPatch(this, this.el, this.id, html, streams, null);
|
|
patch.markPrunableContentForRemoval();
|
|
this.performPatch(patch, false, true);
|
|
this.joinNewChildren();
|
|
this.execNewMounted();
|
|
this.joinPending = false;
|
|
this.liveSocket.dispatchEvents(events);
|
|
this.applyPendingUpdates();
|
|
if (live_patch) {
|
|
const { kind, to } = live_patch;
|
|
this.liveSocket.historyPatch(to, kind);
|
|
}
|
|
this.hideLoader();
|
|
if (this.joinCount > 1) {
|
|
this.triggerReconnected();
|
|
}
|
|
this.stopCallback();
|
|
}
|
|
triggerBeforeUpdateHook(fromEl, toEl) {
|
|
this.liveSocket.triggerDOM("onBeforeElUpdated", [fromEl, toEl]);
|
|
const hook = this.getHook(fromEl);
|
|
const isIgnored = hook && dom_default.isIgnored(fromEl, this.binding(PHX_UPDATE));
|
|
if (hook && !fromEl.isEqualNode(toEl) && !(isIgnored && isEqualObj(fromEl.dataset, toEl.dataset))) {
|
|
hook.__beforeUpdate();
|
|
return hook;
|
|
}
|
|
}
|
|
maybeMounted(el) {
|
|
const phxMounted = el.getAttribute(this.binding(PHX_MOUNTED));
|
|
const hasBeenInvoked = phxMounted && dom_default.private(el, "mounted");
|
|
if (phxMounted && !hasBeenInvoked) {
|
|
this.liveSocket.execJS(el, phxMounted);
|
|
dom_default.putPrivate(el, "mounted", true);
|
|
}
|
|
}
|
|
maybeAddNewHook(el) {
|
|
const newHook = this.addHook(el);
|
|
if (newHook) {
|
|
newHook.__mounted();
|
|
}
|
|
}
|
|
performPatch(patch, pruneCids, isJoinPatch = false) {
|
|
const removedEls = [];
|
|
let phxChildrenAdded = false;
|
|
const updatedHookIds = /* @__PURE__ */ new Set();
|
|
this.liveSocket.triggerDOM("onPatchStart", [patch.targetContainer]);
|
|
patch.after("added", (el) => {
|
|
this.liveSocket.triggerDOM("onNodeAdded", [el]);
|
|
const phxViewportTop = this.binding(PHX_VIEWPORT_TOP);
|
|
const phxViewportBottom = this.binding(PHX_VIEWPORT_BOTTOM);
|
|
dom_default.maintainPrivateHooks(el, el, phxViewportTop, phxViewportBottom);
|
|
this.maybeAddNewHook(el);
|
|
if (el.getAttribute) {
|
|
this.maybeMounted(el);
|
|
}
|
|
});
|
|
patch.after("phxChildAdded", (el) => {
|
|
if (dom_default.isPhxSticky(el)) {
|
|
this.liveSocket.joinRootViews();
|
|
} else {
|
|
phxChildrenAdded = true;
|
|
}
|
|
});
|
|
patch.before("updated", (fromEl, toEl) => {
|
|
const hook = this.triggerBeforeUpdateHook(fromEl, toEl);
|
|
if (hook) {
|
|
updatedHookIds.add(fromEl.id);
|
|
}
|
|
js_default.onBeforeElUpdated(fromEl, toEl);
|
|
});
|
|
patch.after("updated", (el) => {
|
|
if (updatedHookIds.has(el.id)) {
|
|
const hook = this.getHook(el);
|
|
hook && hook.__updated();
|
|
}
|
|
});
|
|
patch.after("discarded", (el) => {
|
|
if (el.nodeType === Node.ELEMENT_NODE) {
|
|
removedEls.push(el);
|
|
}
|
|
});
|
|
patch.after(
|
|
"transitionsDiscarded",
|
|
(els) => this.afterElementsRemoved(els, pruneCids)
|
|
);
|
|
patch.perform(isJoinPatch);
|
|
this.afterElementsRemoved(removedEls, pruneCids);
|
|
this.liveSocket.triggerDOM("onPatchEnd", [patch.targetContainer]);
|
|
return phxChildrenAdded;
|
|
}
|
|
afterElementsRemoved(elements, pruneCids) {
|
|
const destroyedCIDs = [];
|
|
elements.forEach((parent) => {
|
|
const components = dom_default.all(
|
|
parent,
|
|
`[${PHX_VIEW_REF}="${this.id}"][${PHX_COMPONENT}]`
|
|
);
|
|
const hooks2 = dom_default.all(
|
|
parent,
|
|
`[${this.binding(PHX_HOOK)}], [data-phx-hook]`
|
|
);
|
|
components.concat(parent).forEach((el) => {
|
|
const cid = this.componentID(el);
|
|
if (isCid(cid) && destroyedCIDs.indexOf(cid) === -1 && el.getAttribute(PHX_VIEW_REF) === this.id) {
|
|
destroyedCIDs.push(cid);
|
|
}
|
|
});
|
|
hooks2.concat(parent).forEach((hookEl) => {
|
|
const hook = this.getHook(hookEl);
|
|
hook && this.destroyHook(hook);
|
|
});
|
|
});
|
|
if (pruneCids) {
|
|
this.maybePushComponentsDestroyed(destroyedCIDs);
|
|
}
|
|
}
|
|
joinNewChildren() {
|
|
dom_default.findPhxChildren(document, this.id).forEach((el) => this.joinChild(el));
|
|
}
|
|
maybeRecoverForms(html, callback) {
|
|
const phxChange = this.binding("change");
|
|
const oldForms = this.root.formsForRecovery;
|
|
const template = document.createElement("template");
|
|
template.innerHTML = html;
|
|
dom_default.all(template.content, `[${PHX_PORTAL}]`).forEach((portalTemplate) => {
|
|
template.content.firstElementChild.appendChild(
|
|
portalTemplate.content.firstElementChild
|
|
);
|
|
});
|
|
const rootEl = template.content.firstElementChild;
|
|
rootEl.id = this.id;
|
|
rootEl.setAttribute(PHX_ROOT_ID, this.root.id);
|
|
rootEl.setAttribute(PHX_SESSION, this.getSession());
|
|
rootEl.setAttribute(PHX_STATIC, this.getStatic());
|
|
rootEl.setAttribute(PHX_PARENT_ID, this.parent ? this.parent.id : null);
|
|
const formsToRecover = (
|
|
// we go over all forms in the new DOM; because this is only the HTML for the current
|
|
// view, we can be sure that all forms are owned by this view:
|
|
dom_default.all(template.content, "form").filter((newForm) => newForm.id && oldForms[newForm.id]).filter((newForm) => !this.pendingForms.has(newForm.id)).filter(
|
|
(newForm) => oldForms[newForm.id].getAttribute(phxChange) === newForm.getAttribute(phxChange)
|
|
).map((newForm) => {
|
|
return [oldForms[newForm.id], newForm];
|
|
})
|
|
);
|
|
if (formsToRecover.length === 0) {
|
|
return callback();
|
|
}
|
|
formsToRecover.forEach(([oldForm, newForm], i) => {
|
|
this.pendingForms.add(newForm.id);
|
|
this.pushFormRecovery(
|
|
oldForm,
|
|
newForm,
|
|
template.content.firstElementChild,
|
|
() => {
|
|
this.pendingForms.delete(newForm.id);
|
|
if (i === formsToRecover.length - 1) {
|
|
callback();
|
|
}
|
|
}
|
|
);
|
|
});
|
|
}
|
|
getChildById(id) {
|
|
return this.root.children[this.id][id];
|
|
}
|
|
getDescendentByEl(el) {
|
|
var _a2;
|
|
if (el.id === this.id) {
|
|
return this;
|
|
} else {
|
|
return (_a2 = this.children[el.getAttribute(PHX_PARENT_ID)]) == null ? void 0 : _a2[el.id];
|
|
}
|
|
}
|
|
destroyDescendent(id) {
|
|
for (const parentId in this.root.children) {
|
|
for (const childId in this.root.children[parentId]) {
|
|
if (childId === id) {
|
|
return this.root.children[parentId][childId].destroy();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
joinChild(el) {
|
|
const child = this.getChildById(el.id);
|
|
if (!child) {
|
|
const view = new _View(el, this.liveSocket, this);
|
|
this.root.children[this.id][view.id] = view;
|
|
view.join();
|
|
this.childJoins++;
|
|
return true;
|
|
}
|
|
}
|
|
isJoinPending() {
|
|
return this.joinPending;
|
|
}
|
|
ackJoin(_child) {
|
|
this.childJoins--;
|
|
if (this.childJoins === 0) {
|
|
if (this.parent) {
|
|
this.parent.ackJoin(this);
|
|
} else {
|
|
this.onAllChildJoinsComplete();
|
|
}
|
|
}
|
|
}
|
|
onAllChildJoinsComplete() {
|
|
this.pendingForms.clear();
|
|
this.formsForRecovery = {};
|
|
this.joinCallback(() => {
|
|
this.pendingJoinOps.forEach(([view, op]) => {
|
|
if (!view.isDestroyed()) {
|
|
op();
|
|
}
|
|
});
|
|
this.pendingJoinOps = [];
|
|
});
|
|
}
|
|
update(diff, events, isPending = false) {
|
|
if (this.isJoinPending() || this.liveSocket.hasPendingLink() && this.root.isMain()) {
|
|
if (!isPending) {
|
|
this.pendingDiffs.push({ diff, events });
|
|
}
|
|
return false;
|
|
}
|
|
this.rendered.mergeDiff(diff);
|
|
let phxChildrenAdded = false;
|
|
if (this.rendered.isComponentOnlyDiff(diff)) {
|
|
this.liveSocket.time("component patch complete", () => {
|
|
const parentCids = dom_default.findExistingParentCIDs(
|
|
this.id,
|
|
this.rendered.componentCIDs(diff)
|
|
);
|
|
parentCids.forEach((parentCID) => {
|
|
if (this.componentPatch(
|
|
this.rendered.getComponent(diff, parentCID),
|
|
parentCID
|
|
)) {
|
|
phxChildrenAdded = true;
|
|
}
|
|
});
|
|
});
|
|
} else if (!isEmpty(diff)) {
|
|
this.liveSocket.time("full patch complete", () => {
|
|
const [html, streams] = this.renderContainer(diff, "update");
|
|
const patch = new DOMPatch(this, this.el, this.id, html, streams, null);
|
|
phxChildrenAdded = this.performPatch(patch, true);
|
|
});
|
|
}
|
|
this.liveSocket.dispatchEvents(events);
|
|
if (phxChildrenAdded) {
|
|
this.joinNewChildren();
|
|
}
|
|
return true;
|
|
}
|
|
renderContainer(diff, kind) {
|
|
return this.liveSocket.time(`toString diff (${kind})`, () => {
|
|
const tag = this.el.tagName;
|
|
const cids = diff ? this.rendered.componentCIDs(diff) : null;
|
|
const { buffer: html, streams } = this.rendered.toString(cids);
|
|
return [`<${tag}>${html}</${tag}>`, streams];
|
|
});
|
|
}
|
|
componentPatch(diff, cid) {
|
|
if (isEmpty(diff))
|
|
return false;
|
|
const { buffer: html, streams } = this.rendered.componentToString(cid);
|
|
const patch = new DOMPatch(this, this.el, this.id, html, streams, cid);
|
|
const childrenAdded = this.performPatch(patch, true);
|
|
return childrenAdded;
|
|
}
|
|
getHook(el) {
|
|
return this.viewHooks[ViewHook.elementID(el)];
|
|
}
|
|
addHook(el) {
|
|
const hookElId = ViewHook.elementID(el);
|
|
if (el.getAttribute && !this.ownsElement(el)) {
|
|
return;
|
|
}
|
|
if (hookElId && !this.viewHooks[hookElId]) {
|
|
if (ViewHook.deadHook(el)) {
|
|
return;
|
|
}
|
|
const hook = dom_default.getCustomElHook(el) || logError(`no hook found for custom element: ${el.id}`);
|
|
this.viewHooks[hookElId] = hook;
|
|
hook.__attachView(this);
|
|
return hook;
|
|
} else if (hookElId || !el.getAttribute) {
|
|
return;
|
|
} else {
|
|
const hookName = el.getAttribute(`data-phx-${PHX_HOOK}`) || el.getAttribute(this.binding(PHX_HOOK));
|
|
if (!hookName) {
|
|
return;
|
|
}
|
|
const hookDefinition = this.liveSocket.getHookDefinition(hookName);
|
|
if (hookDefinition) {
|
|
if (!el.id) {
|
|
logError(
|
|
`no DOM ID for hook "${hookName}". Hooks require a unique ID on each element.`,
|
|
el
|
|
);
|
|
return;
|
|
}
|
|
let hookInstance;
|
|
try {
|
|
if (typeof hookDefinition === "function" && hookDefinition.prototype instanceof ViewHook) {
|
|
hookInstance = new hookDefinition(this, el);
|
|
} else if (typeof hookDefinition === "object" && hookDefinition !== null) {
|
|
hookInstance = new ViewHook(this, el, hookDefinition);
|
|
} else {
|
|
logError(
|
|
`Invalid hook definition for "${hookName}". Expected a class extending ViewHook or an object definition.`,
|
|
el
|
|
);
|
|
return;
|
|
}
|
|
} catch (e) {
|
|
const errorMessage = e instanceof Error ? e.message : String(e);
|
|
logError(`Failed to create hook "${hookName}": ${errorMessage}`, el);
|
|
return;
|
|
}
|
|
this.viewHooks[ViewHook.elementID(hookInstance.el)] = hookInstance;
|
|
return hookInstance;
|
|
} else if (hookName !== null) {
|
|
logError(`unknown hook found for "${hookName}"`, el);
|
|
}
|
|
}
|
|
}
|
|
destroyHook(hook) {
|
|
const hookId = ViewHook.elementID(hook.el);
|
|
hook.__destroyed();
|
|
hook.__cleanup__();
|
|
delete this.viewHooks[hookId];
|
|
}
|
|
applyPendingUpdates() {
|
|
this.pendingDiffs = this.pendingDiffs.filter(
|
|
({ diff, events }) => !this.update(diff, events, true)
|
|
);
|
|
this.eachChild((child) => child.applyPendingUpdates());
|
|
}
|
|
eachChild(callback) {
|
|
const children = this.root.children[this.id] || {};
|
|
for (const id in children) {
|
|
callback(this.getChildById(id));
|
|
}
|
|
}
|
|
onChannel(event, cb) {
|
|
this.liveSocket.onChannel(this.channel, event, (resp) => {
|
|
if (this.isJoinPending()) {
|
|
if (this.joinCount > 1) {
|
|
this.pendingJoinOps.push(() => cb(resp));
|
|
} else {
|
|
this.root.pendingJoinOps.push([this, () => cb(resp)]);
|
|
}
|
|
} else {
|
|
this.liveSocket.requestDOMUpdate(() => cb(resp));
|
|
}
|
|
});
|
|
}
|
|
bindChannel() {
|
|
this.liveSocket.onChannel(this.channel, "diff", (rawDiff) => {
|
|
this.liveSocket.requestDOMUpdate(() => {
|
|
this.applyDiff(
|
|
"update",
|
|
rawDiff,
|
|
({ diff, events }) => this.update(diff, events)
|
|
);
|
|
});
|
|
});
|
|
this.onChannel(
|
|
"redirect",
|
|
({ to, flash }) => this.onRedirect({ to, flash })
|
|
);
|
|
this.onChannel("live_patch", (redir) => this.onLivePatch(redir));
|
|
this.onChannel("live_redirect", (redir) => this.onLiveRedirect(redir));
|
|
this.channel.onError((reason) => this.onError(reason));
|
|
this.channel.onClose((reason) => this.onClose(reason));
|
|
}
|
|
destroyAllChildren() {
|
|
this.eachChild((child) => child.destroy());
|
|
}
|
|
onLiveRedirect(redir) {
|
|
const { to, kind, flash } = redir;
|
|
const url = this.expandURL(to);
|
|
const e = new CustomEvent("phx:server-navigate", {
|
|
detail: { to, kind, flash }
|
|
});
|
|
this.liveSocket.historyRedirect(e, url, kind, flash);
|
|
}
|
|
onLivePatch(redir) {
|
|
const { to, kind } = redir;
|
|
this.href = this.expandURL(to);
|
|
this.liveSocket.historyPatch(to, kind);
|
|
}
|
|
expandURL(to) {
|
|
return to.startsWith("/") ? `${window.location.protocol}//${window.location.host}${to}` : to;
|
|
}
|
|
/**
|
|
* @param {{to: string, flash?: string, reloadToken?: string}} redirect
|
|
*/
|
|
onRedirect({ to, flash, reloadToken }) {
|
|
this.liveSocket.redirect(to, flash, reloadToken);
|
|
}
|
|
isDestroyed() {
|
|
return this.destroyed;
|
|
}
|
|
joinDead() {
|
|
this.isDead = true;
|
|
}
|
|
joinPush() {
|
|
this.joinPush = this.joinPush || this.channel.join();
|
|
return this.joinPush;
|
|
}
|
|
join(callback) {
|
|
this.showLoader(this.liveSocket.loaderTimeout);
|
|
this.bindChannel();
|
|
if (this.isMain()) {
|
|
this.stopCallback = this.liveSocket.withPageLoading({
|
|
to: this.href,
|
|
kind: "initial"
|
|
});
|
|
}
|
|
this.joinCallback = (onDone) => {
|
|
onDone = onDone || function() {
|
|
};
|
|
callback ? callback(this.joinCount, onDone) : onDone();
|
|
};
|
|
this.wrapPush(() => this.channel.join(), {
|
|
ok: (resp) => this.liveSocket.requestDOMUpdate(() => this.onJoin(resp)),
|
|
error: (error) => this.onJoinError(error),
|
|
timeout: () => this.onJoinError({ reason: "timeout" })
|
|
});
|
|
}
|
|
onJoinError(resp) {
|
|
if (resp.reason === "reload") {
|
|
this.log("error", () => [
|
|
`failed mount with ${resp.status}. Falling back to page reload`,
|
|
resp
|
|
]);
|
|
this.onRedirect({
|
|
to: this.liveSocket.main.href,
|
|
reloadToken: resp.token
|
|
});
|
|
return;
|
|
} else if (resp.reason === "unauthorized" || resp.reason === "stale") {
|
|
this.log("error", () => [
|
|
"unauthorized live_redirect. Falling back to page request",
|
|
resp
|
|
]);
|
|
this.onRedirect({ to: this.liveSocket.main.href, flash: this.flash });
|
|
return;
|
|
}
|
|
if (resp.redirect || resp.live_redirect) {
|
|
this.joinPending = false;
|
|
this.channel.leave();
|
|
}
|
|
if (resp.redirect) {
|
|
return this.onRedirect(resp.redirect);
|
|
}
|
|
if (resp.live_redirect) {
|
|
return this.onLiveRedirect(resp.live_redirect);
|
|
}
|
|
this.log("error", () => ["unable to join", resp]);
|
|
if (this.isMain()) {
|
|
this.displayError(
|
|
[PHX_LOADING_CLASS, PHX_ERROR_CLASS, PHX_SERVER_ERROR_CLASS],
|
|
{ unstructuredError: resp, errorKind: "server" }
|
|
);
|
|
if (this.liveSocket.isConnected()) {
|
|
this.liveSocket.reloadWithJitter(this);
|
|
}
|
|
} else {
|
|
if (this.joinAttempts >= MAX_CHILD_JOIN_ATTEMPTS) {
|
|
this.root.displayError(
|
|
[PHX_LOADING_CLASS, PHX_ERROR_CLASS, PHX_SERVER_ERROR_CLASS],
|
|
{ unstructuredError: resp, errorKind: "server" }
|
|
);
|
|
this.log("error", () => [
|
|
`giving up trying to mount after ${MAX_CHILD_JOIN_ATTEMPTS} tries`,
|
|
resp
|
|
]);
|
|
this.destroy();
|
|
}
|
|
const trueChildEl = dom_default.byId(this.el.id);
|
|
if (trueChildEl) {
|
|
dom_default.mergeAttrs(trueChildEl, this.el);
|
|
this.displayError(
|
|
[PHX_LOADING_CLASS, PHX_ERROR_CLASS, PHX_SERVER_ERROR_CLASS],
|
|
{ unstructuredError: resp, errorKind: "server" }
|
|
);
|
|
this.el = trueChildEl;
|
|
} else {
|
|
this.destroy();
|
|
}
|
|
}
|
|
}
|
|
onClose(reason) {
|
|
if (this.isDestroyed()) {
|
|
return;
|
|
}
|
|
if (this.isMain() && this.liveSocket.hasPendingLink() && reason !== "leave") {
|
|
return this.liveSocket.reloadWithJitter(this);
|
|
}
|
|
this.destroyAllChildren();
|
|
this.liveSocket.dropActiveElement(this);
|
|
if (this.liveSocket.isUnloaded()) {
|
|
this.showLoader(BEFORE_UNLOAD_LOADER_TIMEOUT);
|
|
}
|
|
}
|
|
onError(reason) {
|
|
this.onClose(reason);
|
|
if (this.liveSocket.isConnected()) {
|
|
this.log("error", () => ["view crashed", reason]);
|
|
}
|
|
if (!this.liveSocket.isUnloaded()) {
|
|
if (this.liveSocket.isConnected()) {
|
|
this.displayError(
|
|
[PHX_LOADING_CLASS, PHX_ERROR_CLASS, PHX_SERVER_ERROR_CLASS],
|
|
{ unstructuredError: reason, errorKind: "server" }
|
|
);
|
|
} else {
|
|
this.displayError(
|
|
[PHX_LOADING_CLASS, PHX_ERROR_CLASS, PHX_CLIENT_ERROR_CLASS],
|
|
{ unstructuredError: reason, errorKind: "client" }
|
|
);
|
|
}
|
|
}
|
|
}
|
|
displayError(classes, details = {}) {
|
|
if (this.isMain()) {
|
|
dom_default.dispatchEvent(window, "phx:page-loading-start", {
|
|
detail: __spreadValues({ to: this.href, kind: "error" }, details)
|
|
});
|
|
}
|
|
this.showLoader();
|
|
this.setContainerClasses(...classes);
|
|
this.delayedDisconnected();
|
|
}
|
|
delayedDisconnected() {
|
|
this.disconnectedTimer = setTimeout(() => {
|
|
this.execAll(this.binding("disconnected"));
|
|
}, this.liveSocket.disconnectedTimeout);
|
|
}
|
|
wrapPush(callerPush, receives) {
|
|
const latency = this.liveSocket.getLatencySim();
|
|
const withLatency = latency ? (cb) => setTimeout(() => !this.isDestroyed() && cb(), latency) : (cb) => !this.isDestroyed() && cb();
|
|
withLatency(() => {
|
|
callerPush().receive(
|
|
"ok",
|
|
(resp) => withLatency(() => receives.ok && receives.ok(resp))
|
|
).receive(
|
|
"error",
|
|
(reason) => withLatency(() => receives.error && receives.error(reason))
|
|
).receive(
|
|
"timeout",
|
|
() => withLatency(() => receives.timeout && receives.timeout())
|
|
);
|
|
});
|
|
}
|
|
pushWithReply(refGenerator, event, payload) {
|
|
if (!this.isConnected()) {
|
|
return Promise.reject(new Error("no connection"));
|
|
}
|
|
const [ref, [el], opts] = refGenerator ? refGenerator({ payload }) : [null, [], {}];
|
|
const oldJoinCount = this.joinCount;
|
|
let onLoadingDone = function() {
|
|
};
|
|
if (opts.page_loading) {
|
|
onLoadingDone = this.liveSocket.withPageLoading({
|
|
kind: "element",
|
|
target: el
|
|
});
|
|
}
|
|
if (typeof payload.cid !== "number") {
|
|
delete payload.cid;
|
|
}
|
|
return new Promise((resolve, reject) => {
|
|
this.wrapPush(() => this.channel.push(event, payload, PUSH_TIMEOUT), {
|
|
ok: (resp) => {
|
|
if (ref !== null) {
|
|
this.lastAckRef = ref;
|
|
}
|
|
const finish = (hookReply) => {
|
|
if (resp.redirect) {
|
|
this.onRedirect(resp.redirect);
|
|
}
|
|
if (resp.live_patch) {
|
|
this.onLivePatch(resp.live_patch);
|
|
}
|
|
if (resp.live_redirect) {
|
|
this.onLiveRedirect(resp.live_redirect);
|
|
}
|
|
onLoadingDone();
|
|
resolve({ resp, reply: hookReply, ref });
|
|
};
|
|
if (resp.diff) {
|
|
this.liveSocket.requestDOMUpdate(() => {
|
|
this.applyDiff("update", resp.diff, ({ diff, reply, events }) => {
|
|
if (ref !== null) {
|
|
this.undoRefs(ref, payload.event);
|
|
}
|
|
this.update(diff, events);
|
|
finish(reply);
|
|
});
|
|
});
|
|
} else {
|
|
if (ref !== null) {
|
|
this.undoRefs(ref, payload.event);
|
|
}
|
|
finish(null);
|
|
}
|
|
},
|
|
error: (reason) => reject(new Error(`failed with reason: ${JSON.stringify(reason)}`)),
|
|
timeout: () => {
|
|
reject(new Error("timeout"));
|
|
if (this.joinCount === oldJoinCount) {
|
|
this.liveSocket.reloadWithJitter(this, () => {
|
|
this.log("timeout", () => [
|
|
"received timeout while communicating with server. Falling back to hard refresh for recovery"
|
|
]);
|
|
});
|
|
}
|
|
}
|
|
});
|
|
});
|
|
}
|
|
undoRefs(ref, phxEvent, onlyEls) {
|
|
if (!this.isConnected()) {
|
|
return;
|
|
}
|
|
const selector = `[${PHX_REF_SRC}="${this.refSrc()}"]`;
|
|
if (onlyEls) {
|
|
onlyEls = new Set(onlyEls);
|
|
dom_default.all(document, selector, (parent) => {
|
|
if (onlyEls && !onlyEls.has(parent)) {
|
|
return;
|
|
}
|
|
dom_default.all(
|
|
parent,
|
|
selector,
|
|
(child) => this.undoElRef(child, ref, phxEvent)
|
|
);
|
|
this.undoElRef(parent, ref, phxEvent);
|
|
});
|
|
} else {
|
|
dom_default.all(document, selector, (el) => this.undoElRef(el, ref, phxEvent));
|
|
}
|
|
}
|
|
undoElRef(el, ref, phxEvent) {
|
|
const elRef = new ElementRef(el);
|
|
elRef.maybeUndo(ref, phxEvent, (clonedTree) => {
|
|
const patch = new DOMPatch(this, el, this.id, clonedTree, [], null, {
|
|
undoRef: ref
|
|
});
|
|
const phxChildrenAdded = this.performPatch(patch, true);
|
|
dom_default.all(
|
|
el,
|
|
`[${PHX_REF_SRC}="${this.refSrc()}"]`,
|
|
(child) => this.undoElRef(child, ref, phxEvent)
|
|
);
|
|
if (phxChildrenAdded) {
|
|
this.joinNewChildren();
|
|
}
|
|
});
|
|
}
|
|
refSrc() {
|
|
return this.el.id;
|
|
}
|
|
putRef(elements, phxEvent, eventType, opts = {}) {
|
|
const newRef = this.ref++;
|
|
const disableWith = this.binding(PHX_DISABLE_WITH);
|
|
if (opts.loading) {
|
|
const loadingEls = dom_default.all(document, opts.loading).map((el) => {
|
|
return { el, lock: true, loading: true };
|
|
});
|
|
elements = elements.concat(loadingEls);
|
|
}
|
|
for (const { el, lock, loading } of elements) {
|
|
if (!lock && !loading) {
|
|
throw new Error("putRef requires lock or loading");
|
|
}
|
|
el.setAttribute(PHX_REF_SRC, this.refSrc());
|
|
if (loading) {
|
|
el.setAttribute(PHX_REF_LOADING, newRef);
|
|
}
|
|
if (lock) {
|
|
el.setAttribute(PHX_REF_LOCK, newRef);
|
|
}
|
|
if (!loading || opts.submitter && !(el === opts.submitter || el === opts.form)) {
|
|
continue;
|
|
}
|
|
const lockCompletePromise = new Promise((resolve) => {
|
|
el.addEventListener(`phx:undo-lock:${newRef}`, () => resolve(detail), {
|
|
once: true
|
|
});
|
|
});
|
|
const loadingCompletePromise = new Promise((resolve) => {
|
|
el.addEventListener(
|
|
`phx:undo-loading:${newRef}`,
|
|
() => resolve(detail),
|
|
{ once: true }
|
|
);
|
|
});
|
|
el.classList.add(`phx-${eventType}-loading`);
|
|
const disableText = el.getAttribute(disableWith);
|
|
if (disableText !== null) {
|
|
if (!el.getAttribute(PHX_DISABLE_WITH_RESTORE)) {
|
|
el.setAttribute(PHX_DISABLE_WITH_RESTORE, el.textContent);
|
|
}
|
|
if (disableText !== "") {
|
|
el.textContent = disableText;
|
|
}
|
|
el.setAttribute(
|
|
PHX_DISABLED,
|
|
el.getAttribute(PHX_DISABLED) || el.disabled
|
|
);
|
|
el.setAttribute("disabled", "");
|
|
}
|
|
const detail = {
|
|
event: phxEvent,
|
|
eventType,
|
|
ref: newRef,
|
|
isLoading: loading,
|
|
isLocked: lock,
|
|
lockElements: elements.filter(({ lock: lock2 }) => lock2).map(({ el: el2 }) => el2),
|
|
loadingElements: elements.filter(({ loading: loading2 }) => loading2).map(({ el: el2 }) => el2),
|
|
unlock: (els) => {
|
|
els = Array.isArray(els) ? els : [els];
|
|
this.undoRefs(newRef, phxEvent, els);
|
|
},
|
|
lockComplete: lockCompletePromise,
|
|
loadingComplete: loadingCompletePromise,
|
|
lock: (lockEl) => {
|
|
return new Promise((resolve) => {
|
|
if (this.isAcked(newRef)) {
|
|
return resolve(detail);
|
|
}
|
|
lockEl.setAttribute(PHX_REF_LOCK, newRef);
|
|
lockEl.setAttribute(PHX_REF_SRC, this.refSrc());
|
|
lockEl.addEventListener(
|
|
`phx:lock-stop:${newRef}`,
|
|
() => resolve(detail),
|
|
{ once: true }
|
|
);
|
|
});
|
|
}
|
|
};
|
|
if (opts.payload) {
|
|
detail["payload"] = opts.payload;
|
|
}
|
|
if (opts.target) {
|
|
detail["target"] = opts.target;
|
|
}
|
|
if (opts.originalEvent) {
|
|
detail["originalEvent"] = opts.originalEvent;
|
|
}
|
|
el.dispatchEvent(
|
|
new CustomEvent("phx:push", {
|
|
detail,
|
|
bubbles: true,
|
|
cancelable: false
|
|
})
|
|
);
|
|
if (phxEvent) {
|
|
el.dispatchEvent(
|
|
new CustomEvent(`phx:push:${phxEvent}`, {
|
|
detail,
|
|
bubbles: true,
|
|
cancelable: false
|
|
})
|
|
);
|
|
}
|
|
}
|
|
return [newRef, elements.map(({ el }) => el), opts];
|
|
}
|
|
isAcked(ref) {
|
|
return this.lastAckRef !== null && this.lastAckRef >= ref;
|
|
}
|
|
componentID(el) {
|
|
const cid = el.getAttribute && el.getAttribute(PHX_COMPONENT);
|
|
return cid ? parseInt(cid) : null;
|
|
}
|
|
targetComponentID(target, targetCtx, opts = {}) {
|
|
if (isCid(targetCtx)) {
|
|
return targetCtx;
|
|
}
|
|
const cidOrSelector = opts.target || target.getAttribute(this.binding("target"));
|
|
if (isCid(cidOrSelector)) {
|
|
return parseInt(cidOrSelector);
|
|
} else if (targetCtx && (cidOrSelector !== null || opts.target)) {
|
|
return this.closestComponentID(targetCtx);
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
closestComponentID(targetCtx) {
|
|
if (isCid(targetCtx)) {
|
|
return targetCtx;
|
|
} else if (targetCtx) {
|
|
return maybe(
|
|
// We either use the closest data-phx-component binding, or -
|
|
// in case of portals - continue with the portal source.
|
|
// This is necessary if teleporting an element outside of its LiveComponent.
|
|
targetCtx.closest(`[${PHX_COMPONENT}],[${PHX_TELEPORTED_SRC}]`),
|
|
(el) => {
|
|
if (el.hasAttribute(PHX_COMPONENT)) {
|
|
return this.ownsElement(el) && this.componentID(el);
|
|
}
|
|
if (el.hasAttribute(PHX_TELEPORTED_SRC)) {
|
|
const portalParent = dom_default.byId(el.getAttribute(PHX_TELEPORTED_SRC));
|
|
return this.closestComponentID(portalParent);
|
|
}
|
|
}
|
|
);
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
pushHookEvent(el, targetCtx, event, payload) {
|
|
if (!this.isConnected()) {
|
|
this.log("hook", () => [
|
|
"unable to push hook event. LiveView not connected",
|
|
event,
|
|
payload
|
|
]);
|
|
return Promise.reject(
|
|
new Error("unable to push hook event. LiveView not connected")
|
|
);
|
|
}
|
|
const refGenerator = () => this.putRef([{ el, loading: true, lock: true }], event, "hook", {
|
|
payload,
|
|
target: targetCtx
|
|
});
|
|
return this.pushWithReply(refGenerator, "event", {
|
|
type: "hook",
|
|
event,
|
|
value: payload,
|
|
cid: this.closestComponentID(targetCtx)
|
|
}).then(({ resp: _resp, reply, ref }) => ({ reply, ref }));
|
|
}
|
|
extractMeta(el, meta, value) {
|
|
const prefix = this.binding("value-");
|
|
for (let i = 0; i < el.attributes.length; i++) {
|
|
if (!meta) {
|
|
meta = {};
|
|
}
|
|
const name = el.attributes[i].name;
|
|
if (name.startsWith(prefix)) {
|
|
meta[name.replace(prefix, "")] = el.getAttribute(name);
|
|
}
|
|
}
|
|
if (el.value !== void 0 && !(el instanceof HTMLFormElement)) {
|
|
if (!meta) {
|
|
meta = {};
|
|
}
|
|
meta.value = el.value;
|
|
if (el.tagName === "INPUT" && CHECKABLE_INPUTS.indexOf(el.type) >= 0 && !el.checked) {
|
|
delete meta.value;
|
|
}
|
|
}
|
|
if (value) {
|
|
if (!meta) {
|
|
meta = {};
|
|
}
|
|
for (const key in value) {
|
|
meta[key] = value[key];
|
|
}
|
|
}
|
|
return meta;
|
|
}
|
|
pushEvent(type, el, targetCtx, phxEvent, meta, opts = {}, onReply) {
|
|
this.pushWithReply(
|
|
(maybePayload) => this.putRef([{ el, loading: true, lock: true }], phxEvent, type, __spreadProps(__spreadValues({}, opts), {
|
|
payload: maybePayload == null ? void 0 : maybePayload.payload
|
|
})),
|
|
"event",
|
|
{
|
|
type,
|
|
event: phxEvent,
|
|
value: this.extractMeta(el, meta, opts.value),
|
|
cid: this.targetComponentID(el, targetCtx, opts)
|
|
}
|
|
).then(({ reply }) => onReply && onReply(reply)).catch((error) => logError("Failed to push event", error));
|
|
}
|
|
pushFileProgress(fileEl, entryRef, progress, onReply = function() {
|
|
}) {
|
|
this.liveSocket.withinOwners(fileEl.form, (view, targetCtx) => {
|
|
view.pushWithReply(null, "progress", {
|
|
event: fileEl.getAttribute(view.binding(PHX_PROGRESS)),
|
|
ref: fileEl.getAttribute(PHX_UPLOAD_REF),
|
|
entry_ref: entryRef,
|
|
progress,
|
|
cid: view.targetComponentID(fileEl.form, targetCtx)
|
|
}).then(() => onReply()).catch((error) => logError("Failed to push file progress", error));
|
|
});
|
|
}
|
|
pushInput(inputEl, targetCtx, forceCid, phxEvent, opts, callback) {
|
|
if (!inputEl.form) {
|
|
throw new Error("form events require the input to be inside a form");
|
|
}
|
|
let uploads;
|
|
const cid = isCid(forceCid) ? forceCid : this.targetComponentID(inputEl.form, targetCtx, opts);
|
|
const refGenerator = (maybePayload) => {
|
|
return this.putRef(
|
|
[
|
|
{ el: inputEl, loading: true, lock: true },
|
|
{ el: inputEl.form, loading: true, lock: true }
|
|
],
|
|
phxEvent,
|
|
"change",
|
|
__spreadProps(__spreadValues({}, opts), { payload: maybePayload == null ? void 0 : maybePayload.payload })
|
|
);
|
|
};
|
|
let formData;
|
|
const meta = this.extractMeta(inputEl.form, {}, opts.value);
|
|
const serializeOpts = {};
|
|
if (inputEl instanceof HTMLButtonElement) {
|
|
serializeOpts.submitter = inputEl;
|
|
}
|
|
if (inputEl.getAttribute(this.binding("change"))) {
|
|
formData = serializeForm(inputEl.form, serializeOpts, [inputEl.name]);
|
|
} else {
|
|
formData = serializeForm(inputEl.form, serializeOpts);
|
|
}
|
|
if (dom_default.isUploadInput(inputEl) && inputEl.files && inputEl.files.length > 0) {
|
|
LiveUploader.trackFiles(inputEl, Array.from(inputEl.files));
|
|
}
|
|
uploads = LiveUploader.serializeUploads(inputEl);
|
|
const event = {
|
|
type: "form",
|
|
event: phxEvent,
|
|
value: formData,
|
|
meta: __spreadValues({
|
|
// no target was implicitly sent as "undefined" in LV <= 1.0.5, therefore
|
|
// we have to keep it. In 1.0.6 we switched from passing meta as URL encoded data
|
|
// to passing it directly in the event, but the JSON encode would drop keys with
|
|
// undefined values.
|
|
_target: opts._target || "undefined"
|
|
}, meta),
|
|
uploads,
|
|
cid
|
|
};
|
|
this.pushWithReply(refGenerator, "event", event).then(({ resp }) => {
|
|
if (dom_default.isUploadInput(inputEl) && dom_default.isAutoUpload(inputEl)) {
|
|
ElementRef.onUnlock(inputEl, () => {
|
|
if (LiveUploader.filesAwaitingPreflight(inputEl).length > 0) {
|
|
const [ref, _els] = refGenerator();
|
|
this.undoRefs(ref, phxEvent, [inputEl.form]);
|
|
this.uploadFiles(
|
|
inputEl.form,
|
|
phxEvent,
|
|
targetCtx,
|
|
ref,
|
|
cid,
|
|
(_uploads) => {
|
|
callback && callback(resp);
|
|
this.triggerAwaitingSubmit(inputEl.form, phxEvent);
|
|
this.undoRefs(ref, phxEvent);
|
|
}
|
|
);
|
|
}
|
|
});
|
|
} else {
|
|
callback && callback(resp);
|
|
}
|
|
}).catch((error) => logError("Failed to push input event", error));
|
|
}
|
|
triggerAwaitingSubmit(formEl, phxEvent) {
|
|
const awaitingSubmit = this.getScheduledSubmit(formEl);
|
|
if (awaitingSubmit) {
|
|
const [_el, _ref, _opts, callback] = awaitingSubmit;
|
|
this.cancelSubmit(formEl, phxEvent);
|
|
callback();
|
|
}
|
|
}
|
|
getScheduledSubmit(formEl) {
|
|
return this.formSubmits.find(
|
|
([el, _ref, _opts, _callback]) => el.isSameNode(formEl)
|
|
);
|
|
}
|
|
scheduleSubmit(formEl, ref, opts, callback) {
|
|
if (this.getScheduledSubmit(formEl)) {
|
|
return true;
|
|
}
|
|
this.formSubmits.push([formEl, ref, opts, callback]);
|
|
}
|
|
cancelSubmit(formEl, phxEvent) {
|
|
this.formSubmits = this.formSubmits.filter(
|
|
([el, ref, _opts, _callback]) => {
|
|
if (el.isSameNode(formEl)) {
|
|
this.undoRefs(ref, phxEvent);
|
|
return false;
|
|
} else {
|
|
return true;
|
|
}
|
|
}
|
|
);
|
|
}
|
|
disableForm(formEl, phxEvent, opts = {}) {
|
|
const filterIgnored = (el) => {
|
|
const userIgnored = closestPhxBinding(
|
|
el,
|
|
`${this.binding(PHX_UPDATE)}=ignore`,
|
|
el.form
|
|
);
|
|
return !(userIgnored || closestPhxBinding(el, "data-phx-update=ignore", el.form));
|
|
};
|
|
const filterDisables = (el) => {
|
|
return el.hasAttribute(this.binding(PHX_DISABLE_WITH));
|
|
};
|
|
const filterButton = (el) => el.tagName == "BUTTON";
|
|
const filterInput = (el) => ["INPUT", "TEXTAREA", "SELECT"].includes(el.tagName);
|
|
const formElements = Array.from(formEl.elements);
|
|
const disables = formElements.filter(filterDisables);
|
|
const buttons = formElements.filter(filterButton).filter(filterIgnored);
|
|
const inputs = formElements.filter(filterInput).filter(filterIgnored);
|
|
buttons.forEach((button) => {
|
|
button.setAttribute(PHX_DISABLED, button.disabled);
|
|
button.disabled = true;
|
|
});
|
|
inputs.forEach((input) => {
|
|
input.setAttribute(PHX_READONLY, input.readOnly);
|
|
input.readOnly = true;
|
|
if (input.files) {
|
|
input.setAttribute(PHX_DISABLED, input.disabled);
|
|
input.disabled = true;
|
|
}
|
|
});
|
|
const formEls = disables.concat(buttons).concat(inputs).map((el) => {
|
|
return { el, loading: true, lock: true };
|
|
});
|
|
const els = [{ el: formEl, loading: true, lock: false }].concat(formEls).reverse();
|
|
return this.putRef(els, phxEvent, "submit", opts);
|
|
}
|
|
pushFormSubmit(formEl, targetCtx, phxEvent, submitter, opts, onReply) {
|
|
const refGenerator = (maybePayload) => this.disableForm(formEl, phxEvent, __spreadProps(__spreadValues({}, opts), {
|
|
form: formEl,
|
|
payload: maybePayload == null ? void 0 : maybePayload.payload,
|
|
submitter
|
|
}));
|
|
dom_default.putPrivate(formEl, "submitter", submitter);
|
|
const cid = this.targetComponentID(formEl, targetCtx);
|
|
if (LiveUploader.hasUploadsInProgress(formEl)) {
|
|
const [ref, _els] = refGenerator();
|
|
const push = () => this.pushFormSubmit(
|
|
formEl,
|
|
targetCtx,
|
|
phxEvent,
|
|
submitter,
|
|
opts,
|
|
onReply
|
|
);
|
|
return this.scheduleSubmit(formEl, ref, opts, push);
|
|
} else if (LiveUploader.inputsAwaitingPreflight(formEl).length > 0) {
|
|
const [ref, els] = refGenerator();
|
|
const proxyRefGen = () => [ref, els, opts];
|
|
this.uploadFiles(formEl, phxEvent, targetCtx, ref, cid, (_uploads) => {
|
|
if (LiveUploader.inputsAwaitingPreflight(formEl).length > 0) {
|
|
return this.undoRefs(ref, phxEvent);
|
|
}
|
|
const meta = this.extractMeta(formEl, {}, opts.value);
|
|
const formData = serializeForm(formEl, { submitter });
|
|
this.pushWithReply(proxyRefGen, "event", {
|
|
type: "form",
|
|
event: phxEvent,
|
|
value: formData,
|
|
meta,
|
|
cid
|
|
}).then(({ resp }) => onReply(resp)).catch((error) => logError("Failed to push form submit", error));
|
|
});
|
|
} else if (!(formEl.hasAttribute(PHX_REF_SRC) && formEl.classList.contains("phx-submit-loading"))) {
|
|
const meta = this.extractMeta(formEl, {}, opts.value);
|
|
const formData = serializeForm(formEl, { submitter });
|
|
this.pushWithReply(refGenerator, "event", {
|
|
type: "form",
|
|
event: phxEvent,
|
|
value: formData,
|
|
meta,
|
|
cid
|
|
}).then(({ resp }) => onReply(resp)).catch((error) => logError("Failed to push form submit", error));
|
|
}
|
|
}
|
|
uploadFiles(formEl, phxEvent, targetCtx, ref, cid, onComplete) {
|
|
const joinCountAtUpload = this.joinCount;
|
|
const inputEls = LiveUploader.activeFileInputs(formEl);
|
|
let numFileInputsInProgress = inputEls.length;
|
|
inputEls.forEach((inputEl) => {
|
|
const uploader = new LiveUploader(inputEl, this, () => {
|
|
numFileInputsInProgress--;
|
|
if (numFileInputsInProgress === 0) {
|
|
onComplete();
|
|
}
|
|
});
|
|
const entries = uploader.entries().map((entry) => entry.toPreflightPayload());
|
|
if (entries.length === 0) {
|
|
numFileInputsInProgress--;
|
|
return;
|
|
}
|
|
const payload = {
|
|
ref: inputEl.getAttribute(PHX_UPLOAD_REF),
|
|
entries,
|
|
cid: this.targetComponentID(inputEl.form, targetCtx)
|
|
};
|
|
this.log("upload", () => ["sending preflight request", payload]);
|
|
this.pushWithReply(null, "allow_upload", payload).then(({ resp }) => {
|
|
this.log("upload", () => ["got preflight response", resp]);
|
|
uploader.entries().forEach((entry) => {
|
|
if (resp.entries && !resp.entries[entry.ref]) {
|
|
this.handleFailedEntryPreflight(
|
|
entry.ref,
|
|
"failed preflight",
|
|
uploader
|
|
);
|
|
}
|
|
});
|
|
if (resp.error || Object.keys(resp.entries).length === 0) {
|
|
this.undoRefs(ref, phxEvent);
|
|
const errors = resp.error || [];
|
|
errors.map(([entry_ref, reason]) => {
|
|
this.handleFailedEntryPreflight(entry_ref, reason, uploader);
|
|
});
|
|
} else {
|
|
const onError = (callback) => {
|
|
this.channel.onError(() => {
|
|
if (this.joinCount === joinCountAtUpload) {
|
|
callback();
|
|
}
|
|
});
|
|
};
|
|
uploader.initAdapterUpload(resp, onError, this.liveSocket);
|
|
}
|
|
}).catch((error) => logError("Failed to push upload", error));
|
|
});
|
|
}
|
|
handleFailedEntryPreflight(uploadRef, reason, uploader) {
|
|
if (uploader.isAutoUpload()) {
|
|
const entry = uploader.entries().find((entry2) => entry2.ref === uploadRef.toString());
|
|
if (entry) {
|
|
entry.cancel();
|
|
}
|
|
} else {
|
|
uploader.entries().map((entry) => entry.cancel());
|
|
}
|
|
this.log("upload", () => [`error for entry ${uploadRef}`, reason]);
|
|
}
|
|
dispatchUploads(targetCtx, name, filesOrBlobs) {
|
|
const targetElement = this.targetCtxElement(targetCtx) || this.el;
|
|
const inputs = dom_default.findUploadInputs(targetElement).filter(
|
|
(el) => el.name === name
|
|
);
|
|
if (inputs.length === 0) {
|
|
logError(`no live file inputs found matching the name "${name}"`);
|
|
} else if (inputs.length > 1) {
|
|
logError(`duplicate live file inputs found matching the name "${name}"`);
|
|
} else {
|
|
dom_default.dispatchEvent(inputs[0], PHX_TRACK_UPLOADS, {
|
|
detail: { files: filesOrBlobs }
|
|
});
|
|
}
|
|
}
|
|
targetCtxElement(targetCtx) {
|
|
if (isCid(targetCtx)) {
|
|
const [target] = dom_default.findComponentNodeList(this.id, targetCtx);
|
|
return target;
|
|
} else if (targetCtx) {
|
|
return targetCtx;
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
pushFormRecovery(oldForm, newForm, templateDom, callback) {
|
|
const phxChange = this.binding("change");
|
|
const phxTarget = newForm.getAttribute(this.binding("target")) || newForm;
|
|
const phxEvent = newForm.getAttribute(this.binding(PHX_AUTO_RECOVER)) || newForm.getAttribute(this.binding("change"));
|
|
const inputs = Array.from(oldForm.elements).filter(
|
|
(el) => dom_default.isFormInput(el) && el.name && !el.hasAttribute(phxChange)
|
|
);
|
|
if (inputs.length === 0) {
|
|
callback();
|
|
return;
|
|
}
|
|
inputs.forEach(
|
|
(input2) => input2.hasAttribute(PHX_UPLOAD_REF) && LiveUploader.clearFiles(input2)
|
|
);
|
|
const input = inputs.find((el) => el.type !== "hidden") || inputs[0];
|
|
let pending = 0;
|
|
this.withinTargets(
|
|
phxTarget,
|
|
(targetView, targetCtx) => {
|
|
const cid = this.targetComponentID(newForm, targetCtx);
|
|
pending++;
|
|
let e = new CustomEvent("phx:form-recovery", {
|
|
detail: { sourceElement: oldForm }
|
|
});
|
|
js_default.exec(e, "change", phxEvent, this, input, [
|
|
"push",
|
|
{
|
|
_target: input.name,
|
|
targetView,
|
|
targetCtx,
|
|
newCid: cid,
|
|
callback: () => {
|
|
pending--;
|
|
if (pending === 0) {
|
|
callback();
|
|
}
|
|
}
|
|
}
|
|
]);
|
|
},
|
|
templateDom
|
|
);
|
|
}
|
|
pushLinkPatch(e, href, targetEl, callback) {
|
|
const linkRef = this.liveSocket.setPendingLink(href);
|
|
const loading = e.isTrusted && e.type !== "popstate";
|
|
const refGen = targetEl ? () => this.putRef(
|
|
[{ el: targetEl, loading, lock: true }],
|
|
null,
|
|
"click"
|
|
) : null;
|
|
const fallback = () => this.liveSocket.redirect(window.location.href);
|
|
const url = href.startsWith("/") ? `${location.protocol}//${location.host}${href}` : href;
|
|
this.pushWithReply(refGen, "live_patch", { url }).then(
|
|
({ resp }) => {
|
|
this.liveSocket.requestDOMUpdate(() => {
|
|
if (resp.link_redirect) {
|
|
this.liveSocket.replaceMain(href, null, callback, linkRef);
|
|
} else if (resp.redirect) {
|
|
return;
|
|
} else {
|
|
if (this.liveSocket.commitPendingLink(linkRef)) {
|
|
this.href = href;
|
|
}
|
|
this.applyPendingUpdates();
|
|
callback && callback(linkRef);
|
|
}
|
|
});
|
|
},
|
|
({ error: _error, timeout: _timeout }) => fallback()
|
|
);
|
|
}
|
|
getFormsForRecovery() {
|
|
if (this.joinCount === 0) {
|
|
return {};
|
|
}
|
|
const phxChange = this.binding("change");
|
|
return dom_default.all(
|
|
document,
|
|
`#${CSS.escape(this.id)} form[${phxChange}], [${PHX_TELEPORTED_REF}="${CSS.escape(this.id)}"] form[${phxChange}]`
|
|
).filter((form) => form.id).filter((form) => form.elements.length > 0).filter(
|
|
(form) => form.getAttribute(this.binding(PHX_AUTO_RECOVER)) !== "ignore"
|
|
).map((form) => {
|
|
const clonedForm = form.cloneNode(true);
|
|
morphdom_esm_default(clonedForm, form, {
|
|
onBeforeElUpdated: (fromEl, toEl) => {
|
|
dom_default.copyPrivates(fromEl, toEl);
|
|
if (fromEl.getAttribute("form") === form.id) {
|
|
fromEl.parentNode.removeChild(fromEl);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
});
|
|
const externalElements = document.querySelectorAll(
|
|
`[form="${CSS.escape(form.id)}"]`
|
|
);
|
|
Array.from(externalElements).forEach((el) => {
|
|
const clonedEl = (
|
|
/** @type {HTMLElement} */
|
|
el.cloneNode(true)
|
|
);
|
|
morphdom_esm_default(clonedEl, el);
|
|
dom_default.copyPrivates(clonedEl, el);
|
|
clonedEl.removeAttribute("form");
|
|
clonedForm.appendChild(clonedEl);
|
|
});
|
|
return clonedForm;
|
|
}).reduce((acc, form) => {
|
|
acc[form.id] = form;
|
|
return acc;
|
|
}, {});
|
|
}
|
|
maybePushComponentsDestroyed(destroyedCIDs) {
|
|
let willDestroyCIDs = destroyedCIDs.filter((cid) => {
|
|
return dom_default.findComponentNodeList(this.id, cid).length === 0;
|
|
});
|
|
const onError = (error) => {
|
|
if (!this.isDestroyed()) {
|
|
logError("Failed to push components destroyed", error);
|
|
}
|
|
};
|
|
if (willDestroyCIDs.length > 0) {
|
|
willDestroyCIDs.forEach((cid) => this.rendered.resetRender(cid));
|
|
this.pushWithReply(null, "cids_will_destroy", { cids: willDestroyCIDs }).then(() => {
|
|
this.liveSocket.requestDOMUpdate(() => {
|
|
let completelyDestroyCIDs = willDestroyCIDs.filter((cid) => {
|
|
return dom_default.findComponentNodeList(this.id, cid).length === 0;
|
|
});
|
|
if (completelyDestroyCIDs.length > 0) {
|
|
this.pushWithReply(null, "cids_destroyed", {
|
|
cids: completelyDestroyCIDs
|
|
}).then(({ resp }) => {
|
|
this.rendered.pruneCIDs(resp.cids);
|
|
}).catch(onError);
|
|
}
|
|
});
|
|
}).catch(onError);
|
|
}
|
|
}
|
|
ownsElement(el) {
|
|
let parentViewEl = dom_default.closestViewEl(el);
|
|
return el.getAttribute(PHX_PARENT_ID) === this.id || parentViewEl && parentViewEl.id === this.id || !parentViewEl && this.isDead;
|
|
}
|
|
submitForm(form, targetCtx, phxEvent, submitter, opts = {}) {
|
|
dom_default.putPrivate(form, PHX_HAS_SUBMITTED, true);
|
|
const inputs = Array.from(form.elements);
|
|
inputs.forEach((input) => dom_default.putPrivate(input, PHX_HAS_SUBMITTED, true));
|
|
this.liveSocket.blurActiveElement(this);
|
|
this.pushFormSubmit(form, targetCtx, phxEvent, submitter, opts, () => {
|
|
this.liveSocket.restorePreviouslyActiveFocus();
|
|
});
|
|
}
|
|
binding(kind) {
|
|
return this.liveSocket.binding(kind);
|
|
}
|
|
// phx-portal
|
|
pushPortalElementId(id) {
|
|
this.portalElementIds.add(id);
|
|
}
|
|
dropPortalElementId(id) {
|
|
this.portalElementIds.delete(id);
|
|
}
|
|
destroyPortalElements() {
|
|
if (!this.liveSocket.unloaded) {
|
|
this.portalElementIds.forEach((id) => {
|
|
const el = document.getElementById(id);
|
|
if (el) {
|
|
el.remove();
|
|
}
|
|
});
|
|
}
|
|
}
|
|
};
|
|
var LiveSocket = class {
|
|
constructor(url, phxSocket, opts = {}) {
|
|
this.unloaded = false;
|
|
if (!phxSocket || phxSocket.constructor.name === "Object") {
|
|
throw new Error(`
|
|
a phoenix Socket must be provided as the second argument to the LiveSocket constructor. For example:
|
|
|
|
import {Socket} from "phoenix"
|
|
import {LiveSocket} from "phoenix_live_view"
|
|
let liveSocket = new LiveSocket("/live", Socket, {...})
|
|
`);
|
|
}
|
|
this.socket = new phxSocket(url, opts);
|
|
this.bindingPrefix = opts.bindingPrefix || BINDING_PREFIX;
|
|
this.opts = opts;
|
|
this.params = closure2(opts.params || {});
|
|
this.viewLogger = opts.viewLogger;
|
|
this.metadataCallbacks = opts.metadata || {};
|
|
this.defaults = Object.assign(clone(DEFAULTS), opts.defaults || {});
|
|
this.prevActive = null;
|
|
this.silenced = false;
|
|
this.main = null;
|
|
this.outgoingMainEl = null;
|
|
this.clickStartedAtTarget = null;
|
|
this.linkRef = 1;
|
|
this.roots = {};
|
|
this.href = window.location.href;
|
|
this.pendingLink = null;
|
|
this.currentLocation = clone(window.location);
|
|
this.hooks = opts.hooks || {};
|
|
this.uploaders = opts.uploaders || {};
|
|
this.loaderTimeout = opts.loaderTimeout || LOADER_TIMEOUT;
|
|
this.disconnectedTimeout = opts.disconnectedTimeout || DISCONNECTED_TIMEOUT;
|
|
this.reloadWithJitterTimer = null;
|
|
this.maxReloads = opts.maxReloads || MAX_RELOADS;
|
|
this.reloadJitterMin = opts.reloadJitterMin || RELOAD_JITTER_MIN;
|
|
this.reloadJitterMax = opts.reloadJitterMax || RELOAD_JITTER_MAX;
|
|
this.failsafeJitter = opts.failsafeJitter || FAILSAFE_JITTER;
|
|
this.localStorage = opts.localStorage || window.localStorage;
|
|
this.sessionStorage = opts.sessionStorage || window.sessionStorage;
|
|
this.boundTopLevelEvents = false;
|
|
this.boundEventNames = /* @__PURE__ */ new Set();
|
|
this.blockPhxChangeWhileComposing = opts.blockPhxChangeWhileComposing || false;
|
|
this.serverCloseRef = null;
|
|
this.domCallbacks = Object.assign(
|
|
{
|
|
jsQuerySelectorAll: null,
|
|
onPatchStart: closure2(),
|
|
onPatchEnd: closure2(),
|
|
onNodeAdded: closure2(),
|
|
onBeforeElUpdated: closure2()
|
|
},
|
|
opts.dom || {}
|
|
);
|
|
this.transitions = new TransitionSet();
|
|
this.currentHistoryPosition = parseInt(this.sessionStorage.getItem(PHX_LV_HISTORY_POSITION)) || 0;
|
|
window.addEventListener("pagehide", (_e) => {
|
|
this.unloaded = true;
|
|
});
|
|
this.socket.onOpen(() => {
|
|
if (this.isUnloaded()) {
|
|
window.location.reload();
|
|
}
|
|
});
|
|
}
|
|
// public
|
|
version() {
|
|
return "1.1.30";
|
|
}
|
|
isProfileEnabled() {
|
|
return this.sessionStorage.getItem(PHX_LV_PROFILE) === "true";
|
|
}
|
|
isDebugEnabled() {
|
|
return this.sessionStorage.getItem(PHX_LV_DEBUG) === "true";
|
|
}
|
|
isDebugDisabled() {
|
|
return this.sessionStorage.getItem(PHX_LV_DEBUG) === "false";
|
|
}
|
|
enableDebug() {
|
|
this.sessionStorage.setItem(PHX_LV_DEBUG, "true");
|
|
}
|
|
enableProfiling() {
|
|
this.sessionStorage.setItem(PHX_LV_PROFILE, "true");
|
|
}
|
|
disableDebug() {
|
|
this.sessionStorage.setItem(PHX_LV_DEBUG, "false");
|
|
}
|
|
disableProfiling() {
|
|
this.sessionStorage.removeItem(PHX_LV_PROFILE);
|
|
}
|
|
enableLatencySim(upperBoundMs) {
|
|
this.enableDebug();
|
|
console.log(
|
|
"latency simulator enabled for the duration of this browser session. Call disableLatencySim() to disable"
|
|
);
|
|
this.sessionStorage.setItem(PHX_LV_LATENCY_SIM, upperBoundMs);
|
|
}
|
|
disableLatencySim() {
|
|
this.sessionStorage.removeItem(PHX_LV_LATENCY_SIM);
|
|
}
|
|
getLatencySim() {
|
|
const str = this.sessionStorage.getItem(PHX_LV_LATENCY_SIM);
|
|
return str ? parseInt(str) : null;
|
|
}
|
|
getSocket() {
|
|
return this.socket;
|
|
}
|
|
connect() {
|
|
if (window.location.hostname === "localhost" && !this.isDebugDisabled()) {
|
|
this.enableDebug();
|
|
}
|
|
const doConnect = () => {
|
|
this.resetReloadStatus();
|
|
if (this.joinRootViews()) {
|
|
this.bindTopLevelEvents();
|
|
this.socket.connect();
|
|
} else if (this.main) {
|
|
this.socket.connect();
|
|
} else {
|
|
this.bindTopLevelEvents({ dead: true });
|
|
}
|
|
this.joinDeadView();
|
|
};
|
|
if (["complete", "loaded", "interactive"].indexOf(document.readyState) >= 0) {
|
|
doConnect();
|
|
} else {
|
|
document.addEventListener("DOMContentLoaded", () => doConnect());
|
|
}
|
|
}
|
|
disconnect(callback) {
|
|
clearTimeout(this.reloadWithJitterTimer);
|
|
if (this.serverCloseRef) {
|
|
this.socket.off(this.serverCloseRef);
|
|
this.serverCloseRef = null;
|
|
}
|
|
this.socket.disconnect(callback);
|
|
}
|
|
replaceTransport(transport) {
|
|
clearTimeout(this.reloadWithJitterTimer);
|
|
this.socket.replaceTransport(transport);
|
|
this.connect();
|
|
}
|
|
/**
|
|
* @param {HTMLElement} el
|
|
* @param {string} encodedJS
|
|
* @param {string | null} [eventType]
|
|
*/
|
|
execJS(el, encodedJS, eventType = null) {
|
|
const e = new CustomEvent("phx:exec", { detail: { sourceElement: el } });
|
|
this.owner(el, (view) => js_default.exec(e, eventType, encodedJS, view, el));
|
|
}
|
|
/**
|
|
* Returns an object with methods to manipulate the DOM and execute JavaScript.
|
|
* The applied changes integrate with server DOM patching.
|
|
*
|
|
* @returns {import("./js_commands").LiveSocketJSCommands}
|
|
*/
|
|
js() {
|
|
return js_commands_default(this, "js");
|
|
}
|
|
// private
|
|
unload() {
|
|
if (this.unloaded) {
|
|
return;
|
|
}
|
|
if (this.main && this.isConnected()) {
|
|
this.log(this.main, "socket", () => ["disconnect for page nav"]);
|
|
}
|
|
this.unloaded = true;
|
|
this.destroyAllViews();
|
|
this.disconnect();
|
|
}
|
|
triggerDOM(kind, args) {
|
|
this.domCallbacks[kind](...args);
|
|
}
|
|
time(name, func) {
|
|
if (!this.isProfileEnabled() || !console.time) {
|
|
return func();
|
|
}
|
|
console.time(name);
|
|
const result = func();
|
|
console.timeEnd(name);
|
|
return result;
|
|
}
|
|
log(view, kind, msgCallback) {
|
|
if (this.viewLogger) {
|
|
const [msg, obj] = msgCallback();
|
|
this.viewLogger(view, kind, msg, obj);
|
|
} else if (this.isDebugEnabled()) {
|
|
const [msg, obj] = msgCallback();
|
|
debug(view, kind, msg, obj);
|
|
}
|
|
}
|
|
requestDOMUpdate(callback) {
|
|
this.transitions.after(callback);
|
|
}
|
|
asyncTransition(promise) {
|
|
this.transitions.addAsyncTransition(promise);
|
|
}
|
|
transition(time, onStart, onDone = function() {
|
|
}) {
|
|
this.transitions.addTransition(time, onStart, onDone);
|
|
}
|
|
onChannel(channel, event, cb) {
|
|
channel.on(event, (data) => {
|
|
const latency = this.getLatencySim();
|
|
if (!latency) {
|
|
cb(data);
|
|
} else {
|
|
setTimeout(() => cb(data), latency);
|
|
}
|
|
});
|
|
}
|
|
reloadWithJitter(view, log) {
|
|
clearTimeout(this.reloadWithJitterTimer);
|
|
this.disconnect();
|
|
const minMs = this.reloadJitterMin;
|
|
const maxMs = this.reloadJitterMax;
|
|
let afterMs = Math.floor(Math.random() * (maxMs - minMs + 1)) + minMs;
|
|
const tries = browser_default.updateLocal(
|
|
this.localStorage,
|
|
window.location.pathname,
|
|
CONSECUTIVE_RELOADS,
|
|
0,
|
|
(count) => count + 1
|
|
);
|
|
if (tries >= this.maxReloads) {
|
|
afterMs = this.failsafeJitter;
|
|
}
|
|
this.reloadWithJitterTimer = setTimeout(() => {
|
|
if (view.isDestroyed() || view.isConnected()) {
|
|
return;
|
|
}
|
|
view.destroy();
|
|
log ? log() : this.log(view, "join", () => [
|
|
`encountered ${tries} consecutive reloads`
|
|
]);
|
|
if (tries >= this.maxReloads) {
|
|
this.log(view, "join", () => [
|
|
`exceeded ${this.maxReloads} consecutive reloads. Entering failsafe mode`
|
|
]);
|
|
}
|
|
if (this.hasPendingLink()) {
|
|
window.location = this.pendingLink;
|
|
} else {
|
|
window.location.reload();
|
|
}
|
|
}, afterMs);
|
|
}
|
|
getHookDefinition(name) {
|
|
if (!name) {
|
|
return;
|
|
}
|
|
return this.maybeInternalHook(name) || this.hooks[name] || this.maybeRuntimeHook(name);
|
|
}
|
|
maybeInternalHook(name) {
|
|
return name && name.startsWith("Phoenix.") && hooks_default[name.split(".")[1]];
|
|
}
|
|
maybeRuntimeHook(name) {
|
|
const runtimeHook = document.querySelector(
|
|
`script[${PHX_RUNTIME_HOOK}="${CSS.escape(name)}"]`
|
|
);
|
|
if (!runtimeHook) {
|
|
return;
|
|
}
|
|
let callbacks = window[`phx_hook_${name}`];
|
|
if (!callbacks || typeof callbacks !== "function") {
|
|
logError("a runtime hook must be a function", runtimeHook);
|
|
return;
|
|
}
|
|
const hookDefiniton = callbacks();
|
|
if (hookDefiniton && (typeof hookDefiniton === "object" || typeof hookDefiniton === "function")) {
|
|
return hookDefiniton;
|
|
}
|
|
logError(
|
|
"runtime hook must return an object with hook callbacks or an instance of ViewHook",
|
|
runtimeHook
|
|
);
|
|
}
|
|
isUnloaded() {
|
|
return this.unloaded;
|
|
}
|
|
isConnected() {
|
|
return this.socket.isConnected();
|
|
}
|
|
getBindingPrefix() {
|
|
return this.bindingPrefix;
|
|
}
|
|
binding(kind) {
|
|
return `${this.getBindingPrefix()}${kind}`;
|
|
}
|
|
channel(topic, params) {
|
|
return this.socket.channel(topic, params);
|
|
}
|
|
joinDeadView() {
|
|
const body = document.body;
|
|
if (body && !this.isPhxView(body) && !this.isPhxView(document.firstElementChild)) {
|
|
const view = this.newRootView(body);
|
|
view.setHref(this.getHref());
|
|
view.joinDead();
|
|
if (!this.main) {
|
|
this.main = view;
|
|
}
|
|
window.requestAnimationFrame(() => {
|
|
var _a2;
|
|
view.execNewMounted();
|
|
this.maybeScroll((_a2 = history.state) == null ? void 0 : _a2.scroll);
|
|
});
|
|
}
|
|
}
|
|
joinRootViews() {
|
|
let rootsFound = false;
|
|
dom_default.all(
|
|
document,
|
|
`${PHX_VIEW_SELECTOR}:not([${PHX_PARENT_ID}])`,
|
|
(rootEl) => {
|
|
if (!this.getRootById(rootEl.id)) {
|
|
const view = this.newRootView(rootEl);
|
|
if (!dom_default.isPhxSticky(rootEl)) {
|
|
view.setHref(this.getHref());
|
|
}
|
|
view.join();
|
|
if (rootEl.hasAttribute(PHX_MAIN)) {
|
|
this.main = view;
|
|
}
|
|
}
|
|
rootsFound = true;
|
|
}
|
|
);
|
|
return rootsFound;
|
|
}
|
|
redirect(to, flash, reloadToken) {
|
|
if (reloadToken) {
|
|
browser_default.setCookie(PHX_RELOAD_STATUS, reloadToken, 60);
|
|
}
|
|
this.unload();
|
|
browser_default.redirect(to, flash);
|
|
}
|
|
replaceMain(href, flash, callback = null, linkRef = this.setPendingLink(href)) {
|
|
const liveReferer = this.currentLocation.href;
|
|
this.outgoingMainEl = this.outgoingMainEl || this.main.el;
|
|
const stickies = dom_default.findPhxSticky(document) || [];
|
|
const removeEls = dom_default.all(
|
|
this.outgoingMainEl,
|
|
`[${this.binding("remove")}]`
|
|
).filter((el) => !dom_default.isChildOfAny(el, stickies));
|
|
const newMainEl = dom_default.cloneNode(this.outgoingMainEl, "");
|
|
this.main.showLoader(this.loaderTimeout);
|
|
this.main.destroy();
|
|
this.main = this.newRootView(newMainEl, flash, liveReferer);
|
|
this.main.setRedirect(href);
|
|
this.transitionRemoves(removeEls);
|
|
this.main.join((joinCount, onDone) => {
|
|
if (joinCount === 1 && this.commitPendingLink(linkRef)) {
|
|
this.requestDOMUpdate(() => {
|
|
removeEls.forEach((el) => el.remove());
|
|
stickies.forEach((el) => newMainEl.appendChild(el));
|
|
this.outgoingMainEl.replaceWith(newMainEl);
|
|
this.outgoingMainEl = null;
|
|
callback && callback(linkRef);
|
|
onDone();
|
|
});
|
|
}
|
|
});
|
|
}
|
|
transitionRemoves(elements, callback) {
|
|
const removeAttr = this.binding("remove");
|
|
const silenceEvents = (e) => {
|
|
e.preventDefault();
|
|
e.stopImmediatePropagation();
|
|
};
|
|
elements.forEach((el) => {
|
|
for (const event of this.boundEventNames) {
|
|
el.addEventListener(event, silenceEvents, true);
|
|
}
|
|
this.execJS(el, el.getAttribute(removeAttr), "remove");
|
|
});
|
|
this.requestDOMUpdate(() => {
|
|
elements.forEach((el) => {
|
|
for (const event of this.boundEventNames) {
|
|
el.removeEventListener(event, silenceEvents, true);
|
|
}
|
|
});
|
|
callback && callback();
|
|
});
|
|
}
|
|
isPhxView(el) {
|
|
return el.getAttribute && el.getAttribute(PHX_SESSION) !== null;
|
|
}
|
|
newRootView(el, flash, liveReferer) {
|
|
const view = new View(el, this, null, flash, liveReferer);
|
|
this.roots[view.id] = view;
|
|
return view;
|
|
}
|
|
owner(childEl, callback) {
|
|
let view;
|
|
const viewEl = dom_default.closestViewEl(childEl);
|
|
if (viewEl) {
|
|
view = this.getViewByEl(viewEl);
|
|
} else {
|
|
if (!childEl.isConnected) {
|
|
return null;
|
|
}
|
|
view = this.main;
|
|
}
|
|
return view && callback ? callback(view) : view;
|
|
}
|
|
withinOwners(childEl, callback) {
|
|
this.owner(childEl, (view) => callback(view, childEl));
|
|
}
|
|
getViewByEl(el) {
|
|
const rootId = el.getAttribute(PHX_ROOT_ID);
|
|
return maybe(
|
|
this.getRootById(rootId),
|
|
(root) => root.getDescendentByEl(el)
|
|
);
|
|
}
|
|
getRootById(id) {
|
|
return this.roots[id];
|
|
}
|
|
destroyAllViews() {
|
|
for (const id in this.roots) {
|
|
this.roots[id].destroy();
|
|
delete this.roots[id];
|
|
}
|
|
this.main = null;
|
|
}
|
|
destroyViewByEl(el) {
|
|
const root = this.getRootById(el.getAttribute(PHX_ROOT_ID));
|
|
if (root && root.id === el.id) {
|
|
root.destroy();
|
|
delete this.roots[root.id];
|
|
} else if (root) {
|
|
root.destroyDescendent(el.id);
|
|
}
|
|
}
|
|
getActiveElement() {
|
|
return document.activeElement;
|
|
}
|
|
dropActiveElement(view) {
|
|
if (this.prevActive && view.ownsElement(this.prevActive)) {
|
|
this.prevActive = null;
|
|
}
|
|
}
|
|
restorePreviouslyActiveFocus() {
|
|
if (this.prevActive && this.prevActive !== document.body && this.prevActive instanceof HTMLElement) {
|
|
this.prevActive.focus();
|
|
}
|
|
}
|
|
blurActiveElement() {
|
|
this.prevActive = this.getActiveElement();
|
|
if (this.prevActive !== document.body && this.prevActive instanceof HTMLElement) {
|
|
this.prevActive.blur();
|
|
}
|
|
}
|
|
/**
|
|
* @param {{dead?: boolean}} [options={}]
|
|
*/
|
|
bindTopLevelEvents({ dead } = {}) {
|
|
if (this.boundTopLevelEvents) {
|
|
return;
|
|
}
|
|
this.boundTopLevelEvents = true;
|
|
this.serverCloseRef = this.socket.onClose((event) => {
|
|
if (event && event.code === 1e3 && this.main) {
|
|
return this.reloadWithJitter(this.main);
|
|
}
|
|
});
|
|
document.body.addEventListener("click", function() {
|
|
});
|
|
window.addEventListener(
|
|
"pageshow",
|
|
(e) => {
|
|
if (e.persisted) {
|
|
this.getSocket().disconnect();
|
|
this.withPageLoading({ to: window.location.href, kind: "redirect" });
|
|
window.location.reload();
|
|
}
|
|
},
|
|
true
|
|
);
|
|
if (!dead) {
|
|
this.bindNav();
|
|
}
|
|
this.bindClicks();
|
|
if (!dead) {
|
|
this.bindForms();
|
|
}
|
|
this.bind(
|
|
{ keyup: "keyup", keydown: "keydown" },
|
|
(e, type, view, targetEl, phxEvent, _phxTarget) => {
|
|
const matchKey = targetEl.getAttribute(this.binding(PHX_KEY));
|
|
const pressedKey = e.key && e.key.toLowerCase();
|
|
if (matchKey && matchKey.toLowerCase() !== pressedKey) {
|
|
return;
|
|
}
|
|
const data = __spreadValues({ key: e.key }, this.eventMeta(type, e, targetEl));
|
|
js_default.exec(e, type, phxEvent, view, targetEl, ["push", { data }]);
|
|
}
|
|
);
|
|
this.bind(
|
|
{ blur: "focusout", focus: "focusin" },
|
|
(e, type, view, targetEl, phxEvent, phxTarget) => {
|
|
if (!phxTarget) {
|
|
const data = __spreadValues({ key: e.key }, this.eventMeta(type, e, targetEl));
|
|
js_default.exec(e, type, phxEvent, view, targetEl, ["push", { data }]);
|
|
}
|
|
}
|
|
);
|
|
this.bind(
|
|
{ blur: "blur", focus: "focus" },
|
|
(e, type, view, targetEl, phxEvent, phxTarget) => {
|
|
if (phxTarget === "window") {
|
|
const data = this.eventMeta(type, e, targetEl);
|
|
js_default.exec(e, type, phxEvent, view, targetEl, ["push", { data }]);
|
|
}
|
|
}
|
|
);
|
|
this.on("dragover", (e) => e.preventDefault());
|
|
this.on("dragenter", (e) => {
|
|
const dropzone = closestPhxBinding(
|
|
e.target,
|
|
this.binding(PHX_DROP_TARGET)
|
|
);
|
|
if (!dropzone || !(dropzone instanceof HTMLElement)) {
|
|
return;
|
|
}
|
|
if (eventContainsFiles(e)) {
|
|
this.js().addClass(dropzone, PHX_DROP_TARGET_ACTIVE_CLASS);
|
|
}
|
|
});
|
|
this.on("dragleave", (e) => {
|
|
const dropzone = closestPhxBinding(
|
|
e.target,
|
|
this.binding(PHX_DROP_TARGET)
|
|
);
|
|
if (!dropzone || !(dropzone instanceof HTMLElement)) {
|
|
return;
|
|
}
|
|
const rect = dropzone.getBoundingClientRect();
|
|
if (e.clientX <= rect.left || e.clientX >= rect.right || e.clientY <= rect.top || e.clientY >= rect.bottom) {
|
|
this.js().removeClass(dropzone, PHX_DROP_TARGET_ACTIVE_CLASS);
|
|
}
|
|
});
|
|
this.on("drop", (e) => {
|
|
e.preventDefault();
|
|
const dropzone = closestPhxBinding(
|
|
e.target,
|
|
this.binding(PHX_DROP_TARGET)
|
|
);
|
|
if (!dropzone || !(dropzone instanceof HTMLElement)) {
|
|
return;
|
|
}
|
|
this.js().removeClass(dropzone, PHX_DROP_TARGET_ACTIVE_CLASS);
|
|
const dropTargetId = dropzone.getAttribute(this.binding(PHX_DROP_TARGET));
|
|
const dropTarget = dropTargetId && document.getElementById(dropTargetId);
|
|
const files = Array.from(e.dataTransfer.files || []);
|
|
if (!dropTarget || !(dropTarget instanceof HTMLInputElement) || dropTarget.disabled || files.length === 0 || !(dropTarget.files instanceof FileList)) {
|
|
return;
|
|
}
|
|
LiveUploader.trackFiles(dropTarget, files, e.dataTransfer);
|
|
dropTarget.dispatchEvent(new Event("input", { bubbles: true }));
|
|
});
|
|
this.on(PHX_TRACK_UPLOADS, (e) => {
|
|
const uploadTarget = e.target;
|
|
if (!dom_default.isUploadInput(uploadTarget)) {
|
|
return;
|
|
}
|
|
const files = Array.from(e.detail.files || []).filter(
|
|
(f) => f instanceof File || f instanceof Blob
|
|
);
|
|
LiveUploader.trackFiles(uploadTarget, files);
|
|
uploadTarget.dispatchEvent(new Event("input", { bubbles: true }));
|
|
});
|
|
}
|
|
eventMeta(eventName, e, targetEl) {
|
|
const callback = this.metadataCallbacks[eventName];
|
|
return callback ? callback(e, targetEl) : {};
|
|
}
|
|
setPendingLink(href) {
|
|
this.linkRef++;
|
|
this.pendingLink = href;
|
|
this.resetReloadStatus();
|
|
return this.linkRef;
|
|
}
|
|
// anytime we are navigating or connecting, drop reload cookie in case
|
|
// we issue the cookie but the next request was interrupted and the server never dropped it
|
|
resetReloadStatus() {
|
|
browser_default.deleteCookie(PHX_RELOAD_STATUS);
|
|
}
|
|
commitPendingLink(linkRef) {
|
|
if (this.linkRef !== linkRef) {
|
|
return false;
|
|
} else {
|
|
this.href = this.pendingLink;
|
|
this.pendingLink = null;
|
|
return true;
|
|
}
|
|
}
|
|
getHref() {
|
|
return this.href;
|
|
}
|
|
hasPendingLink() {
|
|
return !!this.pendingLink;
|
|
}
|
|
bind(events, callback) {
|
|
for (const event in events) {
|
|
const browserEventName = events[event];
|
|
this.on(browserEventName, (e) => {
|
|
const binding = this.binding(event);
|
|
const windowBinding = this.binding(`window-${event}`);
|
|
const targetPhxEvent = e.target.getAttribute && e.target.getAttribute(binding);
|
|
if (targetPhxEvent) {
|
|
this.debounce(e.target, e, browserEventName, () => {
|
|
this.withinOwners(e.target, (view) => {
|
|
callback(e, event, view, e.target, targetPhxEvent, null);
|
|
});
|
|
});
|
|
} else {
|
|
dom_default.all(document, `[${windowBinding}]`, (el) => {
|
|
const phxEvent = el.getAttribute(windowBinding);
|
|
this.debounce(el, e, browserEventName, () => {
|
|
this.withinOwners(el, (view) => {
|
|
callback(e, event, view, el, phxEvent, "window");
|
|
});
|
|
});
|
|
});
|
|
}
|
|
});
|
|
}
|
|
}
|
|
bindClicks() {
|
|
this.on("mousedown", (e) => this.clickStartedAtTarget = e.target);
|
|
this.bindClick("click", "click");
|
|
}
|
|
bindClick(eventName, bindingName) {
|
|
const click = this.binding(bindingName);
|
|
window.addEventListener(
|
|
eventName,
|
|
(e) => {
|
|
let target = null;
|
|
if (e.detail === 0)
|
|
this.clickStartedAtTarget = e.target;
|
|
const clickStartedAtTarget = this.clickStartedAtTarget || e.target;
|
|
target = closestPhxBinding(e.target, click);
|
|
this.dispatchClickAway(e, clickStartedAtTarget);
|
|
this.clickStartedAtTarget = null;
|
|
const phxEvent = target && target.getAttribute(click);
|
|
if (!phxEvent) {
|
|
if (dom_default.isNewPageClick(e, window.location)) {
|
|
this.unload();
|
|
}
|
|
return;
|
|
}
|
|
if (target.getAttribute("href") === "#") {
|
|
e.preventDefault();
|
|
}
|
|
if (target.hasAttribute(PHX_REF_SRC)) {
|
|
return;
|
|
}
|
|
this.debounce(target, e, "click", () => {
|
|
this.withinOwners(target, (view) => {
|
|
js_default.exec(e, "click", phxEvent, view, target, [
|
|
"push",
|
|
{ data: this.eventMeta("click", e, target) }
|
|
]);
|
|
});
|
|
});
|
|
},
|
|
false
|
|
);
|
|
}
|
|
dispatchClickAway(e, clickStartedAt) {
|
|
const phxClickAway = this.binding("click-away");
|
|
const portal = clickStartedAt.closest(`[${PHX_TELEPORTED_SRC}]`);
|
|
const portalStartedAt = portal && dom_default.byId(portal.getAttribute(PHX_TELEPORTED_SRC));
|
|
dom_default.all(document, `[${phxClickAway}]`, (el) => {
|
|
let startedAt = clickStartedAt;
|
|
if (portal && !portal.contains(el)) {
|
|
startedAt = portalStartedAt;
|
|
}
|
|
if (!(el.isSameNode(startedAt) || el.contains(startedAt) || // When clicking a link with custom method,
|
|
// phoenix_html triggers a click on a submit button
|
|
// of a hidden form appended to the body. For such cases
|
|
// where the clicked target is hidden, we skip click-away.
|
|
//
|
|
// Also, when we have a portal, we don't want to check the visibility
|
|
// of the portal source, as it's a <template> that is always not visible.
|
|
// Instead, check the visibility of the original click target.
|
|
!js_default.isVisible(clickStartedAt))) {
|
|
this.withinOwners(el, (view) => {
|
|
const phxEvent = el.getAttribute(phxClickAway);
|
|
if (js_default.isVisible(el) && js_default.isInViewport(el)) {
|
|
js_default.exec(e, "click", phxEvent, view, el, [
|
|
"push",
|
|
{ data: this.eventMeta("click", e, e.target) }
|
|
]);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
bindNav() {
|
|
if (!browser_default.canPushState()) {
|
|
return;
|
|
}
|
|
if (history.scrollRestoration) {
|
|
history.scrollRestoration = "manual";
|
|
}
|
|
let scrollTimer = null;
|
|
window.addEventListener("scroll", (_e) => {
|
|
clearTimeout(scrollTimer);
|
|
scrollTimer = setTimeout(() => {
|
|
browser_default.updateCurrentState(
|
|
(state) => Object.assign(state, { scroll: window.scrollY })
|
|
);
|
|
}, 100);
|
|
});
|
|
window.addEventListener(
|
|
"popstate",
|
|
(event) => {
|
|
if (!this.registerNewLocation(window.location)) {
|
|
return;
|
|
}
|
|
const { type, backType, id, scroll, position } = event.state || {};
|
|
const href = window.location.href;
|
|
const isForward = position > this.currentHistoryPosition;
|
|
const navType = isForward ? type : backType || type;
|
|
this.currentHistoryPosition = position || 0;
|
|
this.sessionStorage.setItem(
|
|
PHX_LV_HISTORY_POSITION,
|
|
this.currentHistoryPosition.toString()
|
|
);
|
|
dom_default.dispatchEvent(window, "phx:navigate", {
|
|
detail: {
|
|
href,
|
|
patch: navType === "patch",
|
|
pop: true,
|
|
direction: isForward ? "forward" : "backward"
|
|
}
|
|
});
|
|
this.requestDOMUpdate(() => {
|
|
const callback = () => {
|
|
this.maybeScroll(scroll);
|
|
};
|
|
if (this.main.isConnected() && navType === "patch" && id === this.main.id) {
|
|
this.main.pushLinkPatch(event, href, null, callback);
|
|
} else {
|
|
this.replaceMain(href, null, callback);
|
|
}
|
|
});
|
|
},
|
|
false
|
|
);
|
|
window.addEventListener(
|
|
"click",
|
|
(e) => {
|
|
const target = closestPhxBinding(e.target, PHX_LIVE_LINK);
|
|
const type = target && target.getAttribute(PHX_LIVE_LINK);
|
|
if (!type || !this.isConnected() || !this.main || dom_default.wantsNewTab(e)) {
|
|
return;
|
|
}
|
|
const href = target.href instanceof SVGAnimatedString ? target.href.baseVal : target.href;
|
|
const linkState = target.getAttribute(PHX_LINK_STATE);
|
|
e.preventDefault();
|
|
e.stopImmediatePropagation();
|
|
if (this.pendingLink === href) {
|
|
return;
|
|
}
|
|
this.requestDOMUpdate(() => {
|
|
if (type === "patch") {
|
|
this.pushHistoryPatch(e, href, linkState, target);
|
|
} else if (type === "redirect") {
|
|
this.historyRedirect(e, href, linkState, null, target);
|
|
} else {
|
|
throw new Error(
|
|
`expected ${PHX_LIVE_LINK} to be "patch" or "redirect", got: ${type}`
|
|
);
|
|
}
|
|
const phxClick = target.getAttribute(this.binding("click"));
|
|
if (phxClick) {
|
|
this.requestDOMUpdate(() => this.execJS(target, phxClick, "click"));
|
|
}
|
|
});
|
|
},
|
|
false
|
|
);
|
|
}
|
|
maybeScroll(scroll) {
|
|
if (typeof scroll === "number") {
|
|
requestAnimationFrame(() => {
|
|
window.scrollTo(0, scroll);
|
|
});
|
|
}
|
|
}
|
|
dispatchEvent(event, payload = {}) {
|
|
dom_default.dispatchEvent(window, `phx:${event}`, { detail: payload });
|
|
}
|
|
dispatchEvents(events) {
|
|
events.forEach(([event, payload]) => this.dispatchEvent(event, payload));
|
|
}
|
|
withPageLoading(info, callback) {
|
|
dom_default.dispatchEvent(window, "phx:page-loading-start", { detail: info });
|
|
const done = () => dom_default.dispatchEvent(window, "phx:page-loading-stop", { detail: info });
|
|
return callback ? callback(done) : done;
|
|
}
|
|
pushHistoryPatch(e, href, linkState, targetEl) {
|
|
if (!this.isConnected() || !this.main.isMain()) {
|
|
return browser_default.redirect(href);
|
|
}
|
|
this.withPageLoading({ to: href, kind: "patch" }, (done) => {
|
|
this.main.pushLinkPatch(e, href, targetEl, (linkRef) => {
|
|
this.historyPatch(href, linkState, linkRef);
|
|
done();
|
|
});
|
|
});
|
|
}
|
|
historyPatch(href, linkState, linkRef = this.setPendingLink(href)) {
|
|
if (!this.commitPendingLink(linkRef)) {
|
|
return;
|
|
}
|
|
this.currentHistoryPosition++;
|
|
this.sessionStorage.setItem(
|
|
PHX_LV_HISTORY_POSITION,
|
|
this.currentHistoryPosition.toString()
|
|
);
|
|
browser_default.updateCurrentState((state) => __spreadProps(__spreadValues({}, state), { backType: "patch" }));
|
|
browser_default.pushState(
|
|
linkState,
|
|
{
|
|
type: "patch",
|
|
id: this.main.id,
|
|
position: this.currentHistoryPosition
|
|
},
|
|
href
|
|
);
|
|
dom_default.dispatchEvent(window, "phx:navigate", {
|
|
detail: { patch: true, href, pop: false, direction: "forward" }
|
|
});
|
|
this.registerNewLocation(window.location);
|
|
}
|
|
historyRedirect(e, href, linkState, flash, targetEl) {
|
|
const clickLoading = targetEl && e.isTrusted && e.type !== "popstate";
|
|
if (clickLoading) {
|
|
targetEl.classList.add("phx-click-loading");
|
|
}
|
|
if (!this.isConnected() || !this.main.isMain()) {
|
|
return browser_default.redirect(href, flash);
|
|
}
|
|
if (/^\/$|^\/[^\/]+.*$/.test(href)) {
|
|
const { protocol, host } = window.location;
|
|
href = `${protocol}//${host}${href}`;
|
|
}
|
|
const scroll = window.scrollY;
|
|
this.withPageLoading({ to: href, kind: "redirect" }, (done) => {
|
|
this.replaceMain(href, flash, (linkRef) => {
|
|
if (linkRef === this.linkRef) {
|
|
this.currentHistoryPosition++;
|
|
this.sessionStorage.setItem(
|
|
PHX_LV_HISTORY_POSITION,
|
|
this.currentHistoryPosition.toString()
|
|
);
|
|
browser_default.updateCurrentState((state) => __spreadProps(__spreadValues({}, state), {
|
|
backType: "redirect"
|
|
}));
|
|
browser_default.pushState(
|
|
linkState,
|
|
{
|
|
type: "redirect",
|
|
id: this.main.id,
|
|
scroll,
|
|
position: this.currentHistoryPosition
|
|
},
|
|
href
|
|
);
|
|
dom_default.dispatchEvent(window, "phx:navigate", {
|
|
detail: { href, patch: false, pop: false, direction: "forward" }
|
|
});
|
|
this.registerNewLocation(window.location);
|
|
}
|
|
if (clickLoading) {
|
|
targetEl.classList.remove("phx-click-loading");
|
|
}
|
|
done();
|
|
});
|
|
});
|
|
}
|
|
registerNewLocation(newLocation) {
|
|
const { pathname, search } = this.currentLocation;
|
|
if (pathname + search === newLocation.pathname + newLocation.search) {
|
|
return false;
|
|
} else {
|
|
this.currentLocation = clone(newLocation);
|
|
return true;
|
|
}
|
|
}
|
|
bindForms() {
|
|
let iterations = 0;
|
|
let externalFormSubmitted = false;
|
|
this.on("submit", (e) => {
|
|
const phxSubmit = e.target.getAttribute(this.binding("submit"));
|
|
const phxChange = e.target.getAttribute(this.binding("change"));
|
|
if (!externalFormSubmitted && phxChange && !phxSubmit) {
|
|
externalFormSubmitted = true;
|
|
e.preventDefault();
|
|
this.withinOwners(e.target, (view) => {
|
|
view.disableForm(e.target);
|
|
window.requestAnimationFrame(() => {
|
|
if (dom_default.isUnloadableFormSubmit(e)) {
|
|
this.unload();
|
|
}
|
|
e.target.submit();
|
|
});
|
|
});
|
|
}
|
|
});
|
|
this.on("submit", (e) => {
|
|
const phxEvent = e.target.getAttribute(this.binding("submit"));
|
|
if (!phxEvent) {
|
|
if (dom_default.isUnloadableFormSubmit(e)) {
|
|
this.unload();
|
|
}
|
|
return;
|
|
}
|
|
e.preventDefault();
|
|
e.target.disabled = true;
|
|
this.withinOwners(e.target, (view) => {
|
|
js_default.exec(e, "submit", phxEvent, view, e.target, [
|
|
"push",
|
|
{ submitter: e.submitter }
|
|
]);
|
|
});
|
|
});
|
|
for (const type of ["change", "input"]) {
|
|
this.on(type, (e) => {
|
|
if (e instanceof CustomEvent && (e.target instanceof HTMLInputElement || e.target instanceof HTMLSelectElement || e.target instanceof HTMLTextAreaElement) && e.target.form === void 0) {
|
|
if (e.detail && e.detail.dispatcher) {
|
|
throw new Error(
|
|
`dispatching a custom ${type} event is only supported on input elements inside a form`
|
|
);
|
|
}
|
|
return;
|
|
}
|
|
const phxChange = this.binding("change");
|
|
const input = e.target;
|
|
if (this.blockPhxChangeWhileComposing && e.isComposing) {
|
|
const key = `composition-listener-${type}`;
|
|
if (!dom_default.private(input, key)) {
|
|
dom_default.putPrivate(input, key, true);
|
|
input.addEventListener(
|
|
"compositionend",
|
|
() => {
|
|
input.dispatchEvent(new Event(type, { bubbles: true }));
|
|
dom_default.deletePrivate(input, key);
|
|
},
|
|
{ once: true }
|
|
);
|
|
}
|
|
return;
|
|
}
|
|
const inputEvent = input.getAttribute(phxChange);
|
|
const formEvent = input.form && input.form.getAttribute(phxChange);
|
|
const phxEvent = inputEvent || formEvent;
|
|
if (!phxEvent) {
|
|
return;
|
|
}
|
|
if (input.type === "number" && input.validity && input.validity.badInput) {
|
|
return;
|
|
}
|
|
const dispatcher = inputEvent ? input : input.form;
|
|
const currentIterations = iterations;
|
|
iterations++;
|
|
const { at, type: lastType } = dom_default.private(input, "prev-iteration") || {};
|
|
if (at === currentIterations - 1 && type === "change" && lastType === "input") {
|
|
return;
|
|
}
|
|
dom_default.putPrivate(input, "prev-iteration", {
|
|
at: currentIterations,
|
|
type
|
|
});
|
|
this.debounce(input, e, type, () => {
|
|
this.withinOwners(dispatcher, (view) => {
|
|
dom_default.putPrivate(input, PHX_HAS_FOCUSED, true);
|
|
js_default.exec(e, "change", phxEvent, view, input, [
|
|
"push",
|
|
{ _target: e.target.name, dispatcher }
|
|
]);
|
|
});
|
|
});
|
|
});
|
|
}
|
|
this.on("reset", (e) => {
|
|
const form = e.target;
|
|
dom_default.resetForm(form);
|
|
const input = Array.from(form.elements).find((el) => el.type === "reset");
|
|
if (input) {
|
|
window.requestAnimationFrame(() => {
|
|
input.dispatchEvent(
|
|
new Event("input", { bubbles: true, cancelable: false })
|
|
);
|
|
});
|
|
}
|
|
});
|
|
}
|
|
debounce(el, event, eventType, callback) {
|
|
if (eventType === "blur" || eventType === "focusout") {
|
|
return callback();
|
|
}
|
|
const phxDebounce = this.binding(PHX_DEBOUNCE);
|
|
const phxThrottle = this.binding(PHX_THROTTLE);
|
|
const defaultDebounce = this.defaults.debounce.toString();
|
|
const defaultThrottle = this.defaults.throttle.toString();
|
|
this.withinOwners(el, (view) => {
|
|
const asyncFilter = () => !view.isDestroyed() && document.body.contains(el);
|
|
dom_default.debounce(
|
|
el,
|
|
event,
|
|
phxDebounce,
|
|
defaultDebounce,
|
|
phxThrottle,
|
|
defaultThrottle,
|
|
asyncFilter,
|
|
() => {
|
|
callback();
|
|
}
|
|
);
|
|
});
|
|
}
|
|
silenceEvents(callback) {
|
|
this.silenced = true;
|
|
callback();
|
|
this.silenced = false;
|
|
}
|
|
on(event, callback) {
|
|
this.boundEventNames.add(event);
|
|
window.addEventListener(event, (e) => {
|
|
if (!this.silenced) {
|
|
callback(e);
|
|
}
|
|
});
|
|
}
|
|
jsQuerySelectorAll(sourceEl, query, defaultQuery) {
|
|
const all = this.domCallbacks.jsQuerySelectorAll;
|
|
return all ? all(sourceEl, query, defaultQuery) : defaultQuery();
|
|
}
|
|
};
|
|
var TransitionSet = class {
|
|
constructor() {
|
|
this.transitions = /* @__PURE__ */ new Set();
|
|
this.promises = /* @__PURE__ */ new Set();
|
|
this.pendingOps = [];
|
|
}
|
|
reset() {
|
|
this.transitions.forEach((timer) => {
|
|
clearTimeout(timer);
|
|
this.transitions.delete(timer);
|
|
});
|
|
this.promises.clear();
|
|
this.flushPendingOps();
|
|
}
|
|
after(callback) {
|
|
if (this.size() === 0) {
|
|
callback();
|
|
} else {
|
|
this.pushPendingOp(callback);
|
|
}
|
|
}
|
|
addTransition(time, onStart, onDone) {
|
|
onStart();
|
|
const timer = setTimeout(() => {
|
|
this.transitions.delete(timer);
|
|
onDone();
|
|
this.flushPendingOps();
|
|
}, time);
|
|
this.transitions.add(timer);
|
|
}
|
|
addAsyncTransition(promise) {
|
|
this.promises.add(promise);
|
|
promise.then(() => {
|
|
this.promises.delete(promise);
|
|
this.flushPendingOps();
|
|
});
|
|
}
|
|
pushPendingOp(op) {
|
|
this.pendingOps.push(op);
|
|
}
|
|
size() {
|
|
return this.transitions.size + this.promises.size;
|
|
}
|
|
flushPendingOps() {
|
|
if (this.size() > 0) {
|
|
return;
|
|
}
|
|
const op = this.pendingOps.shift();
|
|
if (op) {
|
|
op();
|
|
this.flushPendingOps();
|
|
}
|
|
}
|
|
};
|
|
var LiveSocket2 = LiveSocket;
|
|
|
|
// ../_build/dev/phoenix-colocated/towerops/index.js
|
|
var hooks = {};
|
|
|
|
// js/app.ts
|
|
var import_topbar = __toESM(require_topbar());
|
|
var import_chart = __toESM(require_chart());
|
|
var import_cytoscape = __toESM(require_cytoscape());
|
|
|
|
// js/device_list_reorder.ts
|
|
var DeviceListReorder = {
|
|
draggedElement: null,
|
|
dragData: null,
|
|
handleDragStart: null,
|
|
handleDragEnd: null,
|
|
handleDragOver: null,
|
|
handleDrop: null,
|
|
dragHandleListeners: [],
|
|
mounted() {
|
|
this.handleDragStart = (e) => {
|
|
const target = e.target.closest("[data-site-id]");
|
|
if (!target) return;
|
|
if (target.getAttribute("draggable") !== "true") return;
|
|
const siteId = target.dataset.siteId;
|
|
const position = parseInt(target.dataset.sitePosition || target.dataset.devicePosition || "0");
|
|
if (target.classList.contains("site-header")) {
|
|
this.draggedElement = target;
|
|
this.dragData = { type: "site", id: siteId, siteId, position };
|
|
target.classList.add("opacity-50");
|
|
} else if (target.classList.contains("device-row")) {
|
|
const deviceId = target.dataset.deviceId;
|
|
this.draggedElement = target;
|
|
this.dragData = { type: "device", id: deviceId, siteId, position };
|
|
target.classList.add("opacity-50");
|
|
}
|
|
e.dataTransfer.effectAllowed = "move";
|
|
};
|
|
this.handleDragEnd = (_e) => {
|
|
if (this.draggedElement) {
|
|
this.draggedElement.classList.remove("opacity-50");
|
|
this.draggedElement = null;
|
|
}
|
|
this.dragData = null;
|
|
this.el.querySelectorAll(".border-blue-500").forEach((el) => {
|
|
el.classList.remove("border-blue-500", "border-t-4", "border-b-4");
|
|
});
|
|
};
|
|
this.handleDragOver = (e) => {
|
|
e.preventDefault();
|
|
if (!this.dragData) return;
|
|
const target = e.target.closest("[data-site-id], [data-device-id]");
|
|
if (!target || target === this.draggedElement) return;
|
|
const rect = target.getBoundingClientRect();
|
|
const middleY = rect.top + rect.height / 2;
|
|
const isBottomHalf = e.clientY > middleY;
|
|
this.el.querySelectorAll(".border-blue-500").forEach((el) => {
|
|
el.classList.remove("border-blue-500", "border-t-4", "border-b-4");
|
|
});
|
|
target.classList.add("border-blue-500", isBottomHalf ? "border-b-4" : "border-t-4");
|
|
};
|
|
this.handleDrop = (e) => {
|
|
e.preventDefault();
|
|
if (!this.dragData) return;
|
|
const target = e.target.closest("[data-site-id], [data-device-id]");
|
|
if (!target || target === this.draggedElement) return;
|
|
const dropSiteId = target.dataset.siteId;
|
|
let dropPosition = parseInt(target.dataset.sitePosition || target.dataset.devicePosition || "0");
|
|
const rect = target.getBoundingClientRect();
|
|
const middleY = rect.top + rect.height / 2;
|
|
if (e.clientY > middleY) {
|
|
dropPosition += 1;
|
|
}
|
|
if (this.dragData.type === "site" && target.classList.contains("site-header")) {
|
|
this.pushEvent("reorder_site", {
|
|
site_id: this.dragData.id,
|
|
new_position: dropPosition
|
|
});
|
|
} else if (this.dragData.type === "device" && target.classList.contains("device-row")) {
|
|
if (dropSiteId === this.dragData.siteId) {
|
|
this.pushEvent("reorder_device", {
|
|
device_id: this.dragData.id,
|
|
new_position: dropPosition
|
|
});
|
|
}
|
|
}
|
|
this.el.querySelectorAll(".border-blue-500").forEach((el) => {
|
|
el.classList.remove("border-blue-500", "border-t-4", "border-b-4");
|
|
});
|
|
};
|
|
this.el.addEventListener("dragstart", this.handleDragStart);
|
|
this.el.addEventListener("dragend", this.handleDragEnd);
|
|
this.el.addEventListener("dragover", this.handleDragOver);
|
|
this.el.addEventListener("drop", this.handleDrop);
|
|
this.dragHandleListeners = [];
|
|
this.el.querySelectorAll(".drag-handle").forEach((handle) => {
|
|
const handler = (e) => {
|
|
e.stopPropagation();
|
|
};
|
|
handle.addEventListener("click", handler);
|
|
this.dragHandleListeners.push({ element: handle, handler });
|
|
});
|
|
},
|
|
destroyed() {
|
|
if (this.handleDragStart) {
|
|
this.el.removeEventListener("dragstart", this.handleDragStart);
|
|
this.handleDragStart = null;
|
|
}
|
|
if (this.handleDragEnd) {
|
|
this.el.removeEventListener("dragend", this.handleDragEnd);
|
|
this.handleDragEnd = null;
|
|
}
|
|
if (this.handleDragOver) {
|
|
this.el.removeEventListener("dragover", this.handleDragOver);
|
|
this.handleDragOver = null;
|
|
}
|
|
if (this.handleDrop) {
|
|
this.el.removeEventListener("drop", this.handleDrop);
|
|
this.handleDrop = null;
|
|
}
|
|
this.dragHandleListeners.forEach(({ element, handler }) => {
|
|
element.removeEventListener("click", handler);
|
|
});
|
|
this.dragHandleListeners = [];
|
|
this.draggedElement = null;
|
|
this.dragData = null;
|
|
}
|
|
};
|
|
|
|
// js/sortable_list.ts
|
|
var SortableList = {
|
|
draggedEl: null,
|
|
handleDragStart: null,
|
|
handleDragEnd: null,
|
|
handleDragOver: null,
|
|
handleDrop: null,
|
|
mounted() {
|
|
const container = this.el;
|
|
const eventName = container.dataset.event || "reorder";
|
|
const itemFromTarget = (t) => {
|
|
const el = t;
|
|
return el ? el.closest("[data-id]") || null : null;
|
|
};
|
|
const itemIsDirectChild = (item) => {
|
|
return !!item && item.parentElement === container;
|
|
};
|
|
this.handleDragStart = (e) => {
|
|
const item = itemFromTarget(e.target);
|
|
if (!itemIsDirectChild(item) || item.getAttribute("draggable") !== "true") return;
|
|
this.draggedEl = item;
|
|
item.classList.add("opacity-50");
|
|
e.dataTransfer.effectAllowed = "move";
|
|
};
|
|
this.handleDragEnd = (_e) => {
|
|
if (this.draggedEl) {
|
|
this.draggedEl.classList.remove("opacity-50");
|
|
this.draggedEl = null;
|
|
}
|
|
container.querySelectorAll(".sortable-drop-target").forEach((el) => {
|
|
el.classList.remove("sortable-drop-target", "border-t-4", "border-b-4", "border-blue-500");
|
|
});
|
|
};
|
|
this.handleDragOver = (e) => {
|
|
e.preventDefault();
|
|
if (!this.draggedEl) return;
|
|
const target = itemFromTarget(e.target);
|
|
if (!itemIsDirectChild(target) || target === this.draggedEl) return;
|
|
const rect = target.getBoundingClientRect();
|
|
const isBottomHalf = e.clientY > rect.top + rect.height / 2;
|
|
container.querySelectorAll(".sortable-drop-target").forEach((el) => {
|
|
el.classList.remove("sortable-drop-target", "border-t-4", "border-b-4", "border-blue-500");
|
|
});
|
|
target.classList.add(
|
|
"sortable-drop-target",
|
|
"border-blue-500",
|
|
isBottomHalf ? "border-b-4" : "border-t-4"
|
|
);
|
|
};
|
|
this.handleDrop = (e) => {
|
|
e.preventDefault();
|
|
if (!this.draggedEl) return;
|
|
const target = itemFromTarget(e.target);
|
|
if (!itemIsDirectChild(target) || target === this.draggedEl) return;
|
|
const rect = target.getBoundingClientRect();
|
|
const isBottomHalf = e.clientY > rect.top + rect.height / 2;
|
|
if (isBottomHalf) {
|
|
container.insertBefore(this.draggedEl, target.nextSibling);
|
|
} else {
|
|
container.insertBefore(this.draggedEl, target);
|
|
}
|
|
const orderedIds = Array.from(
|
|
container.querySelectorAll(":scope > [data-id]")
|
|
).map((el) => el.dataset.id);
|
|
this.pushEvent(eventName, { ordered_ids: orderedIds });
|
|
};
|
|
container.addEventListener("dragstart", this.handleDragStart);
|
|
container.addEventListener("dragend", this.handleDragEnd);
|
|
container.addEventListener("dragover", this.handleDragOver);
|
|
container.addEventListener("drop", this.handleDrop);
|
|
},
|
|
destroyed() {
|
|
if (this.handleDragStart) this.el.removeEventListener("dragstart", this.handleDragStart);
|
|
if (this.handleDragEnd) this.el.removeEventListener("dragend", this.handleDragEnd);
|
|
if (this.handleDragOver) this.el.removeEventListener("dragover", this.handleDragOver);
|
|
if (this.handleDrop) this.el.removeEventListener("drop", this.handleDrop);
|
|
this.draggedEl = null;
|
|
}
|
|
};
|
|
|
|
// js/cookie_consent.js
|
|
var clickListenerAdded = false;
|
|
function initCookieConsent() {
|
|
if (hasConsentCookie()) {
|
|
hideBanner();
|
|
}
|
|
if (!clickListenerAdded) {
|
|
document.addEventListener("click", (event) => {
|
|
if (event.target.matches('[data-cookie-consent="accept"]') || event.target.closest('[data-cookie-consent="accept"]')) {
|
|
acceptCookies();
|
|
}
|
|
});
|
|
clickListenerAdded = true;
|
|
}
|
|
}
|
|
function hasConsentCookie() {
|
|
return document.cookie.split("; ").some((cookie) => cookie.startsWith("cookie_consent=accepted"));
|
|
}
|
|
function hideBanner() {
|
|
const banner = document.getElementById("cookie-consent-banner");
|
|
if (banner) {
|
|
banner.style.display = "none";
|
|
}
|
|
}
|
|
function acceptCookies() {
|
|
const expiryDate = /* @__PURE__ */ new Date();
|
|
expiryDate.setFullYear(expiryDate.getFullYear() + 1);
|
|
const isProduction = window.location.protocol === "https:";
|
|
const secureFlag = isProduction ? "; Secure" : "";
|
|
document.cookie = `cookie_consent=accepted; expires=${expiryDate.toUTCString()}; path=/; SameSite=Lax${secureFlag}`;
|
|
const banner = document.getElementById("cookie-consent-banner");
|
|
if (banner) {
|
|
banner.classList.add("opacity-0", "translate-y-4");
|
|
setTimeout(() => {
|
|
banner.remove();
|
|
}, 200);
|
|
}
|
|
}
|
|
|
|
// js/app.ts
|
|
function getTimeRangeMs(range2) {
|
|
switch (range2) {
|
|
case "1h":
|
|
return 1 * 60 * 60 * 1e3;
|
|
case "6h":
|
|
return 6 * 60 * 60 * 1e3;
|
|
case "12h":
|
|
return 12 * 60 * 60 * 1e3;
|
|
case "24h":
|
|
return 24 * 60 * 60 * 1e3;
|
|
case "7d":
|
|
return 7 * 24 * 60 * 60 * 1e3;
|
|
case "30d":
|
|
return 30 * 24 * 60 * 60 * 1e3;
|
|
default:
|
|
return 24 * 60 * 60 * 1e3;
|
|
}
|
|
}
|
|
var SensorChart = {
|
|
mounted() {
|
|
var _a2, _b;
|
|
this.isLiveMode = ((_a2 = this.el) == null ? void 0 : _a2.dataset.range) === "live";
|
|
this.createChart();
|
|
(_b = this.handleEvent) == null ? void 0 : _b.call(this, "live_data_update", (data) => {
|
|
this.handleLiveDataUpdate(data);
|
|
});
|
|
},
|
|
updated() {
|
|
var _a2;
|
|
const newRange = (_a2 = this.el) == null ? void 0 : _a2.dataset.range;
|
|
const wasLiveMode = this.isLiveMode;
|
|
this.isLiveMode = newRange === "live";
|
|
if (wasLiveMode !== this.isLiveMode) {
|
|
if (this.chart) {
|
|
this.chart.destroy();
|
|
}
|
|
this.createChart();
|
|
} else if (!this.isLiveMode) {
|
|
if (this.chart) {
|
|
this.chart.destroy();
|
|
}
|
|
this.createChart();
|
|
}
|
|
},
|
|
destroyed() {
|
|
if (this.chart) {
|
|
this.chart.destroy();
|
|
this.chart = null;
|
|
}
|
|
},
|
|
createChart() {
|
|
var _a2;
|
|
if (!this.el) return;
|
|
const dataAttr = this.el.dataset.chart;
|
|
if (!dataAttr) return;
|
|
const data = JSON.parse(dataAttr);
|
|
const canvas = this.el.querySelector("canvas");
|
|
if (!canvas) return;
|
|
const ctx = canvas.getContext("2d");
|
|
if (!ctx) return;
|
|
const unit = (_a2 = this.el.dataset.unit) != null ? _a2 : "%";
|
|
const autoScale = this.el.dataset.autoScale === "true" || this.el.dataset.autoScale === "true";
|
|
const showZeroLine = this.el.dataset.showZeroLine === "true" || this.el.dataset.showZeroLine === "true";
|
|
const dualAxis = this.el.dataset.dualAxis === "true";
|
|
const range2 = this.el.dataset.range || "24h";
|
|
const isTrafficChart = unit === "bps";
|
|
const colors = [
|
|
"rgb(59, 130, 246)",
|
|
// blue
|
|
"rgb(239, 68, 68)",
|
|
// red
|
|
"rgb(34, 197, 94)",
|
|
// green
|
|
"rgb(234, 179, 8)",
|
|
// yellow
|
|
"rgb(168, 85, 247)",
|
|
// purple
|
|
"rgb(236, 72, 153)",
|
|
// pink
|
|
"rgb(14, 165, 233)",
|
|
// sky
|
|
"rgb(249, 115, 22)"
|
|
// orange
|
|
];
|
|
const datasets = data.datasets.map((dataset, index) => {
|
|
const color = colors[index % colors.length];
|
|
const baseConfig = __spreadProps(__spreadValues({}, dataset), {
|
|
borderColor: color,
|
|
backgroundColor: color.replace("rgb", "rgba").replace(")", ", 0.2)"),
|
|
borderWidth: 2,
|
|
tension: 0.4,
|
|
pointRadius: 0,
|
|
pointHoverRadius: 4
|
|
});
|
|
if (dataset.yAxisID) {
|
|
baseConfig.yAxisID = dataset.yAxisID;
|
|
}
|
|
if (dualAxis && dataset.yAxisID === "y1") {
|
|
baseConfig.stepped = "before";
|
|
baseConfig.tension = 0;
|
|
baseConfig.fill = "origin";
|
|
baseConfig.borderWidth = 1;
|
|
baseConfig.borderColor = "rgb(34, 197, 94)";
|
|
baseConfig.backgroundColor = "rgba(34, 197, 94, 0.1)";
|
|
} else if (isTrafficChart) {
|
|
baseConfig.fill = "origin";
|
|
} else {
|
|
baseConfig.fill = false;
|
|
}
|
|
return baseConfig;
|
|
});
|
|
const formatBps = (bps) => {
|
|
const absBps = Math.abs(bps);
|
|
if (absBps >= 1e9) {
|
|
return (absBps / 1e9).toFixed(2) + " Gbps";
|
|
} else if (absBps >= 1e6) {
|
|
return (absBps / 1e6).toFixed(2) + " Mbps";
|
|
} else if (absBps >= 1e3) {
|
|
return (absBps / 1e3).toFixed(2) + " Kbps";
|
|
} else {
|
|
return absBps.toFixed(2) + " bps";
|
|
}
|
|
};
|
|
let yAxisConfig = {};
|
|
if (autoScale) {
|
|
if (showZeroLine && unit === "bps") {
|
|
let maxAbsTrafficValue = 0;
|
|
let maxAbsCapacityValue = 0;
|
|
datasets.forEach((dataset) => {
|
|
if (dataset.data && dataset.data.length > 0) {
|
|
dataset.data.forEach((point) => {
|
|
var _a3;
|
|
if (point && typeof point.y === "number") {
|
|
const absValue = Math.abs(point.y);
|
|
if ((_a3 = dataset.label) == null ? void 0 : _a3.startsWith("Capacity")) {
|
|
maxAbsCapacityValue = Math.max(maxAbsCapacityValue, absValue);
|
|
} else {
|
|
maxAbsTrafficValue = Math.max(maxAbsTrafficValue, absValue);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
});
|
|
const maxAbsValue = maxAbsTrafficValue > 0 ? maxAbsTrafficValue : maxAbsCapacityValue;
|
|
const paddedMaxAbsValue = Math.max(maxAbsValue * 1.1, 1e3);
|
|
yAxisConfig = {
|
|
min: -paddedMaxAbsValue,
|
|
max: paddedMaxAbsValue,
|
|
ticks: {
|
|
callback: function(value) {
|
|
return formatBps(value);
|
|
}
|
|
},
|
|
grid: {
|
|
color: function(context) {
|
|
if (context.tick.value === 0) {
|
|
return "rgba(0, 0, 0, 0.3)";
|
|
}
|
|
return "rgba(0, 0, 0, 0.05)";
|
|
},
|
|
lineWidth: function(context) {
|
|
if (context.tick.value === 0) {
|
|
return 2;
|
|
}
|
|
return 1;
|
|
}
|
|
}
|
|
};
|
|
} else {
|
|
yAxisConfig = {
|
|
beginAtZero: showZeroLine,
|
|
ticks: {
|
|
callback: function(value) {
|
|
if (unit === "bps") {
|
|
return formatBps(value);
|
|
}
|
|
if (unit === "") {
|
|
return Math.round(value);
|
|
}
|
|
return value.toFixed(1) + " " + unit;
|
|
}
|
|
},
|
|
grid: {
|
|
color: function(context) {
|
|
if (showZeroLine && context.tick.value === 0) {
|
|
return "rgba(0, 0, 0, 0.3)";
|
|
}
|
|
return "rgba(0, 0, 0, 0.05)";
|
|
},
|
|
lineWidth: function(context) {
|
|
if (showZeroLine && context.tick.value === 0) {
|
|
return 2;
|
|
}
|
|
return 1;
|
|
}
|
|
}
|
|
};
|
|
}
|
|
} else {
|
|
yAxisConfig = {
|
|
min: 0,
|
|
max: 100,
|
|
ticks: {
|
|
callback: function(value) {
|
|
if (unit === "bps") {
|
|
return formatBps(value);
|
|
}
|
|
if (unit === "") {
|
|
return Math.round(value);
|
|
}
|
|
return value.toFixed(1) + " " + unit;
|
|
}
|
|
},
|
|
grid: {
|
|
color: "rgba(0, 0, 0, 0.05)"
|
|
}
|
|
};
|
|
}
|
|
const now = Date.now();
|
|
let xAxisConfig;
|
|
if (this.isLiveMode) {
|
|
xAxisConfig = {
|
|
type: "linear",
|
|
min: now - 5 * 60 * 1e3,
|
|
max: now,
|
|
ticks: {
|
|
callback: function(value) {
|
|
const date = new Date(value);
|
|
return date.toLocaleTimeString("en-US", {
|
|
hour: "2-digit",
|
|
minute: "2-digit",
|
|
second: "2-digit",
|
|
hour12: false
|
|
});
|
|
},
|
|
maxTicksLimit: 10
|
|
},
|
|
grid: {
|
|
display: false
|
|
}
|
|
};
|
|
} else {
|
|
const timeRangeMs = getTimeRangeMs(range2);
|
|
const rangeStart = now - timeRangeMs;
|
|
xAxisConfig = {
|
|
type: "linear",
|
|
min: rangeStart,
|
|
max: now,
|
|
ticks: {
|
|
callback: function(value) {
|
|
const date = new Date(value);
|
|
if (timeRangeMs > 24 * 60 * 60 * 1e3) {
|
|
return date.toLocaleString("en-US", {
|
|
month: "short",
|
|
day: "numeric",
|
|
hour: "2-digit",
|
|
minute: "2-digit",
|
|
hour12: false
|
|
});
|
|
} else {
|
|
return date.toLocaleTimeString("en-US", { hour: "2-digit", minute: "2-digit", hour12: false });
|
|
}
|
|
},
|
|
maxTicksLimit: 12
|
|
},
|
|
grid: {
|
|
display: false
|
|
}
|
|
};
|
|
}
|
|
this.chart = new import_chart.default(ctx, {
|
|
type: "line",
|
|
data: { datasets },
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
animation: false,
|
|
interaction: {
|
|
mode: "index",
|
|
intersect: false
|
|
},
|
|
plugins: {
|
|
legend: {
|
|
position: "bottom",
|
|
labels: {
|
|
usePointStyle: true,
|
|
padding: 15
|
|
}
|
|
},
|
|
tooltip: {
|
|
callbacks: {
|
|
title: function(context) {
|
|
const timestamp = context[0].parsed.x;
|
|
const date = new Date(timestamp);
|
|
return date.toLocaleString("en-US", {
|
|
month: "short",
|
|
day: "numeric",
|
|
hour: "2-digit",
|
|
minute: "2-digit",
|
|
hour12: false
|
|
});
|
|
},
|
|
label: function(context) {
|
|
if (dualAxis && context.dataset.yAxisID === "y1") {
|
|
return context.dataset.label + ": " + (context.parsed.y === 1 ? "Up" : "Down");
|
|
}
|
|
if (unit === "bps") {
|
|
return context.dataset.label + ": " + formatBps(context.parsed.y);
|
|
}
|
|
if (unit === "") {
|
|
return context.dataset.label + ": " + Math.round(context.parsed.y);
|
|
}
|
|
return context.dataset.label + ": " + context.parsed.y.toFixed(1) + " " + unit;
|
|
}
|
|
}
|
|
}
|
|
},
|
|
scales: __spreadValues({
|
|
x: xAxisConfig,
|
|
y: yAxisConfig
|
|
}, dualAxis ? {
|
|
y1: {
|
|
position: "right",
|
|
min: -0.1,
|
|
max: 1.1,
|
|
grid: { drawOnChartArea: false },
|
|
ticks: {
|
|
stepSize: 1,
|
|
callback: function(value) {
|
|
if (value === 1) return "Up";
|
|
if (value === 0) return "Down";
|
|
return "";
|
|
}
|
|
}
|
|
}
|
|
} : {})
|
|
}
|
|
});
|
|
const loadingEl = this.el.querySelector("[data-loading]");
|
|
if (loadingEl) {
|
|
loadingEl.remove();
|
|
}
|
|
},
|
|
handleLiveDataUpdate(event) {
|
|
var _a2;
|
|
if (!this.chart || !this.isLiveMode) return;
|
|
const { points } = event;
|
|
const now = Date.now();
|
|
points.forEach((point) => {
|
|
const dataset = this.chart.data.datasets.find(
|
|
(ds) => ds.label === point.label
|
|
);
|
|
if (dataset && dataset.data) {
|
|
dataset.data.push({
|
|
x: point.timestamp,
|
|
y: point.value
|
|
});
|
|
const cutoff = now - 5 * 60 * 1e3;
|
|
dataset.data = dataset.data.filter(
|
|
(p) => p.x >= cutoff
|
|
);
|
|
} else if (!dataset) {
|
|
const colors = [
|
|
"rgb(59, 130, 246)",
|
|
// blue
|
|
"rgb(239, 68, 68)",
|
|
// red
|
|
"rgb(34, 197, 94)",
|
|
// green
|
|
"rgb(234, 179, 8)",
|
|
// yellow
|
|
"rgb(168, 85, 247)",
|
|
// purple
|
|
"rgb(236, 72, 153)",
|
|
// pink
|
|
"rgb(14, 165, 233)",
|
|
// sky
|
|
"rgb(249, 115, 22)"
|
|
// orange
|
|
];
|
|
const index = this.chart.data.datasets.length;
|
|
const color = colors[index % colors.length];
|
|
this.chart.data.datasets.push({
|
|
label: point.label,
|
|
data: [{ x: point.timestamp, y: point.value }],
|
|
borderColor: color,
|
|
backgroundColor: color.replace("rgb", "rgba").replace(")", ", 0.2)"),
|
|
borderWidth: 2,
|
|
tension: 0.4,
|
|
pointRadius: 0,
|
|
pointHoverRadius: 4,
|
|
fill: false
|
|
});
|
|
}
|
|
});
|
|
if ((_a2 = this.chart.options.scales) == null ? void 0 : _a2.x) {
|
|
this.chart.options.scales.x.min = now - 5 * 60 * 1e3;
|
|
this.chart.options.scales.x.max = now;
|
|
}
|
|
this.chart.update("none");
|
|
}
|
|
};
|
|
var CopyToClipboard = {
|
|
handleClick: null,
|
|
mounted() {
|
|
this.handleClick = (e) => {
|
|
e.preventDefault();
|
|
const targetId = this.el.dataset.target;
|
|
if (!targetId) {
|
|
console.error("No data-target attribute found on copy button");
|
|
return;
|
|
}
|
|
const targetEl = document.querySelector(targetId);
|
|
if (!targetEl) {
|
|
console.error(`Target element not found: ${targetId}`);
|
|
return;
|
|
}
|
|
let text = "";
|
|
if (targetEl.tagName === "INPUT" || targetEl.tagName === "TEXTAREA") {
|
|
text = targetEl.value;
|
|
} else {
|
|
text = targetEl.innerText || targetEl.textContent || "";
|
|
}
|
|
text = text.trim();
|
|
if (text) {
|
|
navigator.clipboard.writeText(text).then(() => {
|
|
console.log("Copied to clipboard successfully");
|
|
const originalHTML = this.el.innerHTML;
|
|
const originalClasses = this.el.className;
|
|
this.el.innerHTML = '<svg class="h-3.5 w-3.5" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5" /></svg><span>Copied!</span>';
|
|
this.el.className = originalClasses.replace("bg-blue-600", "bg-green-600").replace("hover:bg-blue-700", "hover:bg-green-700").replace("bg-blue-500", "bg-green-500").replace("hover:bg-blue-600", "hover:bg-green-600");
|
|
setTimeout(() => {
|
|
this.el.innerHTML = originalHTML;
|
|
this.el.className = originalClasses;
|
|
}, 2e3);
|
|
}).catch((err) => {
|
|
console.error("Failed to copy:", err);
|
|
const originalHTML = this.el.innerHTML;
|
|
const originalClasses = this.el.className;
|
|
this.el.innerHTML = '<svg class="h-3.5 w-3.5" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" /></svg><span>Failed</span>';
|
|
this.el.className = originalClasses.replace("bg-blue-600", "bg-red-600").replace("hover:bg-blue-700", "hover:bg-red-700").replace("bg-blue-500", "bg-red-500").replace("hover:bg-blue-600", "hover:bg-red-600");
|
|
setTimeout(() => {
|
|
this.el.innerHTML = originalHTML;
|
|
this.el.className = originalClasses;
|
|
}, 2e3);
|
|
});
|
|
} else {
|
|
console.error("No text found to copy");
|
|
}
|
|
};
|
|
this.el.addEventListener("click", this.handleClick);
|
|
},
|
|
destroyed() {
|
|
if (this.handleClick) {
|
|
this.el.removeEventListener("click", this.handleClick);
|
|
this.handleClick = null;
|
|
}
|
|
}
|
|
};
|
|
var ScrollToTop = {
|
|
mounted() {
|
|
this.handleEvent("scroll_to_top", () => {
|
|
window.scrollTo({ top: 0, behavior: "smooth" });
|
|
});
|
|
}
|
|
};
|
|
var AutoDismissFlash = {
|
|
timeout: null,
|
|
mounted() {
|
|
const dismissAfter = parseInt(this.el.dataset.dismissAfter || "30000", 10);
|
|
this.timeout = setTimeout(() => {
|
|
this.el.click();
|
|
}, dismissAfter);
|
|
},
|
|
destroyed() {
|
|
if (this.timeout) {
|
|
clearTimeout(this.timeout);
|
|
this.timeout = null;
|
|
}
|
|
}
|
|
};
|
|
var BetaBannerDismiss = {
|
|
handleDismiss: null,
|
|
mounted() {
|
|
this.applyBannerState();
|
|
},
|
|
updated() {
|
|
this.applyBannerState();
|
|
},
|
|
applyBannerState() {
|
|
const isHelpPage = this.el.dataset.alwaysShow === "true";
|
|
if (isHelpPage) {
|
|
const dismissBtn = this.el.querySelector("[data-dismiss]");
|
|
if (dismissBtn) {
|
|
dismissBtn.style.display = "none";
|
|
}
|
|
} else {
|
|
const isDismissed = localStorage.getItem("betaBannerDismissed") === "true";
|
|
if (isDismissed) {
|
|
this.el.style.display = "none";
|
|
}
|
|
if (!this.handleDismiss) {
|
|
const dismissBtn = this.el.querySelector("[data-dismiss]");
|
|
if (dismissBtn) {
|
|
this.handleDismiss = (e) => {
|
|
e.preventDefault();
|
|
localStorage.setItem("betaBannerDismissed", "true");
|
|
this.el.style.display = "none";
|
|
};
|
|
dismissBtn.addEventListener("click", this.handleDismiss);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
destroyed() {
|
|
const dismissBtn = this.el.querySelector("[data-dismiss]");
|
|
if (dismissBtn && this.handleDismiss) {
|
|
dismissBtn.removeEventListener("click", this.handleDismiss);
|
|
this.handleDismiss = null;
|
|
}
|
|
}
|
|
};
|
|
var NetworkMap = {
|
|
cy: null,
|
|
_topologyData: null,
|
|
_zoomInHandler: null,
|
|
_zoomOutHandler: null,
|
|
_fitHandler: null,
|
|
mounted() {
|
|
const topologyData = JSON.parse(this.el.dataset.topology || "{}");
|
|
this._topologyData = topologyData;
|
|
this.initializeCytoscape(topologyData);
|
|
this.handleEvent("update_topology", (payload) => {
|
|
if (this.cy) {
|
|
this._topologyData = payload.topology;
|
|
this.updateTopology(payload.topology);
|
|
}
|
|
});
|
|
this.handleEvent("apply_filter", (payload) => {
|
|
if (!this.cy) return;
|
|
this._applyFilter(payload.filter);
|
|
});
|
|
this.handleEvent("search_nodes", (payload) => {
|
|
if (!this.cy) return;
|
|
this._searchNodes(payload.query);
|
|
});
|
|
this.handleEvent("change_layout", (payload) => {
|
|
if (!this.cy || !this._topologyData) return;
|
|
this._changeLayout(payload.mode, this._topologyData);
|
|
});
|
|
},
|
|
updated() {
|
|
const topologyData = JSON.parse(this.el.dataset.topology || "{}");
|
|
this.updateTopology(topologyData);
|
|
},
|
|
destroyed() {
|
|
const zoomIn = document.getElementById("cy-zoom-in");
|
|
const zoomOut = document.getElementById("cy-zoom-out");
|
|
const fit = document.getElementById("cy-fit");
|
|
if (zoomIn && this._zoomInHandler) {
|
|
zoomIn.removeEventListener("click", this._zoomInHandler);
|
|
}
|
|
if (zoomOut && this._zoomOutHandler) {
|
|
zoomOut.removeEventListener("click", this._zoomOutHandler);
|
|
}
|
|
if (fit && this._fitHandler) {
|
|
fit.removeEventListener("click", this._fitHandler);
|
|
}
|
|
this._zoomInHandler = null;
|
|
this._zoomOutHandler = null;
|
|
this._fitHandler = null;
|
|
if (this.cy) {
|
|
try {
|
|
this.cy.stop();
|
|
} catch (_e) {
|
|
}
|
|
this.cy.destroy();
|
|
this.cy = null;
|
|
}
|
|
},
|
|
_initControls() {
|
|
const ZOOM_STEP = 0.25;
|
|
const zoomIn = document.getElementById("cy-zoom-in");
|
|
const zoomOut = document.getElementById("cy-zoom-out");
|
|
const fit = document.getElementById("cy-fit");
|
|
if (zoomIn) {
|
|
this._zoomInHandler = () => {
|
|
if (!this.cy) return;
|
|
this.cy.zoom({
|
|
level: Math.min(this.cy.zoom() + ZOOM_STEP, this.cy.maxZoom()),
|
|
renderedPosition: { x: this.cy.width() / 2, y: this.cy.height() / 2 }
|
|
});
|
|
};
|
|
zoomIn.addEventListener("click", this._zoomInHandler);
|
|
}
|
|
if (zoomOut) {
|
|
this._zoomOutHandler = () => {
|
|
if (!this.cy) return;
|
|
this.cy.zoom({
|
|
level: Math.max(this.cy.zoom() - ZOOM_STEP, this.cy.minZoom()),
|
|
renderedPosition: { x: this.cy.width() / 2, y: this.cy.height() / 2 }
|
|
});
|
|
};
|
|
zoomOut.addEventListener("click", this._zoomOutHandler);
|
|
}
|
|
if (fit) {
|
|
this._fitHandler = () => {
|
|
if (!this.cy) return;
|
|
this.cy.fit(void 0, 50);
|
|
};
|
|
fit.addEventListener("click", this._fitHandler);
|
|
}
|
|
},
|
|
initializeCytoscape(topology) {
|
|
var _a2, _b;
|
|
const isDark = document.documentElement.getAttribute("data-theme") === "dark";
|
|
const roleColors = {
|
|
router: "#3B82F6",
|
|
// blue
|
|
switch: "#10B981",
|
|
// green
|
|
wireless: "#8B5CF6",
|
|
// purple
|
|
firewall: "#EF4444",
|
|
// red
|
|
server: "#F59E0B",
|
|
// amber
|
|
unknown: "#9CA3AF"
|
|
// light gray
|
|
};
|
|
const roleShapes = {
|
|
router: "round-rectangle",
|
|
switch: "diamond",
|
|
wireless: "triangle",
|
|
firewall: "hexagon",
|
|
server: "rectangle",
|
|
unknown: "ellipse"
|
|
};
|
|
const signalHealthColors = {
|
|
good: "#10B981",
|
|
// green
|
|
degraded: "#F59E0B",
|
|
// yellow
|
|
critical: "#EF4444"
|
|
// red
|
|
};
|
|
const getEdgeStyle = (confidence, signalHealth) => {
|
|
if (signalHealth && signalHealthColors[signalHealth]) {
|
|
return { color: signalHealthColors[signalHealth], style: "solid", dashPattern: [] };
|
|
}
|
|
if (confidence > 0.9) {
|
|
return { color: "#10B981", style: "solid", dashPattern: [] };
|
|
} else if (confidence >= 0.5) {
|
|
return { color: "#F59E0B", style: "dashed", dashPattern: [6, 3] };
|
|
} else {
|
|
return { color: "#9CA3AF", style: "dashed", dashPattern: [2, 3] };
|
|
}
|
|
};
|
|
const computePresetPositions = (nodes) => {
|
|
const DEVICE_SPACING = 110;
|
|
const SITE_PADDING = 50;
|
|
const SITE_GAP = 90;
|
|
const SITE_COLS = 3;
|
|
const siteGroups = /* @__PURE__ */ new Map();
|
|
const unparented = [];
|
|
nodes.forEach((node) => {
|
|
if (node.type === "site") return;
|
|
if (node.parent) {
|
|
if (!siteGroups.has(node.parent)) siteGroups.set(node.parent, []);
|
|
siteGroups.get(node.parent).push(node.id);
|
|
} else {
|
|
unparented.push(node.id);
|
|
}
|
|
});
|
|
const positions = {};
|
|
let curX = 0, curY = 0, maxH = 0, col = 0;
|
|
siteGroups.forEach((deviceIds) => {
|
|
const n = deviceIds.length;
|
|
const cols = Math.max(1, Math.ceil(Math.sqrt(n)));
|
|
const rows = Math.ceil(n / cols);
|
|
const innerW = (cols - 1) * DEVICE_SPACING;
|
|
const innerH = (rows - 1) * DEVICE_SPACING;
|
|
const cx = curX + SITE_PADDING + innerW / 2;
|
|
const cy = curY + SITE_PADDING + innerH / 2;
|
|
deviceIds.forEach((id, i) => {
|
|
const dc = i % cols;
|
|
const dr = Math.floor(i / cols);
|
|
positions[id] = {
|
|
x: cx + dc * DEVICE_SPACING - innerW / 2,
|
|
y: cy + dr * DEVICE_SPACING - innerH / 2
|
|
};
|
|
});
|
|
const totalW = innerW + SITE_PADDING * 2 + DEVICE_SPACING;
|
|
const totalH = innerH + SITE_PADDING * 2 + DEVICE_SPACING;
|
|
maxH = Math.max(maxH, totalH);
|
|
col++;
|
|
if (col >= SITE_COLS) {
|
|
col = 0;
|
|
curX = 0;
|
|
curY += maxH + SITE_GAP;
|
|
maxH = 0;
|
|
} else {
|
|
curX += totalW + SITE_GAP;
|
|
}
|
|
});
|
|
const unY = curY + maxH + SITE_GAP;
|
|
unparented.forEach((id, i) => {
|
|
const uc = i % 6;
|
|
const ur = Math.floor(i / 6);
|
|
positions[id] = { x: uc * DEVICE_SPACING, y: unY + ur * DEVICE_SPACING };
|
|
});
|
|
return positions;
|
|
};
|
|
const presetPositions = computePresetPositions(topology.nodes || []);
|
|
const elements = [];
|
|
(_a2 = topology.nodes) == null ? void 0 : _a2.forEach((node) => {
|
|
const data = {
|
|
id: node.id,
|
|
label: node.label,
|
|
type: node.type,
|
|
status: node.status,
|
|
discovered: node.discovered,
|
|
ip_address: node.ip_address,
|
|
site_name: node.site_name,
|
|
manufacturer: node.manufacturer,
|
|
client_count: node.client_count || 0,
|
|
signal_health: node.signal_health,
|
|
has_alerts: node.has_alerts || false,
|
|
latitude: node.latitude,
|
|
longitude: node.longitude,
|
|
device_role: node.device_role
|
|
};
|
|
if (node.parent) data.parent = node.parent;
|
|
elements.push({
|
|
data,
|
|
classes: node.type === "site" ? "site-group" : node.discovered ? "discovered" : node.status
|
|
});
|
|
});
|
|
(_b = topology.edges) == null ? void 0 : _b.forEach((edge) => {
|
|
var _a3;
|
|
const sourceLabel = edge.source_interface || "";
|
|
const targetLabel = edge.target_interface || "";
|
|
const label = [sourceLabel, targetLabel].filter(Boolean).join(" \u2194 ");
|
|
elements.push({
|
|
data: {
|
|
id: edge.id,
|
|
source: edge.source,
|
|
target: edge.target,
|
|
source_interface: edge.source_interface,
|
|
target_interface: edge.target_interface,
|
|
link_type: edge.link_type,
|
|
confidence: (_a3 = edge.confidence) != null ? _a3 : 0.5,
|
|
if_speed: edge.if_speed,
|
|
signal_health: edge.signal_health,
|
|
snr: edge.snr,
|
|
label
|
|
}
|
|
});
|
|
});
|
|
const getEdgeWidth = (speed) => {
|
|
if (!speed) return 1.5;
|
|
if (speed >= 1e10) return 5;
|
|
if (speed >= 1e9) return 3.5;
|
|
if (speed >= 1e8) return 2.5;
|
|
return 1.5;
|
|
};
|
|
this.cy = (0, import_cytoscape.default)({
|
|
container: this.el,
|
|
elements,
|
|
style: [
|
|
{
|
|
selector: "node",
|
|
style: {
|
|
"background-color": function(ele) {
|
|
return roleColors[ele.data("type")] || roleColors.unknown;
|
|
},
|
|
"shape": function(ele) {
|
|
return roleShapes[ele.data("type")] || roleShapes.unknown;
|
|
},
|
|
"label": function(ele) {
|
|
const label = ele.data("label") || "";
|
|
const clients = ele.data("client_count");
|
|
if (clients > 0) {
|
|
return `${label}
|
|
\u{1F4E1} ${clients} clients`;
|
|
}
|
|
return label;
|
|
},
|
|
"color": isDark ? "#fff" : "#000",
|
|
"text-valign": "bottom",
|
|
"text-halign": "center",
|
|
"text-margin-y": 6,
|
|
"font-size": "13px",
|
|
"font-weight": "500",
|
|
"text-wrap": "wrap",
|
|
"text-max-width": "140px",
|
|
"width": 44,
|
|
"height": 44,
|
|
"border-width": 2,
|
|
"border-color": function(ele) {
|
|
const status = ele.data("status");
|
|
if (status === "down") return "#dc2626";
|
|
if (status === "unknown") return "#ca8a04";
|
|
const type = ele.data("type");
|
|
const darkerColors = {
|
|
router: "#2563EB",
|
|
switch: "#059669",
|
|
wireless: "#7C3AED",
|
|
firewall: "#DC2626",
|
|
server: "#D97706",
|
|
unknown: "#6B7280"
|
|
};
|
|
return darkerColors[type] || darkerColors.unknown;
|
|
},
|
|
"overlay-color": function(ele) {
|
|
const status = ele.data("status");
|
|
if (status === "down") return "#ef4444";
|
|
return "#000";
|
|
},
|
|
"overlay-opacity": function(ele) {
|
|
const status = ele.data("status");
|
|
if (status === "down") return 0.15;
|
|
return 0;
|
|
}
|
|
}
|
|
},
|
|
{
|
|
selector: 'node[status = "down"]',
|
|
style: {
|
|
"border-width": 3,
|
|
"border-color": "#dc2626",
|
|
"background-blacken": -0.3
|
|
}
|
|
},
|
|
{
|
|
selector: "node.discovered",
|
|
style: {
|
|
"border-style": "dashed",
|
|
"border-width": 2,
|
|
"border-color": "#9ca3af",
|
|
"opacity": 0.6,
|
|
"width": 34,
|
|
"height": 34,
|
|
"font-size": "11px"
|
|
}
|
|
},
|
|
{
|
|
selector: "node:selected",
|
|
style: {
|
|
"border-width": 4,
|
|
"border-color": "#fbbf24"
|
|
}
|
|
},
|
|
{
|
|
selector: "node.highlighted",
|
|
style: {
|
|
"border-width": 4,
|
|
"border-color": "#3b82f6",
|
|
"overlay-color": "#3b82f6",
|
|
"overlay-opacity": 0.1
|
|
}
|
|
},
|
|
{
|
|
selector: "node.search-match",
|
|
style: {
|
|
"border-width": 4,
|
|
"border-color": "#f59e0b",
|
|
"overlay-color": "#f59e0b",
|
|
"overlay-opacity": 0.15,
|
|
"z-index": 999
|
|
}
|
|
},
|
|
{
|
|
selector: "$node > node",
|
|
// compound parent selector
|
|
style: {
|
|
"background-color": isDark ? "#1e293b" : "#f8fafc",
|
|
"background-opacity": 0.7,
|
|
"border-width": 2,
|
|
"border-color": isDark ? "#475569" : "#cbd5e1",
|
|
"border-style": "solid",
|
|
"shape": "round-rectangle",
|
|
"padding": "30px",
|
|
"text-valign": "top",
|
|
"text-halign": "center",
|
|
"text-margin-y": 8,
|
|
"label": "data(label)",
|
|
"font-size": "14px",
|
|
"font-weight": "700",
|
|
"color": isDark ? "#94a3b8" : "#475569"
|
|
}
|
|
},
|
|
{
|
|
selector: "edge",
|
|
style: {
|
|
"width": function(ele) {
|
|
return getEdgeWidth(ele.data("if_speed"));
|
|
},
|
|
"line-color": function(ele) {
|
|
return getEdgeStyle(ele.data("confidence"), ele.data("signal_health")).color;
|
|
},
|
|
"line-style": function(ele) {
|
|
return getEdgeStyle(ele.data("confidence"), ele.data("signal_health")).style;
|
|
},
|
|
"line-dash-pattern": function(ele) {
|
|
const pattern = getEdgeStyle(ele.data("confidence"), ele.data("signal_health")).dashPattern;
|
|
return pattern.length > 0 ? pattern : [1, 0];
|
|
},
|
|
"target-arrow-color": function(ele) {
|
|
return getEdgeStyle(ele.data("confidence"), ele.data("signal_health")).color;
|
|
},
|
|
"curve-style": "bezier",
|
|
"label": "data(label)",
|
|
"font-size": "8px",
|
|
"color": isDark ? "#d1d5db" : "#4b5563",
|
|
"text-background-color": isDark ? "#1f2937" : "#ffffff",
|
|
"text-background-opacity": 0.85,
|
|
"text-background-padding": "2px",
|
|
"text-rotation": "autorotate",
|
|
"text-margin-y": -8,
|
|
"text-wrap": "wrap",
|
|
"text-max-width": "120px"
|
|
}
|
|
},
|
|
{
|
|
selector: "edge:selected",
|
|
style: {
|
|
"line-color": "#fbbf24",
|
|
"width": 3
|
|
}
|
|
}
|
|
],
|
|
layout: {
|
|
name: "preset",
|
|
positions: (node) => presetPositions[node.id()] || { x: 0, y: 0 },
|
|
fit: true,
|
|
padding: 50
|
|
},
|
|
minZoom: 0.2,
|
|
maxZoom: 3,
|
|
wheelSensitivity: 1
|
|
});
|
|
this.cy.on("tap", "node", (evt) => {
|
|
const node = evt.target;
|
|
const nodeData = node.data();
|
|
if (nodeData.type === "site") return;
|
|
this.pushEvent("node_clicked", {
|
|
node_id: nodeData.id,
|
|
node_type: nodeData.discovered ? "discovered" : "managed"
|
|
});
|
|
});
|
|
this.handleEvent("highlight_node", (payload) => {
|
|
if (!this.cy) return;
|
|
this.cy.nodes().removeClass("highlighted");
|
|
const node = this.cy.getElementById(payload.node_id);
|
|
if (node.length > 0) {
|
|
node.addClass("highlighted");
|
|
}
|
|
});
|
|
this.handleEvent("clear_highlight", () => {
|
|
if (!this.cy) return;
|
|
this.cy.nodes().removeClass("highlighted");
|
|
});
|
|
this.cy.on("mouseover", "node", (evt) => {
|
|
const node = evt.target;
|
|
const d = node.data();
|
|
let tooltip = d.label || "";
|
|
if (d.ip_address) tooltip += `
|
|
${d.ip_address}`;
|
|
if (d.site_name) tooltip += `
|
|
\u{1F4CD} ${d.site_name}`;
|
|
if (d.manufacturer) tooltip += `
|
|
${d.manufacturer}`;
|
|
if (d.client_count > 0) tooltip += `
|
|
\u{1F4E1} ${d.client_count} clients`;
|
|
if (d.signal_health) {
|
|
const healthIcon = d.signal_health === "good" ? "\u{1F7E2}" : d.signal_health === "degraded" ? "\u{1F7E1}" : "\u{1F534}";
|
|
tooltip += `
|
|
${healthIcon} Signal: ${d.signal_health}`;
|
|
}
|
|
node.style("label", tooltip);
|
|
});
|
|
this.cy.on("mouseout", "node", (evt) => {
|
|
const node = evt.target;
|
|
const d = node.data();
|
|
const clients = d.client_count;
|
|
const label = d.label || "";
|
|
node.style("label", clients > 0 ? `${label}
|
|
\u{1F4E1} ${clients} clients` : label);
|
|
});
|
|
this.cy.on("mouseover", "edge", (evt) => {
|
|
const edge = evt.target;
|
|
const data = edge.data();
|
|
const srcNode = this.cy.getElementById(data.source);
|
|
const tgtNode = this.cy.getElementById(data.target);
|
|
const srcName = srcNode.data("label") || data.source;
|
|
const tgtName = tgtNode.data("label") || data.target;
|
|
let tooltip = `${srcName} \u2194 ${tgtName}`;
|
|
if (data.snr != null) tooltip += `
|
|
SNR ${data.snr} dB`;
|
|
if (data.signal_health) {
|
|
const healthIcon = data.signal_health === "good" ? "\u{1F7E2}" : data.signal_health === "degraded" ? "\u{1F7E1}" : "\u{1F534}";
|
|
tooltip += ` ${healthIcon}`;
|
|
}
|
|
if (data.if_speed) {
|
|
const mbps = data.if_speed / 1e6;
|
|
tooltip += `
|
|
${mbps >= 1e3 ? (mbps / 1e3).toFixed(1) + " Gbps" : mbps + " Mbps"}`;
|
|
}
|
|
if (data.link_type) tooltip += `
|
|
${data.link_type.toUpperCase()}`;
|
|
const confidence = data.confidence;
|
|
if (confidence != null) tooltip += ` (${Math.round(confidence * 100)}%)`;
|
|
edge.style({
|
|
"line-color": "#fbbf24",
|
|
"width": Math.max(getEdgeWidth(data.if_speed), 3),
|
|
"label": tooltip
|
|
});
|
|
});
|
|
this.cy.on("mouseout", "edge", (evt) => {
|
|
var _a3;
|
|
const edge = evt.target;
|
|
const data = edge.data();
|
|
const edgeStyle = getEdgeStyle((_a3 = data.confidence) != null ? _a3 : 0.5, data.signal_health);
|
|
edge.style({
|
|
"line-color": edgeStyle.color,
|
|
"width": getEdgeWidth(data.if_speed),
|
|
"label": data.label || ""
|
|
});
|
|
});
|
|
this._initControls();
|
|
},
|
|
updateTopology(topology) {
|
|
var _a2, _b;
|
|
if (!this.cy) return;
|
|
const incomingNodes = /* @__PURE__ */ new Map();
|
|
(_a2 = topology.nodes) == null ? void 0 : _a2.forEach((node) => {
|
|
incomingNodes.set(node.id, node);
|
|
});
|
|
const incomingEdges = /* @__PURE__ */ new Map();
|
|
(_b = topology.edges) == null ? void 0 : _b.forEach((edge) => {
|
|
incomingEdges.set(edge.id, edge);
|
|
});
|
|
const existingNodeIds = /* @__PURE__ */ new Set();
|
|
const existingEdgeIds = /* @__PURE__ */ new Set();
|
|
this.cy.nodes().forEach((node) => {
|
|
const id = node.id();
|
|
if (incomingNodes.has(id)) {
|
|
const incoming = incomingNodes.get(id);
|
|
node.data("label", incoming.label);
|
|
node.data("type", incoming.type);
|
|
node.data("status", incoming.status);
|
|
node.data("discovered", incoming.discovered);
|
|
node.data("ip_address", incoming.ip_address);
|
|
node.data("site_name", incoming.site_name);
|
|
node.data("manufacturer", incoming.manufacturer);
|
|
if (incoming.parent) node.data("parent", incoming.parent);
|
|
existingNodeIds.add(id);
|
|
} else {
|
|
node.remove();
|
|
}
|
|
});
|
|
this.cy.edges().forEach((edge) => {
|
|
var _a3;
|
|
const id = edge.id();
|
|
if (incomingEdges.has(id)) {
|
|
const incoming = incomingEdges.get(id);
|
|
edge.data("confidence", (_a3 = incoming.confidence) != null ? _a3 : 0.5);
|
|
edge.data("link_type", incoming.link_type);
|
|
edge.data("source_interface", incoming.source_interface);
|
|
edge.data("target_interface", incoming.target_interface);
|
|
const sourceLabel = incoming.source_interface || "";
|
|
const targetLabel = incoming.target_interface || "";
|
|
edge.data("label", [sourceLabel, targetLabel].filter(Boolean).join(" \u2194 "));
|
|
existingEdgeIds.add(id);
|
|
} else {
|
|
edge.remove();
|
|
}
|
|
});
|
|
const newElements = [];
|
|
incomingNodes.forEach((node, id) => {
|
|
if (!existingNodeIds.has(id)) {
|
|
newElements.push({
|
|
group: "nodes",
|
|
data: {
|
|
id: node.id,
|
|
label: node.label,
|
|
type: node.type,
|
|
status: node.status,
|
|
discovered: node.discovered,
|
|
ip_address: node.ip_address,
|
|
site_name: node.site_name,
|
|
manufacturer: node.manufacturer,
|
|
parent: node.parent
|
|
},
|
|
classes: node.discovered ? "discovered" : node.status
|
|
});
|
|
}
|
|
});
|
|
incomingEdges.forEach((edge, id) => {
|
|
var _a3;
|
|
if (!existingEdgeIds.has(id)) {
|
|
const sourceLabel = edge.source_interface || "";
|
|
const targetLabel = edge.target_interface || "";
|
|
const label = [sourceLabel, targetLabel].filter(Boolean).join(" \u2194 ");
|
|
newElements.push({
|
|
group: "edges",
|
|
data: {
|
|
id: edge.id,
|
|
source: edge.source,
|
|
target: edge.target,
|
|
source_interface: edge.source_interface,
|
|
target_interface: edge.target_interface,
|
|
link_type: edge.link_type,
|
|
confidence: (_a3 = edge.confidence) != null ? _a3 : 0.5,
|
|
if_speed: edge.if_speed,
|
|
label
|
|
}
|
|
});
|
|
}
|
|
});
|
|
if (newElements.length > 0) {
|
|
this.cy.add(newElements);
|
|
const allNodes = topology.nodes || [];
|
|
const newPositions = this._computePresetPositions(allNodes);
|
|
this.cy.layout({
|
|
name: "preset",
|
|
positions: (node) => newPositions[node.id()] || { x: 0, y: 0 },
|
|
fit: true,
|
|
padding: 50
|
|
}).run();
|
|
}
|
|
},
|
|
// Shared position computation — same algorithm as in initializeCytoscape
|
|
_computePresetPositions(nodes) {
|
|
const DEVICE_SPACING = 110;
|
|
const SITE_PADDING = 50;
|
|
const SITE_GAP = 90;
|
|
const SITE_COLS = 3;
|
|
const siteGroups = /* @__PURE__ */ new Map();
|
|
const unparented = [];
|
|
nodes.forEach((node) => {
|
|
if (node.type === "site") return;
|
|
if (node.parent) {
|
|
if (!siteGroups.has(node.parent)) siteGroups.set(node.parent, []);
|
|
siteGroups.get(node.parent).push(node.id);
|
|
} else {
|
|
unparented.push(node.id);
|
|
}
|
|
});
|
|
const positions = {};
|
|
let curX = 0, curY = 0, maxH = 0, col = 0;
|
|
siteGroups.forEach((deviceIds) => {
|
|
const n = deviceIds.length;
|
|
const cols = Math.max(1, Math.ceil(Math.sqrt(n)));
|
|
const rows = Math.ceil(n / cols);
|
|
const innerW = (cols - 1) * DEVICE_SPACING;
|
|
const innerH = (rows - 1) * DEVICE_SPACING;
|
|
const cx = curX + SITE_PADDING + innerW / 2;
|
|
const cy = curY + SITE_PADDING + innerH / 2;
|
|
deviceIds.forEach((id, i) => {
|
|
const dc = i % cols;
|
|
const dr = Math.floor(i / cols);
|
|
positions[id] = {
|
|
x: cx + dc * DEVICE_SPACING - innerW / 2,
|
|
y: cy + dr * DEVICE_SPACING - innerH / 2
|
|
};
|
|
});
|
|
const totalW = innerW + SITE_PADDING * 2 + DEVICE_SPACING;
|
|
const totalH = innerH + SITE_PADDING * 2 + DEVICE_SPACING;
|
|
maxH = Math.max(maxH, totalH);
|
|
col++;
|
|
if (col >= SITE_COLS) {
|
|
col = 0;
|
|
curX = 0;
|
|
curY += maxH + SITE_GAP;
|
|
maxH = 0;
|
|
} else {
|
|
curX += totalW + SITE_GAP;
|
|
}
|
|
});
|
|
const unY = curY + maxH + SITE_GAP;
|
|
unparented.forEach((id, i) => {
|
|
const uc = i % 6;
|
|
const ur = Math.floor(i / 6);
|
|
positions[id] = { x: uc * DEVICE_SPACING, y: unY + ur * DEVICE_SPACING };
|
|
});
|
|
return positions;
|
|
},
|
|
// --- Filter, Search, Layout methods ---
|
|
_applyFilter(filter) {
|
|
if (!this.cy) return;
|
|
this.cy.elements().style("display", "element");
|
|
if (filter === "degraded") {
|
|
const matchEdges = this.cy.edges().filter((e) => {
|
|
const health = e.data("signal_health");
|
|
return health === "degraded" || health === "critical";
|
|
});
|
|
const connectedNodes = matchEdges.connectedNodes();
|
|
const parents = connectedNodes.parents();
|
|
const visible = matchEdges.union(connectedNodes).union(parents);
|
|
this.cy.elements().not(visible).style("display", "none");
|
|
} else if (filter === "alerts") {
|
|
const alertNodes = this.cy.nodes().filter((n) => {
|
|
return n.data("has_alerts") === true || n.data("status") === "down";
|
|
});
|
|
const connectedEdges = alertNodes.connectedEdges();
|
|
const parents = alertNodes.parents();
|
|
const visible = alertNodes.union(connectedEdges).union(parents);
|
|
this.cy.elements().not(visible).style("display", "none");
|
|
}
|
|
},
|
|
_searchNodes(query) {
|
|
if (!this.cy) return;
|
|
this.cy.nodes().removeClass("search-match");
|
|
if (!query || query.trim() === "") return;
|
|
const q = query.toLowerCase();
|
|
const matches = this.cy.nodes().filter((n) => {
|
|
const d = n.data();
|
|
return d.label && d.label.toLowerCase().includes(q) || d.ip_address && d.ip_address.toLowerCase().includes(q) || d.site_name && d.site_name.toLowerCase().includes(q) || d.manufacturer && d.manufacturer.toLowerCase().includes(q);
|
|
});
|
|
matches.addClass("search-match");
|
|
if (matches.length > 0) {
|
|
this.cy.fit(matches, 80);
|
|
}
|
|
},
|
|
_changeLayout(mode, topology) {
|
|
if (!this.cy) return;
|
|
if (mode === "geo") {
|
|
const geoNodes = (topology.nodes || []).filter((n) => n.latitude != null && n.longitude != null);
|
|
if (geoNodes.length === 0) return;
|
|
const lats = geoNodes.map((n) => n.latitude);
|
|
const lngs = geoNodes.map((n) => n.longitude);
|
|
const minLat = Math.min(...lats), maxLat = Math.max(...lats);
|
|
const minLng = Math.min(...lngs), maxLng = Math.max(...lngs);
|
|
const width = this.cy.width() - 100;
|
|
const height = this.cy.height() - 100;
|
|
const positions = {};
|
|
const latRange = maxLat - minLat || 1;
|
|
const lngRange = maxLng - minLng || 1;
|
|
(topology.nodes || []).forEach((n) => {
|
|
if (n.latitude != null && n.longitude != null) {
|
|
positions[n.id] = {
|
|
x: 50 + (n.longitude - minLng) / lngRange * width,
|
|
y: 50 + (maxLat - n.latitude) / latRange * height
|
|
// invert Y for map orientation
|
|
};
|
|
}
|
|
});
|
|
let offsetX = 0;
|
|
(topology.nodes || []).forEach((n) => {
|
|
if (n.type === "site") return;
|
|
if (!positions[n.id]) {
|
|
if (n.parent && positions[n.parent]) {
|
|
positions[n.id] = {
|
|
x: positions[n.parent].x + (Math.random() - 0.5) * 60,
|
|
y: positions[n.parent].y + (Math.random() - 0.5) * 60
|
|
};
|
|
} else {
|
|
positions[n.id] = { x: offsetX * 80, y: height + 100 };
|
|
offsetX++;
|
|
}
|
|
}
|
|
});
|
|
this.cy.layout({
|
|
name: "preset",
|
|
positions: (node) => positions[node.id()] || { x: 0, y: 0 },
|
|
fit: true,
|
|
padding: 50,
|
|
animate: true,
|
|
animationDuration: 500
|
|
}).run();
|
|
} else {
|
|
const allNodes = topology.nodes || [];
|
|
const newPositions = this._computePresetPositions(allNodes);
|
|
this.cy.layout({
|
|
name: "preset",
|
|
positions: (node) => newPositions[node.id()] || { x: 0, y: 0 },
|
|
fit: true,
|
|
padding: 50,
|
|
animate: true,
|
|
animationDuration: 500
|
|
}).run();
|
|
}
|
|
}
|
|
};
|
|
var DynamicFavicon = {
|
|
statusColors: { green: "#22c55e", yellow: "#eab308", red: "#ef4444" },
|
|
cache: {},
|
|
originalHref: null,
|
|
getFaviconPng(status) {
|
|
if (this.cache[status]) return this.cache[status];
|
|
const color = this.statusColors[status] || this.statusColors.green;
|
|
const canvas = document.createElement("canvas");
|
|
canvas.width = 64;
|
|
canvas.height = 64;
|
|
const ctx = canvas.getContext("2d");
|
|
ctx.beginPath();
|
|
ctx.arc(32, 32, 32, 0, Math.PI * 2);
|
|
ctx.fillStyle = color;
|
|
ctx.fill();
|
|
this.cache[status] = canvas.toDataURL("image/png");
|
|
return this.cache[status];
|
|
},
|
|
applyStatus() {
|
|
const faviconEl = document.getElementById("favicon");
|
|
if (!faviconEl) return;
|
|
const status = this.el.dataset.status || "green";
|
|
faviconEl.type = "image/png";
|
|
faviconEl.href = this.getFaviconPng(status);
|
|
},
|
|
mounted() {
|
|
const faviconEl = document.getElementById("favicon");
|
|
if (faviconEl) this.originalHref = faviconEl.href;
|
|
this.applyStatus();
|
|
},
|
|
updated() {
|
|
this.applyStatus();
|
|
},
|
|
destroyed() {
|
|
const faviconEl = document.getElementById("favicon");
|
|
if (faviconEl && this.originalHref) {
|
|
faviconEl.type = "image/png";
|
|
faviconEl.href = this.originalHref;
|
|
}
|
|
}
|
|
};
|
|
var MikrotikPortSync = {
|
|
handleSslChange: null,
|
|
sslCheckbox: null,
|
|
setupListener() {
|
|
if (this.sslCheckbox && this.handleSslChange) {
|
|
this.sslCheckbox.removeEventListener("change", this.handleSslChange);
|
|
}
|
|
const sslCheckbox = this.el.querySelector('[name="device[mikrotik_use_ssl]"]');
|
|
const portInput = this.el.querySelector('[name="device[mikrotik_port]"]');
|
|
if (!sslCheckbox || !portInput) return;
|
|
this.sslCheckbox = sslCheckbox;
|
|
this.handleSslChange = () => {
|
|
const isChecked = sslCheckbox.checked;
|
|
const currentPort = portInput.value.trim();
|
|
if (currentPort === "" || currentPort === "8729" || currentPort === "8728") {
|
|
portInput.value = isChecked ? "8729" : "8728";
|
|
portInput.dispatchEvent(new Event("input", { bubbles: true }));
|
|
}
|
|
};
|
|
sslCheckbox.addEventListener("change", this.handleSslChange);
|
|
},
|
|
mounted() {
|
|
this.setupListener();
|
|
},
|
|
updated() {
|
|
this.setupListener();
|
|
},
|
|
destroyed() {
|
|
if (this.sslCheckbox && this.handleSslChange) {
|
|
this.sslCheckbox.removeEventListener("change", this.handleSslChange);
|
|
this.handleSslChange = null;
|
|
this.sslCheckbox = null;
|
|
}
|
|
}
|
|
};
|
|
var LeafletMap = {
|
|
map: null,
|
|
mounted() {
|
|
const lat = parseFloat(this.el.dataset.lat);
|
|
const lng = parseFloat(this.el.dataset.lng);
|
|
const zoom = parseInt(this.el.dataset.zoom || "14");
|
|
const title = this.el.dataset.markerTitle || "";
|
|
if (isNaN(lat) || isNaN(lng)) return;
|
|
const initMap = () => {
|
|
if (typeof L === "undefined") {
|
|
setTimeout(initMap, 100);
|
|
return;
|
|
}
|
|
this.map = L.map(this.el, { scrollWheelZoom: false, zoomControl: true });
|
|
this.map.setView([lat, lng], zoom);
|
|
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
|
|
maxZoom: 19,
|
|
attribution: "\xA9 OpenStreetMap"
|
|
}).addTo(this.map);
|
|
L.marker([lat, lng]).addTo(this.map).bindPopup(title);
|
|
setTimeout(() => this.map.invalidateSize(), 200);
|
|
};
|
|
initMap();
|
|
},
|
|
destroyed() {
|
|
if (this.map) {
|
|
this.map.remove();
|
|
this.map = null;
|
|
}
|
|
}
|
|
};
|
|
var leafletLoad = null;
|
|
function ensureLeaflet() {
|
|
if (typeof window.L !== "undefined") return Promise.resolve();
|
|
if (leafletLoad) return leafletLoad;
|
|
leafletLoad = new Promise((resolve, reject) => {
|
|
if (!document.getElementById("leaflet-css")) {
|
|
const css = document.createElement("link");
|
|
css.id = "leaflet-css";
|
|
css.rel = "stylesheet";
|
|
css.href = "/vendor/leaflet/leaflet.css";
|
|
document.head.appendChild(css);
|
|
}
|
|
const existing = document.getElementById("leaflet-js");
|
|
if (existing) {
|
|
if (typeof window.L !== "undefined") {
|
|
resolve();
|
|
} else {
|
|
existing.addEventListener("load", () => resolve(), { once: true });
|
|
existing.addEventListener("error", (e) => reject(e), { once: true });
|
|
}
|
|
return;
|
|
}
|
|
const script = document.createElement("script");
|
|
script.id = "leaflet-js";
|
|
script.src = "/vendor/leaflet/leaflet.js";
|
|
script.async = true;
|
|
script.onload = () => resolve();
|
|
script.onerror = (e) => reject(e);
|
|
document.head.appendChild(script);
|
|
});
|
|
return leafletLoad;
|
|
}
|
|
var SitesMap = {
|
|
map: null,
|
|
markers: null,
|
|
mounted() {
|
|
ensureLeaflet().then(() => {
|
|
const sitesData = JSON.parse(this.el.dataset.sites || "[]");
|
|
this.initializeLeaflet(sitesData);
|
|
this.handleEvent("site_clicked", (payload) => {
|
|
this.pushEvent("site_clicked", payload);
|
|
});
|
|
}).catch((e) => {
|
|
console.error("SitesMap: Leaflet failed to load", e);
|
|
});
|
|
},
|
|
updated() {
|
|
if (this.map) {
|
|
const sitesData = JSON.parse(this.el.dataset.sites || "[]");
|
|
this.updateSites(sitesData);
|
|
}
|
|
},
|
|
destroyed() {
|
|
if (this.map) {
|
|
this.map.remove();
|
|
this.map = null;
|
|
this.markers = null;
|
|
}
|
|
},
|
|
initializeLeaflet(sites) {
|
|
this.map = L.map(this.el, {
|
|
zoomControl: true,
|
|
scrollWheelZoom: true
|
|
});
|
|
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
|
|
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
|
|
maxZoom: 18
|
|
}).addTo(this.map);
|
|
this.updateSites(sites);
|
|
},
|
|
updateSites(sites) {
|
|
if (!this.map) return;
|
|
if (this.markers) {
|
|
this.map.removeLayer(this.markers);
|
|
}
|
|
this.markers = L.layerGroup();
|
|
if (sites.length === 0) {
|
|
this.map.setView([39.8283, -98.5795], 4);
|
|
this.markers.addTo(this.map);
|
|
return;
|
|
}
|
|
const bounds = L.latLngBounds([]);
|
|
sites.forEach((site) => {
|
|
if (site.latitude && site.longitude) {
|
|
const marker = L.marker([site.latitude, site.longitude]);
|
|
let popupContent = `<div class="p-2">
|
|
<h3 class="font-semibold text-lg mb-1">${site.name}</h3>`;
|
|
if (site.description) {
|
|
popupContent += `<p class="text-sm text-gray-600 mb-1">${site.description}</p>`;
|
|
}
|
|
if (site.address) {
|
|
popupContent += `<p class="text-xs text-gray-500 mb-1">${site.address}</p>`;
|
|
}
|
|
popupContent += `<p class="text-xs text-gray-500 mb-2">
|
|
${site.latitude.toFixed(4)}, ${site.longitude.toFixed(4)}
|
|
</p>`;
|
|
if (site.device_count > 0) {
|
|
popupContent += `<p class="text-xs text-blue-600 mb-2">
|
|
${site.device_count} device${site.device_count !== 1 ? "s" : ""}
|
|
</p>`;
|
|
}
|
|
popupContent += `<button
|
|
data-site-id="${site.id}"
|
|
data-action="view-site"
|
|
class="text-xs bg-blue-600 text-white px-2 py-1 rounded hover:bg-blue-700"
|
|
>
|
|
View Site \u2192
|
|
</button></div>`;
|
|
marker.bindPopup(popupContent);
|
|
marker.on("popupopen", () => {
|
|
var _a2, _b;
|
|
const button = (_b = (_a2 = marker.getPopup()) == null ? void 0 : _a2.getElement()) == null ? void 0 : _b.querySelector('[data-action="view-site"]');
|
|
if (button) {
|
|
button.addEventListener("click", () => {
|
|
this.pushEvent("site_clicked", { site_id: button.dataset.siteId });
|
|
});
|
|
}
|
|
});
|
|
this.markers.addLayer(marker);
|
|
bounds.extend([site.latitude, site.longitude]);
|
|
}
|
|
});
|
|
this.markers.addTo(this.map);
|
|
if (bounds.isValid()) {
|
|
this.map.fitBounds(bounds, { padding: [20, 20] });
|
|
}
|
|
}
|
|
};
|
|
var CoverageLocationPicker = {
|
|
map: null,
|
|
marker: null,
|
|
programmaticMove: false,
|
|
mounted() {
|
|
ensureLeaflet().then(() => this.initMap()).catch((e) => {
|
|
console.error("CoverageLocationPicker: Leaflet failed to load", e);
|
|
});
|
|
},
|
|
updated() {
|
|
if (this.map) this.syncMarkerFromAttrs();
|
|
},
|
|
destroyed() {
|
|
if (this.map) {
|
|
this.map.remove();
|
|
this.map = null;
|
|
this.marker = null;
|
|
}
|
|
},
|
|
initMap() {
|
|
const lat = this.markerLat();
|
|
const lon = this.markerLon();
|
|
const hasFix = lat !== null && lon !== null;
|
|
const center = hasFix ? [lat, lon] : [30.27, -97.74];
|
|
const zoom = hasFix ? 15 : 6;
|
|
this.map = L.map(this.el, { zoomControl: true, scrollWheelZoom: true }).setView(center, zoom);
|
|
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
|
|
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
|
|
maxZoom: 19
|
|
}).addTo(this.map);
|
|
if (hasFix) {
|
|
this.marker = L.marker([lat, lon], {
|
|
draggable: true,
|
|
autoPan: true
|
|
}).addTo(this.map);
|
|
this.marker.on("dragend", (e) => {
|
|
const ll = e.target.getLatLng();
|
|
this.pushEvent("location_picked", { lat: ll.lat, lon: ll.lng });
|
|
});
|
|
}
|
|
},
|
|
syncMarkerFromAttrs() {
|
|
const lat = this.markerLat();
|
|
const lon = this.markerLon();
|
|
if (lat === null || lon === null) return;
|
|
if (!this.marker) {
|
|
this.marker = L.marker([lat, lon], {
|
|
draggable: true,
|
|
autoPan: true
|
|
}).addTo(this.map);
|
|
this.marker.on("dragend", (e) => {
|
|
const ll = e.target.getLatLng();
|
|
this.pushEvent("location_picked", { lat: ll.lat, lon: ll.lng });
|
|
});
|
|
this.map.setView([lat, lon], 15);
|
|
return;
|
|
}
|
|
const cur = this.marker.getLatLng();
|
|
if (Math.abs(cur.lat - lat) > 1e-7 || Math.abs(cur.lng - lon) > 1e-7) {
|
|
this.marker.setLatLng([lat, lon]);
|
|
this.map.panTo([lat, lon]);
|
|
}
|
|
},
|
|
markerLat() {
|
|
const v = this.el.dataset.markerLat;
|
|
if (!v) return null;
|
|
const n = parseFloat(v);
|
|
return Number.isFinite(n) ? n : null;
|
|
},
|
|
markerLon() {
|
|
const v = this.el.dataset.markerLon;
|
|
if (!v) return null;
|
|
const n = parseFloat(v);
|
|
return Number.isFinite(n) ? n : null;
|
|
}
|
|
};
|
|
var CoverageMap = {
|
|
map: null,
|
|
marker: null,
|
|
overlay: null,
|
|
opacityListener: null,
|
|
mounted() {
|
|
ensureLeaflet().then(() => this.init()).catch((e) => {
|
|
console.error("CoverageMap: Leaflet failed to load", e);
|
|
});
|
|
},
|
|
updated() {
|
|
if (this.map) {
|
|
this.refreshOverlay();
|
|
}
|
|
},
|
|
destroyed() {
|
|
if (this.opacityListener) {
|
|
const slider = document.getElementById("coverage-opacity-slider");
|
|
if (slider) slider.removeEventListener("input", this.opacityListener);
|
|
this.opacityListener = null;
|
|
}
|
|
if (this.map) {
|
|
this.map.remove();
|
|
this.map = null;
|
|
this.marker = null;
|
|
this.overlay = null;
|
|
}
|
|
},
|
|
init() {
|
|
const lat = parseFloat(this.el.dataset.lat || "0");
|
|
const lon = parseFloat(this.el.dataset.lon || "0");
|
|
const azimuth = parseFloat(this.el.dataset.azimuth || "0");
|
|
const name = this.el.dataset.name || "Coverage";
|
|
this.map = L.map(this.el, { zoomControl: true, scrollWheelZoom: true }).setView([lat, lon], 13);
|
|
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
|
|
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
|
|
maxZoom: 19
|
|
}).addTo(this.map);
|
|
const antennaIcon = L.divIcon({
|
|
className: "coverage-antenna-marker",
|
|
html: `
|
|
<div style="position:relative;width:32px;height:32px">
|
|
<div style="position:absolute;top:50%;left:50%;width:0;height:0;
|
|
transform:translate(-50%,-100%) rotate(${azimuth}deg);
|
|
transform-origin:50% 100%;
|
|
border-left:24px solid transparent;
|
|
border-right:24px solid transparent;
|
|
border-bottom:48px solid rgba(59,130,246,0.35);"></div>
|
|
<div style="position:absolute;top:50%;left:50%;width:14px;height:14px;
|
|
transform:translate(-50%,-50%);
|
|
background:#2563eb;border:2px solid white;border-radius:50%;
|
|
box-shadow:0 0 0 1px rgba(0,0,0,0.2);"></div>
|
|
</div>
|
|
`,
|
|
iconSize: [32, 32],
|
|
iconAnchor: [16, 16]
|
|
});
|
|
this.marker = L.marker([lat, lon], { icon: antennaIcon, title: name }).addTo(this.map);
|
|
this.refreshOverlay();
|
|
this.bindOpacitySlider();
|
|
},
|
|
refreshOverlay() {
|
|
const png = this.el.dataset.png;
|
|
const bboxJson = this.el.dataset.bbox;
|
|
if (this.overlay) {
|
|
this.map.removeLayer(this.overlay);
|
|
this.overlay = null;
|
|
}
|
|
if (!png || !bboxJson) return;
|
|
let bbox;
|
|
try {
|
|
bbox = JSON.parse(bboxJson);
|
|
} catch (e) {
|
|
return;
|
|
}
|
|
if (!Array.isArray(bbox) || bbox.length !== 4) return;
|
|
const [minLat, minLon, maxLat, maxLon] = bbox;
|
|
const opacity = this.currentOpacity();
|
|
this.overlay = L.imageOverlay(png, [[minLat, minLon], [maxLat, maxLon]], {
|
|
opacity,
|
|
interactive: false
|
|
}).addTo(this.map);
|
|
this.map.fitBounds([[minLat, minLon], [maxLat, maxLon]], { padding: [20, 20] });
|
|
},
|
|
bindOpacitySlider() {
|
|
const slider = document.getElementById("coverage-opacity-slider");
|
|
if (!slider) return;
|
|
this.opacityListener = (e) => {
|
|
const v = parseInt(e.target.value, 10) / 100;
|
|
if (this.overlay) this.overlay.setOpacity(v);
|
|
const label = document.getElementById("coverage-opacity-label");
|
|
if (label) label.textContent = `${Math.round(v * 100)}%`;
|
|
};
|
|
slider.addEventListener("input", this.opacityListener);
|
|
},
|
|
currentOpacity() {
|
|
const slider = document.getElementById("coverage-opacity-slider");
|
|
if (!slider) return 0.7;
|
|
return parseInt(slider.value, 10) / 100;
|
|
}
|
|
};
|
|
var MultiCoverageMap = {
|
|
map: null,
|
|
baseStreets: null,
|
|
baseSatellite: null,
|
|
layerCtl: null,
|
|
searchControl: null,
|
|
overlays: /* @__PURE__ */ new Map(),
|
|
markers: /* @__PURE__ */ new Map(),
|
|
enabled: /* @__PURE__ */ new Set(),
|
|
coverages: [],
|
|
opacityListener: null,
|
|
searchListener: null,
|
|
probeMarker: null,
|
|
searchMarker: null,
|
|
mounted() {
|
|
ensureLeaflet().then(() => this.init()).catch((e) => {
|
|
console.error("MultiCoverageMap: Leaflet failed to load", e);
|
|
});
|
|
},
|
|
destroyed() {
|
|
if (this.opacityListener) {
|
|
const slider = document.getElementById("coverage-opacity-slider");
|
|
if (slider) slider.removeEventListener("input", this.opacityListener);
|
|
this.opacityListener = null;
|
|
}
|
|
if (this.searchListener) {
|
|
const input = document.getElementById("coverage-map-search");
|
|
if (input) input.removeEventListener("keydown", this.searchListener);
|
|
this.searchListener = null;
|
|
}
|
|
if (this.map) {
|
|
this.map.remove();
|
|
this.map = null;
|
|
this.overlays.clear();
|
|
this.markers.clear();
|
|
this.enabled.clear();
|
|
}
|
|
},
|
|
init() {
|
|
this.coverages = JSON.parse(this.el.dataset.coverages || "[]");
|
|
const enabledList = JSON.parse(this.el.dataset.enabled || "[]");
|
|
this.enabled = new Set(enabledList);
|
|
const init = this.computeInitialView();
|
|
this.injectToolbar();
|
|
this.map = L.map(this.el, { zoomControl: true, scrollWheelZoom: true, attributionControl: true }).setView([init.lat, init.lon], init.zoom);
|
|
this.baseStreets = L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
|
|
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
|
|
maxZoom: 19
|
|
});
|
|
this.baseSatellite = L.tileLayer(
|
|
"https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}",
|
|
{
|
|
attribution: "Tiles © Esri",
|
|
maxZoom: 19
|
|
}
|
|
);
|
|
this.baseSatellite.addTo(this.map);
|
|
this.coverages.forEach((c) => this.addCoverageLayer(c));
|
|
this.applyEnabled();
|
|
this.map.on("click", (e) => {
|
|
this.placeProbeMarker(e.latlng.lat, e.latlng.lng);
|
|
this.pushEvent("probe_point", { lat: e.latlng.lat, lon: e.latlng.lng });
|
|
});
|
|
this.bindOpacitySlider();
|
|
this.bindBaseToggle();
|
|
this.bindSearch();
|
|
this.handleEvent("coverage:enabled-changed", ({ enabled }) => {
|
|
this.enabled = new Set(enabled);
|
|
this.applyEnabled();
|
|
});
|
|
this.handleEvent("coverage:list-changed", (payload) => {
|
|
this.overlays.forEach((o) => this.map.removeLayer(o));
|
|
this.markers.forEach((m) => this.map.removeLayer(m));
|
|
this.overlays.clear();
|
|
this.markers.clear();
|
|
this.coverages = payload.coverages;
|
|
this.enabled = new Set(payload.enabled);
|
|
this.coverages.forEach((c) => this.addCoverageLayer(c));
|
|
this.applyEnabled();
|
|
});
|
|
},
|
|
computeInitialView() {
|
|
if (this.coverages.length === 0) return { lat: 31, lon: -97, zoom: 6 };
|
|
const lats = [];
|
|
const lons = [];
|
|
this.coverages.forEach((c) => {
|
|
if (c.tx.lat !== null && c.tx.lon !== null) {
|
|
lats.push(c.tx.lat);
|
|
lons.push(c.tx.lon);
|
|
}
|
|
});
|
|
if (lats.length === 0) {
|
|
const [minLat, minLon, maxLat, maxLon] = this.coverages[0].bbox;
|
|
return { lat: (minLat + maxLat) / 2, lon: (minLon + maxLon) / 2, zoom: 12 };
|
|
}
|
|
const lat = lats.reduce((s, v) => s + v, 0) / lats.length;
|
|
const lon = lons.reduce((s, v) => s + v, 0) / lons.length;
|
|
return { lat, lon, zoom: lats.length === 1 ? 13 : 11 };
|
|
},
|
|
injectToolbar() {
|
|
if (document.getElementById("coverage-map-toolbar")) return;
|
|
const toolbar = document.createElement("div");
|
|
toolbar.id = "coverage-map-toolbar";
|
|
toolbar.className = "pointer-events-none fixed top-32 left-6 z-[1100] flex flex-col gap-2 w-72 max-w-[90vw]";
|
|
toolbar.innerHTML = `
|
|
<div class="pointer-events-auto rounded-lg border border-gray-200 dark:border-white/10 bg-white/95 dark:bg-gray-900/95 backdrop-blur shadow-lg p-2 flex gap-1">
|
|
<button type="button" id="coverage-base-streets" class="flex-1 px-2 py-1 text-xs rounded font-medium text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800">Map</button>
|
|
<button type="button" id="coverage-base-satellite" class="flex-1 px-2 py-1 text-xs rounded font-medium text-gray-900 dark:text-white bg-blue-100 dark:bg-blue-900/40">Satellite</button>
|
|
</div>
|
|
<div class="pointer-events-auto rounded-lg border border-gray-200 dark:border-white/10 bg-white/95 dark:bg-gray-900/95 backdrop-blur shadow-lg">
|
|
<input type="text" id="coverage-map-search" placeholder="Search address..." class="w-full px-3 py-2 text-sm bg-transparent text-gray-900 dark:text-gray-100 placeholder-gray-500 focus:outline-none" />
|
|
</div>
|
|
`;
|
|
document.body.appendChild(toolbar);
|
|
this.cleanupToolbar = () => {
|
|
const el = document.getElementById("coverage-map-toolbar");
|
|
if (el) el.remove();
|
|
};
|
|
},
|
|
addCoverageLayer(c) {
|
|
var _a2;
|
|
const [minLat, minLon, maxLat, maxLon] = c.bbox;
|
|
const overlay = L.imageOverlay(c.png, [[minLat, minLon], [maxLat, maxLon]], {
|
|
opacity: this.currentOpacity(),
|
|
interactive: false
|
|
});
|
|
this.overlays.set(c.id, overlay);
|
|
if (c.tx.lat !== null && c.tx.lon !== null) {
|
|
const az = (_a2 = c.tx.azimuth) != null ? _a2 : 0;
|
|
const icon = L.divIcon({
|
|
className: "coverage-antenna-marker",
|
|
html: `
|
|
<div style="position:relative;width:32px;height:32px">
|
|
<div style="position:absolute;top:50%;left:50%;width:0;height:0;
|
|
transform:translate(-50%,-100%) rotate(${az}deg);
|
|
transform-origin:50% 100%;
|
|
border-left:18px solid transparent;
|
|
border-right:18px solid transparent;
|
|
border-bottom:36px solid rgba(59,130,246,0.35);"></div>
|
|
<div style="position:absolute;top:50%;left:50%;width:12px;height:12px;
|
|
transform:translate(-50%,-50%);
|
|
background:#2563eb;border:2px solid white;border-radius:50%;
|
|
box-shadow:0 0 0 1px rgba(0,0,0,0.2);"></div>
|
|
</div>
|
|
`,
|
|
iconSize: [32, 32],
|
|
iconAnchor: [16, 16]
|
|
});
|
|
const marker = L.marker([c.tx.lat, c.tx.lon], { icon, title: c.name });
|
|
this.markers.set(c.id, marker);
|
|
}
|
|
},
|
|
applyEnabled() {
|
|
this.coverages.forEach((c) => {
|
|
const overlay = this.overlays.get(c.id);
|
|
const marker = this.markers.get(c.id);
|
|
const on = this.enabled.has(c.id);
|
|
if (overlay) {
|
|
if (on && !this.map.hasLayer(overlay)) overlay.addTo(this.map);
|
|
if (!on && this.map.hasLayer(overlay)) this.map.removeLayer(overlay);
|
|
}
|
|
if (marker) {
|
|
if (on && !this.map.hasLayer(marker)) marker.addTo(this.map);
|
|
if (!on && this.map.hasLayer(marker)) this.map.removeLayer(marker);
|
|
}
|
|
});
|
|
},
|
|
bindOpacitySlider() {
|
|
const slider = document.getElementById("coverage-opacity-slider");
|
|
if (!slider) return;
|
|
this.opacityListener = (e) => {
|
|
const v = parseInt(e.target.value, 10) / 100;
|
|
this.overlays.forEach((o) => o.setOpacity(v));
|
|
const label = document.getElementById("coverage-opacity-label");
|
|
if (label) label.textContent = `${Math.round(v * 100)}%`;
|
|
};
|
|
slider.addEventListener("input", this.opacityListener);
|
|
},
|
|
currentOpacity() {
|
|
const slider = document.getElementById("coverage-opacity-slider");
|
|
if (!slider) return 0.7;
|
|
return parseInt(slider.value, 10) / 100;
|
|
},
|
|
bindBaseToggle() {
|
|
const streets = document.getElementById("coverage-base-streets");
|
|
const satellite = document.getElementById("coverage-base-satellite");
|
|
if (!streets || !satellite) return;
|
|
streets.addEventListener("click", () => {
|
|
if (this.map.hasLayer(this.baseSatellite)) this.map.removeLayer(this.baseSatellite);
|
|
if (!this.map.hasLayer(this.baseStreets)) this.baseStreets.addTo(this.map);
|
|
streets.classList.add("text-gray-900", "dark:text-white", "bg-blue-100", "dark:bg-blue-900/40");
|
|
satellite.classList.remove("text-gray-900", "dark:text-white", "bg-blue-100", "dark:bg-blue-900/40");
|
|
});
|
|
satellite.addEventListener("click", () => {
|
|
if (this.map.hasLayer(this.baseStreets)) this.map.removeLayer(this.baseStreets);
|
|
if (!this.map.hasLayer(this.baseSatellite)) this.baseSatellite.addTo(this.map);
|
|
satellite.classList.add("text-gray-900", "dark:text-white", "bg-blue-100", "dark:bg-blue-900/40");
|
|
streets.classList.remove("text-gray-900", "dark:text-white", "bg-blue-100", "dark:bg-blue-900/40");
|
|
});
|
|
},
|
|
bindSearch() {
|
|
const input = document.getElementById("coverage-map-search");
|
|
if (!input) return;
|
|
this.searchListener = async (e) => {
|
|
if (e.key !== "Enter") return;
|
|
const q = input.value.trim();
|
|
if (!q) return;
|
|
try {
|
|
const url = `https://nominatim.openstreetmap.org/search?format=json&limit=1&q=${encodeURIComponent(q)}`;
|
|
const res = await fetch(url, { headers: { "Accept": "application/json" } });
|
|
if (!res.ok) return;
|
|
const data = await res.json();
|
|
if (!data || data.length === 0) return;
|
|
const lat = parseFloat(data[0].lat);
|
|
const lon = parseFloat(data[0].lon);
|
|
if (!Number.isFinite(lat) || !Number.isFinite(lon)) return;
|
|
this.map.setView([lat, lon], 16);
|
|
if (this.searchMarker) this.map.removeLayer(this.searchMarker);
|
|
this.searchMarker = L.marker([lat, lon]).addTo(this.map).bindPopup(data[0].display_name).openPopup();
|
|
} catch (err) {
|
|
console.error("Coverage search failed:", err);
|
|
}
|
|
};
|
|
input.addEventListener("keydown", this.searchListener);
|
|
},
|
|
placeProbeMarker(lat, lon) {
|
|
if (this.probeMarker) this.map.removeLayer(this.probeMarker);
|
|
const icon = L.divIcon({
|
|
className: "coverage-probe-marker",
|
|
html: `<div style="width:14px;height:14px;border-radius:50%;background:#dc2626;border:3px solid white;box-shadow:0 0 0 1px rgba(0,0,0,0.4)"></div>`,
|
|
iconSize: [14, 14],
|
|
iconAnchor: [7, 7]
|
|
});
|
|
this.probeMarker = L.marker([lat, lon], { icon, interactive: false }).addTo(this.map);
|
|
},
|
|
cleanupToolbar: null
|
|
};
|
|
var _a;
|
|
var csrfToken = (_a = document.querySelector("meta[name='csrf-token']")) == null ? void 0 : _a.getAttribute("content");
|
|
if (!csrfToken) {
|
|
throw new Error("CSRF token meta tag not found");
|
|
}
|
|
var userTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC";
|
|
var GlobalSearchTrigger = {
|
|
handleClick: null,
|
|
mounted() {
|
|
this.handleClick = () => {
|
|
document.dispatchEvent(new KeyboardEvent("keydown", { key: "k", metaKey: true }));
|
|
};
|
|
this.el.addEventListener("click", this.handleClick);
|
|
},
|
|
destroyed() {
|
|
if (this.handleClick) {
|
|
this.el.removeEventListener("click", this.handleClick);
|
|
this.handleClick = null;
|
|
}
|
|
}
|
|
};
|
|
var GlobalSearch = {
|
|
mounted() {
|
|
this.handleKeydown = (e) => {
|
|
if ((e.metaKey || e.ctrlKey) && e.key === "k") {
|
|
e.preventDefault();
|
|
this.pushEventTo(this.el, "open", {});
|
|
}
|
|
if (e.key === "Escape" && this.el.querySelector("[role=dialog]")) {
|
|
this.pushEventTo(this.el, "close", {});
|
|
}
|
|
};
|
|
document.addEventListener("keydown", this.handleKeydown);
|
|
},
|
|
updated() {
|
|
const input = this.el.querySelector("#global-search-input");
|
|
if (input) input.focus();
|
|
},
|
|
destroyed() {
|
|
document.removeEventListener("keydown", this.handleKeydown);
|
|
}
|
|
};
|
|
var StatusTitle = {
|
|
baseTitle: null,
|
|
mounted() {
|
|
this.baseTitle = document.title.replace(/^(?:(?:🔴|🟡|🟢)\s)+/u, "");
|
|
const observer = new MutationObserver(() => {
|
|
const currentTitle = document.title;
|
|
if (currentTitle && !currentTitle.startsWith("\u{1F534}") && !currentTitle.startsWith("\u{1F7E1}") && !currentTitle.startsWith("\u{1F7E2}")) {
|
|
this.baseTitle = currentTitle;
|
|
}
|
|
});
|
|
observer.observe(document.querySelector("title"), {
|
|
childList: true,
|
|
characterData: true,
|
|
subtree: true
|
|
});
|
|
this.handleEvent("update_status_emoji", ({ emoji }) => {
|
|
const baseTitle = this.baseTitle || document.title.replace(/^(?:(?:🔴|🟡|🟢)\s)+/u, "");
|
|
document.title = emoji ? `${emoji} ${baseTitle}` : baseTitle;
|
|
});
|
|
},
|
|
destroyed() {
|
|
if (this.observer) {
|
|
this.observer.disconnect();
|
|
}
|
|
}
|
|
};
|
|
var SidebarCollapse = {
|
|
mounted() {
|
|
this.el.addEventListener("click", (e) => {
|
|
if (e.target.closest("[data-sidebar-toggle]")) {
|
|
const html = document.documentElement;
|
|
html.classList.toggle("sidebar-collapsed");
|
|
localStorage.setItem("sidebarCollapsed", String(html.classList.contains("sidebar-collapsed")));
|
|
}
|
|
});
|
|
}
|
|
};
|
|
var ThemeSelector = {
|
|
mounted() {
|
|
this.updateActive();
|
|
window.addEventListener("phx:set-theme", () => this.updateActive());
|
|
},
|
|
updateActive() {
|
|
const current = localStorage.getItem("phx:theme") || "system";
|
|
this.el.querySelectorAll("[data-phx-theme]").forEach((btn) => {
|
|
const isActive = btn.dataset.phxTheme === current;
|
|
btn.setAttribute("aria-pressed", isActive ? "true" : "false");
|
|
btn.classList.toggle("ring-2", isActive);
|
|
btn.classList.toggle("ring-indigo-500", isActive);
|
|
btn.classList.toggle("bg-indigo-50", isActive);
|
|
btn.classList.toggle("dark:bg-indigo-900/20", isActive);
|
|
btn.classList.toggle("text-indigo-700", isActive);
|
|
btn.classList.toggle("dark:text-indigo-300", isActive);
|
|
});
|
|
}
|
|
};
|
|
var WeathermapViewer = {
|
|
cy: null,
|
|
_topologyData: null,
|
|
_zoomInHandler: null,
|
|
_zoomOutHandler: null,
|
|
_fitHandler: null,
|
|
mounted() {
|
|
const topologyData = JSON.parse(this.el.dataset.topology || "{}");
|
|
this._topologyData = topologyData;
|
|
this.initializeCytoscape(topologyData);
|
|
this.handleEvent("update_weathermap", (payload) => {
|
|
if (this.cy) {
|
|
this._topologyData = payload.topology;
|
|
this.updateTopology(payload.topology);
|
|
}
|
|
});
|
|
this.handleEvent("apply_filter", (payload) => {
|
|
if (!this.cy) return;
|
|
this._applyFilter(payload.filter);
|
|
});
|
|
this.handleEvent("search_nodes", (payload) => {
|
|
if (!this.cy) return;
|
|
this._searchNodes(payload.query);
|
|
});
|
|
this.handleEvent("change_layout", (payload) => {
|
|
if (!this.cy || !this._topologyData) return;
|
|
this._changeLayout(payload.mode, this._topologyData);
|
|
});
|
|
},
|
|
updated() {
|
|
const topologyData = JSON.parse(this.el.dataset.topology || "{}");
|
|
this.updateTopology(topologyData);
|
|
},
|
|
destroyed() {
|
|
const zoomIn = document.getElementById("cy-zoom-in");
|
|
const zoomOut = document.getElementById("cy-zoom-out");
|
|
const fit = document.getElementById("cy-fit");
|
|
if (zoomIn && this._zoomInHandler) {
|
|
zoomIn.removeEventListener("click", this._zoomInHandler);
|
|
}
|
|
if (zoomOut && this._zoomOutHandler) {
|
|
zoomOut.removeEventListener("click", this._zoomOutHandler);
|
|
}
|
|
if (fit && this._fitHandler) {
|
|
fit.removeEventListener("click", this._fitHandler);
|
|
}
|
|
this._zoomInHandler = null;
|
|
this._zoomOutHandler = null;
|
|
this._fitHandler = null;
|
|
if (this.cy) {
|
|
try {
|
|
this.cy.stop();
|
|
} catch (_e) {
|
|
}
|
|
this.cy.destroy();
|
|
this.cy = null;
|
|
}
|
|
},
|
|
initializeCytoscape(topology) {
|
|
var _a2, _b;
|
|
const isDark = document.documentElement.getAttribute("data-theme") === "dark";
|
|
const roleColors = {
|
|
router: "#3B82F6",
|
|
// blue
|
|
switch: "#10B981",
|
|
// green
|
|
wireless: "#8B5CF6",
|
|
// purple
|
|
firewall: "#EF4444",
|
|
// red
|
|
server: "#F59E0B",
|
|
// amber
|
|
unknown: "#9CA3AF"
|
|
// light gray
|
|
};
|
|
const roleShapes = {
|
|
router: "round-rectangle",
|
|
switch: "diamond",
|
|
wireless: "triangle",
|
|
firewall: "hexagon",
|
|
server: "rectangle",
|
|
unknown: "ellipse"
|
|
};
|
|
const utilizationColors = {
|
|
low: "#10B981",
|
|
// green (0-30%)
|
|
medium: "#F59E0B",
|
|
// yellow (30-60%)
|
|
high: "#F97316",
|
|
// orange (60-80%)
|
|
critical: "#EF4444"
|
|
// red (80%+)
|
|
};
|
|
const getWeathermapEdgeStyle = (edge) => {
|
|
const utilizationLevel = edge.utilization_level;
|
|
const confidence = edge.confidence || 0.5;
|
|
if (utilizationLevel && utilizationColors[utilizationLevel]) {
|
|
return {
|
|
color: utilizationColors[utilizationLevel],
|
|
style: "solid",
|
|
dashPattern: []
|
|
};
|
|
}
|
|
if (confidence > 0.9) {
|
|
return { color: "#9CA3AF", style: "solid", dashPattern: [] };
|
|
} else if (confidence >= 0.5) {
|
|
return { color: "#9CA3AF", style: "dashed", dashPattern: [6, 3] };
|
|
} else {
|
|
return { color: "#D1D5DB", style: "dashed", dashPattern: [2, 3] };
|
|
}
|
|
};
|
|
const computeSimplePositions = (nodes) => {
|
|
const positions = {};
|
|
const SPACING = 120;
|
|
const cols = Math.ceil(Math.sqrt(nodes.filter((n) => n.type !== "site").length));
|
|
let x = 0, y = 0, col = 0;
|
|
nodes.forEach((node, i) => {
|
|
if (node.type === "site") return;
|
|
positions[node.id] = { x: x * SPACING, y: y * SPACING };
|
|
col++;
|
|
if (col >= cols) {
|
|
col = 0;
|
|
x = 0;
|
|
y++;
|
|
} else {
|
|
x++;
|
|
}
|
|
});
|
|
return positions;
|
|
};
|
|
const presetPositions = computeSimplePositions(topology.nodes || []);
|
|
const elements = [];
|
|
(_a2 = topology.nodes) == null ? void 0 : _a2.forEach((node) => {
|
|
if (node.type === "site") return;
|
|
const data = {
|
|
id: node.id,
|
|
label: node.label,
|
|
type: node.type,
|
|
status: node.status,
|
|
discovered: node.discovered,
|
|
ip_address: node.ip_address,
|
|
site_name: node.site_name,
|
|
manufacturer: node.manufacturer,
|
|
client_count: node.client_count || 0,
|
|
signal_health: node.signal_health,
|
|
has_alerts: node.has_alerts || false,
|
|
device_role: node.device_role
|
|
};
|
|
elements.push({
|
|
data,
|
|
classes: node.discovered ? "discovered" : node.status
|
|
});
|
|
});
|
|
(_b = topology.edges) == null ? void 0 : _b.forEach((edge) => {
|
|
var _a3;
|
|
let label = "";
|
|
if (edge.utilization_text) {
|
|
label = edge.utilization_text;
|
|
} else if (edge.source_interface && edge.target_interface) {
|
|
label = `${edge.source_interface} \u2194 ${edge.target_interface}`;
|
|
}
|
|
elements.push({
|
|
data: {
|
|
id: edge.id,
|
|
source: edge.source,
|
|
target: edge.target,
|
|
source_interface: edge.source_interface,
|
|
target_interface: edge.target_interface,
|
|
link_type: edge.link_type,
|
|
confidence: (_a3 = edge.confidence) != null ? _a3 : 0.5,
|
|
if_speed: edge.if_speed,
|
|
utilization_level: edge.utilization_level,
|
|
utilization_pct: edge.utilization_pct,
|
|
utilization_text: edge.utilization_text,
|
|
throughput_bps: edge.throughput_bps,
|
|
capacity_bps: edge.capacity_bps,
|
|
signal_health: edge.signal_health,
|
|
snr: edge.snr,
|
|
label
|
|
}
|
|
});
|
|
});
|
|
const getEdgeWidth = (speed) => {
|
|
if (!speed) return 2;
|
|
if (speed >= 1e10) return 6;
|
|
if (speed >= 1e9) return 4;
|
|
if (speed >= 1e8) return 3;
|
|
return 2;
|
|
};
|
|
this.cy = (0, import_cytoscape.default)({
|
|
container: this.el,
|
|
elements,
|
|
style: [
|
|
{
|
|
selector: "node",
|
|
style: {
|
|
"background-color": function(ele) {
|
|
return roleColors[ele.data("type")] || roleColors.unknown;
|
|
},
|
|
"shape": function(ele) {
|
|
return roleShapes[ele.data("type")] || roleShapes.unknown;
|
|
},
|
|
"label": "data(label)",
|
|
"color": isDark ? "#fff" : "#000",
|
|
"text-valign": "bottom",
|
|
"text-halign": "center",
|
|
"text-margin-y": 6,
|
|
"font-size": "13px",
|
|
"font-weight": "500",
|
|
"text-wrap": "wrap",
|
|
"text-max-width": "140px",
|
|
"width": 44,
|
|
"height": 44,
|
|
"border-width": 2,
|
|
"border-color": function(ele) {
|
|
const status = ele.data("status");
|
|
if (status === "down") return "#dc2626";
|
|
if (status === "unknown") return "#ca8a04";
|
|
const type = ele.data("type");
|
|
const darkerColors = {
|
|
router: "#2563EB",
|
|
switch: "#059669",
|
|
wireless: "#7C3AED",
|
|
firewall: "#DC2626",
|
|
server: "#D97706",
|
|
unknown: "#6B7280"
|
|
};
|
|
return darkerColors[type] || darkerColors.unknown;
|
|
}
|
|
}
|
|
},
|
|
{
|
|
selector: 'node[status = "down"]',
|
|
style: {
|
|
"border-width": 3,
|
|
"border-color": "#dc2626",
|
|
"background-blacken": -0.3
|
|
}
|
|
},
|
|
{
|
|
selector: "node.discovered",
|
|
style: {
|
|
"border-style": "dashed",
|
|
"border-width": 2,
|
|
"border-color": "#9ca3af",
|
|
"opacity": 0.6,
|
|
"width": 34,
|
|
"height": 34,
|
|
"font-size": "11px"
|
|
}
|
|
},
|
|
{
|
|
selector: "edge",
|
|
style: {
|
|
"width": function(ele) {
|
|
return getEdgeWidth(ele.data("if_speed"));
|
|
},
|
|
"line-color": function(ele) {
|
|
return getWeathermapEdgeStyle(ele.data()).color;
|
|
},
|
|
"line-style": function(ele) {
|
|
return getWeathermapEdgeStyle(ele.data()).style;
|
|
},
|
|
"line-dash-pattern": function(ele) {
|
|
const pattern = getWeathermapEdgeStyle(ele.data()).dashPattern;
|
|
return pattern.length > 0 ? pattern : [1, 0];
|
|
},
|
|
"curve-style": "bezier",
|
|
"label": "data(label)",
|
|
"font-size": "9px",
|
|
"color": isDark ? "#d1d5db" : "#4b5563",
|
|
"text-background-color": isDark ? "#1f2937" : "#ffffff",
|
|
"text-background-opacity": 0.9,
|
|
"text-background-padding": "3px",
|
|
"text-rotation": "autorotate",
|
|
"text-margin-y": -10
|
|
}
|
|
}
|
|
],
|
|
layout: {
|
|
name: "preset",
|
|
positions: (node) => presetPositions[node.id()] || { x: 0, y: 0 },
|
|
fit: true,
|
|
padding: 50
|
|
},
|
|
minZoom: 0.2,
|
|
maxZoom: 3,
|
|
wheelSensitivity: 1
|
|
});
|
|
this.cy.on("tap", "node", (evt) => {
|
|
const node = evt.target;
|
|
const nodeData = node.data();
|
|
this.pushEvent("node_clicked", {
|
|
node_id: nodeData.id,
|
|
node_type: nodeData.discovered ? "discovered" : "managed"
|
|
});
|
|
});
|
|
this.handleEvent("highlight_node", (payload) => {
|
|
if (!this.cy) return;
|
|
this.cy.nodes().removeClass("highlighted");
|
|
const node = this.cy.getElementById(payload.node_id);
|
|
if (node.length > 0) {
|
|
node.addClass("highlighted");
|
|
}
|
|
});
|
|
this.handleEvent("clear_highlight", () => {
|
|
if (!this.cy) return;
|
|
this.cy.nodes().removeClass("highlighted");
|
|
});
|
|
this.cy.on("mouseover", "edge", (evt) => {
|
|
const edge = evt.target;
|
|
const data = edge.data();
|
|
const srcNode = this.cy.getElementById(data.source);
|
|
const tgtNode = this.cy.getElementById(data.target);
|
|
const srcName = srcNode.data("label") || data.source;
|
|
const tgtName = tgtNode.data("label") || data.target;
|
|
let tooltip = `${srcName} \u2194 ${tgtName}`;
|
|
if (data.utilization_text) {
|
|
tooltip += `
|
|
\u{1F6A6} ${data.utilization_text}`;
|
|
if (data.utilization_pct != null) {
|
|
tooltip += ` (${data.utilization_pct}%)`;
|
|
}
|
|
}
|
|
edge.style({
|
|
"line-color": "#fbbf24",
|
|
"width": Math.max(getEdgeWidth(data.if_speed), 4),
|
|
"label": tooltip
|
|
});
|
|
});
|
|
this.cy.on("mouseout", "edge", (evt) => {
|
|
const edge = evt.target;
|
|
const data = edge.data();
|
|
const edgeStyle = getWeathermapEdgeStyle(data);
|
|
edge.style({
|
|
"line-color": edgeStyle.color,
|
|
"width": getEdgeWidth(data.if_speed),
|
|
"label": data.label || ""
|
|
});
|
|
});
|
|
this._initControls();
|
|
},
|
|
_initControls() {
|
|
const ZOOM_STEP = 0.25;
|
|
const zoomIn = document.getElementById("cy-zoom-in");
|
|
const zoomOut = document.getElementById("cy-zoom-out");
|
|
const fit = document.getElementById("cy-fit");
|
|
if (zoomIn) {
|
|
this._zoomInHandler = () => {
|
|
if (!this.cy) return;
|
|
this.cy.zoom({
|
|
level: Math.min(this.cy.zoom() + ZOOM_STEP, this.cy.maxZoom()),
|
|
renderedPosition: { x: this.cy.width() / 2, y: this.cy.height() / 2 }
|
|
});
|
|
};
|
|
zoomIn.addEventListener("click", this._zoomInHandler);
|
|
}
|
|
if (zoomOut) {
|
|
this._zoomOutHandler = () => {
|
|
if (!this.cy) return;
|
|
this.cy.zoom({
|
|
level: Math.max(this.cy.zoom() - ZOOM_STEP, this.cy.minZoom()),
|
|
renderedPosition: { x: this.cy.width() / 2, y: this.cy.height() / 2 }
|
|
});
|
|
};
|
|
zoomOut.addEventListener("click", this._zoomOutHandler);
|
|
}
|
|
if (fit) {
|
|
this._fitHandler = () => {
|
|
if (!this.cy) return;
|
|
this.cy.fit(void 0, 50);
|
|
};
|
|
fit.addEventListener("click", this._fitHandler);
|
|
}
|
|
},
|
|
updateTopology(topology) {
|
|
if (!this.cy) return;
|
|
this.cy.destroy();
|
|
this.initializeCytoscape(topology);
|
|
},
|
|
_applyFilter(filter) {
|
|
if (!this.cy) return;
|
|
this.cy.elements().style("display", "element");
|
|
if (filter === "high_util") {
|
|
const matchEdges = this.cy.edges().filter((e) => {
|
|
const level = e.data("utilization_level");
|
|
return level === "high" || level === "critical";
|
|
});
|
|
const connectedNodes = matchEdges.connectedNodes();
|
|
const visible = matchEdges.union(connectedNodes);
|
|
this.cy.elements().not(visible).style("display", "none");
|
|
} else if (filter === "critical") {
|
|
const matchEdges = this.cy.edges().filter((e) => {
|
|
const level = e.data("utilization_level");
|
|
return level === "critical";
|
|
});
|
|
const connectedNodes = matchEdges.connectedNodes();
|
|
const visible = matchEdges.union(connectedNodes);
|
|
this.cy.elements().not(visible).style("display", "none");
|
|
}
|
|
},
|
|
_searchNodes(query) {
|
|
if (!this.cy) return;
|
|
this.cy.nodes().removeClass("search-match");
|
|
if (!query || query.trim() === "") return;
|
|
const q = query.toLowerCase();
|
|
const matches = this.cy.nodes().filter((n) => {
|
|
const d = n.data();
|
|
return d.label && d.label.toLowerCase().includes(q) || d.ip_address && d.ip_address.toLowerCase().includes(q) || d.site_name && d.site_name.toLowerCase().includes(q) || d.manufacturer && d.manufacturer.toLowerCase().includes(q);
|
|
});
|
|
matches.addClass("search-match");
|
|
if (matches.length > 0) {
|
|
this.cy.fit(matches, 80);
|
|
}
|
|
},
|
|
_changeLayout(mode, topology) {
|
|
if (!this.cy) return;
|
|
this.cy.layout({
|
|
name: "circle",
|
|
animate: true,
|
|
animationDuration: 500
|
|
}).run();
|
|
}
|
|
};
|
|
var liveSocket = new LiveSocket2("/live", Socket, {
|
|
longPollFallbackMs: 5e3,
|
|
params: { _csrf_token: csrfToken, timezone: userTimezone },
|
|
hooks: __spreadProps(__spreadValues({}, hooks), { SensorChart, CopyToClipboard, ScrollToTop, AutoDismissFlash, BetaBannerDismiss, NetworkMap, WeathermapViewer, SitesMap, CoverageMap, MultiCoverageMap, CoverageLocationPicker, LeafletMap, DeviceListReorder, SortableList, MikrotikPortSync, GlobalSearch, GlobalSearchTrigger, DynamicFavicon, StatusTitle, ThemeSelector, SidebarCollapse })
|
|
});
|
|
import_topbar.default.config({ barColors: { 0: "#29d" }, shadowColor: "rgba(0, 0, 0, .3)" });
|
|
window.addEventListener("phx:page-loading-start", (_info) => import_topbar.default.show(300));
|
|
window.addEventListener("phx:page-loading-stop", (_info) => {
|
|
import_topbar.default.hide();
|
|
initCookieConsent();
|
|
});
|
|
window.addEventListener("phx:copy", (event) => {
|
|
const el = event.target;
|
|
let text = "";
|
|
if (el.tagName === "INPUT" || el.tagName === "TEXTAREA") {
|
|
text = el.value;
|
|
} else {
|
|
text = el.innerText || el.textContent || "";
|
|
}
|
|
if (text) {
|
|
navigator.clipboard.writeText(text).then(() => {
|
|
console.log("Copied to clipboard:", text.substring(0, 50) + (text.length > 50 ? "..." : ""));
|
|
}).catch((err) => {
|
|
console.error("Failed to copy text:", err);
|
|
});
|
|
} else {
|
|
console.warn("No text found to copy from element:", el);
|
|
}
|
|
});
|
|
window.addEventListener("phx:download", (event) => {
|
|
const { content, filename, mime_type } = event.detail;
|
|
const blob = new Blob([content], { type: mime_type });
|
|
const url = window.URL.createObjectURL(blob);
|
|
const link = document.createElement("a");
|
|
link.href = url;
|
|
link.download = filename;
|
|
document.body.appendChild(link);
|
|
link.click();
|
|
document.body.removeChild(link);
|
|
window.URL.revokeObjectURL(url);
|
|
});
|
|
document.addEventListener("visibilitychange", () => {
|
|
if (document.visibilityState === "visible") {
|
|
if (liveSocket.socket.connectionState() !== "open") {
|
|
liveSocket.socket.disconnect(() => liveSocket.socket.connect());
|
|
}
|
|
}
|
|
});
|
|
liveSocket.connect();
|
|
document.addEventListener("DOMContentLoaded", () => {
|
|
initCookieConsent();
|
|
});
|
|
window.liveSocket = liveSocket;
|
|
if (true) {
|
|
window.addEventListener("phx:live_reload:attached", ({ detail: reloader }) => {
|
|
reloader.enableServerLogs();
|
|
let keyDown = null;
|
|
window.addEventListener("keydown", (e) => keyDown = e.key);
|
|
window.addEventListener("keyup", (_e) => keyDown = null);
|
|
window.addEventListener("click", (e) => {
|
|
if (keyDown === "c") {
|
|
e.preventDefault();
|
|
e.stopImmediatePropagation();
|
|
reloader.openEditorAtCaller(e.target);
|
|
} else if (keyDown === "d") {
|
|
e.preventDefault();
|
|
e.stopImmediatePropagation();
|
|
reloader.openEditorAtDef(e.target);
|
|
}
|
|
}, true);
|
|
window.liveReloader = reloader;
|
|
});
|
|
}
|
|
if (typeof navigator !== "undefined" && navigator.modelContext) {
|
|
navigator.modelContext.provideContext({
|
|
tools: [
|
|
{
|
|
name: "navigate",
|
|
description: "Navigate to a page on TowerOps",
|
|
inputSchema: {
|
|
type: "object",
|
|
properties: {
|
|
path: {
|
|
type: "string",
|
|
description: "The path to navigate to, e.g. /dashboard or /users/register"
|
|
}
|
|
},
|
|
required: ["path"]
|
|
},
|
|
execute({ path }) {
|
|
window.location.href = path;
|
|
}
|
|
},
|
|
{
|
|
name: "view_api_docs",
|
|
description: "Open the TowerOps API documentation",
|
|
inputSchema: {
|
|
type: "object",
|
|
properties: {}
|
|
},
|
|
execute() {
|
|
window.location.href = "/docs/api";
|
|
}
|
|
},
|
|
{
|
|
name: "register",
|
|
description: "Start the registration flow for a new TowerOps account",
|
|
inputSchema: {
|
|
type: "object",
|
|
properties: {}
|
|
},
|
|
execute() {
|
|
window.location.href = "/users/register";
|
|
}
|
|
}
|
|
]
|
|
});
|
|
}
|
|
})();
|
|
/**
|
|
* @license MIT
|
|
* topbar 3.0.0
|
|
* http://buunguyen.github.io/topbar
|
|
* Copyright (c) 2024 Buu Nguyen
|
|
*/
|
|
/*!
|
|
* Chart.js v4.4.1
|
|
* https://www.chartjs.org
|
|
* (c) 2023 Chart.js Contributors
|
|
* Released under the MIT License
|
|
*/
|
|
/*!
|
|
* @kurkle/color v0.3.2
|
|
* https://github.com/kurkle/color#readme
|
|
* (c) 2023 Jukka Kurkela
|
|
* Released under the MIT License
|
|
*/
|
|
/*!
|
|
Embeddable Minimum Strictly-Compliant Promises/A+ 1.1.1 Thenable
|
|
Copyright (c) 2013-2014 Ralf S. Engelschall (http://engelschall.com)
|
|
Licensed under The MIT License (http://opensource.org/licenses/MIT)
|
|
*/
|
|
/*! Bezier curve function generator. Copyright Gaetan Renaudeau. MIT License: http://en.wikipedia.org/wiki/MIT_License */
|
|
/*! Runge-Kutta spring physics function generator. Adapted from Framer.js, copyright Koen Bok. MIT License: http://en.wikipedia.org/wiki/MIT_License */
|