PluginProbe
SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent / 3.4.9
SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent v3.4.9
3.5.4 3.5.3 3.5.2 3.5.1 3.4.9 3.5.0 3.4.8 3.4.7 trunk 2.3.1 3.3.6 3.3.7 3.3.8 3.3.9 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.6
supportcandy / asset / libs / chartjs / dist / chunks / helpers.segment.js

helpers.segment.js in SupportCandy – AI Customer Support Ticket System & Live Chatbot Agent 3.4.9, at asset/libs/chartjs/dist/chunks/helpers.segment.js

2,433 lines 67.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /*!
2 * Chart.js v3.2.0
3 * https://www.chartjs.org
4 * (c) 2021 Chart.js Contributors
5 * Released under the MIT License
6 */
7 function fontString(pixelSize, fontStyle, fontFamily) {
8 return fontStyle + ' ' + pixelSize + 'px ' + fontFamily;
9 }
10 const requestAnimFrame = (function() {
11 if (typeof window === 'undefined') {
12 return function(callback) {
13 return callback();
14 };
15 }
16 return window.requestAnimationFrame;
17 }());
18 function throttled(fn, thisArg, updateFn) {
19 const updateArgs = updateFn || ((args) => Array.prototype.slice.call(args));
20 let ticking = false;
21 let args = [];
22 return function(...rest) {
23 args = updateArgs(rest);
24 if (!ticking) {
25 ticking = true;
26 requestAnimFrame.call(window, () => {
27 ticking = false;
28 fn.apply(thisArg, args);
29 });
30 }
31 };
32 }
33 function debounce(fn, delay) {
34 let timeout;
35 return function() {
36 if (delay) {
37 clearTimeout(timeout);
38 timeout = setTimeout(fn, delay);
39 } else {
40 fn();
41 }
42 return delay;
43 };
44 }
45 const _toLeftRightCenter = (align) => align === 'start' ? 'left' : align === 'end' ? 'right' : 'center';
46 const _alignStartEnd = (align, start, end) => align === 'start' ? start : align === 'end' ? end : (start + end) / 2;
47 const _textX = (align, left, right) => align === 'right' ? right : align === 'center' ? (left + right) / 2 : left;
48
49 function noop() {}
50 const uid = (function() {
51 let id = 0;
52 return function() {
53 return id++;
54 };
55 }());
56 function isNullOrUndef(value) {
57 return value === null || typeof value === 'undefined';
58 }
59 function isArray(value) {
60 if (Array.isArray && Array.isArray(value)) {
61 return true;
62 }
63 const type = Object.prototype.toString.call(value);
64 if (type.substr(0, 7) === '[object' && type.substr(-6) === 'Array]') {
65 return true;
66 }
67 return false;
68 }
69 function isObject(value) {
70 return value !== null && Object.prototype.toString.call(value) === '[object Object]';
71 }
72 const isNumberFinite = (value) => (typeof value === 'number' || value instanceof Number) && isFinite(+value);
73 function finiteOrDefault(value, defaultValue) {
74 return isNumberFinite(value) ? value : defaultValue;
75 }
76 function valueOrDefault(value, defaultValue) {
77 return typeof value === 'undefined' ? defaultValue : value;
78 }
79 const toPercentage = (value, dimension) =>
80 typeof value === 'string' && value.endsWith('%') ?
81 parseFloat(value) / 100
82 : value / dimension;
83 const toDimension = (value, dimension) =>
84 typeof value === 'string' && value.endsWith('%') ?
85 parseFloat(value) / 100 * dimension
86 : +value;
87 function callback(fn, args, thisArg) {
88 if (fn && typeof fn.call === 'function') {
89 return fn.apply(thisArg, args);
90 }
91 }
92 function each(loopable, fn, thisArg, reverse) {
93 let i, len, keys;
94 if (isArray(loopable)) {
95 len = loopable.length;
96 if (reverse) {
97 for (i = len - 1; i >= 0; i--) {
98 fn.call(thisArg, loopable[i], i);
99 }
100 } else {
101 for (i = 0; i < len; i++) {
102 fn.call(thisArg, loopable[i], i);
103 }
104 }
105 } else if (isObject(loopable)) {
106 keys = Object.keys(loopable);
107 len = keys.length;
108 for (i = 0; i < len; i++) {
109 fn.call(thisArg, loopable[keys[i]], keys[i]);
110 }
111 }
112 }
113 function _elementsEqual(a0, a1) {
114 let i, ilen, v0, v1;
115 if (!a0 || !a1 || a0.length !== a1.length) {
116 return false;
117 }
118 for (i = 0, ilen = a0.length; i < ilen; ++i) {
119 v0 = a0[i];
120 v1 = a1[i];
121 if (v0.datasetIndex !== v1.datasetIndex || v0.index !== v1.index) {
122 return false;
123 }
124 }
125 return true;
126 }
127 function clone$1(source) {
128 if (isArray(source)) {
129 return source.map(clone$1);
130 }
131 if (isObject(source)) {
132 const target = Object.create(null);
133 const keys = Object.keys(source);
134 const klen = keys.length;
135 let k = 0;
136 for (; k < klen; ++k) {
137 target[keys[k]] = clone$1(source[keys[k]]);
138 }
139 return target;
140 }
141 return source;
142 }
143 function isValidKey(key) {
144 return ['__proto__', 'prototype', 'constructor'].indexOf(key) === -1;
145 }
146 function _merger(key, target, source, options) {
147 if (!isValidKey(key)) {
148 return;
149 }
150 const tval = target[key];
151 const sval = source[key];
152 if (isObject(tval) && isObject(sval)) {
153 merge(tval, sval, options);
154 } else {
155 target[key] = clone$1(sval);
156 }
157 }
158 function merge(target, source, options) {
159 const sources = isArray(source) ? source : [source];
160 const ilen = sources.length;
161 if (!isObject(target)) {
162 return target;
163 }
164 options = options || {};
165 const merger = options.merger || _merger;
166 for (let i = 0; i < ilen; ++i) {
167 source = sources[i];
168 if (!isObject(source)) {
169 continue;
170 }
171 const keys = Object.keys(source);
172 for (let k = 0, klen = keys.length; k < klen; ++k) {
173 merger(keys[k], target, source, options);
174 }
175 }
176 return target;
177 }
178 function mergeIf(target, source) {
179 return merge(target, source, {merger: _mergerIf});
180 }
181 function _mergerIf(key, target, source) {
182 if (!isValidKey(key)) {
183 return;
184 }
185 const tval = target[key];
186 const sval = source[key];
187 if (isObject(tval) && isObject(sval)) {
188 mergeIf(tval, sval);
189 } else if (!Object.prototype.hasOwnProperty.call(target, key)) {
190 target[key] = clone$1(sval);
191 }
192 }
193 function _deprecated(scope, value, previous, current) {
194 if (value !== undefined) {
195 console.warn(scope + ': "' + previous +
196 '" is deprecated. Please use "' + current + '" instead');
197 }
198 }
199 const emptyString = '';
200 const dot = '.';
201 function indexOfDotOrLength(key, start) {
202 const idx = key.indexOf(dot, start);
203 return idx === -1 ? key.length : idx;
204 }
205 function resolveObjectKey(obj, key) {
206 if (key === emptyString) {
207 return obj;
208 }
209 let pos = 0;
210 let idx = indexOfDotOrLength(key, pos);
211 while (obj && idx > pos) {
212 obj = obj[key.substr(pos, idx - pos)];
213 pos = idx + 1;
214 idx = indexOfDotOrLength(key, pos);
215 }
216 return obj;
217 }
218 function _capitalize(str) {
219 return str.charAt(0).toUpperCase() + str.slice(1);
220 }
221 const defined = (value) => typeof value !== 'undefined';
222 const isFunction = (value) => typeof value === 'function';
223 const setsEqual = (a, b) => {
224 if (a.size !== b.size) {
225 return false;
226 }
227 for (const item of a) {
228 if (!b.has(item)) {
229 return false;
230 }
231 }
232 return true;
233 };
234
235 const PI = Math.PI;
236 const TAU = 2 * PI;
237 const PITAU = TAU + PI;
238 const INFINITY = Number.POSITIVE_INFINITY;
239 const RAD_PER_DEG = PI / 180;
240 const HALF_PI = PI / 2;
241 const QUARTER_PI = PI / 4;
242 const TWO_THIRDS_PI = PI * 2 / 3;
243 const log10 = Math.log10;
244 const sign = Math.sign;
245 function niceNum(range) {
246 const niceRange = Math.pow(10, Math.floor(log10(range)));
247 const fraction = range / niceRange;
248 const niceFraction = fraction <= 1 ? 1 : fraction <= 2 ? 2 : fraction <= 5 ? 5 : 10;
249 return niceFraction * niceRange;
250 }
251 function _factorize(value) {
252 const result = [];
253 const sqrt = Math.sqrt(value);
254 let i;
255 for (i = 1; i < sqrt; i++) {
256 if (value % i === 0) {
257 result.push(i);
258 result.push(value / i);
259 }
260 }
261 if (sqrt === (sqrt | 0)) {
262 result.push(sqrt);
263 }
264 result.sort((a, b) => a - b).pop();
265 return result;
266 }
267 function isNumber(n) {
268 return !isNaN(parseFloat(n)) && isFinite(n);
269 }
270 function almostEquals(x, y, epsilon) {
271 return Math.abs(x - y) < epsilon;
272 }
273 function almostWhole(x, epsilon) {
274 const rounded = Math.round(x);
275 return ((rounded - epsilon) <= x) && ((rounded + epsilon) >= x);
276 }
277 function _setMinAndMaxByKey(array, target, property) {
278 let i, ilen, value;
279 for (i = 0, ilen = array.length; i < ilen; i++) {
280 value = array[i][property];
281 if (!isNaN(value)) {
282 target.min = Math.min(target.min, value);
283 target.max = Math.max(target.max, value);
284 }
285 }
286 }
287 function toRadians(degrees) {
288 return degrees * (PI / 180);
289 }
290 function toDegrees(radians) {
291 return radians * (180 / PI);
292 }
293 function _decimalPlaces(x) {
294 if (!isNumberFinite(x)) {
295 return;
296 }
297 let e = 1;
298 let p = 0;
299 while (Math.round(x * e) / e !== x) {
300 e *= 10;
301 p++;
302 }
303 return p;
304 }
305 function getAngleFromPoint(centrePoint, anglePoint) {
306 const distanceFromXCenter = anglePoint.x - centrePoint.x;
307 const distanceFromYCenter = anglePoint.y - centrePoint.y;
308 const radialDistanceFromCenter = Math.sqrt(distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter);
309 let angle = Math.atan2(distanceFromYCenter, distanceFromXCenter);
310 if (angle < (-0.5 * PI)) {
311 angle += TAU;
312 }
313 return {
314 angle,
315 distance: radialDistanceFromCenter
316 };
317 }
318 function distanceBetweenPoints(pt1, pt2) {
319 return Math.sqrt(Math.pow(pt2.x - pt1.x, 2) + Math.pow(pt2.y - pt1.y, 2));
320 }
321 function _angleDiff(a, b) {
322 return (a - b + PITAU) % TAU - PI;
323 }
324 function _normalizeAngle(a) {
325 return (a % TAU + TAU) % TAU;
326 }
327 function _angleBetween(angle, start, end) {
328 const a = _normalizeAngle(angle);
329 const s = _normalizeAngle(start);
330 const e = _normalizeAngle(end);
331 const angleToStart = _normalizeAngle(s - a);
332 const angleToEnd = _normalizeAngle(e - a);
333 const startToAngle = _normalizeAngle(a - s);
334 const endToAngle = _normalizeAngle(a - e);
335 return a === s || a === e || (angleToStart > angleToEnd && startToAngle < endToAngle);
336 }
337 function _limitValue(value, min, max) {
338 return Math.max(min, Math.min(max, value));
339 }
340 function _int16Range(value) {
341 return _limitValue(value, -32768, 32767);
342 }
343
344 const atEdge = (t) => t === 0 || t === 1;
345 const elasticIn = (t, s, p) => -(Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * TAU / p));
346 const elasticOut = (t, s, p) => Math.pow(2, -10 * t) * Math.sin((t - s) * TAU / p) + 1;
347 const effects = {
348 linear: t => t,
349 easeInQuad: t => t * t,
350 easeOutQuad: t => -t * (t - 2),
351 easeInOutQuad: t => ((t /= 0.5) < 1)
352 ? 0.5 * t * t
353 : -0.5 * ((--t) * (t - 2) - 1),
354 easeInCubic: t => t * t * t,
355 easeOutCubic: t => (t -= 1) * t * t + 1,
356 easeInOutCubic: t => ((t /= 0.5) < 1)
357 ? 0.5 * t * t * t
358 : 0.5 * ((t -= 2) * t * t + 2),
359 easeInQuart: t => t * t * t * t,
360 easeOutQuart: t => -((t -= 1) * t * t * t - 1),
361 easeInOutQuart: t => ((t /= 0.5) < 1)
362 ? 0.5 * t * t * t * t
363 : -0.5 * ((t -= 2) * t * t * t - 2),
364 easeInQuint: t => t * t * t * t * t,
365 easeOutQuint: t => (t -= 1) * t * t * t * t + 1,
366 easeInOutQuint: t => ((t /= 0.5) < 1)
367 ? 0.5 * t * t * t * t * t
368 : 0.5 * ((t -= 2) * t * t * t * t + 2),
369 easeInSine: t => -Math.cos(t * HALF_PI) + 1,
370 easeOutSine: t => Math.sin(t * HALF_PI),
371 easeInOutSine: t => -0.5 * (Math.cos(PI * t) - 1),
372 easeInExpo: t => (t === 0) ? 0 : Math.pow(2, 10 * (t - 1)),
373 easeOutExpo: t => (t === 1) ? 1 : -Math.pow(2, -10 * t) + 1,
374 easeInOutExpo: t => atEdge(t) ? t : t < 0.5
375 ? 0.5 * Math.pow(2, 10 * (t * 2 - 1))
376 : 0.5 * (-Math.pow(2, -10 * (t * 2 - 1)) + 2),
377 easeInCirc: t => (t >= 1) ? t : -(Math.sqrt(1 - t * t) - 1),
378 easeOutCirc: t => Math.sqrt(1 - (t -= 1) * t),
379 easeInOutCirc: t => ((t /= 0.5) < 1)
380 ? -0.5 * (Math.sqrt(1 - t * t) - 1)
381 : 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1),
382 easeInElastic: t => atEdge(t) ? t : elasticIn(t, 0.075, 0.3),
383 easeOutElastic: t => atEdge(t) ? t : elasticOut(t, 0.075, 0.3),
384 easeInOutElastic(t) {
385 const s = 0.1125;
386 const p = 0.45;
387 return atEdge(t) ? t :
388 t < 0.5
389 ? 0.5 * elasticIn(t * 2, s, p)
390 : 0.5 + 0.5 * elasticOut(t * 2 - 1, s, p);
391 },
392 easeInBack(t) {
393 const s = 1.70158;
394 return t * t * ((s + 1) * t - s);
395 },
396 easeOutBack(t) {
397 const s = 1.70158;
398 return (t -= 1) * t * ((s + 1) * t + s) + 1;
399 },
400 easeInOutBack(t) {
401 let s = 1.70158;
402 if ((t /= 0.5) < 1) {
403 return 0.5 * (t * t * (((s *= (1.525)) + 1) * t - s));
404 }
405 return 0.5 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2);
406 },
407 easeInBounce: t => 1 - effects.easeOutBounce(1 - t),
408 easeOutBounce(t) {
409 const m = 7.5625;
410 const d = 2.75;
411 if (t < (1 / d)) {
412 return m * t * t;
413 }
414 if (t < (2 / d)) {
415 return m * (t -= (1.5 / d)) * t + 0.75;
416 }
417 if (t < (2.5 / d)) {
418 return m * (t -= (2.25 / d)) * t + 0.9375;
419 }
420 return m * (t -= (2.625 / d)) * t + 0.984375;
421 },
422 easeInOutBounce: t => (t < 0.5)
423 ? effects.easeInBounce(t * 2) * 0.5
424 : effects.easeOutBounce(t * 2 - 1) * 0.5 + 0.5,
425 };
426
427 /*!
428 * @kurkle/color v0.1.9
429 * https://github.com/kurkle/color#readme
430 * (c) 2020 Jukka Kurkela
431 * Released under the MIT License
432 */
433 const map = {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};
434 const hex = '0123456789ABCDEF';
435 const h1 = (b) => hex[b & 0xF];
436 const h2 = (b) => hex[(b & 0xF0) >> 4] + hex[b & 0xF];
437 const eq = (b) => (((b & 0xF0) >> 4) === (b & 0xF));
438 function isShort(v) {
439 return eq(v.r) && eq(v.g) && eq(v.b) && eq(v.a);
440 }
441 function hexParse(str) {
442 var len = str.length;
443 var ret;
444 if (str[0] === '#') {
445 if (len === 4 || len === 5) {
446 ret = {
447 r: 255 & map[str[1]] * 17,
448 g: 255 & map[str[2]] * 17,
449 b: 255 & map[str[3]] * 17,
450 a: len === 5 ? map[str[4]] * 17 : 255
451 };
452 } else if (len === 7 || len === 9) {
453 ret = {
454 r: map[str[1]] << 4 | map[str[2]],
455 g: map[str[3]] << 4 | map[str[4]],
456 b: map[str[5]] << 4 | map[str[6]],
457 a: len === 9 ? (map[str[7]] << 4 | map[str[8]]) : 255
458 };
459 }
460 }
461 return ret;
462 }
463 function hexString(v) {
464 var f = isShort(v) ? h1 : h2;
465 return v
466 ? '#' + f(v.r) + f(v.g) + f(v.b) + (v.a < 255 ? f(v.a) : '')
467 : v;
468 }
469 function round(v) {
470 return v + 0.5 | 0;
471 }
472 const lim = (v, l, h) => Math.max(Math.min(v, h), l);
473 function p2b(v) {
474 return lim(round(v * 2.55), 0, 255);
475 }
476 function n2b(v) {
477 return lim(round(v * 255), 0, 255);
478 }
479 function b2n(v) {
480 return lim(round(v / 2.55) / 100, 0, 1);
481 }
482 function n2p(v) {
483 return lim(round(v * 100), 0, 100);
484 }
485 const RGB_RE = /^rgba?\(\s*([-+.\d]+)(%)?[\s,]+([-+.e\d]+)(%)?[\s,]+([-+.e\d]+)(%)?(?:[\s,/]+([-+.e\d]+)(%)?)?\s*\)$/;
486 function rgbParse(str) {
487 const m = RGB_RE.exec(str);
488 let a = 255;
489 let r, g, b;
490 if (!m) {
491 return;
492 }
493 if (m[7] !== r) {
494 const v = +m[7];
495 a = 255 & (m[8] ? p2b(v) : v * 255);
496 }
497 r = +m[1];
498 g = +m[3];
499 b = +m[5];
500 r = 255 & (m[2] ? p2b(r) : r);
501 g = 255 & (m[4] ? p2b(g) : g);
502 b = 255 & (m[6] ? p2b(b) : b);
503 return {
504 r: r,
505 g: g,
506 b: b,
507 a: a
508 };
509 }
510 function rgbString(v) {
511 return v && (
512 v.a < 255
513 ? `rgba(${v.r}, ${v.g}, ${v.b}, ${b2n(v.a)})`
514 : `rgb(${v.r}, ${v.g}, ${v.b})`
515 );
516 }
517 const HUE_RE = /^(hsla?|hwb|hsv)\(\s*([-+.e\d]+)(?:deg)?[\s,]+([-+.e\d]+)%[\s,]+([-+.e\d]+)%(?:[\s,]+([-+.e\d]+)(%)?)?\s*\)$/;
518 function hsl2rgbn(h, s, l) {
519 const a = s * Math.min(l, 1 - l);
520 const f = (n, k = (n + h / 30) % 12) => l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
521 return [f(0), f(8), f(4)];
522 }
523 function hsv2rgbn(h, s, v) {
524 const f = (n, k = (n + h / 60) % 6) => v - v * s * Math.max(Math.min(k, 4 - k, 1), 0);
525 return [f(5), f(3), f(1)];
526 }
527 function hwb2rgbn(h, w, b) {
528 const rgb = hsl2rgbn(h, 1, 0.5);
529 let i;
530 if (w + b > 1) {
531 i = 1 / (w + b);
532 w *= i;
533 b *= i;
534 }
535 for (i = 0; i < 3; i++) {
536 rgb[i] *= 1 - w - b;
537 rgb[i] += w;
538 }
539 return rgb;
540 }
541 function rgb2hsl(v) {
542 const range = 255;
543 const r = v.r / range;
544 const g = v.g / range;
545 const b = v.b / range;
546 const max = Math.max(r, g, b);
547 const min = Math.min(r, g, b);
548 const l = (max + min) / 2;
549 let h, s, d;
550 if (max !== min) {
551 d = max - min;
552 s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
553 h = max === r
554 ? ((g - b) / d) + (g < b ? 6 : 0)
555 : max === g
556 ? (b - r) / d + 2
557 : (r - g) / d + 4;
558 h = h * 60 + 0.5;
559 }
560 return [h | 0, s || 0, l];
561 }
562 function calln(f, a, b, c) {
563 return (
564 Array.isArray(a)
565 ? f(a[0], a[1], a[2])
566 : f(a, b, c)
567 ).map(n2b);
568 }
569 function hsl2rgb(h, s, l) {
570 return calln(hsl2rgbn, h, s, l);
571 }
572 function hwb2rgb(h, w, b) {
573 return calln(hwb2rgbn, h, w, b);
574 }
575 function hsv2rgb(h, s, v) {
576 return calln(hsv2rgbn, h, s, v);
577 }
578 function hue(h) {
579 return (h % 360 + 360) % 360;
580 }
581 function hueParse(str) {
582 const m = HUE_RE.exec(str);
583 let a = 255;
584 let v;
585 if (!m) {
586 return;
587 }
588 if (m[5] !== v) {
589 a = m[6] ? p2b(+m[5]) : n2b(+m[5]);
590 }
591 const h = hue(+m[2]);
592 const p1 = +m[3] / 100;
593 const p2 = +m[4] / 100;
594 if (m[1] === 'hwb') {
595 v = hwb2rgb(h, p1, p2);
596 } else if (m[1] === 'hsv') {
597 v = hsv2rgb(h, p1, p2);
598 } else {
599 v = hsl2rgb(h, p1, p2);
600 }
601 return {
602 r: v[0],
603 g: v[1],
604 b: v[2],
605 a: a
606 };
607 }
608 function rotate(v, deg) {
609 var h = rgb2hsl(v);
610 h[0] = hue(h[0] + deg);
611 h = hsl2rgb(h);
612 v.r = h[0];
613 v.g = h[1];
614 v.b = h[2];
615 }
616 function hslString(v) {
617 if (!v) {
618 return;
619 }
620 const a = rgb2hsl(v);
621 const h = a[0];
622 const s = n2p(a[1]);
623 const l = n2p(a[2]);
624 return v.a < 255
625 ? `hsla(${h}, ${s}%, ${l}%, ${b2n(v.a)})`
626 : `hsl(${h}, ${s}%, ${l}%)`;
627 }
628 const map$1 = {
629 x: 'dark',
630 Z: 'light',
631 Y: 're',
632 X: 'blu',
633 W: 'gr',
634 V: 'medium',
635 U: 'slate',
636 A: 'ee',
637 T: 'ol',
638 S: 'or',
639 B: 'ra',
640 C: 'lateg',
641 D: 'ights',
642 R: 'in',
643 Q: 'turquois',
644 E: 'hi',
645 P: 'ro',
646 O: 'al',
647 N: 'le',
648 M: 'de',
649 L: 'yello',
650 F: 'en',
651 K: 'ch',
652 G: 'arks',
653 H: 'ea',
654 I: 'ightg',
655 J: 'wh'
656 };
657 const names = {
658 OiceXe: 'f0f8ff',
659 antiquewEte: 'faebd7',
660 aqua: 'ffff',
661 aquamarRe: '7fffd4',
662 azuY: 'f0ffff',
663 beige: 'f5f5dc',
664 bisque: 'ffe4c4',
665 black: '0',
666 blanKedOmond: 'ffebcd',
667 Xe: 'ff',
668 XeviTet: '8a2be2',
669 bPwn: 'a52a2a',
670 burlywood: 'deb887',
671 caMtXe: '5f9ea0',
672 KartYuse: '7fff00',
673 KocTate: 'd2691e',
674 cSO: 'ff7f50',
675 cSnflowerXe: '6495ed',
676 cSnsilk: 'fff8dc',
677 crimson: 'dc143c',
678 cyan: 'ffff',
679 xXe: '8b',
680 xcyan: '8b8b',
681 xgTMnPd: 'b8860b',
682 xWay: 'a9a9a9',
683 xgYF: '6400',
684 xgYy: 'a9a9a9',
685 xkhaki: 'bdb76b',
686 xmagFta: '8b008b',
687 xTivegYF: '556b2f',
688 xSange: 'ff8c00',
689 xScEd: '9932cc',
690 xYd: '8b0000',
691 xsOmon: 'e9967a',
692 xsHgYF: '8fbc8f',
693 xUXe: '483d8b',
694 xUWay: '2f4f4f',
695 xUgYy: '2f4f4f',
696 xQe: 'ced1',
697 xviTet: '9400d3',
698 dAppRk: 'ff1493',
699 dApskyXe: 'bfff',
700 dimWay: '696969',
701 dimgYy: '696969',
702 dodgerXe: '1e90ff',
703 fiYbrick: 'b22222',
704 flSOwEte: 'fffaf0',
705 foYstWAn: '228b22',
706 fuKsia: 'ff00ff',
707 gaRsbSo: 'dcdcdc',
708 ghostwEte: 'f8f8ff',
709 gTd: 'ffd700',
710 gTMnPd: 'daa520',
711 Way: '808080',
712 gYF: '8000',
713 gYFLw: 'adff2f',
714 gYy: '808080',
715 honeyMw: 'f0fff0',
716 hotpRk: 'ff69b4',
717 RdianYd: 'cd5c5c',
718 Rdigo: '4b0082',
719 ivSy: 'fffff0',
720 khaki: 'f0e68c',
721 lavFMr: 'e6e6fa',
722 lavFMrXsh: 'fff0f5',
723 lawngYF: '7cfc00',
724 NmoncEffon: 'fffacd',
725 ZXe: 'add8e6',
726 ZcSO: 'f08080',
727 Zcyan: 'e0ffff',
728 ZgTMnPdLw: 'fafad2',
729 ZWay: 'd3d3d3',
730 ZgYF: '90ee90',
731 ZgYy: 'd3d3d3',
732 ZpRk: 'ffb6c1',
733 ZsOmon: 'ffa07a',
734 ZsHgYF: '20b2aa',
735 ZskyXe: '87cefa',
736 ZUWay: '778899',
737 ZUgYy: '778899',
738 ZstAlXe: 'b0c4de',
739 ZLw: 'ffffe0',
740 lime: 'ff00',
741 limegYF: '32cd32',
742 lRF: 'faf0e6',
743 magFta: 'ff00ff',
744 maPon: '800000',
745 VaquamarRe: '66cdaa',
746 VXe: 'cd',
747 VScEd: 'ba55d3',
748 VpurpN: '9370db',
749 VsHgYF: '3cb371',
750 VUXe: '7b68ee',
751 VsprRggYF: 'fa9a',
752 VQe: '48d1cc',
753 VviTetYd: 'c71585',
754 midnightXe: '191970',
755 mRtcYam: 'f5fffa',
756 mistyPse: 'ffe4e1',
757 moccasR: 'ffe4b5',
758 navajowEte: 'ffdead',
759 navy: '80',
760 Tdlace: 'fdf5e6',
761 Tive: '808000',
762 TivedBb: '6b8e23',
763 Sange: 'ffa500',
764 SangeYd: 'ff4500',
765 ScEd: 'da70d6',
766 pOegTMnPd: 'eee8aa',
767 pOegYF: '98fb98',
768 pOeQe: 'afeeee',
769 pOeviTetYd: 'db7093',
770 papayawEp: 'ffefd5',
771 pHKpuff: 'ffdab9',
772 peru: 'cd853f',
773 pRk: 'ffc0cb',
774 plum: 'dda0dd',
775 powMrXe: 'b0e0e6',
776 purpN: '800080',
777 YbeccapurpN: '663399',
778 Yd: 'ff0000',
779 Psybrown: 'bc8f8f',
780 PyOXe: '4169e1',
781 saddNbPwn: '8b4513',
782 sOmon: 'fa8072',
783 sandybPwn: 'f4a460',
784 sHgYF: '2e8b57',
785 sHshell: 'fff5ee',
786 siFna: 'a0522d',
787 silver: 'c0c0c0',
788 skyXe: '87ceeb',
789 UXe: '6a5acd',
790 UWay: '708090',
791 UgYy: '708090',
792 snow: 'fffafa',
793 sprRggYF: 'ff7f',
794 stAlXe: '4682b4',
795 tan: 'd2b48c',
796 teO: '8080',
797 tEstN: 'd8bfd8',
798 tomato: 'ff6347',
799 Qe: '40e0d0',
800 viTet: 'ee82ee',
801 JHt: 'f5deb3',
802 wEte: 'ffffff',
803 wEtesmoke: 'f5f5f5',
804 Lw: 'ffff00',
805 LwgYF: '9acd32'
806 };
807 function unpack() {
808 const unpacked = {};
809 const keys = Object.keys(names);
810 const tkeys = Object.keys(map$1);
811 let i, j, k, ok, nk;
812 for (i = 0; i < keys.length; i++) {
813 ok = nk = keys[i];
814 for (j = 0; j < tkeys.length; j++) {
815 k = tkeys[j];
816 nk = nk.replace(k, map$1[k]);
817 }
818 k = parseInt(names[ok], 16);
819 unpacked[nk] = [k >> 16 & 0xFF, k >> 8 & 0xFF, k & 0xFF];
820 }
821 return unpacked;
822 }
823 let names$1;
824 function nameParse(str) {
825 if (!names$1) {
826 names$1 = unpack();
827 names$1.transparent = [0, 0, 0, 0];
828 }
829 const a = names$1[str.toLowerCase()];
830 return a && {
831 r: a[0],
832 g: a[1],
833 b: a[2],
834 a: a.length === 4 ? a[3] : 255
835 };
836 }
837 function modHSL(v, i, ratio) {
838 if (v) {
839 let tmp = rgb2hsl(v);
840 tmp[i] = Math.max(0, Math.min(tmp[i] + tmp[i] * ratio, i === 0 ? 360 : 1));
841 tmp = hsl2rgb(tmp);
842 v.r = tmp[0];
843 v.g = tmp[1];
844 v.b = tmp[2];
845 }
846 }
847 function clone(v, proto) {
848 return v ? Object.assign(proto || {}, v) : v;
849 }
850 function fromObject(input) {
851 var v = {r: 0, g: 0, b: 0, a: 255};
852 if (Array.isArray(input)) {
853 if (input.length >= 3) {
854 v = {r: input[0], g: input[1], b: input[2], a: 255};
855 if (input.length > 3) {
856 v.a = n2b(input[3]);
857 }
858 }
859 } else {
860 v = clone(input, {r: 0, g: 0, b: 0, a: 1});
861 v.a = n2b(v.a);
862 }
863 return v;
864 }
865 function functionParse(str) {
866 if (str.charAt(0) === 'r') {
867 return rgbParse(str);
868 }
869 return hueParse(str);
870 }
871 class Color {
872 constructor(input) {
873 if (input instanceof Color) {
874 return input;
875 }
876 const type = typeof input;
877 let v;
878 if (type === 'object') {
879 v = fromObject(input);
880 } else if (type === 'string') {
881 v = hexParse(input) || nameParse(input) || functionParse(input);
882 }
883 this._rgb = v;
884 this._valid = !!v;
885 }
886 get valid() {
887 return this._valid;
888 }
889 get rgb() {
890 var v = clone(this._rgb);
891 if (v) {
892 v.a = b2n(v.a);
893 }
894 return v;
895 }
896 set rgb(obj) {
897 this._rgb = fromObject(obj);
898 }
899 rgbString() {
900 return this._valid ? rgbString(this._rgb) : this._rgb;
901 }
902 hexString() {
903 return this._valid ? hexString(this._rgb) : this._rgb;
904 }
905 hslString() {
906 return this._valid ? hslString(this._rgb) : this._rgb;
907 }
908 mix(color, weight) {
909 const me = this;
910 if (color) {
911 const c1 = me.rgb;
912 const c2 = color.rgb;
913 let w2;
914 const p = weight === w2 ? 0.5 : weight;
915 const w = 2 * p - 1;
916 const a = c1.a - c2.a;
917 const w1 = ((w * a === -1 ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
918 w2 = 1 - w1;
919 c1.r = 0xFF & w1 * c1.r + w2 * c2.r + 0.5;
920 c1.g = 0xFF & w1 * c1.g + w2 * c2.g + 0.5;
921 c1.b = 0xFF & w1 * c1.b + w2 * c2.b + 0.5;
922 c1.a = p * c1.a + (1 - p) * c2.a;
923 me.rgb = c1;
924 }
925 return me;
926 }
927 clone() {
928 return new Color(this.rgb);
929 }
930 alpha(a) {
931 this._rgb.a = n2b(a);
932 return this;
933 }
934 clearer(ratio) {
935 const rgb = this._rgb;
936 rgb.a *= 1 - ratio;
937 return this;
938 }
939 greyscale() {
940 const rgb = this._rgb;
941 const val = round(rgb.r * 0.3 + rgb.g * 0.59 + rgb.b * 0.11);
942 rgb.r = rgb.g = rgb.b = val;
943 return this;
944 }
945 opaquer(ratio) {
946 const rgb = this._rgb;
947 rgb.a *= 1 + ratio;
948 return this;
949 }
950 negate() {
951 const v = this._rgb;
952 v.r = 255 - v.r;
953 v.g = 255 - v.g;
954 v.b = 255 - v.b;
955 return this;
956 }
957 lighten(ratio) {
958 modHSL(this._rgb, 2, ratio);
959 return this;
960 }
961 darken(ratio) {
962 modHSL(this._rgb, 2, -ratio);
963 return this;
964 }
965 saturate(ratio) {
966 modHSL(this._rgb, 1, ratio);
967 return this;
968 }
969 desaturate(ratio) {
970 modHSL(this._rgb, 1, -ratio);
971 return this;
972 }
973 rotate(deg) {
974 rotate(this._rgb, deg);
975 return this;
976 }
977 }
978 function index_esm(input) {
979 return new Color(input);
980 }
981
982 const isPatternOrGradient = (value) => value instanceof CanvasGradient || value instanceof CanvasPattern;
983 function color(value) {
984 return isPatternOrGradient(value) ? value : index_esm(value);
985 }
986 function getHoverColor(value) {
987 return isPatternOrGradient(value)
988 ? value
989 : index_esm(value).saturate(0.5).darken(0.1).hexString();
990 }
991
992 const overrides = Object.create(null);
993 const descriptors = Object.create(null);
994 function getScope$1(node, key) {
995 if (!key) {
996 return node;
997 }
998 const keys = key.split('.');
999 for (let i = 0, n = keys.length; i < n; ++i) {
1000 const k = keys[i];
1001 node = node[k] || (node[k] = Object.create(null));
1002 }
1003 return node;
1004 }
1005 function set(root, scope, values) {
1006 if (typeof scope === 'string') {
1007 return merge(getScope$1(root, scope), values);
1008 }
1009 return merge(getScope$1(root, ''), scope);
1010 }
1011 class Defaults {
1012 constructor(_descriptors) {
1013 this.animation = undefined;
1014 this.backgroundColor = 'rgba(0,0,0,0.1)';
1015 this.borderColor = 'rgba(0,0,0,0.1)';
1016 this.color = '#666';
1017 this.datasets = {};
1018 this.devicePixelRatio = (context) => context.chart.platform.getDevicePixelRatio();
1019 this.elements = {};
1020 this.events = [
1021 'mousemove',
1022 'mouseout',
1023 'click',
1024 'touchstart',
1025 'touchmove'
1026 ];
1027 this.font = {
1028 family: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
1029 size: 12,
1030 style: 'normal',
1031 lineHeight: 1.2,
1032 weight: null
1033 };
1034 this.hover = {};
1035 this.hoverBackgroundColor = (ctx, options) => getHoverColor(options.backgroundColor);
1036 this.hoverBorderColor = (ctx, options) => getHoverColor(options.borderColor);
1037 this.hoverColor = (ctx, options) => getHoverColor(options.color);
1038 this.indexAxis = 'x';
1039 this.interaction = {
1040 mode: 'nearest',
1041 intersect: true
1042 };
1043 this.maintainAspectRatio = true;
1044 this.onHover = null;
1045 this.onClick = null;
1046 this.parsing = true;
1047 this.plugins = {};
1048 this.responsive = true;
1049 this.scale = undefined;
1050 this.scales = {};
1051 this.showLine = true;
1052 this.describe(_descriptors);
1053 }
1054 set(scope, values) {
1055 return set(this, scope, values);
1056 }
1057 get(scope) {
1058 return getScope$1(this, scope);
1059 }
1060 describe(scope, values) {
1061 return set(descriptors, scope, values);
1062 }
1063 override(scope, values) {
1064 return set(overrides, scope, values);
1065 }
1066 route(scope, name, targetScope, targetName) {
1067 const scopeObject = getScope$1(this, scope);
1068 const targetScopeObject = getScope$1(this, targetScope);
1069 const privateName = '_' + name;
1070 Object.defineProperties(scopeObject, {
1071 [privateName]: {
1072 value: scopeObject[name],
1073 writable: true
1074 },
1075 [name]: {
1076 enumerable: true,
1077 get() {
1078 const local = this[privateName];
1079 const target = targetScopeObject[targetName];
1080 if (isObject(local)) {
1081 return Object.assign({}, target, local);
1082 }
1083 return valueOrDefault(local, target);
1084 },
1085 set(value) {
1086 this[privateName] = value;
1087 }
1088 }
1089 });
1090 }
1091 }
1092 var defaults = new Defaults({
1093 _scriptable: (name) => !name.startsWith('on'),
1094 _indexable: (name) => name !== 'events',
1095 hover: {
1096 _fallback: 'interaction'
1097 },
1098 interaction: {
1099 _scriptable: false,
1100 _indexable: false,
1101 }
1102 });
1103
1104 function toFontString(font) {
1105 if (!font || isNullOrUndef(font.size) || isNullOrUndef(font.family)) {
1106 return null;
1107 }
1108 return (font.style ? font.style + ' ' : '')
1109 + (font.weight ? font.weight + ' ' : '')
1110 + font.size + 'px '
1111 + font.family;
1112 }
1113 function _measureText(ctx, data, gc, longest, string) {
1114 let textWidth = data[string];
1115 if (!textWidth) {
1116 textWidth = data[string] = ctx.measureText(string).width;
1117 gc.push(string);
1118 }
1119 if (textWidth > longest) {
1120 longest = textWidth;
1121 }
1122 return longest;
1123 }
1124 function _longestText(ctx, font, arrayOfThings, cache) {
1125 cache = cache || {};
1126 let data = cache.data = cache.data || {};
1127 let gc = cache.garbageCollect = cache.garbageCollect || [];
1128 if (cache.font !== font) {
1129 data = cache.data = {};
1130 gc = cache.garbageCollect = [];
1131 cache.font = font;
1132 }
1133 ctx.save();
1134 ctx.font = font;
1135 let longest = 0;
1136 const ilen = arrayOfThings.length;
1137 let i, j, jlen, thing, nestedThing;
1138 for (i = 0; i < ilen; i++) {
1139 thing = arrayOfThings[i];
1140 if (thing !== undefined && thing !== null && isArray(thing) !== true) {
1141 longest = _measureText(ctx, data, gc, longest, thing);
1142 } else if (isArray(thing)) {
1143 for (j = 0, jlen = thing.length; j < jlen; j++) {
1144 nestedThing = thing[j];
1145 if (nestedThing !== undefined && nestedThing !== null && !isArray(nestedThing)) {
1146 longest = _measureText(ctx, data, gc, longest, nestedThing);
1147 }
1148 }
1149 }
1150 }
1151 ctx.restore();
1152 const gcLen = gc.length / 2;
1153 if (gcLen > arrayOfThings.length) {
1154 for (i = 0; i < gcLen; i++) {
1155 delete data[gc[i]];
1156 }
1157 gc.splice(0, gcLen);
1158 }
1159 return longest;
1160 }
1161 function _alignPixel(chart, pixel, width) {
1162 const devicePixelRatio = chart.currentDevicePixelRatio;
1163 const halfWidth = width !== 0 ? Math.max(width / 2, 0.5) : 0;
1164 return Math.round((pixel - halfWidth) * devicePixelRatio) / devicePixelRatio + halfWidth;
1165 }
1166 function clearCanvas(canvas, ctx) {
1167 ctx = ctx || canvas.getContext('2d');
1168 ctx.save();
1169 ctx.resetTransform();
1170 ctx.clearRect(0, 0, canvas.width, canvas.height);
1171 ctx.restore();
1172 }
1173 function drawPoint(ctx, options, x, y) {
1174 let type, xOffset, yOffset, size, cornerRadius;
1175 const style = options.pointStyle;
1176 const rotation = options.rotation;
1177 const radius = options.radius;
1178 let rad = (rotation || 0) * RAD_PER_DEG;
1179 if (style && typeof style === 'object') {
1180 type = style.toString();
1181 if (type === '[object HTMLImageElement]' || type === '[object HTMLCanvasElement]') {
1182 ctx.save();
1183 ctx.translate(x, y);
1184 ctx.rotate(rad);
1185 ctx.drawImage(style, -style.width / 2, -style.height / 2, style.width, style.height);
1186 ctx.restore();
1187 return;
1188 }
1189 }
1190 if (isNaN(radius) || radius <= 0) {
1191 return;
1192 }
1193 ctx.beginPath();
1194 switch (style) {
1195 default:
1196 ctx.arc(x, y, radius, 0, TAU);
1197 ctx.closePath();
1198 break;
1199 case 'triangle':
1200 ctx.moveTo(x + Math.sin(rad) * radius, y - Math.cos(rad) * radius);
1201 rad += TWO_THIRDS_PI;
1202 ctx.lineTo(x + Math.sin(rad) * radius, y - Math.cos(rad) * radius);
1203 rad += TWO_THIRDS_PI;
1204 ctx.lineTo(x + Math.sin(rad) * radius, y - Math.cos(rad) * radius);
1205 ctx.closePath();
1206 break;
1207 case 'rectRounded':
1208 cornerRadius = radius * 0.516;
1209 size = radius - cornerRadius;
1210 xOffset = Math.cos(rad + QUARTER_PI) * size;
1211 yOffset = Math.sin(rad + QUARTER_PI) * size;
1212 ctx.arc(x - xOffset, y - yOffset, cornerRadius, rad - PI, rad - HALF_PI);
1213 ctx.arc(x + yOffset, y - xOffset, cornerRadius, rad - HALF_PI, rad);
1214 ctx.arc(x + xOffset, y + yOffset, cornerRadius, rad, rad + HALF_PI);
1215 ctx.arc(x - yOffset, y + xOffset, cornerRadius, rad + HALF_PI, rad + PI);
1216 ctx.closePath();
1217 break;
1218 case 'rect':
1219 if (!rotation) {
1220 size = Math.SQRT1_2 * radius;
1221 ctx.rect(x - size, y - size, 2 * size, 2 * size);
1222 break;
1223 }
1224 rad += QUARTER_PI;
1225 case 'rectRot':
1226 xOffset = Math.cos(rad) * radius;
1227 yOffset = Math.sin(rad) * radius;
1228 ctx.moveTo(x - xOffset, y - yOffset);
1229 ctx.lineTo(x + yOffset, y - xOffset);
1230 ctx.lineTo(x + xOffset, y + yOffset);
1231 ctx.lineTo(x - yOffset, y + xOffset);
1232 ctx.closePath();
1233 break;
1234 case 'crossRot':
1235 rad += QUARTER_PI;
1236 case 'cross':
1237 xOffset = Math.cos(rad) * radius;
1238 yOffset = Math.sin(rad) * radius;
1239 ctx.moveTo(x - xOffset, y - yOffset);
1240 ctx.lineTo(x + xOffset, y + yOffset);
1241 ctx.moveTo(x + yOffset, y - xOffset);
1242 ctx.lineTo(x - yOffset, y + xOffset);
1243 break;
1244 case 'star':
1245 xOffset = Math.cos(rad) * radius;
1246 yOffset = Math.sin(rad) * radius;
1247 ctx.moveTo(x - xOffset, y - yOffset);
1248 ctx.lineTo(x + xOffset, y + yOffset);
1249 ctx.moveTo(x + yOffset, y - xOffset);
1250 ctx.lineTo(x - yOffset, y + xOffset);
1251 rad += QUARTER_PI;
1252 xOffset = Math.cos(rad) * radius;
1253 yOffset = Math.sin(rad) * radius;
1254 ctx.moveTo(x - xOffset, y - yOffset);
1255 ctx.lineTo(x + xOffset, y + yOffset);
1256 ctx.moveTo(x + yOffset, y - xOffset);
1257 ctx.lineTo(x - yOffset, y + xOffset);
1258 break;
1259 case 'line':
1260 xOffset = Math.cos(rad) * radius;
1261 yOffset = Math.sin(rad) * radius;
1262 ctx.moveTo(x - xOffset, y - yOffset);
1263 ctx.lineTo(x + xOffset, y + yOffset);
1264 break;
1265 case 'dash':
1266 ctx.moveTo(x, y);
1267 ctx.lineTo(x + Math.cos(rad) * radius, y + Math.sin(rad) * radius);
1268 break;
1269 }
1270 ctx.fill();
1271 if (options.borderWidth > 0) {
1272 ctx.stroke();
1273 }
1274 }
1275 function _isPointInArea(point, area, margin) {
1276 margin = margin || 0.5;
1277 return point && point.x > area.left - margin && point.x < area.right + margin &&
1278 point.y > area.top - margin && point.y < area.bottom + margin;
1279 }
1280 function clipArea(ctx, area) {
1281 ctx.save();
1282 ctx.beginPath();
1283 ctx.rect(area.left, area.top, area.right - area.left, area.bottom - area.top);
1284 ctx.clip();
1285 }
1286 function unclipArea(ctx) {
1287 ctx.restore();
1288 }
1289 function _steppedLineTo(ctx, previous, target, flip, mode) {
1290 if (!previous) {
1291 return ctx.lineTo(target.x, target.y);
1292 }
1293 if (mode === 'middle') {
1294 const midpoint = (previous.x + target.x) / 2.0;
1295 ctx.lineTo(midpoint, previous.y);
1296 ctx.lineTo(midpoint, target.y);
1297 } else if (mode === 'after' !== !!flip) {
1298 ctx.lineTo(previous.x, target.y);
1299 } else {
1300 ctx.lineTo(target.x, previous.y);
1301 }
1302 ctx.lineTo(target.x, target.y);
1303 }
1304 function _bezierCurveTo(ctx, previous, target, flip) {
1305 if (!previous) {
1306 return ctx.lineTo(target.x, target.y);
1307 }
1308 ctx.bezierCurveTo(
1309 flip ? previous.cp1x : previous.cp2x,
1310 flip ? previous.cp1y : previous.cp2y,
1311 flip ? target.cp2x : target.cp1x,
1312 flip ? target.cp2y : target.cp1y,
1313 target.x,
1314 target.y);
1315 }
1316 function renderText(ctx, text, x, y, font, opts = {}) {
1317 const lines = isArray(text) ? text : [text];
1318 const stroke = opts.strokeWidth > 0 && opts.strokeColor !== '';
1319 let i, line;
1320 ctx.save();
1321 if (opts.translation) {
1322 ctx.translate(opts.translation[0], opts.translation[1]);
1323 }
1324 if (!isNullOrUndef(opts.rotation)) {
1325 ctx.rotate(opts.rotation);
1326 }
1327 ctx.font = font.string;
1328 if (opts.color) {
1329 ctx.fillStyle = opts.color;
1330 }
1331 if (opts.textAlign) {
1332 ctx.textAlign = opts.textAlign;
1333 }
1334 if (opts.textBaseline) {
1335 ctx.textBaseline = opts.textBaseline;
1336 }
1337 for (i = 0; i < lines.length; ++i) {
1338 line = lines[i];
1339 if (stroke) {
1340 if (opts.strokeColor) {
1341 ctx.strokeStyle = opts.strokeColor;
1342 }
1343 if (!isNullOrUndef(opts.strokeWidth)) {
1344 ctx.lineWidth = opts.strokeWidth;
1345 }
1346 ctx.strokeText(line, x, y, opts.maxWidth);
1347 }
1348 ctx.fillText(line, x, y, opts.maxWidth);
1349 if (opts.strikethrough || opts.underline) {
1350 const metrics = ctx.measureText(line);
1351 const left = x - metrics.actualBoundingBoxLeft;
1352 const right = x + metrics.actualBoundingBoxRight;
1353 const top = y - metrics.actualBoundingBoxAscent;
1354 const bottom = y + metrics.actualBoundingBoxDescent;
1355 const yDecoration = opts.strikethrough ? (top + bottom) / 2 : bottom;
1356 ctx.strokeStyle = ctx.fillStyle;
1357 ctx.beginPath();
1358 ctx.lineWidth = opts.decorationWidth || 2;
1359 ctx.moveTo(left, yDecoration);
1360 ctx.lineTo(right, yDecoration);
1361 ctx.stroke();
1362 }
1363 y += font.lineHeight;
1364 }
1365 ctx.restore();
1366 }
1367 function addRoundedRectPath(ctx, rect) {
1368 const {x, y, w, h, radius} = rect;
1369 ctx.arc(x + radius.topLeft, y + radius.topLeft, radius.topLeft, -HALF_PI, PI, true);
1370 ctx.lineTo(x, y + h - radius.bottomLeft);
1371 ctx.arc(x + radius.bottomLeft, y + h - radius.bottomLeft, radius.bottomLeft, PI, HALF_PI, true);
1372 ctx.lineTo(x + w - radius.bottomRight, y + h);
1373 ctx.arc(x + w - radius.bottomRight, y + h - radius.bottomRight, radius.bottomRight, HALF_PI, 0, true);
1374 ctx.lineTo(x + w, y + radius.topRight);
1375 ctx.arc(x + w - radius.topRight, y + radius.topRight, radius.topRight, 0, -HALF_PI, true);
1376 ctx.lineTo(x + radius.topLeft, y);
1377 }
1378
1379 const LINE_HEIGHT = new RegExp(/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/);
1380 const FONT_STYLE = new RegExp(/^(normal|italic|initial|inherit|unset|(oblique( -?[0-9]?[0-9]deg)?))$/);
1381 function toLineHeight(value, size) {
1382 const matches = ('' + value).match(LINE_HEIGHT);
1383 if (!matches || matches[1] === 'normal') {
1384 return size * 1.2;
1385 }
1386 value = +matches[2];
1387 switch (matches[3]) {
1388 case 'px':
1389 return value;
1390 case '%':
1391 value /= 100;
1392 break;
1393 }
1394 return size * value;
1395 }
1396 const numberOrZero = v => +v || 0;
1397 function _readValueToProps(value, props) {
1398 const ret = {};
1399 const objProps = isObject(props);
1400 const keys = objProps ? Object.keys(props) : props;
1401 const read = isObject(value)
1402 ? objProps
1403 ? prop => valueOrDefault(value[prop], value[props[prop]])
1404 : prop => value[prop]
1405 : () => value;
1406 for (const prop of keys) {
1407 ret[prop] = numberOrZero(read(prop));
1408 }
1409 return ret;
1410 }
1411 function toTRBL(value) {
1412 return _readValueToProps(value, {top: 'y', right: 'x', bottom: 'y', left: 'x'});
1413 }
1414 function toTRBLCorners(value) {
1415 return _readValueToProps(value, ['topLeft', 'topRight', 'bottomLeft', 'bottomRight']);
1416 }
1417 function toPadding(value) {
1418 const obj = toTRBL(value);
1419 obj.width = obj.left + obj.right;
1420 obj.height = obj.top + obj.bottom;
1421 return obj;
1422 }
1423 function toFont(options, fallback) {
1424 options = options || {};
1425 fallback = fallback || defaults.font;
1426 let size = valueOrDefault(options.size, fallback.size);
1427 if (typeof size === 'string') {
1428 size = parseInt(size, 10);
1429 }
1430 let style = valueOrDefault(options.style, fallback.style);
1431 if (style && !('' + style).match(FONT_STYLE)) {
1432 console.warn('Invalid font style specified: "' + style + '"');
1433 style = '';
1434 }
1435 const font = {
1436 family: valueOrDefault(options.family, fallback.family),
1437 lineHeight: toLineHeight(valueOrDefault(options.lineHeight, fallback.lineHeight), size),
1438 size,
1439 style,
1440 weight: valueOrDefault(options.weight, fallback.weight),
1441 string: ''
1442 };
1443 font.string = toFontString(font);
1444 return font;
1445 }
1446 function resolve(inputs, context, index, info) {
1447 let cacheable = true;
1448 let i, ilen, value;
1449 for (i = 0, ilen = inputs.length; i < ilen; ++i) {
1450 value = inputs[i];
1451 if (value === undefined) {
1452 continue;
1453 }
1454 if (context !== undefined && typeof value === 'function') {
1455 value = value(context);
1456 cacheable = false;
1457 }
1458 if (index !== undefined && isArray(value)) {
1459 value = value[index % value.length];
1460 cacheable = false;
1461 }
1462 if (value !== undefined) {
1463 if (info && !cacheable) {
1464 info.cacheable = false;
1465 }
1466 return value;
1467 }
1468 }
1469 }
1470 function _addGrace(minmax, grace) {
1471 const {min, max} = minmax;
1472 return {
1473 min: min - Math.abs(toDimension(grace, min)),
1474 max: max + toDimension(grace, max)
1475 };
1476 }
1477
1478 function _lookup(table, value, cmp) {
1479 cmp = cmp || ((index) => table[index] < value);
1480 let hi = table.length - 1;
1481 let lo = 0;
1482 let mid;
1483 while (hi - lo > 1) {
1484 mid = (lo + hi) >> 1;
1485 if (cmp(mid)) {
1486 lo = mid;
1487 } else {
1488 hi = mid;
1489 }
1490 }
1491 return {lo, hi};
1492 }
1493 const _lookupByKey = (table, key, value) =>
1494 _lookup(table, value, index => table[index][key] < value);
1495 const _rlookupByKey = (table, key, value) =>
1496 _lookup(table, value, index => table[index][key] >= value);
1497 function _filterBetween(values, min, max) {
1498 let start = 0;
1499 let end = values.length;
1500 while (start < end && values[start] < min) {
1501 start++;
1502 }
1503 while (end > start && values[end - 1] > max) {
1504 end--;
1505 }
1506 return start > 0 || end < values.length
1507 ? values.slice(start, end)
1508 : values;
1509 }
1510 const arrayEvents = ['push', 'pop', 'shift', 'splice', 'unshift'];
1511 function listenArrayEvents(array, listener) {
1512 if (array._chartjs) {
1513 array._chartjs.listeners.push(listener);
1514 return;
1515 }
1516 Object.defineProperty(array, '_chartjs', {
1517 configurable: true,
1518 enumerable: false,
1519 value: {
1520 listeners: [listener]
1521 }
1522 });
1523 arrayEvents.forEach((key) => {
1524 const method = '_onData' + _capitalize(key);
1525 const base = array[key];
1526 Object.defineProperty(array, key, {
1527 configurable: true,
1528 enumerable: false,
1529 value(...args) {
1530 const res = base.apply(this, args);
1531 array._chartjs.listeners.forEach((object) => {
1532 if (typeof object[method] === 'function') {
1533 object[method](...args);
1534 }
1535 });
1536 return res;
1537 }
1538 });
1539 });
1540 }
1541 function unlistenArrayEvents(array, listener) {
1542 const stub = array._chartjs;
1543 if (!stub) {
1544 return;
1545 }
1546 const listeners = stub.listeners;
1547 const index = listeners.indexOf(listener);
1548 if (index !== -1) {
1549 listeners.splice(index, 1);
1550 }
1551 if (listeners.length > 0) {
1552 return;
1553 }
1554 arrayEvents.forEach((key) => {
1555 delete array[key];
1556 });
1557 delete array._chartjs;
1558 }
1559 function _arrayUnique(items) {
1560 const set = new Set();
1561 let i, ilen;
1562 for (i = 0, ilen = items.length; i < ilen; ++i) {
1563 set.add(items[i]);
1564 }
1565 if (set.size === ilen) {
1566 return items;
1567 }
1568 const result = [];
1569 set.forEach(item => {
1570 result.push(item);
1571 });
1572 return result;
1573 }
1574
1575 function _createResolver(scopes, prefixes = [''], rootScopes = scopes, fallback, getTarget = () => scopes[0]) {
1576 if (!defined(fallback)) {
1577 fallback = _resolve('_fallback', scopes);
1578 }
1579 const cache = {
1580 [Symbol.toStringTag]: 'Object',
1581 _cacheable: true,
1582 _scopes: scopes,
1583 _rootScopes: rootScopes,
1584 _fallback: fallback,
1585 _getTarget: getTarget,
1586 override: (scope) => _createResolver([scope, ...scopes], prefixes, rootScopes, fallback),
1587 };
1588 return new Proxy(cache, {
1589 deleteProperty(target, prop) {
1590 delete target[prop];
1591 delete target._keys;
1592 delete scopes[0][prop];
1593 return true;
1594 },
1595 get(target, prop) {
1596 return _cached(target, prop,
1597 () => _resolveWithPrefixes(prop, prefixes, scopes, target));
1598 },
1599 getOwnPropertyDescriptor(target, prop) {
1600 return Reflect.getOwnPropertyDescriptor(target._scopes[0], prop);
1601 },
1602 getPrototypeOf() {
1603 return Reflect.getPrototypeOf(scopes[0]);
1604 },
1605 has(target, prop) {
1606 return getKeysFromAllScopes(target).includes(prop);
1607 },
1608 ownKeys(target) {
1609 return getKeysFromAllScopes(target);
1610 },
1611 set(target, prop, value) {
1612 const storage = target._storage || (target._storage = getTarget());
1613 storage[prop] = value;
1614 delete target[prop];
1615 delete target._keys;
1616 return true;
1617 }
1618 });
1619 }
1620 function _attachContext(proxy, context, subProxy, descriptorDefaults) {
1621 const cache = {
1622 _cacheable: false,
1623 _proxy: proxy,
1624 _context: context,
1625 _subProxy: subProxy,
1626 _stack: new Set(),
1627 _descriptors: _descriptors(proxy, descriptorDefaults),
1628 setContext: (ctx) => _attachContext(proxy, ctx, subProxy, descriptorDefaults),
1629 override: (scope) => _attachContext(proxy.override(scope), context, subProxy, descriptorDefaults)
1630 };
1631 return new Proxy(cache, {
1632 deleteProperty(target, prop) {
1633 delete target[prop];
1634 delete proxy[prop];
1635 return true;
1636 },
1637 get(target, prop, receiver) {
1638 return _cached(target, prop,
1639 () => _resolveWithContext(target, prop, receiver));
1640 },
1641 getOwnPropertyDescriptor(target, prop) {
1642 return target._descriptors.allKeys
1643 ? Reflect.has(proxy, prop) ? {enumerable: true, configurable: true} : undefined
1644 : Reflect.getOwnPropertyDescriptor(proxy, prop);
1645 },
1646 getPrototypeOf() {
1647 return Reflect.getPrototypeOf(proxy);
1648 },
1649 has(target, prop) {
1650 return Reflect.has(proxy, prop);
1651 },
1652 ownKeys() {
1653 return Reflect.ownKeys(proxy);
1654 },
1655 set(target, prop, value) {
1656 proxy[prop] = value;
1657 delete target[prop];
1658 return true;
1659 }
1660 });
1661 }
1662 function _descriptors(proxy, defaults = {scriptable: true, indexable: true}) {
1663 const {_scriptable = defaults.scriptable, _indexable = defaults.indexable, _allKeys = defaults.allKeys} = proxy;
1664 return {
1665 allKeys: _allKeys,
1666 scriptable: _scriptable,
1667 indexable: _indexable,
1668 isScriptable: isFunction(_scriptable) ? _scriptable : () => _scriptable,
1669 isIndexable: isFunction(_indexable) ? _indexable : () => _indexable
1670 };
1671 }
1672 const readKey = (prefix, name) => prefix ? prefix + _capitalize(name) : name;
1673 const needsSubResolver = (prop, value) => isObject(value) && prop !== 'adapters';
1674 function _cached(target, prop, resolve) {
1675 let value = target[prop];
1676 if (defined(value)) {
1677 return value;
1678 }
1679 value = resolve();
1680 if (defined(value)) {
1681 target[prop] = value;
1682 }
1683 return value;
1684 }
1685 function _resolveWithContext(target, prop, receiver) {
1686 const {_proxy, _context, _subProxy, _descriptors: descriptors} = target;
1687 let value = _proxy[prop];
1688 if (isFunction(value) && descriptors.isScriptable(prop)) {
1689 value = _resolveScriptable(prop, value, target, receiver);
1690 }
1691 if (isArray(value) && value.length) {
1692 value = _resolveArray(prop, value, target, descriptors.isIndexable);
1693 }
1694 if (needsSubResolver(prop, value)) {
1695 value = _attachContext(value, _context, _subProxy && _subProxy[prop], descriptors);
1696 }
1697 return value;
1698 }
1699 function _resolveScriptable(prop, value, target, receiver) {
1700 const {_proxy, _context, _subProxy, _stack} = target;
1701 if (_stack.has(prop)) {
1702 throw new Error('Recursion detected: ' + [..._stack].join('->') + '->' + prop);
1703 }
1704 _stack.add(prop);
1705 value = value(_context, _subProxy || receiver);
1706 _stack.delete(prop);
1707 if (isObject(value)) {
1708 value = createSubResolver(_proxy._scopes, _proxy, prop, value);
1709 }
1710 return value;
1711 }
1712 function _resolveArray(prop, value, target, isIndexable) {
1713 const {_proxy, _context, _subProxy, _descriptors: descriptors} = target;
1714 if (defined(_context.index) && isIndexable(prop)) {
1715 value = value[_context.index % value.length];
1716 } else if (isObject(value[0])) {
1717 const arr = value;
1718 const scopes = _proxy._scopes.filter(s => s !== arr);
1719 value = [];
1720 for (const item of arr) {
1721 const resolver = createSubResolver(scopes, _proxy, prop, item);
1722 value.push(_attachContext(resolver, _context, _subProxy && _subProxy[prop], descriptors));
1723 }
1724 }
1725 return value;
1726 }
1727 function resolveFallback(fallback, prop, value) {
1728 return isFunction(fallback) ? fallback(prop, value) : fallback;
1729 }
1730 const getScope = (key, parent) => key === true ? parent
1731 : typeof key === 'string' ? resolveObjectKey(parent, key) : undefined;
1732 function addScopes(set, parentScopes, key, parentFallback) {
1733 for (const parent of parentScopes) {
1734 const scope = getScope(key, parent);
1735 if (scope) {
1736 set.add(scope);
1737 const fallback = resolveFallback(scope._fallback, key, scope);
1738 if (defined(fallback) && fallback !== key && fallback !== parentFallback) {
1739 return fallback;
1740 }
1741 } else if (scope === false && defined(parentFallback) && key !== parentFallback) {
1742 return null;
1743 }
1744 }
1745 return false;
1746 }
1747 function createSubResolver(parentScopes, resolver, prop, value) {
1748 const rootScopes = resolver._rootScopes;
1749 const fallback = resolveFallback(resolver._fallback, prop, value);
1750 const allScopes = [...parentScopes, ...rootScopes];
1751 const set = new Set();
1752 set.add(value);
1753 let key = addScopesFromKey(set, allScopes, prop, fallback || prop);
1754 if (key === null) {
1755 return false;
1756 }
1757 if (defined(fallback) && fallback !== prop) {
1758 key = addScopesFromKey(set, allScopes, fallback, key);
1759 if (key === null) {
1760 return false;
1761 }
1762 }
1763 return _createResolver([...set], [''], rootScopes, fallback, () => {
1764 const parent = resolver._getTarget();
1765 if (!(prop in parent)) {
1766 parent[prop] = {};
1767 }
1768 return parent[prop];
1769 });
1770 }
1771 function addScopesFromKey(set, allScopes, key, fallback) {
1772 while (key) {
1773 key = addScopes(set, allScopes, key, fallback);
1774 }
1775 return key;
1776 }
1777 function _resolveWithPrefixes(prop, prefixes, scopes, proxy) {
1778 let value;
1779 for (const prefix of prefixes) {
1780 value = _resolve(readKey(prefix, prop), scopes);
1781 if (defined(value)) {
1782 return needsSubResolver(prop, value)
1783 ? createSubResolver(scopes, proxy, prop, value)
1784 : value;
1785 }
1786 }
1787 }
1788 function _resolve(key, scopes) {
1789 for (const scope of scopes) {
1790 if (!scope) {
1791 continue;
1792 }
1793 const value = scope[key];
1794 if (defined(value)) {
1795 return value;
1796 }
1797 }
1798 }
1799 function getKeysFromAllScopes(target) {
1800 let keys = target._keys;
1801 if (!keys) {
1802 keys = target._keys = resolveKeysFromAllScopes(target._scopes);
1803 }
1804 return keys;
1805 }
1806 function resolveKeysFromAllScopes(scopes) {
1807 const set = new Set();
1808 for (const scope of scopes) {
1809 for (const key of Object.keys(scope).filter(k => !k.startsWith('_'))) {
1810 set.add(key);
1811 }
1812 }
1813 return [...set];
1814 }
1815
1816 const EPSILON = Number.EPSILON || 1e-14;
1817 const getPoint = (points, i) => i < points.length && !points[i].skip && points[i];
1818 function splineCurve(firstPoint, middlePoint, afterPoint, t) {
1819 const previous = firstPoint.skip ? middlePoint : firstPoint;
1820 const current = middlePoint;
1821 const next = afterPoint.skip ? middlePoint : afterPoint;
1822 const d01 = distanceBetweenPoints(current, previous);
1823 const d12 = distanceBetweenPoints(next, current);
1824 let s01 = d01 / (d01 + d12);
1825 let s12 = d12 / (d01 + d12);
1826 s01 = isNaN(s01) ? 0 : s01;
1827 s12 = isNaN(s12) ? 0 : s12;
1828 const fa = t * s01;
1829 const fb = t * s12;
1830 return {
1831 previous: {
1832 x: current.x - fa * (next.x - previous.x),
1833 y: current.y - fa * (next.y - previous.y)
1834 },
1835 next: {
1836 x: current.x + fb * (next.x - previous.x),
1837 y: current.y + fb * (next.y - previous.y)
1838 }
1839 };
1840 }
1841 function monotoneAdjust(points, deltaK, mK) {
1842 const pointsLen = points.length;
1843 let alphaK, betaK, tauK, squaredMagnitude, pointCurrent;
1844 let pointAfter = getPoint(points, 0);
1845 for (let i = 0; i < pointsLen - 1; ++i) {
1846 pointCurrent = pointAfter;
1847 pointAfter = getPoint(points, i + 1);
1848 if (!pointCurrent || !pointAfter) {
1849 continue;
1850 }
1851 if (almostEquals(deltaK[i], 0, EPSILON)) {
1852 mK[i] = mK[i + 1] = 0;
1853 continue;
1854 }
1855 alphaK = mK[i] / deltaK[i];
1856 betaK = mK[i + 1] / deltaK[i];
1857 squaredMagnitude = Math.pow(alphaK, 2) + Math.pow(betaK, 2);
1858 if (squaredMagnitude <= 9) {
1859 continue;
1860 }
1861 tauK = 3 / Math.sqrt(squaredMagnitude);
1862 mK[i] = alphaK * tauK * deltaK[i];
1863 mK[i + 1] = betaK * tauK * deltaK[i];
1864 }
1865 }
1866 function monotoneCompute(points, mK) {
1867 const pointsLen = points.length;
1868 let deltaX, pointBefore, pointCurrent;
1869 let pointAfter = getPoint(points, 0);
1870 for (let i = 0; i < pointsLen; ++i) {
1871 pointBefore = pointCurrent;
1872 pointCurrent = pointAfter;
1873 pointAfter = getPoint(points, i + 1);
1874 if (!pointCurrent) {
1875 continue;
1876 }
1877 const {x, y} = pointCurrent;
1878 if (pointBefore) {
1879 deltaX = (x - pointBefore.x) / 3;
1880 pointCurrent.cp1x = x - deltaX;
1881 pointCurrent.cp1y = y - deltaX * mK[i];
1882 }
1883 if (pointAfter) {
1884 deltaX = (pointAfter.x - x) / 3;
1885 pointCurrent.cp2x = x + deltaX;
1886 pointCurrent.cp2y = y + deltaX * mK[i];
1887 }
1888 }
1889 }
1890 function splineCurveMonotone(points) {
1891 const pointsLen = points.length;
1892 const deltaK = Array(pointsLen).fill(0);
1893 const mK = Array(pointsLen);
1894 let i, pointBefore, pointCurrent;
1895 let pointAfter = getPoint(points, 0);
1896 for (i = 0; i < pointsLen; ++i) {
1897 pointBefore = pointCurrent;
1898 pointCurrent = pointAfter;
1899 pointAfter = getPoint(points, i + 1);
1900 if (!pointCurrent) {
1901 continue;
1902 }
1903 if (pointAfter) {
1904 const slopeDeltaX = (pointAfter.x - pointCurrent.x);
1905 deltaK[i] = slopeDeltaX !== 0 ? (pointAfter.y - pointCurrent.y) / slopeDeltaX : 0;
1906 }
1907 mK[i] = !pointBefore ? deltaK[i]
1908 : !pointAfter ? deltaK[i - 1]
1909 : (sign(deltaK[i - 1]) !== sign(deltaK[i])) ? 0
1910 : (deltaK[i - 1] + deltaK[i]) / 2;
1911 }
1912 monotoneAdjust(points, deltaK, mK);
1913 monotoneCompute(points, mK);
1914 }
1915 function capControlPoint(pt, min, max) {
1916 return Math.max(Math.min(pt, max), min);
1917 }
1918 function capBezierPoints(points, area) {
1919 let i, ilen, point, inArea, inAreaPrev;
1920 let inAreaNext = _isPointInArea(points[0], area);
1921 for (i = 0, ilen = points.length; i < ilen; ++i) {
1922 inAreaPrev = inArea;
1923 inArea = inAreaNext;
1924 inAreaNext = i < ilen - 1 && _isPointInArea(points[i + 1], area);
1925 if (!inArea) {
1926 continue;
1927 }
1928 point = points[i];
1929 if (inAreaPrev) {
1930 point.cp1x = capControlPoint(point.cp1x, area.left, area.right);
1931 point.cp1y = capControlPoint(point.cp1y, area.top, area.bottom);
1932 }
1933 if (inAreaNext) {
1934 point.cp2x = capControlPoint(point.cp2x, area.left, area.right);
1935 point.cp2y = capControlPoint(point.cp2y, area.top, area.bottom);
1936 }
1937 }
1938 }
1939 function _updateBezierControlPoints(points, options, area, loop) {
1940 let i, ilen, point, controlPoints;
1941 if (options.spanGaps) {
1942 points = points.filter((pt) => !pt.skip);
1943 }
1944 if (options.cubicInterpolationMode === 'monotone') {
1945 splineCurveMonotone(points);
1946 } else {
1947 let prev = loop ? points[points.length - 1] : points[0];
1948 for (i = 0, ilen = points.length; i < ilen; ++i) {
1949 point = points[i];
1950 controlPoints = splineCurve(
1951 prev,
1952 point,
1953 points[Math.min(i + 1, ilen - (loop ? 0 : 1)) % ilen],
1954 options.tension
1955 );
1956 point.cp1x = controlPoints.previous.x;
1957 point.cp1y = controlPoints.previous.y;
1958 point.cp2x = controlPoints.next.x;
1959 point.cp2y = controlPoints.next.y;
1960 prev = point;
1961 }
1962 }
1963 if (options.capBezierPoints) {
1964 capBezierPoints(points, area);
1965 }
1966 }
1967
1968 function _getParentNode(domNode) {
1969 let parent = domNode.parentNode;
1970 if (parent && parent.toString() === '[object ShadowRoot]') {
1971 parent = parent.host;
1972 }
1973 return parent;
1974 }
1975 function parseMaxStyle(styleValue, node, parentProperty) {
1976 let valueInPixels;
1977 if (typeof styleValue === 'string') {
1978 valueInPixels = parseInt(styleValue, 10);
1979 if (styleValue.indexOf('%') !== -1) {
1980 valueInPixels = valueInPixels / 100 * node.parentNode[parentProperty];
1981 }
1982 } else {
1983 valueInPixels = styleValue;
1984 }
1985 return valueInPixels;
1986 }
1987 const getComputedStyle = (element) => window.getComputedStyle(element, null);
1988 function getStyle(el, property) {
1989 return getComputedStyle(el).getPropertyValue(property);
1990 }
1991 const positions = ['top', 'right', 'bottom', 'left'];
1992 function getPositionedStyle(styles, style, suffix) {
1993 const result = {};
1994 suffix = suffix ? '-' + suffix : '';
1995 for (let i = 0; i < 4; i++) {
1996 const pos = positions[i];
1997 result[pos] = parseFloat(styles[style + '-' + pos + suffix]) || 0;
1998 }
1999 result.width = result.left + result.right;
2000 result.height = result.top + result.bottom;
2001 return result;
2002 }
2003 const useOffsetPos = (x, y, target) => (x > 0 || y > 0) && (!target || !target.shadowRoot);
2004 function getCanvasPosition(evt, canvas) {
2005 const e = evt.native || evt;
2006 const touches = e.touches;
2007 const source = touches && touches.length ? touches[0] : e;
2008 const {offsetX, offsetY} = source;
2009 let box = false;
2010 let x, y;
2011 if (useOffsetPos(offsetX, offsetY, e.target)) {
2012 x = offsetX;
2013 y = offsetY;
2014 } else {
2015 const rect = canvas.getBoundingClientRect();
2016 x = source.clientX - rect.left;
2017 y = source.clientY - rect.top;
2018 box = true;
2019 }
2020 return {x, y, box};
2021 }
2022 function getRelativePosition(evt, chart) {
2023 const {canvas, currentDevicePixelRatio} = chart;
2024 const style = getComputedStyle(canvas);
2025 const borderBox = style.boxSizing === 'border-box';
2026 const paddings = getPositionedStyle(style, 'padding');
2027 const borders = getPositionedStyle(style, 'border', 'width');
2028 const {x, y, box} = getCanvasPosition(evt, canvas);
2029 const xOffset = paddings.left + (box && borders.left);
2030 const yOffset = paddings.top + (box && borders.top);
2031 let {width, height} = chart;
2032 if (borderBox) {
2033 width -= paddings.width + borders.width;
2034 height -= paddings.height + borders.height;
2035 }
2036 return {
2037 x: Math.round((x - xOffset) / width * canvas.width / currentDevicePixelRatio),
2038 y: Math.round((y - yOffset) / height * canvas.height / currentDevicePixelRatio)
2039 };
2040 }
2041 function getContainerSize(canvas, width, height) {
2042 let maxWidth, maxHeight;
2043 if (width === undefined || height === undefined) {
2044 const container = _getParentNode(canvas);
2045 if (!container) {
2046 width = canvas.clientWidth;
2047 height = canvas.clientHeight;
2048 } else {
2049 const rect = container.getBoundingClientRect();
2050 const containerStyle = getComputedStyle(container);
2051 const containerBorder = getPositionedStyle(containerStyle, 'border', 'width');
2052 const containerPadding = getPositionedStyle(containerStyle, 'padding');
2053 width = rect.width - containerPadding.width - containerBorder.width;
2054 height = rect.height - containerPadding.height - containerBorder.height;
2055 maxWidth = parseMaxStyle(containerStyle.maxWidth, container, 'clientWidth');
2056 maxHeight = parseMaxStyle(containerStyle.maxHeight, container, 'clientHeight');
2057 }
2058 }
2059 return {
2060 width,
2061 height,
2062 maxWidth: maxWidth || INFINITY,
2063 maxHeight: maxHeight || INFINITY
2064 };
2065 }
2066 const round1 = v => Math.round(v * 10) / 10;
2067 function getMaximumSize(canvas, bbWidth, bbHeight, aspectRatio) {
2068 const style = getComputedStyle(canvas);
2069 const margins = getPositionedStyle(style, 'margin');
2070 const maxWidth = parseMaxStyle(style.maxWidth, canvas, 'clientWidth') || INFINITY;
2071 const maxHeight = parseMaxStyle(style.maxHeight, canvas, 'clientHeight') || INFINITY;
2072 const containerSize = getContainerSize(canvas, bbWidth, bbHeight);
2073 let {width, height} = containerSize;
2074 if (style.boxSizing === 'content-box') {
2075 const borders = getPositionedStyle(style, 'border', 'width');
2076 const paddings = getPositionedStyle(style, 'padding');
2077 width -= paddings.width + borders.width;
2078 height -= paddings.height + borders.height;
2079 }
2080 width = Math.max(0, width - margins.width);
2081 height = Math.max(0, aspectRatio ? Math.floor(width / aspectRatio) : height - margins.height);
2082 width = round1(Math.min(width, maxWidth, containerSize.maxWidth));
2083 height = round1(Math.min(height, maxHeight, containerSize.maxHeight));
2084 if (width && !height) {
2085 height = round1(width / 2);
2086 }
2087 return {
2088 width,
2089 height
2090 };
2091 }
2092 function retinaScale(chart, forceRatio, forceStyle) {
2093 const pixelRatio = chart.currentDevicePixelRatio = forceRatio || 1;
2094 const {canvas, width, height} = chart;
2095 canvas.height = height * pixelRatio;
2096 canvas.width = width * pixelRatio;
2097 chart.ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);
2098 if (canvas.style && (forceStyle || (!canvas.style.height && !canvas.style.width))) {
2099 canvas.style.height = height + 'px';
2100 canvas.style.width = width + 'px';
2101 }
2102 }
2103 const supportsEventListenerOptions = (function() {
2104 let passiveSupported = false;
2105 try {
2106 const options = {
2107 get passive() {
2108 passiveSupported = true;
2109 return false;
2110 }
2111 };
2112 window.addEventListener('test', null, options);
2113 window.removeEventListener('test', null, options);
2114 } catch (e) {
2115 }
2116 return passiveSupported;
2117 }());
2118 function readUsedSize(element, property) {
2119 const value = getStyle(element, property);
2120 const matches = value && value.match(/^(\d+)(\.\d+)?px$/);
2121 return matches ? +matches[1] : undefined;
2122 }
2123
2124 function _pointInLine(p1, p2, t, mode) {
2125 return {
2126 x: p1.x + t * (p2.x - p1.x),
2127 y: p1.y + t * (p2.y - p1.y)
2128 };
2129 }
2130 function _steppedInterpolation(p1, p2, t, mode) {
2131 return {
2132 x: p1.x + t * (p2.x - p1.x),
2133 y: mode === 'middle' ? t < 0.5 ? p1.y : p2.y
2134 : mode === 'after' ? t < 1 ? p1.y : p2.y
2135 : t > 0 ? p2.y : p1.y
2136 };
2137 }
2138 function _bezierInterpolation(p1, p2, t, mode) {
2139 const cp1 = {x: p1.cp2x, y: p1.cp2y};
2140 const cp2 = {x: p2.cp1x, y: p2.cp1y};
2141 const a = _pointInLine(p1, cp1, t);
2142 const b = _pointInLine(cp1, cp2, t);
2143 const c = _pointInLine(cp2, p2, t);
2144 const d = _pointInLine(a, b, t);
2145 const e = _pointInLine(b, c, t);
2146 return _pointInLine(d, e, t);
2147 }
2148
2149 const intlCache = new Map();
2150 function getNumberFormat(locale, options) {
2151 options = options || {};
2152 const cacheKey = locale + JSON.stringify(options);
2153 let formatter = intlCache.get(cacheKey);
2154 if (!formatter) {
2155 formatter = new Intl.NumberFormat(locale, options);
2156 intlCache.set(cacheKey, formatter);
2157 }
2158 return formatter;
2159 }
2160 function formatNumber(num, locale, options) {
2161 return getNumberFormat(locale, options).format(num);
2162 }
2163
2164 const getRightToLeftAdapter = function(rectX, width) {
2165 return {
2166 x(x) {
2167 return rectX + rectX + width - x;
2168 },
2169 setWidth(w) {
2170 width = w;
2171 },
2172 textAlign(align) {
2173 if (align === 'center') {
2174 return align;
2175 }
2176 return align === 'right' ? 'left' : 'right';
2177 },
2178 xPlus(x, value) {
2179 return x - value;
2180 },
2181 leftForLtr(x, itemWidth) {
2182 return x - itemWidth;
2183 },
2184 };
2185 };
2186 const getLeftToRightAdapter = function() {
2187 return {
2188 x(x) {
2189 return x;
2190 },
2191 setWidth(w) {
2192 },
2193 textAlign(align) {
2194 return align;
2195 },
2196 xPlus(x, value) {
2197 return x + value;
2198 },
2199 leftForLtr(x, _itemWidth) {
2200 return x;
2201 },
2202 };
2203 };
2204 function getRtlAdapter(rtl, rectX, width) {
2205 return rtl ? getRightToLeftAdapter(rectX, width) : getLeftToRightAdapter();
2206 }
2207 function overrideTextDirection(ctx, direction) {
2208 let style, original;
2209 if (direction === 'ltr' || direction === 'rtl') {
2210 style = ctx.canvas.style;
2211 original = [
2212 style.getPropertyValue('direction'),
2213 style.getPropertyPriority('direction'),
2214 ];
2215 style.setProperty('direction', direction, 'important');
2216 ctx.prevTextDirection = original;
2217 }
2218 }
2219 function restoreTextDirection(ctx, original) {
2220 if (original !== undefined) {
2221 delete ctx.prevTextDirection;
2222 ctx.canvas.style.setProperty('direction', original[0], original[1]);
2223 }
2224 }
2225
2226 function propertyFn(property) {
2227 if (property === 'angle') {
2228 return {
2229 between: _angleBetween,
2230 compare: _angleDiff,
2231 normalize: _normalizeAngle,
2232 };
2233 }
2234 return {
2235 between: (n, s, e) => n >= Math.min(s, e) && n <= Math.max(e, s),
2236 compare: (a, b) => a - b,
2237 normalize: x => x
2238 };
2239 }
2240 function normalizeSegment({start, end, count, loop, style}) {
2241 return {
2242 start: start % count,
2243 end: end % count,
2244 loop: loop && (end - start + 1) % count === 0,
2245 style
2246 };
2247 }
2248 function getSegment(segment, points, bounds) {
2249 const {property, start: startBound, end: endBound} = bounds;
2250 const {between, normalize} = propertyFn(property);
2251 const count = points.length;
2252 let {start, end, loop} = segment;
2253 let i, ilen;
2254 if (loop) {
2255 start += count;
2256 end += count;
2257 for (i = 0, ilen = count; i < ilen; ++i) {
2258 if (!between(normalize(points[start % count][property]), startBound, endBound)) {
2259 break;
2260 }
2261 start--;
2262 end--;
2263 }
2264 start %= count;
2265 end %= count;
2266 }
2267 if (end < start) {
2268 end += count;
2269 }
2270 return {start, end, loop, style: segment.style};
2271 }
2272 function _boundSegment(segment, points, bounds) {
2273 if (!bounds) {
2274 return [segment];
2275 }
2276 const {property, start: startBound, end: endBound} = bounds;
2277 const count = points.length;
2278 const {compare, between, normalize} = propertyFn(property);
2279 const {start, end, loop, style} = getSegment(segment, points, bounds);
2280 const result = [];
2281 let inside = false;
2282 let subStart = null;
2283 let value, point, prevValue;
2284 const startIsBefore = () => between(startBound, prevValue, value) && compare(startBound, prevValue) !== 0;
2285 const endIsBefore = () => compare(endBound, value) === 0 || between(endBound, prevValue, value);
2286 const shouldStart = () => inside || startIsBefore();
2287 const shouldStop = () => !inside || endIsBefore();
2288 for (let i = start, prev = start; i <= end; ++i) {
2289 point = points[i % count];
2290 if (point.skip) {
2291 continue;
2292 }
2293 value = normalize(point[property]);
2294 inside = between(value, startBound, endBound);
2295 if (subStart === null && shouldStart()) {
2296 subStart = compare(value, startBound) === 0 ? i : prev;
2297 }
2298 if (subStart !== null && shouldStop()) {
2299 result.push(normalizeSegment({start: subStart, end: i, loop, count, style}));
2300 subStart = null;
2301 }
2302 prev = i;
2303 prevValue = value;
2304 }
2305 if (subStart !== null) {
2306 result.push(normalizeSegment({start: subStart, end, loop, count, style}));
2307 }
2308 return result;
2309 }
2310 function _boundSegments(line, bounds) {
2311 const result = [];
2312 const segments = line.segments;
2313 for (let i = 0; i < segments.length; i++) {
2314 const sub = _boundSegment(segments[i], line.points, bounds);
2315 if (sub.length) {
2316 result.push(...sub);
2317 }
2318 }
2319 return result;
2320 }
2321 function findStartAndEnd(points, count, loop, spanGaps) {
2322 let start = 0;
2323 let end = count - 1;
2324 if (loop && !spanGaps) {
2325 while (start < count && !points[start].skip) {
2326 start++;
2327 }
2328 }
2329 while (start < count && points[start].skip) {
2330 start++;
2331 }
2332 start %= count;
2333 if (loop) {
2334 end += start;
2335 }
2336 while (end > start && points[end % count].skip) {
2337 end--;
2338 }
2339 end %= count;
2340 return {start, end};
2341 }
2342 function solidSegments(points, start, max, loop) {
2343 const count = points.length;
2344 const result = [];
2345 let last = start;
2346 let prev = points[start];
2347 let end;
2348 for (end = start + 1; end <= max; ++end) {
2349 const cur = points[end % count];
2350 if (cur.skip || cur.stop) {
2351 if (!prev.skip) {
2352 loop = false;
2353 result.push({start: start % count, end: (end - 1) % count, loop});
2354 start = last = cur.stop ? end : null;
2355 }
2356 } else {
2357 last = end;
2358 if (prev.skip) {
2359 start = end;
2360 }
2361 }
2362 prev = cur;
2363 }
2364 if (last !== null) {
2365 result.push({start: start % count, end: last % count, loop});
2366 }
2367 return result;
2368 }
2369 function _computeSegments(line, segmentOptions) {
2370 const points = line.points;
2371 const spanGaps = line.options.spanGaps;
2372 const count = points.length;
2373 if (!count) {
2374 return [];
2375 }
2376 const loop = !!line._loop;
2377 const {start, end} = findStartAndEnd(points, count, loop, spanGaps);
2378 if (spanGaps === true) {
2379 return splitByStyles([{start, end, loop}], points, segmentOptions);
2380 }
2381 const max = end < start ? end + count : end;
2382 const completeLoop = !!line._fullLoop && start === 0 && end === count - 1;
2383 return splitByStyles(solidSegments(points, start, max, completeLoop), points, segmentOptions);
2384 }
2385 function splitByStyles(segments, points, segmentOptions) {
2386 if (!segmentOptions || !segmentOptions.setContext || !points) {
2387 return segments;
2388 }
2389 return doSplitByStyles(segments, points, segmentOptions);
2390 }
2391 function doSplitByStyles(segments, points, segmentOptions) {
2392 const count = points.length;
2393 const result = [];
2394 let start = segments[0].start;
2395 let i = start;
2396 for (const segment of segments) {
2397 let prevStyle, style;
2398 let prev = points[start % count];
2399 for (i = start + 1; i <= segment.end; i++) {
2400 const pt = points[i % count];
2401 style = readStyle(segmentOptions.setContext({type: 'segment', p0: prev, p1: pt}));
2402 if (styleChanged(style, prevStyle)) {
2403 result.push({start: start, end: i - 1, loop: segment.loop, style: prevStyle});
2404 prevStyle = style;
2405 start = i - 1;
2406 }
2407 prev = pt;
2408 prevStyle = style;
2409 }
2410 if (start < i - 1) {
2411 result.push({start, end: i - 1, loop: segment.loop, style});
2412 start = i - 1;
2413 }
2414 }
2415 return result;
2416 }
2417 function readStyle(options) {
2418 return {
2419 backgroundColor: options.backgroundColor,
2420 borderCapStyle: options.borderCapStyle,
2421 borderDash: options.borderDash,
2422 borderDashOffset: options.borderDashOffset,
2423 borderJoinStyle: options.borderJoinStyle,
2424 borderWidth: options.borderWidth,
2425 borderColor: options.borderColor
2426 };
2427 }
2428 function styleChanged(style, prevStyle) {
2429 return prevStyle && JSON.stringify(style) !== JSON.stringify(prevStyle);
2430 }
2431
2432 export { merge as $, _isPointInArea as A, _rlookupByKey as B, toPadding as C, each as D, getMaximumSize as E, _getParentNode as F, readUsedSize as G, HALF_PI as H, throttled as I, supportsEventListenerOptions as J, log10 as K, _factorize as L, finiteOrDefault as M, callback as N, _addGrace as O, PI as P, toDegrees as Q, _measureText as R, _int16Range as S, TAU as T, _alignPixel as U, renderText as V, toFont as W, _toLeftRightCenter as X, _alignStartEnd as Y, overrides as Z, _arrayUnique as _, resolve as a, _capitalize as a0, descriptors as a1, isFunction as a2, _attachContext as a3, _createResolver as a4, _descriptors as a5, mergeIf as a6, uid as a7, debounce as a8, retinaScale as a9, niceNum as aA, almostWhole as aB, almostEquals as aC, _decimalPlaces as aD, _longestText as aE, _filterBetween as aF, _lookup as aG, getHoverColor as aH, clone$1 as aI, _merger as aJ, _mergerIf as aK, _deprecated as aL, toFontString as aM, splineCurve as aN, splineCurveMonotone as aO, getStyle as aP, fontString as aQ, toLineHeight as aR, PITAU as aS, INFINITY as aT, RAD_PER_DEG as aU, QUARTER_PI as aV, TWO_THIRDS_PI as aW, _angleDiff as aX, clearCanvas as aa, setsEqual as ab, _elementsEqual as ac, getAngleFromPoint as ad, _readValueToProps as ae, _updateBezierControlPoints as af, _computeSegments as ag, _boundSegments as ah, _steppedInterpolation as ai, _bezierInterpolation as aj, _pointInLine as ak, _steppedLineTo as al, _bezierCurveTo as am, drawPoint as an, addRoundedRectPath as ao, toTRBL as ap, toTRBLCorners as aq, _boundSegment as ar, _normalizeAngle as as, getRtlAdapter as at, overrideTextDirection as au, _textX as av, restoreTextDirection as aw, noop as ax, distanceBetweenPoints as ay, _setMinAndMaxByKey as az, isArray as b, color as c, defaults as d, effects as e, resolveObjectKey as f, isNumberFinite as g, defined as h, isObject as i, isNullOrUndef as j, clipArea as k, listenArrayEvents as l, unclipArea as m, toPercentage as n, toDimension as o, formatNumber as p, _angleBetween as q, requestAnimFrame as r, sign as s, toRadians as t, unlistenArrayEvents as u, valueOrDefault as v, isNumber as w, _limitValue as x, _lookupByKey as y, getRelativePosition as z };
2433