UNPKG

1.67 MBJavaScriptView Raw
1(function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3 typeof define === 'function' && define.amd ? define(['exports'], factory) :
4 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.F2 = {}));
5}(this, (function (exports) { 'use strict';
6
7 /******************************************************************************
8 Copyright (c) Microsoft Corporation.
9
10 Permission to use, copy, modify, and/or distribute this software for any
11 purpose with or without fee is hereby granted.
12
13 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
14 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
15 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
16 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
17 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
18 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 PERFORMANCE OF THIS SOFTWARE.
20 ***************************************************************************** */
21 /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
22
23 var extendStatics = function(d, b) {
24 extendStatics = Object.setPrototypeOf ||
25 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
26 function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
27 return extendStatics(d, b);
28 };
29
30 function __extends(d, b) {
31 if (typeof b !== "function" && b !== null)
32 throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
33 extendStatics(d, b);
34 function __() { this.constructor = d; }
35 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
36 }
37
38 var __assign = function() {
39 __assign = Object.assign || function __assign(t) {
40 for (var s, i = 1, n = arguments.length; i < n; i++) {
41 s = arguments[i];
42 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
43 }
44 return t;
45 };
46 return __assign.apply(this, arguments);
47 };
48
49 function __rest(s, e) {
50 var t = {};
51 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
52 t[p] = s[p];
53 if (s != null && typeof Object.getOwnPropertySymbols === "function")
54 for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
55 if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
56 t[p[i]] = s[p[i]];
57 }
58 return t;
59 }
60
61 function __awaiter(thisArg, _arguments, P, generator) {
62 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
63 return new (P || (P = Promise))(function (resolve, reject) {
64 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
65 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
66 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
67 step((generator = generator.apply(thisArg, _arguments || [])).next());
68 });
69 }
70
71 function __generator(thisArg, body) {
72 var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
73 return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
74 function verb(n) { return function (v) { return step([n, v]); }; }
75 function step(op) {
76 if (f) throw new TypeError("Generator is already executing.");
77 while (g && (g = 0, op[0] && (_ = 0)), _) try {
78 if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
79 if (y = 0, t) op = [op[0] & 2, t.value];
80 switch (op[0]) {
81 case 0: case 1: t = op; break;
82 case 4: _.label++; return { value: op[1], done: false };
83 case 5: _.label++; y = op[1]; op = [0]; continue;
84 case 7: op = _.ops.pop(); _.trys.pop(); continue;
85 default:
86 if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
87 if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
88 if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
89 if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
90 if (t[2]) _.ops.pop();
91 _.trys.pop(); continue;
92 }
93 op = body.call(thisArg, _);
94 } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
95 if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
96 }
97 }
98
99 function __values(o) {
100 var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
101 if (m) return m.call(o);
102 if (o && typeof o.length === "number") return {
103 next: function () {
104 if (o && i >= o.length) o = void 0;
105 return { value: o && o[i++], done: !o };
106 }
107 };
108 throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
109 }
110
111 function __read(o, n) {
112 var m = typeof Symbol === "function" && o[Symbol.iterator];
113 if (!m) return o;
114 var i = m.call(o), r, ar = [], e;
115 try {
116 while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
117 }
118 catch (error) { e = { error: error }; }
119 finally {
120 try {
121 if (r && !r.done && (m = i["return"])) m.call(i);
122 }
123 finally { if (e) throw e.error; }
124 }
125 return ar;
126 }
127
128 function __spreadArray(to, from, pack) {
129 if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
130 if (ar || !(i in from)) {
131 if (!ar) ar = Array.prototype.slice.call(from, 0, i);
132 ar[i] = from[i];
133 }
134 }
135 return to.concat(ar || Array.prototype.slice.call(from));
136 }
137
138 var _SuppressedError = typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
139 var e = new Error(message);
140 return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
141 };
142
143 var isArrayLike = function (value) {
144 /**
145 * isArrayLike([1, 2, 3]) => true
146 * isArrayLike(document.body.children) => true
147 * isArrayLike('abc') => true
148 * isArrayLike(Function) => false
149 */
150 return value !== null && typeof value !== 'function' && isFinite(value.length);
151 };
152
153 var filter = function (arr, func) {
154 if (!isArrayLike(arr)) {
155 return arr;
156 }
157 var result = [];
158 for (var index = 0; index < arr.length; index++) {
159 var value = arr[index];
160 if (func(value, index)) {
161 result.push(value);
162 }
163 }
164 return result;
165 };
166
167 /**
168 * @see https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore#_isfunction
169 */
170 var isFunction = (function (value) {
171 return typeof value === 'function';
172 });
173
174 // isFinite,
175 var isNil = function (value) {
176 /**
177 * isNil(null) => true
178 * isNil() => true
179 */
180 return value === null || value === undefined;
181 };
182
183 var toString = {}.toString;
184 var isType = function (value, type) { return toString.call(value) === '[object ' + type + ']'; };
185
186 var isArray = (function (value) {
187 return Array.isArray ? Array.isArray(value) : isType(value, 'Array');
188 });
189
190 var isObject = (function (value) {
191 /**
192 * isObject({}) => true
193 * isObject([1, 2, 3]) => true
194 * isObject(Function) => true
195 * isObject(null) => false
196 */
197 var type = typeof value;
198 return (value !== null && type === 'object') || type === 'function';
199 });
200
201 function each(elements, func) {
202 if (!elements) {
203 return;
204 }
205 var rst;
206 if (isArray(elements)) {
207 for (var i = 0, len = elements.length; i < len; i++) {
208 rst = func(elements[i], i);
209 if (rst === false) {
210 break;
211 }
212 }
213 }
214 else if (isObject(elements)) {
215 for (var k in elements) {
216 if (elements.hasOwnProperty(k)) {
217 rst = func(elements[k], k);
218 if (rst === false) {
219 break;
220 }
221 }
222 }
223 }
224 }
225
226 var keys = Object.keys
227 ? function (obj) { return Object.keys(obj); }
228 : function (obj) {
229 var result = [];
230 each(obj, function (value, key) {
231 if (!(isFunction(obj) && key === 'prototype')) {
232 result.push(key);
233 }
234 });
235 return result;
236 };
237
238 function isMatch(obj, attrs) {
239 var _keys = keys(attrs);
240 var length = _keys.length;
241 if (isNil(obj))
242 return !length;
243 for (var i = 0; i < length; i += 1) {
244 var key = _keys[i];
245 if (attrs[key] !== obj[key] || !(key in obj)) {
246 return false;
247 }
248 }
249 return true;
250 }
251
252 var isObjectLike = function (value) {
253 /**
254 * isObjectLike({}) => true
255 * isObjectLike([1, 2, 3]) => true
256 * isObjectLike(Function) => false
257 * isObjectLike(null) => false
258 */
259 return typeof value === 'object' && value !== null;
260 };
261
262 var isPlainObject = function (value) {
263 /**
264 * isObjectLike(new Foo) => false
265 * isObjectLike([1, 2, 3]) => false
266 * isObjectLike({ x: 0, y: 0 }) => true
267 * isObjectLike(Object.create(null)) => true
268 */
269 if (!isObjectLike(value) || !isType(value, 'Object')) {
270 return false;
271 }
272 if (Object.getPrototypeOf(value) === null) {
273 return true;
274 }
275 var proto = value;
276 while (Object.getPrototypeOf(proto) !== null) {
277 proto = Object.getPrototypeOf(proto);
278 }
279 return Object.getPrototypeOf(value) === proto;
280 };
281
282 function find(arr, predicate) {
283 if (!isArray(arr))
284 return null;
285 var _predicate;
286 if (isFunction(predicate)) {
287 _predicate = predicate;
288 }
289 if (isPlainObject(predicate)) {
290 _predicate = function (a) { return isMatch(a, predicate); };
291 }
292 if (_predicate) {
293 for (var i = 0; i < arr.length; i += 1) {
294 if (_predicate(arr[i])) {
295 return arr[i];
296 }
297 }
298 }
299 return null;
300 }
301
302 function findIndex(arr, predicate, fromIndex) {
303 if (fromIndex === void 0) { fromIndex = 0; }
304 for (var i = fromIndex; i < arr.length; i++) {
305 if (predicate(arr[i], i)) {
306 // 找到终止循环
307 return i;
308 }
309 }
310 return -1;
311 }
312
313 /**
314 * Flattens `array` a single level deep.
315 *
316 * @param {Array} arr The array to flatten.
317 * @return {Array} Returns the new flattened array.
318 * @example
319 *
320 * flatten([1, [2, [3, [4]], 5]]); // => [1, 2, [3, [4]], 5]
321 */
322 var flatten = function (arr) {
323 if (!isArray(arr)) {
324 return [];
325 }
326 var rst = [];
327 for (var i = 0; i < arr.length; i++) {
328 rst = rst.concat(arr[i]);
329 }
330 return rst;
331 };
332
333 /**
334 * @param {Array} arr The array to iterate over.
335 * @return {*} Returns the maximum value.
336 * @example
337 *
338 * max([1, 2]);
339 * // => 2
340 *
341 * max([]);
342 * // => undefined
343 *
344 * const data = new Array(1250010).fill(1).map((d,idx) => idx);
345 *
346 * max(data);
347 * // => 1250010
348 * // Math.max(...data) will encounter "Maximum call stack size exceeded" error
349 */
350 var max = (function (arr) {
351 if (!isArray(arr)) {
352 return undefined;
353 }
354 return arr.reduce(function (prev, curr) {
355 return Math.max(prev, curr);
356 }, arr[0]);
357 });
358
359 /**
360 * @param {Array} arr The array to iterate over.
361 * @return {*} Returns the minimum value.
362 * @example
363 *
364 * min([1, 2]);
365 * // => 1
366 *
367 * min([]);
368 * // => undefined
369 *
370 * const data = new Array(1250010).fill(1).map((d,idx) => idx);
371 *
372 * min(data);
373 * // => 1250010
374 * // Math.min(...data) will encounter "Maximum call stack size exceeded" error
375 */
376 var min = (function (arr) {
377 if (!isArray(arr)) {
378 return undefined;
379 }
380 return arr.reduce(function (prev, curr) {
381 return Math.min(prev, curr);
382 }, arr[0]);
383 });
384
385 var getRange = function (values) {
386 // 存在 NaN 时,min,max 判定会出问题
387 var filterValues = values.filter(function (v) { return !isNaN(v); });
388 if (!filterValues.length) {
389 // 如果没有数值则直接返回0
390 return {
391 min: 0,
392 max: 0,
393 };
394 }
395 if (isArray(values[0])) {
396 var tmp = [];
397 for (var i = 0; i < values.length; i++) {
398 tmp = tmp.concat(values[i]);
399 }
400 filterValues = tmp;
401 }
402 var max$1 = max(filterValues);
403 var min$1 = min(filterValues);
404 return {
405 min: min$1,
406 max: max$1,
407 };
408 };
409
410 var reduce = function (arr, fn, init) {
411 if (!isArray(arr) && !isPlainObject(arr)) {
412 return arr;
413 }
414 var result = init;
415 each(arr, function (data, i) {
416 result = fn(result, data, i);
417 });
418 return result;
419 };
420
421 var isString = (function (str) {
422 return isType(str, 'String');
423 });
424
425 var valuesOfKey = (function (data, name) {
426 var rst = [];
427 var tmpMap = {};
428 for (var i = 0; i < data.length; i++) {
429 var obj = data[i];
430 var value = obj[name];
431 if (!isNil(value)) {
432 // flatten
433 if (!isArray(value)) {
434 value = [value];
435 }
436 for (var j = 0; j < value.length; j++) {
437 var val = value[j];
438 // unique
439 if (!tmpMap[val]) {
440 rst.push(val);
441 tmpMap[val] = true;
442 }
443 }
444 }
445 }
446 return rst;
447 });
448
449 function head(o) {
450 if (isArrayLike(o)) {
451 return o[0];
452 }
453 return undefined;
454 }
455
456 function last(o) {
457 if (isArrayLike(o)) {
458 var arr = o;
459 return arr[arr.length - 1];
460 }
461 return undefined;
462 }
463
464 var hasOwnProperty = Object.prototype.hasOwnProperty;
465 function groupBy(data, condition) {
466 if (!condition || !isArray(data)) {
467 return {};
468 }
469 var result = {};
470 // 兼容方法和 字符串的写法
471 var predicate = isFunction(condition) ? condition : function (item) { return item[condition]; };
472 var key;
473 for (var i = 0; i < data.length; i++) {
474 var item = data[i];
475 key = predicate(item);
476 if (hasOwnProperty.call(result, key)) {
477 result[key].push(item);
478 }
479 else {
480 result[key] = [item];
481 }
482 }
483 return result;
484 }
485
486 /**
487 * 将数据分组成 map
488 * @param data
489 * @param condition
490 */
491 function groupToMap(data, condition) {
492 if (!condition) {
493 return {
494 0: data,
495 };
496 }
497 if (!isFunction(condition)) {
498 // 如果是字符串,则按照 a*b 风格成数组
499 var paramscondition_1 = isArray(condition) ? condition : condition.replace(/\s+/g, '').split('*');
500 condition = function (row) {
501 var unique = '_'; // 避免出现数字作为Key的情况,会进行按照数字的排序
502 // 根据字段列表的值,拼接成 key
503 for (var i = 0, l = paramscondition_1.length; i < l; i++) {
504 unique += row[paramscondition_1[i]] && row[paramscondition_1[i]].toString();
505 }
506 return unique;
507 };
508 }
509 return groupBy(data, condition);
510 }
511
512 var group = (function (data, condition) {
513 if (!condition) {
514 // 没有条件,则自身改成数组
515 return [data];
516 }
517 var groups = groupToMap(data, condition);
518 var array = [];
519 for (var i in groups) {
520 array.push(groups[i]);
521 }
522 return array;
523 });
524
525 var clamp = function (a, min, max) {
526 if (a < min) {
527 return min;
528 }
529 else if (a > max) {
530 return max;
531 }
532 return a;
533 };
534
535 /**
536 * 判断是否数字
537 * @return {Boolean} 是否数字
538 */
539 var isNumber = function (value) {
540 return isType(value, 'Number');
541 };
542
543 var PRECISION = 0.00001; // numbers less than this is considered as 0
544 function isNumberEqual(a, b, precision) {
545 if (precision === void 0) { precision = PRECISION; }
546 return Math.abs(a - b) < precision;
547 }
548
549 var mod = function (n, m) {
550 return ((n % m) + m) % m;
551 };
552
553 var toString$1 = (function (value) {
554 if (isNil(value))
555 return '';
556 return value.toString();
557 });
558
559 var upperFirst = function (value) {
560 var str = toString$1(value);
561 return str.charAt(0).toUpperCase() + str.substring(1);
562 };
563
564 var toString$2 = {}.toString;
565 var getType = function (value) {
566 return toString$2
567 .call(value)
568 .replace(/^\[object /, '')
569 .replace(/]$/, '');
570 };
571
572 /**
573 * 是否是布尔类型
574 *
575 * @param {Object} value 测试的值
576 * @return {Boolean}
577 */
578 var isBoolean = function (value) {
579 return isType(value, 'Boolean');
580 };
581
582 var isDate = function (value) {
583 return isType(value, 'Date');
584 };
585
586 var isNull = function (value) {
587 return value === null;
588 };
589
590 var objectProto = Object.prototype;
591 var isPrototype = function (value) {
592 var Ctor = value && value.constructor;
593 var proto = (typeof Ctor === 'function' && Ctor.prototype) || objectProto;
594 return value === proto;
595 };
596
597 var isUndefined = function (value) {
598 return value === undefined;
599 };
600
601 // FIXME: Mutable param should be forbidden in static lang.
602 function _mix(dist, obj) {
603 for (var key in obj) {
604 if (obj.hasOwnProperty(key) && key !== 'constructor' && obj[key] !== undefined) {
605 dist[key] = obj[key];
606 }
607 }
608 }
609 function mix(dist, src1, src2, src3) {
610 if (src1)
611 _mix(dist, src1);
612 if (src2)
613 _mix(dist, src2);
614 if (src3)
615 _mix(dist, src3);
616 return dist;
617 }
618
619 var clone = function (obj) {
620 if (typeof obj !== 'object' || obj === null) {
621 return obj;
622 }
623 var rst;
624 if (isArray(obj)) {
625 rst = [];
626 for (var i = 0, l = obj.length; i < l; i++) {
627 if (typeof obj[i] === 'object' && obj[i] != null) {
628 rst[i] = clone(obj[i]);
629 }
630 else {
631 rst[i] = obj[i];
632 }
633 }
634 }
635 else {
636 rst = {};
637 for (var k in obj) {
638 if (typeof obj[k] === 'object' && obj[k] != null) {
639 rst[k] = clone(obj[k]);
640 }
641 else {
642 rst[k] = obj[k];
643 }
644 }
645 }
646 return rst;
647 };
648
649 var MAX_MIX_LEVEL = 5;
650 function hasOwn(object, property) {
651 if (Object.hasOwn) {
652 return Object.hasOwn(object, property);
653 }
654 if (object == null) {
655 throw new TypeError('Cannot convert undefined or null to object');
656 }
657 return Object.prototype.hasOwnProperty.call(Object(object), property);
658 }
659 function _deepMix(dist, src, level, maxLevel) {
660 level = level || 0;
661 maxLevel = maxLevel || MAX_MIX_LEVEL;
662 for (var key in src) {
663 if (hasOwn(src, key)) {
664 var value = src[key];
665 if (value !== null && isPlainObject(value)) {
666 if (!isPlainObject(dist[key])) {
667 dist[key] = {};
668 }
669 if (level < maxLevel) {
670 _deepMix(dist[key], value, level + 1, maxLevel);
671 }
672 else {
673 dist[key] = src[key];
674 }
675 }
676 else if (isArray(value)) {
677 dist[key] = [];
678 dist[key] = dist[key].concat(value);
679 }
680 else if (value !== undefined) {
681 dist[key] = value;
682 }
683 }
684 }
685 }
686 // todo 重写
687 var deepMix = function (rst) {
688 var args = [];
689 for (var _i = 1; _i < arguments.length; _i++) {
690 args[_i - 1] = arguments[_i];
691 }
692 for (var i = 0; i < args.length; i += 1) {
693 _deepMix(rst, args[i]);
694 }
695 return rst;
696 };
697
698 var hasOwnProperty$1 = Object.prototype.hasOwnProperty;
699 function isEmpty(value) {
700 /**
701 * isEmpty(null) => true
702 * isEmpty() => true
703 * isEmpty(true) => true
704 * isEmpty(1) => true
705 * isEmpty([1, 2, 3]) => false
706 * isEmpty('abc') => false
707 * isEmpty({ a: 1 }) => false
708 */
709 if (isNil(value)) {
710 return true;
711 }
712 if (isArrayLike(value)) {
713 return !value.length;
714 }
715 var type = getType(value);
716 if (type === 'Map' || type === 'Set') {
717 return !value.size;
718 }
719 if (isPrototype(value)) {
720 return !Object.keys(value).length;
721 }
722 for (var key in value) {
723 if (hasOwnProperty$1.call(value, key)) {
724 return false;
725 }
726 }
727 return true;
728 }
729
730 var isEqual = function (value, other) {
731 if (value === other) {
732 return true;
733 }
734 if (!value || !other) {
735 return false;
736 }
737 if (isString(value) || isString(other)) {
738 return false;
739 }
740 if (isArrayLike(value) || isArrayLike(other)) {
741 if (value.length !== other.length) {
742 return false;
743 }
744 var rst = true;
745 for (var i = 0; i < value.length; i++) {
746 rst = isEqual(value[i], other[i]);
747 if (!rst) {
748 break;
749 }
750 }
751 return rst;
752 }
753 if (isObjectLike(value) || isObjectLike(other)) {
754 var valueKeys = Object.keys(value);
755 var otherKeys = Object.keys(other);
756 if (valueKeys.length !== otherKeys.length) {
757 return false;
758 }
759 var rst = true;
760 for (var i = 0; i < valueKeys.length; i++) {
761 rst = isEqual(value[valueKeys[i]], other[valueKeys[i]]);
762 if (!rst) {
763 break;
764 }
765 }
766 return rst;
767 }
768 return false;
769 };
770
771 var map = function (arr, func) {
772 if (!isArrayLike(arr)) {
773 // @ts-ignore
774 return arr;
775 }
776 var result = [];
777 for (var index = 0; index < arr.length; index++) {
778 var value = arr[index];
779 result.push(func(value, index));
780 }
781 return result;
782 };
783
784 var identity = function (v) { return v; };
785 var mapValues = (function (object, func) {
786 if (func === void 0) { func = identity; }
787 var r = {};
788 if (isObject(object) && !isNil(object)) {
789 Object.keys(object).forEach(function (key) {
790 // @ts-ignore
791 r[key] = func(object[key], key);
792 });
793 }
794 return r;
795 });
796
797 /**
798 * https://github.com/developit/dlv/blob/master/index.js
799 * @param obj
800 * @param key
801 * @param defaultValue
802 */
803 var get = (function (obj, key, defaultValue) {
804 var p = 0;
805 var keyArr = isString(key) ? key.split('.') : key;
806 while (obj && p < keyArr.length) {
807 obj = obj[keyArr[p++]];
808 }
809 return obj === undefined || p < keyArr.length ? defaultValue : obj;
810 });
811
812 var hasOwnProperty$2 = Object.prototype.hasOwnProperty;
813 var pick = (function (object, keys) {
814 if (object === null || !isPlainObject(object)) {
815 return {};
816 }
817 var result = {};
818 each(keys, function (key) {
819 if (hasOwnProperty$2.call(object, key)) {
820 result[key] = object[key];
821 }
822 });
823 return result;
824 });
825
826 var omit = (function (obj, keys) {
827 return reduce(obj, function (r, curr, key) {
828 if (!keys.includes(key)) {
829 r[key] = curr;
830 }
831 return r;
832 }, {});
833 });
834
835 /**
836 * k-v 存储
837 */
838 var default_1 = /** @class */ (function () {
839 function default_1() {
840 this.map = {};
841 }
842 default_1.prototype.has = function (key) {
843 return this.map[key] !== undefined;
844 };
845 default_1.prototype.get = function (key, def) {
846 var v = this.map[key];
847 return v === undefined ? def : v;
848 };
849 default_1.prototype.set = function (key, value) {
850 this.map[key] = value;
851 };
852 default_1.prototype.clear = function () {
853 this.map = {};
854 };
855 default_1.prototype.delete = function (key) {
856 delete this.map[key];
857 };
858 default_1.prototype.size = function () {
859 return Object.keys(this.map).length;
860 };
861 return default_1;
862 }());
863
864 /**
865 * Common utilities
866 * @module glMatrix
867 */
868 // Configuration Constants
869 var EPSILON = 0.000001;
870 var ARRAY_TYPE = typeof Float32Array !== 'undefined' ? Float32Array : Array;
871 if (!Math.hypot) Math.hypot = function () {
872 var y = 0,
873 i = arguments.length;
874
875 while (i--) {
876 y += arguments[i] * arguments[i];
877 }
878
879 return Math.sqrt(y);
880 };
881
882 /**
883 * Rotates a mat2d by the given angle
884 *
885 * @param {mat2d} out the receiving matrix
886 * @param {ReadonlyMat2d} a the matrix to rotate
887 * @param {Number} rad the angle to rotate the matrix by
888 * @returns {mat2d} out
889 */
890
891 function rotate(out, a, rad) {
892 var a0 = a[0],
893 a1 = a[1],
894 a2 = a[2],
895 a3 = a[3],
896 a4 = a[4],
897 a5 = a[5];
898 var s = Math.sin(rad);
899 var c = Math.cos(rad);
900 out[0] = a0 * c + a2 * s;
901 out[1] = a1 * c + a3 * s;
902 out[2] = a0 * -s + a2 * c;
903 out[3] = a1 * -s + a3 * c;
904 out[4] = a4;
905 out[5] = a5;
906 return out;
907 }
908
909 /**
910 * 3x3 Matrix
911 * @module mat3
912 */
913
914 /**
915 * Creates a new identity mat3
916 *
917 * @returns {mat3} a new 3x3 matrix
918 */
919
920 function create() {
921 var out = new ARRAY_TYPE(9);
922
923 if (ARRAY_TYPE != Float32Array) {
924 out[1] = 0;
925 out[2] = 0;
926 out[3] = 0;
927 out[5] = 0;
928 out[6] = 0;
929 out[7] = 0;
930 }
931
932 out[0] = 1;
933 out[4] = 1;
934 out[8] = 1;
935 return out;
936 }
937 /**
938 * Copies the upper-left 3x3 values into the given mat3.
939 *
940 * @param {mat3} out the receiving 3x3 matrix
941 * @param {ReadonlyMat4} a the source 4x4 matrix
942 * @returns {mat3} out
943 */
944
945 function fromMat4(out, a) {
946 out[0] = a[0];
947 out[1] = a[1];
948 out[2] = a[2];
949 out[3] = a[4];
950 out[4] = a[5];
951 out[5] = a[6];
952 out[6] = a[8];
953 out[7] = a[9];
954 out[8] = a[10];
955 return out;
956 }
957 /**
958 * Create a new mat3 with the given values
959 *
960 * @param {Number} m00 Component in column 0, row 0 position (index 0)
961 * @param {Number} m01 Component in column 0, row 1 position (index 1)
962 * @param {Number} m02 Component in column 0, row 2 position (index 2)
963 * @param {Number} m10 Component in column 1, row 0 position (index 3)
964 * @param {Number} m11 Component in column 1, row 1 position (index 4)
965 * @param {Number} m12 Component in column 1, row 2 position (index 5)
966 * @param {Number} m20 Component in column 2, row 0 position (index 6)
967 * @param {Number} m21 Component in column 2, row 1 position (index 7)
968 * @param {Number} m22 Component in column 2, row 2 position (index 8)
969 * @returns {mat3} A new mat3
970 */
971
972 function fromValues(m00, m01, m02, m10, m11, m12, m20, m21, m22) {
973 var out = new ARRAY_TYPE(9);
974 out[0] = m00;
975 out[1] = m01;
976 out[2] = m02;
977 out[3] = m10;
978 out[4] = m11;
979 out[5] = m12;
980 out[6] = m20;
981 out[7] = m21;
982 out[8] = m22;
983 return out;
984 }
985
986 /**
987 * 4x4 Matrix<br>Format: column-major, when typed out it looks like row-major<br>The matrices are being post multiplied.
988 * @module mat4
989 */
990
991 /**
992 * Creates a new identity mat4
993 *
994 * @returns {mat4} a new 4x4 matrix
995 */
996
997 function create$1() {
998 var out = new ARRAY_TYPE(16);
999
1000 if (ARRAY_TYPE != Float32Array) {
1001 out[1] = 0;
1002 out[2] = 0;
1003 out[3] = 0;
1004 out[4] = 0;
1005 out[6] = 0;
1006 out[7] = 0;
1007 out[8] = 0;
1008 out[9] = 0;
1009 out[11] = 0;
1010 out[12] = 0;
1011 out[13] = 0;
1012 out[14] = 0;
1013 }
1014
1015 out[0] = 1;
1016 out[5] = 1;
1017 out[10] = 1;
1018 out[15] = 1;
1019 return out;
1020 }
1021 /**
1022 * Creates a new mat4 initialized with values from an existing matrix
1023 *
1024 * @param {ReadonlyMat4} a matrix to clone
1025 * @returns {mat4} a new 4x4 matrix
1026 */
1027
1028 function clone$1(a) {
1029 var out = new ARRAY_TYPE(16);
1030 out[0] = a[0];
1031 out[1] = a[1];
1032 out[2] = a[2];
1033 out[3] = a[3];
1034 out[4] = a[4];
1035 out[5] = a[5];
1036 out[6] = a[6];
1037 out[7] = a[7];
1038 out[8] = a[8];
1039 out[9] = a[9];
1040 out[10] = a[10];
1041 out[11] = a[11];
1042 out[12] = a[12];
1043 out[13] = a[13];
1044 out[14] = a[14];
1045 out[15] = a[15];
1046 return out;
1047 }
1048 /**
1049 * Copy the values from one mat4 to another
1050 *
1051 * @param {mat4} out the receiving matrix
1052 * @param {ReadonlyMat4} a the source matrix
1053 * @returns {mat4} out
1054 */
1055
1056 function copy(out, a) {
1057 out[0] = a[0];
1058 out[1] = a[1];
1059 out[2] = a[2];
1060 out[3] = a[3];
1061 out[4] = a[4];
1062 out[5] = a[5];
1063 out[6] = a[6];
1064 out[7] = a[7];
1065 out[8] = a[8];
1066 out[9] = a[9];
1067 out[10] = a[10];
1068 out[11] = a[11];
1069 out[12] = a[12];
1070 out[13] = a[13];
1071 out[14] = a[14];
1072 out[15] = a[15];
1073 return out;
1074 }
1075 /**
1076 * Create a new mat4 with the given values
1077 *
1078 * @param {Number} m00 Component in column 0, row 0 position (index 0)
1079 * @param {Number} m01 Component in column 0, row 1 position (index 1)
1080 * @param {Number} m02 Component in column 0, row 2 position (index 2)
1081 * @param {Number} m03 Component in column 0, row 3 position (index 3)
1082 * @param {Number} m10 Component in column 1, row 0 position (index 4)
1083 * @param {Number} m11 Component in column 1, row 1 position (index 5)
1084 * @param {Number} m12 Component in column 1, row 2 position (index 6)
1085 * @param {Number} m13 Component in column 1, row 3 position (index 7)
1086 * @param {Number} m20 Component in column 2, row 0 position (index 8)
1087 * @param {Number} m21 Component in column 2, row 1 position (index 9)
1088 * @param {Number} m22 Component in column 2, row 2 position (index 10)
1089 * @param {Number} m23 Component in column 2, row 3 position (index 11)
1090 * @param {Number} m30 Component in column 3, row 0 position (index 12)
1091 * @param {Number} m31 Component in column 3, row 1 position (index 13)
1092 * @param {Number} m32 Component in column 3, row 2 position (index 14)
1093 * @param {Number} m33 Component in column 3, row 3 position (index 15)
1094 * @returns {mat4} A new mat4
1095 */
1096
1097 function fromValues$1(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) {
1098 var out = new ARRAY_TYPE(16);
1099 out[0] = m00;
1100 out[1] = m01;
1101 out[2] = m02;
1102 out[3] = m03;
1103 out[4] = m10;
1104 out[5] = m11;
1105 out[6] = m12;
1106 out[7] = m13;
1107 out[8] = m20;
1108 out[9] = m21;
1109 out[10] = m22;
1110 out[11] = m23;
1111 out[12] = m30;
1112 out[13] = m31;
1113 out[14] = m32;
1114 out[15] = m33;
1115 return out;
1116 }
1117 /**
1118 * Set the components of a mat4 to the given values
1119 *
1120 * @param {mat4} out the receiving matrix
1121 * @param {Number} m00 Component in column 0, row 0 position (index 0)
1122 * @param {Number} m01 Component in column 0, row 1 position (index 1)
1123 * @param {Number} m02 Component in column 0, row 2 position (index 2)
1124 * @param {Number} m03 Component in column 0, row 3 position (index 3)
1125 * @param {Number} m10 Component in column 1, row 0 position (index 4)
1126 * @param {Number} m11 Component in column 1, row 1 position (index 5)
1127 * @param {Number} m12 Component in column 1, row 2 position (index 6)
1128 * @param {Number} m13 Component in column 1, row 3 position (index 7)
1129 * @param {Number} m20 Component in column 2, row 0 position (index 8)
1130 * @param {Number} m21 Component in column 2, row 1 position (index 9)
1131 * @param {Number} m22 Component in column 2, row 2 position (index 10)
1132 * @param {Number} m23 Component in column 2, row 3 position (index 11)
1133 * @param {Number} m30 Component in column 3, row 0 position (index 12)
1134 * @param {Number} m31 Component in column 3, row 1 position (index 13)
1135 * @param {Number} m32 Component in column 3, row 2 position (index 14)
1136 * @param {Number} m33 Component in column 3, row 3 position (index 15)
1137 * @returns {mat4} out
1138 */
1139
1140 function set(out, m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) {
1141 out[0] = m00;
1142 out[1] = m01;
1143 out[2] = m02;
1144 out[3] = m03;
1145 out[4] = m10;
1146 out[5] = m11;
1147 out[6] = m12;
1148 out[7] = m13;
1149 out[8] = m20;
1150 out[9] = m21;
1151 out[10] = m22;
1152 out[11] = m23;
1153 out[12] = m30;
1154 out[13] = m31;
1155 out[14] = m32;
1156 out[15] = m33;
1157 return out;
1158 }
1159 /**
1160 * Set a mat4 to the identity matrix
1161 *
1162 * @param {mat4} out the receiving matrix
1163 * @returns {mat4} out
1164 */
1165
1166 function identity$1(out) {
1167 out[0] = 1;
1168 out[1] = 0;
1169 out[2] = 0;
1170 out[3] = 0;
1171 out[4] = 0;
1172 out[5] = 1;
1173 out[6] = 0;
1174 out[7] = 0;
1175 out[8] = 0;
1176 out[9] = 0;
1177 out[10] = 1;
1178 out[11] = 0;
1179 out[12] = 0;
1180 out[13] = 0;
1181 out[14] = 0;
1182 out[15] = 1;
1183 return out;
1184 }
1185 /**
1186 * Transpose the values of a mat4
1187 *
1188 * @param {mat4} out the receiving matrix
1189 * @param {ReadonlyMat4} a the source matrix
1190 * @returns {mat4} out
1191 */
1192
1193 function transpose(out, a) {
1194 // If we are transposing ourselves we can skip a few steps but have to cache some values
1195 if (out === a) {
1196 var a01 = a[1],
1197 a02 = a[2],
1198 a03 = a[3];
1199 var a12 = a[6],
1200 a13 = a[7];
1201 var a23 = a[11];
1202 out[1] = a[4];
1203 out[2] = a[8];
1204 out[3] = a[12];
1205 out[4] = a01;
1206 out[6] = a[9];
1207 out[7] = a[13];
1208 out[8] = a02;
1209 out[9] = a12;
1210 out[11] = a[14];
1211 out[12] = a03;
1212 out[13] = a13;
1213 out[14] = a23;
1214 } else {
1215 out[0] = a[0];
1216 out[1] = a[4];
1217 out[2] = a[8];
1218 out[3] = a[12];
1219 out[4] = a[1];
1220 out[5] = a[5];
1221 out[6] = a[9];
1222 out[7] = a[13];
1223 out[8] = a[2];
1224 out[9] = a[6];
1225 out[10] = a[10];
1226 out[11] = a[14];
1227 out[12] = a[3];
1228 out[13] = a[7];
1229 out[14] = a[11];
1230 out[15] = a[15];
1231 }
1232
1233 return out;
1234 }
1235 /**
1236 * Inverts a mat4
1237 *
1238 * @param {mat4} out the receiving matrix
1239 * @param {ReadonlyMat4} a the source matrix
1240 * @returns {mat4} out
1241 */
1242
1243 function invert(out, a) {
1244 var a00 = a[0],
1245 a01 = a[1],
1246 a02 = a[2],
1247 a03 = a[3];
1248 var a10 = a[4],
1249 a11 = a[5],
1250 a12 = a[6],
1251 a13 = a[7];
1252 var a20 = a[8],
1253 a21 = a[9],
1254 a22 = a[10],
1255 a23 = a[11];
1256 var a30 = a[12],
1257 a31 = a[13],
1258 a32 = a[14],
1259 a33 = a[15];
1260 var b00 = a00 * a11 - a01 * a10;
1261 var b01 = a00 * a12 - a02 * a10;
1262 var b02 = a00 * a13 - a03 * a10;
1263 var b03 = a01 * a12 - a02 * a11;
1264 var b04 = a01 * a13 - a03 * a11;
1265 var b05 = a02 * a13 - a03 * a12;
1266 var b06 = a20 * a31 - a21 * a30;
1267 var b07 = a20 * a32 - a22 * a30;
1268 var b08 = a20 * a33 - a23 * a30;
1269 var b09 = a21 * a32 - a22 * a31;
1270 var b10 = a21 * a33 - a23 * a31;
1271 var b11 = a22 * a33 - a23 * a32; // Calculate the determinant
1272
1273 var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
1274
1275 if (!det) {
1276 return null;
1277 }
1278
1279 det = 1.0 / det;
1280 out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
1281 out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
1282 out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
1283 out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;
1284 out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
1285 out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
1286 out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
1287 out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;
1288 out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
1289 out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
1290 out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
1291 out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;
1292 out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;
1293 out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;
1294 out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;
1295 out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;
1296 return out;
1297 }
1298 /**
1299 * Calculates the adjugate of a mat4
1300 *
1301 * @param {mat4} out the receiving matrix
1302 * @param {ReadonlyMat4} a the source matrix
1303 * @returns {mat4} out
1304 */
1305
1306 function adjoint(out, a) {
1307 var a00 = a[0],
1308 a01 = a[1],
1309 a02 = a[2],
1310 a03 = a[3];
1311 var a10 = a[4],
1312 a11 = a[5],
1313 a12 = a[6],
1314 a13 = a[7];
1315 var a20 = a[8],
1316 a21 = a[9],
1317 a22 = a[10],
1318 a23 = a[11];
1319 var a30 = a[12],
1320 a31 = a[13],
1321 a32 = a[14],
1322 a33 = a[15];
1323 out[0] = a11 * (a22 * a33 - a23 * a32) - a21 * (a12 * a33 - a13 * a32) + a31 * (a12 * a23 - a13 * a22);
1324 out[1] = -(a01 * (a22 * a33 - a23 * a32) - a21 * (a02 * a33 - a03 * a32) + a31 * (a02 * a23 - a03 * a22));
1325 out[2] = a01 * (a12 * a33 - a13 * a32) - a11 * (a02 * a33 - a03 * a32) + a31 * (a02 * a13 - a03 * a12);
1326 out[3] = -(a01 * (a12 * a23 - a13 * a22) - a11 * (a02 * a23 - a03 * a22) + a21 * (a02 * a13 - a03 * a12));
1327 out[4] = -(a10 * (a22 * a33 - a23 * a32) - a20 * (a12 * a33 - a13 * a32) + a30 * (a12 * a23 - a13 * a22));
1328 out[5] = a00 * (a22 * a33 - a23 * a32) - a20 * (a02 * a33 - a03 * a32) + a30 * (a02 * a23 - a03 * a22);
1329 out[6] = -(a00 * (a12 * a33 - a13 * a32) - a10 * (a02 * a33 - a03 * a32) + a30 * (a02 * a13 - a03 * a12));
1330 out[7] = a00 * (a12 * a23 - a13 * a22) - a10 * (a02 * a23 - a03 * a22) + a20 * (a02 * a13 - a03 * a12);
1331 out[8] = a10 * (a21 * a33 - a23 * a31) - a20 * (a11 * a33 - a13 * a31) + a30 * (a11 * a23 - a13 * a21);
1332 out[9] = -(a00 * (a21 * a33 - a23 * a31) - a20 * (a01 * a33 - a03 * a31) + a30 * (a01 * a23 - a03 * a21));
1333 out[10] = a00 * (a11 * a33 - a13 * a31) - a10 * (a01 * a33 - a03 * a31) + a30 * (a01 * a13 - a03 * a11);
1334 out[11] = -(a00 * (a11 * a23 - a13 * a21) - a10 * (a01 * a23 - a03 * a21) + a20 * (a01 * a13 - a03 * a11));
1335 out[12] = -(a10 * (a21 * a32 - a22 * a31) - a20 * (a11 * a32 - a12 * a31) + a30 * (a11 * a22 - a12 * a21));
1336 out[13] = a00 * (a21 * a32 - a22 * a31) - a20 * (a01 * a32 - a02 * a31) + a30 * (a01 * a22 - a02 * a21);
1337 out[14] = -(a00 * (a11 * a32 - a12 * a31) - a10 * (a01 * a32 - a02 * a31) + a30 * (a01 * a12 - a02 * a11));
1338 out[15] = a00 * (a11 * a22 - a12 * a21) - a10 * (a01 * a22 - a02 * a21) + a20 * (a01 * a12 - a02 * a11);
1339 return out;
1340 }
1341 /**
1342 * Calculates the determinant of a mat4
1343 *
1344 * @param {ReadonlyMat4} a the source matrix
1345 * @returns {Number} determinant of a
1346 */
1347
1348 function determinant(a) {
1349 var a00 = a[0],
1350 a01 = a[1],
1351 a02 = a[2],
1352 a03 = a[3];
1353 var a10 = a[4],
1354 a11 = a[5],
1355 a12 = a[6],
1356 a13 = a[7];
1357 var a20 = a[8],
1358 a21 = a[9],
1359 a22 = a[10],
1360 a23 = a[11];
1361 var a30 = a[12],
1362 a31 = a[13],
1363 a32 = a[14],
1364 a33 = a[15];
1365 var b00 = a00 * a11 - a01 * a10;
1366 var b01 = a00 * a12 - a02 * a10;
1367 var b02 = a00 * a13 - a03 * a10;
1368 var b03 = a01 * a12 - a02 * a11;
1369 var b04 = a01 * a13 - a03 * a11;
1370 var b05 = a02 * a13 - a03 * a12;
1371 var b06 = a20 * a31 - a21 * a30;
1372 var b07 = a20 * a32 - a22 * a30;
1373 var b08 = a20 * a33 - a23 * a30;
1374 var b09 = a21 * a32 - a22 * a31;
1375 var b10 = a21 * a33 - a23 * a31;
1376 var b11 = a22 * a33 - a23 * a32; // Calculate the determinant
1377
1378 return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
1379 }
1380 /**
1381 * Multiplies two mat4s
1382 *
1383 * @param {mat4} out the receiving matrix
1384 * @param {ReadonlyMat4} a the first operand
1385 * @param {ReadonlyMat4} b the second operand
1386 * @returns {mat4} out
1387 */
1388
1389 function multiply(out, a, b) {
1390 var a00 = a[0],
1391 a01 = a[1],
1392 a02 = a[2],
1393 a03 = a[3];
1394 var a10 = a[4],
1395 a11 = a[5],
1396 a12 = a[6],
1397 a13 = a[7];
1398 var a20 = a[8],
1399 a21 = a[9],
1400 a22 = a[10],
1401 a23 = a[11];
1402 var a30 = a[12],
1403 a31 = a[13],
1404 a32 = a[14],
1405 a33 = a[15]; // Cache only the current line of the second matrix
1406
1407 var b0 = b[0],
1408 b1 = b[1],
1409 b2 = b[2],
1410 b3 = b[3];
1411 out[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
1412 out[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
1413 out[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
1414 out[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
1415 b0 = b[4];
1416 b1 = b[5];
1417 b2 = b[6];
1418 b3 = b[7];
1419 out[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
1420 out[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
1421 out[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
1422 out[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
1423 b0 = b[8];
1424 b1 = b[9];
1425 b2 = b[10];
1426 b3 = b[11];
1427 out[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
1428 out[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
1429 out[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
1430 out[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
1431 b0 = b[12];
1432 b1 = b[13];
1433 b2 = b[14];
1434 b3 = b[15];
1435 out[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
1436 out[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
1437 out[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
1438 out[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
1439 return out;
1440 }
1441 /**
1442 * Translate a mat4 by the given vector
1443 *
1444 * @param {mat4} out the receiving matrix
1445 * @param {ReadonlyMat4} a the matrix to translate
1446 * @param {ReadonlyVec3} v vector to translate by
1447 * @returns {mat4} out
1448 */
1449
1450 function translate(out, a, v) {
1451 var x = v[0],
1452 y = v[1],
1453 z = v[2];
1454 var a00, a01, a02, a03;
1455 var a10, a11, a12, a13;
1456 var a20, a21, a22, a23;
1457
1458 if (a === out) {
1459 out[12] = a[0] * x + a[4] * y + a[8] * z + a[12];
1460 out[13] = a[1] * x + a[5] * y + a[9] * z + a[13];
1461 out[14] = a[2] * x + a[6] * y + a[10] * z + a[14];
1462 out[15] = a[3] * x + a[7] * y + a[11] * z + a[15];
1463 } else {
1464 a00 = a[0];
1465 a01 = a[1];
1466 a02 = a[2];
1467 a03 = a[3];
1468 a10 = a[4];
1469 a11 = a[5];
1470 a12 = a[6];
1471 a13 = a[7];
1472 a20 = a[8];
1473 a21 = a[9];
1474 a22 = a[10];
1475 a23 = a[11];
1476 out[0] = a00;
1477 out[1] = a01;
1478 out[2] = a02;
1479 out[3] = a03;
1480 out[4] = a10;
1481 out[5] = a11;
1482 out[6] = a12;
1483 out[7] = a13;
1484 out[8] = a20;
1485 out[9] = a21;
1486 out[10] = a22;
1487 out[11] = a23;
1488 out[12] = a00 * x + a10 * y + a20 * z + a[12];
1489 out[13] = a01 * x + a11 * y + a21 * z + a[13];
1490 out[14] = a02 * x + a12 * y + a22 * z + a[14];
1491 out[15] = a03 * x + a13 * y + a23 * z + a[15];
1492 }
1493
1494 return out;
1495 }
1496 /**
1497 * Scales the mat4 by the dimensions in the given vec3 not using vectorization
1498 *
1499 * @param {mat4} out the receiving matrix
1500 * @param {ReadonlyMat4} a the matrix to scale
1501 * @param {ReadonlyVec3} v the vec3 to scale the matrix by
1502 * @returns {mat4} out
1503 **/
1504
1505 function scale(out, a, v) {
1506 var x = v[0],
1507 y = v[1],
1508 z = v[2];
1509 out[0] = a[0] * x;
1510 out[1] = a[1] * x;
1511 out[2] = a[2] * x;
1512 out[3] = a[3] * x;
1513 out[4] = a[4] * y;
1514 out[5] = a[5] * y;
1515 out[6] = a[6] * y;
1516 out[7] = a[7] * y;
1517 out[8] = a[8] * z;
1518 out[9] = a[9] * z;
1519 out[10] = a[10] * z;
1520 out[11] = a[11] * z;
1521 out[12] = a[12];
1522 out[13] = a[13];
1523 out[14] = a[14];
1524 out[15] = a[15];
1525 return out;
1526 }
1527 /**
1528 * Rotates a mat4 by the given angle around the given axis
1529 *
1530 * @param {mat4} out the receiving matrix
1531 * @param {ReadonlyMat4} a the matrix to rotate
1532 * @param {Number} rad the angle to rotate the matrix by
1533 * @param {ReadonlyVec3} axis the axis to rotate around
1534 * @returns {mat4} out
1535 */
1536
1537 function rotate$1(out, a, rad, axis) {
1538 var x = axis[0],
1539 y = axis[1],
1540 z = axis[2];
1541 var len = Math.hypot(x, y, z);
1542 var s, c, t;
1543 var a00, a01, a02, a03;
1544 var a10, a11, a12, a13;
1545 var a20, a21, a22, a23;
1546 var b00, b01, b02;
1547 var b10, b11, b12;
1548 var b20, b21, b22;
1549
1550 if (len < EPSILON) {
1551 return null;
1552 }
1553
1554 len = 1 / len;
1555 x *= len;
1556 y *= len;
1557 z *= len;
1558 s = Math.sin(rad);
1559 c = Math.cos(rad);
1560 t = 1 - c;
1561 a00 = a[0];
1562 a01 = a[1];
1563 a02 = a[2];
1564 a03 = a[3];
1565 a10 = a[4];
1566 a11 = a[5];
1567 a12 = a[6];
1568 a13 = a[7];
1569 a20 = a[8];
1570 a21 = a[9];
1571 a22 = a[10];
1572 a23 = a[11]; // Construct the elements of the rotation matrix
1573
1574 b00 = x * x * t + c;
1575 b01 = y * x * t + z * s;
1576 b02 = z * x * t - y * s;
1577 b10 = x * y * t - z * s;
1578 b11 = y * y * t + c;
1579 b12 = z * y * t + x * s;
1580 b20 = x * z * t + y * s;
1581 b21 = y * z * t - x * s;
1582 b22 = z * z * t + c; // Perform rotation-specific matrix multiplication
1583
1584 out[0] = a00 * b00 + a10 * b01 + a20 * b02;
1585 out[1] = a01 * b00 + a11 * b01 + a21 * b02;
1586 out[2] = a02 * b00 + a12 * b01 + a22 * b02;
1587 out[3] = a03 * b00 + a13 * b01 + a23 * b02;
1588 out[4] = a00 * b10 + a10 * b11 + a20 * b12;
1589 out[5] = a01 * b10 + a11 * b11 + a21 * b12;
1590 out[6] = a02 * b10 + a12 * b11 + a22 * b12;
1591 out[7] = a03 * b10 + a13 * b11 + a23 * b12;
1592 out[8] = a00 * b20 + a10 * b21 + a20 * b22;
1593 out[9] = a01 * b20 + a11 * b21 + a21 * b22;
1594 out[10] = a02 * b20 + a12 * b21 + a22 * b22;
1595 out[11] = a03 * b20 + a13 * b21 + a23 * b22;
1596
1597 if (a !== out) {
1598 // If the source and destination differ, copy the unchanged last row
1599 out[12] = a[12];
1600 out[13] = a[13];
1601 out[14] = a[14];
1602 out[15] = a[15];
1603 }
1604
1605 return out;
1606 }
1607 /**
1608 * Rotates a matrix by the given angle around the X axis
1609 *
1610 * @param {mat4} out the receiving matrix
1611 * @param {ReadonlyMat4} a the matrix to rotate
1612 * @param {Number} rad the angle to rotate the matrix by
1613 * @returns {mat4} out
1614 */
1615
1616 function rotateX(out, a, rad) {
1617 var s = Math.sin(rad);
1618 var c = Math.cos(rad);
1619 var a10 = a[4];
1620 var a11 = a[5];
1621 var a12 = a[6];
1622 var a13 = a[7];
1623 var a20 = a[8];
1624 var a21 = a[9];
1625 var a22 = a[10];
1626 var a23 = a[11];
1627
1628 if (a !== out) {
1629 // If the source and destination differ, copy the unchanged rows
1630 out[0] = a[0];
1631 out[1] = a[1];
1632 out[2] = a[2];
1633 out[3] = a[3];
1634 out[12] = a[12];
1635 out[13] = a[13];
1636 out[14] = a[14];
1637 out[15] = a[15];
1638 } // Perform axis-specific matrix multiplication
1639
1640
1641 out[4] = a10 * c + a20 * s;
1642 out[5] = a11 * c + a21 * s;
1643 out[6] = a12 * c + a22 * s;
1644 out[7] = a13 * c + a23 * s;
1645 out[8] = a20 * c - a10 * s;
1646 out[9] = a21 * c - a11 * s;
1647 out[10] = a22 * c - a12 * s;
1648 out[11] = a23 * c - a13 * s;
1649 return out;
1650 }
1651 /**
1652 * Rotates a matrix by the given angle around the Y axis
1653 *
1654 * @param {mat4} out the receiving matrix
1655 * @param {ReadonlyMat4} a the matrix to rotate
1656 * @param {Number} rad the angle to rotate the matrix by
1657 * @returns {mat4} out
1658 */
1659
1660 function rotateY(out, a, rad) {
1661 var s = Math.sin(rad);
1662 var c = Math.cos(rad);
1663 var a00 = a[0];
1664 var a01 = a[1];
1665 var a02 = a[2];
1666 var a03 = a[3];
1667 var a20 = a[8];
1668 var a21 = a[9];
1669 var a22 = a[10];
1670 var a23 = a[11];
1671
1672 if (a !== out) {
1673 // If the source and destination differ, copy the unchanged rows
1674 out[4] = a[4];
1675 out[5] = a[5];
1676 out[6] = a[6];
1677 out[7] = a[7];
1678 out[12] = a[12];
1679 out[13] = a[13];
1680 out[14] = a[14];
1681 out[15] = a[15];
1682 } // Perform axis-specific matrix multiplication
1683
1684
1685 out[0] = a00 * c - a20 * s;
1686 out[1] = a01 * c - a21 * s;
1687 out[2] = a02 * c - a22 * s;
1688 out[3] = a03 * c - a23 * s;
1689 out[8] = a00 * s + a20 * c;
1690 out[9] = a01 * s + a21 * c;
1691 out[10] = a02 * s + a22 * c;
1692 out[11] = a03 * s + a23 * c;
1693 return out;
1694 }
1695 /**
1696 * Rotates a matrix by the given angle around the Z axis
1697 *
1698 * @param {mat4} out the receiving matrix
1699 * @param {ReadonlyMat4} a the matrix to rotate
1700 * @param {Number} rad the angle to rotate the matrix by
1701 * @returns {mat4} out
1702 */
1703
1704 function rotateZ(out, a, rad) {
1705 var s = Math.sin(rad);
1706 var c = Math.cos(rad);
1707 var a00 = a[0];
1708 var a01 = a[1];
1709 var a02 = a[2];
1710 var a03 = a[3];
1711 var a10 = a[4];
1712 var a11 = a[5];
1713 var a12 = a[6];
1714 var a13 = a[7];
1715
1716 if (a !== out) {
1717 // If the source and destination differ, copy the unchanged last row
1718 out[8] = a[8];
1719 out[9] = a[9];
1720 out[10] = a[10];
1721 out[11] = a[11];
1722 out[12] = a[12];
1723 out[13] = a[13];
1724 out[14] = a[14];
1725 out[15] = a[15];
1726 } // Perform axis-specific matrix multiplication
1727
1728
1729 out[0] = a00 * c + a10 * s;
1730 out[1] = a01 * c + a11 * s;
1731 out[2] = a02 * c + a12 * s;
1732 out[3] = a03 * c + a13 * s;
1733 out[4] = a10 * c - a00 * s;
1734 out[5] = a11 * c - a01 * s;
1735 out[6] = a12 * c - a02 * s;
1736 out[7] = a13 * c - a03 * s;
1737 return out;
1738 }
1739 /**
1740 * Creates a matrix from a vector translation
1741 * This is equivalent to (but much faster than):
1742 *
1743 * mat4.identity(dest);
1744 * mat4.translate(dest, dest, vec);
1745 *
1746 * @param {mat4} out mat4 receiving operation result
1747 * @param {ReadonlyVec3} v Translation vector
1748 * @returns {mat4} out
1749 */
1750
1751 function fromTranslation(out, v) {
1752 out[0] = 1;
1753 out[1] = 0;
1754 out[2] = 0;
1755 out[3] = 0;
1756 out[4] = 0;
1757 out[5] = 1;
1758 out[6] = 0;
1759 out[7] = 0;
1760 out[8] = 0;
1761 out[9] = 0;
1762 out[10] = 1;
1763 out[11] = 0;
1764 out[12] = v[0];
1765 out[13] = v[1];
1766 out[14] = v[2];
1767 out[15] = 1;
1768 return out;
1769 }
1770 /**
1771 * Creates a matrix from a vector scaling
1772 * This is equivalent to (but much faster than):
1773 *
1774 * mat4.identity(dest);
1775 * mat4.scale(dest, dest, vec);
1776 *
1777 * @param {mat4} out mat4 receiving operation result
1778 * @param {ReadonlyVec3} v Scaling vector
1779 * @returns {mat4} out
1780 */
1781
1782 function fromScaling(out, v) {
1783 out[0] = v[0];
1784 out[1] = 0;
1785 out[2] = 0;
1786 out[3] = 0;
1787 out[4] = 0;
1788 out[5] = v[1];
1789 out[6] = 0;
1790 out[7] = 0;
1791 out[8] = 0;
1792 out[9] = 0;
1793 out[10] = v[2];
1794 out[11] = 0;
1795 out[12] = 0;
1796 out[13] = 0;
1797 out[14] = 0;
1798 out[15] = 1;
1799 return out;
1800 }
1801 /**
1802 * Creates a matrix from a given angle around a given axis
1803 * This is equivalent to (but much faster than):
1804 *
1805 * mat4.identity(dest);
1806 * mat4.rotate(dest, dest, rad, axis);
1807 *
1808 * @param {mat4} out mat4 receiving operation result
1809 * @param {Number} rad the angle to rotate the matrix by
1810 * @param {ReadonlyVec3} axis the axis to rotate around
1811 * @returns {mat4} out
1812 */
1813
1814 function fromRotation(out, rad, axis) {
1815 var x = axis[0],
1816 y = axis[1],
1817 z = axis[2];
1818 var len = Math.hypot(x, y, z);
1819 var s, c, t;
1820
1821 if (len < EPSILON) {
1822 return null;
1823 }
1824
1825 len = 1 / len;
1826 x *= len;
1827 y *= len;
1828 z *= len;
1829 s = Math.sin(rad);
1830 c = Math.cos(rad);
1831 t = 1 - c; // Perform rotation-specific matrix multiplication
1832
1833 out[0] = x * x * t + c;
1834 out[1] = y * x * t + z * s;
1835 out[2] = z * x * t - y * s;
1836 out[3] = 0;
1837 out[4] = x * y * t - z * s;
1838 out[5] = y * y * t + c;
1839 out[6] = z * y * t + x * s;
1840 out[7] = 0;
1841 out[8] = x * z * t + y * s;
1842 out[9] = y * z * t - x * s;
1843 out[10] = z * z * t + c;
1844 out[11] = 0;
1845 out[12] = 0;
1846 out[13] = 0;
1847 out[14] = 0;
1848 out[15] = 1;
1849 return out;
1850 }
1851 /**
1852 * Creates a matrix from the given angle around the X axis
1853 * This is equivalent to (but much faster than):
1854 *
1855 * mat4.identity(dest);
1856 * mat4.rotateX(dest, dest, rad);
1857 *
1858 * @param {mat4} out mat4 receiving operation result
1859 * @param {Number} rad the angle to rotate the matrix by
1860 * @returns {mat4} out
1861 */
1862
1863 function fromXRotation(out, rad) {
1864 var s = Math.sin(rad);
1865 var c = Math.cos(rad); // Perform axis-specific matrix multiplication
1866
1867 out[0] = 1;
1868 out[1] = 0;
1869 out[2] = 0;
1870 out[3] = 0;
1871 out[4] = 0;
1872 out[5] = c;
1873 out[6] = s;
1874 out[7] = 0;
1875 out[8] = 0;
1876 out[9] = -s;
1877 out[10] = c;
1878 out[11] = 0;
1879 out[12] = 0;
1880 out[13] = 0;
1881 out[14] = 0;
1882 out[15] = 1;
1883 return out;
1884 }
1885 /**
1886 * Creates a matrix from the given angle around the Y axis
1887 * This is equivalent to (but much faster than):
1888 *
1889 * mat4.identity(dest);
1890 * mat4.rotateY(dest, dest, rad);
1891 *
1892 * @param {mat4} out mat4 receiving operation result
1893 * @param {Number} rad the angle to rotate the matrix by
1894 * @returns {mat4} out
1895 */
1896
1897 function fromYRotation(out, rad) {
1898 var s = Math.sin(rad);
1899 var c = Math.cos(rad); // Perform axis-specific matrix multiplication
1900
1901 out[0] = c;
1902 out[1] = 0;
1903 out[2] = -s;
1904 out[3] = 0;
1905 out[4] = 0;
1906 out[5] = 1;
1907 out[6] = 0;
1908 out[7] = 0;
1909 out[8] = s;
1910 out[9] = 0;
1911 out[10] = c;
1912 out[11] = 0;
1913 out[12] = 0;
1914 out[13] = 0;
1915 out[14] = 0;
1916 out[15] = 1;
1917 return out;
1918 }
1919 /**
1920 * Creates a matrix from the given angle around the Z axis
1921 * This is equivalent to (but much faster than):
1922 *
1923 * mat4.identity(dest);
1924 * mat4.rotateZ(dest, dest, rad);
1925 *
1926 * @param {mat4} out mat4 receiving operation result
1927 * @param {Number} rad the angle to rotate the matrix by
1928 * @returns {mat4} out
1929 */
1930
1931 function fromZRotation(out, rad) {
1932 var s = Math.sin(rad);
1933 var c = Math.cos(rad); // Perform axis-specific matrix multiplication
1934
1935 out[0] = c;
1936 out[1] = s;
1937 out[2] = 0;
1938 out[3] = 0;
1939 out[4] = -s;
1940 out[5] = c;
1941 out[6] = 0;
1942 out[7] = 0;
1943 out[8] = 0;
1944 out[9] = 0;
1945 out[10] = 1;
1946 out[11] = 0;
1947 out[12] = 0;
1948 out[13] = 0;
1949 out[14] = 0;
1950 out[15] = 1;
1951 return out;
1952 }
1953 /**
1954 * Creates a matrix from a quaternion rotation and vector translation
1955 * This is equivalent to (but much faster than):
1956 *
1957 * mat4.identity(dest);
1958 * mat4.translate(dest, vec);
1959 * let quatMat = mat4.create();
1960 * quat4.toMat4(quat, quatMat);
1961 * mat4.multiply(dest, quatMat);
1962 *
1963 * @param {mat4} out mat4 receiving operation result
1964 * @param {quat4} q Rotation quaternion
1965 * @param {ReadonlyVec3} v Translation vector
1966 * @returns {mat4} out
1967 */
1968
1969 function fromRotationTranslation(out, q, v) {
1970 // Quaternion math
1971 var x = q[0],
1972 y = q[1],
1973 z = q[2],
1974 w = q[3];
1975 var x2 = x + x;
1976 var y2 = y + y;
1977 var z2 = z + z;
1978 var xx = x * x2;
1979 var xy = x * y2;
1980 var xz = x * z2;
1981 var yy = y * y2;
1982 var yz = y * z2;
1983 var zz = z * z2;
1984 var wx = w * x2;
1985 var wy = w * y2;
1986 var wz = w * z2;
1987 out[0] = 1 - (yy + zz);
1988 out[1] = xy + wz;
1989 out[2] = xz - wy;
1990 out[3] = 0;
1991 out[4] = xy - wz;
1992 out[5] = 1 - (xx + zz);
1993 out[6] = yz + wx;
1994 out[7] = 0;
1995 out[8] = xz + wy;
1996 out[9] = yz - wx;
1997 out[10] = 1 - (xx + yy);
1998 out[11] = 0;
1999 out[12] = v[0];
2000 out[13] = v[1];
2001 out[14] = v[2];
2002 out[15] = 1;
2003 return out;
2004 }
2005 /**
2006 * Creates a new mat4 from a dual quat.
2007 *
2008 * @param {mat4} out Matrix
2009 * @param {ReadonlyQuat2} a Dual Quaternion
2010 * @returns {mat4} mat4 receiving operation result
2011 */
2012
2013 function fromQuat2(out, a) {
2014 var translation = new ARRAY_TYPE(3);
2015 var bx = -a[0],
2016 by = -a[1],
2017 bz = -a[2],
2018 bw = a[3],
2019 ax = a[4],
2020 ay = a[5],
2021 az = a[6],
2022 aw = a[7];
2023 var magnitude = bx * bx + by * by + bz * bz + bw * bw; //Only scale if it makes sense
2024
2025 if (magnitude > 0) {
2026 translation[0] = (ax * bw + aw * bx + ay * bz - az * by) * 2 / magnitude;
2027 translation[1] = (ay * bw + aw * by + az * bx - ax * bz) * 2 / magnitude;
2028 translation[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2 / magnitude;
2029 } else {
2030 translation[0] = (ax * bw + aw * bx + ay * bz - az * by) * 2;
2031 translation[1] = (ay * bw + aw * by + az * bx - ax * bz) * 2;
2032 translation[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2;
2033 }
2034
2035 fromRotationTranslation(out, a, translation);
2036 return out;
2037 }
2038 /**
2039 * Returns the translation vector component of a transformation
2040 * matrix. If a matrix is built with fromRotationTranslation,
2041 * the returned vector will be the same as the translation vector
2042 * originally supplied.
2043 * @param {vec3} out Vector to receive translation component
2044 * @param {ReadonlyMat4} mat Matrix to be decomposed (input)
2045 * @return {vec3} out
2046 */
2047
2048 function getTranslation(out, mat) {
2049 out[0] = mat[12];
2050 out[1] = mat[13];
2051 out[2] = mat[14];
2052 return out;
2053 }
2054 /**
2055 * Returns the scaling factor component of a transformation
2056 * matrix. If a matrix is built with fromRotationTranslationScale
2057 * with a normalized Quaternion paramter, the returned vector will be
2058 * the same as the scaling vector
2059 * originally supplied.
2060 * @param {vec3} out Vector to receive scaling factor component
2061 * @param {ReadonlyMat4} mat Matrix to be decomposed (input)
2062 * @return {vec3} out
2063 */
2064
2065 function getScaling(out, mat) {
2066 var m11 = mat[0];
2067 var m12 = mat[1];
2068 var m13 = mat[2];
2069 var m21 = mat[4];
2070 var m22 = mat[5];
2071 var m23 = mat[6];
2072 var m31 = mat[8];
2073 var m32 = mat[9];
2074 var m33 = mat[10];
2075 out[0] = Math.hypot(m11, m12, m13);
2076 out[1] = Math.hypot(m21, m22, m23);
2077 out[2] = Math.hypot(m31, m32, m33);
2078 return out;
2079 }
2080 /**
2081 * Returns a quaternion representing the rotational component
2082 * of a transformation matrix. If a matrix is built with
2083 * fromRotationTranslation, the returned quaternion will be the
2084 * same as the quaternion originally supplied.
2085 * @param {quat} out Quaternion to receive the rotation component
2086 * @param {ReadonlyMat4} mat Matrix to be decomposed (input)
2087 * @return {quat} out
2088 */
2089
2090 function getRotation(out, mat) {
2091 var scaling = new ARRAY_TYPE(3);
2092 getScaling(scaling, mat);
2093 var is1 = 1 / scaling[0];
2094 var is2 = 1 / scaling[1];
2095 var is3 = 1 / scaling[2];
2096 var sm11 = mat[0] * is1;
2097 var sm12 = mat[1] * is2;
2098 var sm13 = mat[2] * is3;
2099 var sm21 = mat[4] * is1;
2100 var sm22 = mat[5] * is2;
2101 var sm23 = mat[6] * is3;
2102 var sm31 = mat[8] * is1;
2103 var sm32 = mat[9] * is2;
2104 var sm33 = mat[10] * is3;
2105 var trace = sm11 + sm22 + sm33;
2106 var S = 0;
2107
2108 if (trace > 0) {
2109 S = Math.sqrt(trace + 1.0) * 2;
2110 out[3] = 0.25 * S;
2111 out[0] = (sm23 - sm32) / S;
2112 out[1] = (sm31 - sm13) / S;
2113 out[2] = (sm12 - sm21) / S;
2114 } else if (sm11 > sm22 && sm11 > sm33) {
2115 S = Math.sqrt(1.0 + sm11 - sm22 - sm33) * 2;
2116 out[3] = (sm23 - sm32) / S;
2117 out[0] = 0.25 * S;
2118 out[1] = (sm12 + sm21) / S;
2119 out[2] = (sm31 + sm13) / S;
2120 } else if (sm22 > sm33) {
2121 S = Math.sqrt(1.0 + sm22 - sm11 - sm33) * 2;
2122 out[3] = (sm31 - sm13) / S;
2123 out[0] = (sm12 + sm21) / S;
2124 out[1] = 0.25 * S;
2125 out[2] = (sm23 + sm32) / S;
2126 } else {
2127 S = Math.sqrt(1.0 + sm33 - sm11 - sm22) * 2;
2128 out[3] = (sm12 - sm21) / S;
2129 out[0] = (sm31 + sm13) / S;
2130 out[1] = (sm23 + sm32) / S;
2131 out[2] = 0.25 * S;
2132 }
2133
2134 return out;
2135 }
2136 /**
2137 * Creates a matrix from a quaternion rotation, vector translation and vector scale
2138 * This is equivalent to (but much faster than):
2139 *
2140 * mat4.identity(dest);
2141 * mat4.translate(dest, vec);
2142 * let quatMat = mat4.create();
2143 * quat4.toMat4(quat, quatMat);
2144 * mat4.multiply(dest, quatMat);
2145 * mat4.scale(dest, scale)
2146 *
2147 * @param {mat4} out mat4 receiving operation result
2148 * @param {quat4} q Rotation quaternion
2149 * @param {ReadonlyVec3} v Translation vector
2150 * @param {ReadonlyVec3} s Scaling vector
2151 * @returns {mat4} out
2152 */
2153
2154 function fromRotationTranslationScale(out, q, v, s) {
2155 // Quaternion math
2156 var x = q[0],
2157 y = q[1],
2158 z = q[2],
2159 w = q[3];
2160 var x2 = x + x;
2161 var y2 = y + y;
2162 var z2 = z + z;
2163 var xx = x * x2;
2164 var xy = x * y2;
2165 var xz = x * z2;
2166 var yy = y * y2;
2167 var yz = y * z2;
2168 var zz = z * z2;
2169 var wx = w * x2;
2170 var wy = w * y2;
2171 var wz = w * z2;
2172 var sx = s[0];
2173 var sy = s[1];
2174 var sz = s[2];
2175 out[0] = (1 - (yy + zz)) * sx;
2176 out[1] = (xy + wz) * sx;
2177 out[2] = (xz - wy) * sx;
2178 out[3] = 0;
2179 out[4] = (xy - wz) * sy;
2180 out[5] = (1 - (xx + zz)) * sy;
2181 out[6] = (yz + wx) * sy;
2182 out[7] = 0;
2183 out[8] = (xz + wy) * sz;
2184 out[9] = (yz - wx) * sz;
2185 out[10] = (1 - (xx + yy)) * sz;
2186 out[11] = 0;
2187 out[12] = v[0];
2188 out[13] = v[1];
2189 out[14] = v[2];
2190 out[15] = 1;
2191 return out;
2192 }
2193 /**
2194 * Creates a matrix from a quaternion rotation, vector translation and vector scale, rotating and scaling around the given origin
2195 * This is equivalent to (but much faster than):
2196 *
2197 * mat4.identity(dest);
2198 * mat4.translate(dest, vec);
2199 * mat4.translate(dest, origin);
2200 * let quatMat = mat4.create();
2201 * quat4.toMat4(quat, quatMat);
2202 * mat4.multiply(dest, quatMat);
2203 * mat4.scale(dest, scale)
2204 * mat4.translate(dest, negativeOrigin);
2205 *
2206 * @param {mat4} out mat4 receiving operation result
2207 * @param {quat4} q Rotation quaternion
2208 * @param {ReadonlyVec3} v Translation vector
2209 * @param {ReadonlyVec3} s Scaling vector
2210 * @param {ReadonlyVec3} o The origin vector around which to scale and rotate
2211 * @returns {mat4} out
2212 */
2213
2214 function fromRotationTranslationScaleOrigin(out, q, v, s, o) {
2215 // Quaternion math
2216 var x = q[0],
2217 y = q[1],
2218 z = q[2],
2219 w = q[3];
2220 var x2 = x + x;
2221 var y2 = y + y;
2222 var z2 = z + z;
2223 var xx = x * x2;
2224 var xy = x * y2;
2225 var xz = x * z2;
2226 var yy = y * y2;
2227 var yz = y * z2;
2228 var zz = z * z2;
2229 var wx = w * x2;
2230 var wy = w * y2;
2231 var wz = w * z2;
2232 var sx = s[0];
2233 var sy = s[1];
2234 var sz = s[2];
2235 var ox = o[0];
2236 var oy = o[1];
2237 var oz = o[2];
2238 var out0 = (1 - (yy + zz)) * sx;
2239 var out1 = (xy + wz) * sx;
2240 var out2 = (xz - wy) * sx;
2241 var out4 = (xy - wz) * sy;
2242 var out5 = (1 - (xx + zz)) * sy;
2243 var out6 = (yz + wx) * sy;
2244 var out8 = (xz + wy) * sz;
2245 var out9 = (yz - wx) * sz;
2246 var out10 = (1 - (xx + yy)) * sz;
2247 out[0] = out0;
2248 out[1] = out1;
2249 out[2] = out2;
2250 out[3] = 0;
2251 out[4] = out4;
2252 out[5] = out5;
2253 out[6] = out6;
2254 out[7] = 0;
2255 out[8] = out8;
2256 out[9] = out9;
2257 out[10] = out10;
2258 out[11] = 0;
2259 out[12] = v[0] + ox - (out0 * ox + out4 * oy + out8 * oz);
2260 out[13] = v[1] + oy - (out1 * ox + out5 * oy + out9 * oz);
2261 out[14] = v[2] + oz - (out2 * ox + out6 * oy + out10 * oz);
2262 out[15] = 1;
2263 return out;
2264 }
2265 /**
2266 * Calculates a 4x4 matrix from the given quaternion
2267 *
2268 * @param {mat4} out mat4 receiving operation result
2269 * @param {ReadonlyQuat} q Quaternion to create matrix from
2270 *
2271 * @returns {mat4} out
2272 */
2273
2274 function fromQuat(out, q) {
2275 var x = q[0],
2276 y = q[1],
2277 z = q[2],
2278 w = q[3];
2279 var x2 = x + x;
2280 var y2 = y + y;
2281 var z2 = z + z;
2282 var xx = x * x2;
2283 var yx = y * x2;
2284 var yy = y * y2;
2285 var zx = z * x2;
2286 var zy = z * y2;
2287 var zz = z * z2;
2288 var wx = w * x2;
2289 var wy = w * y2;
2290 var wz = w * z2;
2291 out[0] = 1 - yy - zz;
2292 out[1] = yx + wz;
2293 out[2] = zx - wy;
2294 out[3] = 0;
2295 out[4] = yx - wz;
2296 out[5] = 1 - xx - zz;
2297 out[6] = zy + wx;
2298 out[7] = 0;
2299 out[8] = zx + wy;
2300 out[9] = zy - wx;
2301 out[10] = 1 - xx - yy;
2302 out[11] = 0;
2303 out[12] = 0;
2304 out[13] = 0;
2305 out[14] = 0;
2306 out[15] = 1;
2307 return out;
2308 }
2309 /**
2310 * Generates a frustum matrix with the given bounds
2311 *
2312 * @param {mat4} out mat4 frustum matrix will be written into
2313 * @param {Number} left Left bound of the frustum
2314 * @param {Number} right Right bound of the frustum
2315 * @param {Number} bottom Bottom bound of the frustum
2316 * @param {Number} top Top bound of the frustum
2317 * @param {Number} near Near bound of the frustum
2318 * @param {Number} far Far bound of the frustum
2319 * @returns {mat4} out
2320 */
2321
2322 function frustum(out, left, right, bottom, top, near, far) {
2323 var rl = 1 / (right - left);
2324 var tb = 1 / (top - bottom);
2325 var nf = 1 / (near - far);
2326 out[0] = near * 2 * rl;
2327 out[1] = 0;
2328 out[2] = 0;
2329 out[3] = 0;
2330 out[4] = 0;
2331 out[5] = near * 2 * tb;
2332 out[6] = 0;
2333 out[7] = 0;
2334 out[8] = (right + left) * rl;
2335 out[9] = (top + bottom) * tb;
2336 out[10] = (far + near) * nf;
2337 out[11] = -1;
2338 out[12] = 0;
2339 out[13] = 0;
2340 out[14] = far * near * 2 * nf;
2341 out[15] = 0;
2342 return out;
2343 }
2344 /**
2345 * Generates a perspective projection matrix with the given bounds.
2346 * The near/far clip planes correspond to a normalized device coordinate Z range of [-1, 1],
2347 * which matches WebGL/OpenGL's clip volume.
2348 * Passing null/undefined/no value for far will generate infinite projection matrix.
2349 *
2350 * @param {mat4} out mat4 frustum matrix will be written into
2351 * @param {number} fovy Vertical field of view in radians
2352 * @param {number} aspect Aspect ratio. typically viewport width/height
2353 * @param {number} near Near bound of the frustum
2354 * @param {number} far Far bound of the frustum, can be null or Infinity
2355 * @returns {mat4} out
2356 */
2357
2358 function perspectiveNO(out, fovy, aspect, near, far) {
2359 var f = 1.0 / Math.tan(fovy / 2),
2360 nf;
2361 out[0] = f / aspect;
2362 out[1] = 0;
2363 out[2] = 0;
2364 out[3] = 0;
2365 out[4] = 0;
2366 out[5] = f;
2367 out[6] = 0;
2368 out[7] = 0;
2369 out[8] = 0;
2370 out[9] = 0;
2371 out[11] = -1;
2372 out[12] = 0;
2373 out[13] = 0;
2374 out[15] = 0;
2375
2376 if (far != null && far !== Infinity) {
2377 nf = 1 / (near - far);
2378 out[10] = (far + near) * nf;
2379 out[14] = 2 * far * near * nf;
2380 } else {
2381 out[10] = -1;
2382 out[14] = -2 * near;
2383 }
2384
2385 return out;
2386 }
2387 /**
2388 * Alias for {@link mat4.perspectiveNO}
2389 * @function
2390 */
2391
2392 var perspective = perspectiveNO;
2393 /**
2394 * Generates a perspective projection matrix suitable for WebGPU with the given bounds.
2395 * The near/far clip planes correspond to a normalized device coordinate Z range of [0, 1],
2396 * which matches WebGPU/Vulkan/DirectX/Metal's clip volume.
2397 * Passing null/undefined/no value for far will generate infinite projection matrix.
2398 *
2399 * @param {mat4} out mat4 frustum matrix will be written into
2400 * @param {number} fovy Vertical field of view in radians
2401 * @param {number} aspect Aspect ratio. typically viewport width/height
2402 * @param {number} near Near bound of the frustum
2403 * @param {number} far Far bound of the frustum, can be null or Infinity
2404 * @returns {mat4} out
2405 */
2406
2407 function perspectiveZO(out, fovy, aspect, near, far) {
2408 var f = 1.0 / Math.tan(fovy / 2),
2409 nf;
2410 out[0] = f / aspect;
2411 out[1] = 0;
2412 out[2] = 0;
2413 out[3] = 0;
2414 out[4] = 0;
2415 out[5] = f;
2416 out[6] = 0;
2417 out[7] = 0;
2418 out[8] = 0;
2419 out[9] = 0;
2420 out[11] = -1;
2421 out[12] = 0;
2422 out[13] = 0;
2423 out[15] = 0;
2424
2425 if (far != null && far !== Infinity) {
2426 nf = 1 / (near - far);
2427 out[10] = far * nf;
2428 out[14] = far * near * nf;
2429 } else {
2430 out[10] = -1;
2431 out[14] = -near;
2432 }
2433
2434 return out;
2435 }
2436 /**
2437 * Generates a perspective projection matrix with the given field of view.
2438 * This is primarily useful for generating projection matrices to be used
2439 * with the still experiemental WebVR API.
2440 *
2441 * @param {mat4} out mat4 frustum matrix will be written into
2442 * @param {Object} fov Object containing the following values: upDegrees, downDegrees, leftDegrees, rightDegrees
2443 * @param {number} near Near bound of the frustum
2444 * @param {number} far Far bound of the frustum
2445 * @returns {mat4} out
2446 */
2447
2448 function perspectiveFromFieldOfView(out, fov, near, far) {
2449 var upTan = Math.tan(fov.upDegrees * Math.PI / 180.0);
2450 var downTan = Math.tan(fov.downDegrees * Math.PI / 180.0);
2451 var leftTan = Math.tan(fov.leftDegrees * Math.PI / 180.0);
2452 var rightTan = Math.tan(fov.rightDegrees * Math.PI / 180.0);
2453 var xScale = 2.0 / (leftTan + rightTan);
2454 var yScale = 2.0 / (upTan + downTan);
2455 out[0] = xScale;
2456 out[1] = 0.0;
2457 out[2] = 0.0;
2458 out[3] = 0.0;
2459 out[4] = 0.0;
2460 out[5] = yScale;
2461 out[6] = 0.0;
2462 out[7] = 0.0;
2463 out[8] = -((leftTan - rightTan) * xScale * 0.5);
2464 out[9] = (upTan - downTan) * yScale * 0.5;
2465 out[10] = far / (near - far);
2466 out[11] = -1.0;
2467 out[12] = 0.0;
2468 out[13] = 0.0;
2469 out[14] = far * near / (near - far);
2470 out[15] = 0.0;
2471 return out;
2472 }
2473 /**
2474 * Generates a orthogonal projection matrix with the given bounds.
2475 * The near/far clip planes correspond to a normalized device coordinate Z range of [-1, 1],
2476 * which matches WebGL/OpenGL's clip volume.
2477 *
2478 * @param {mat4} out mat4 frustum matrix will be written into
2479 * @param {number} left Left bound of the frustum
2480 * @param {number} right Right bound of the frustum
2481 * @param {number} bottom Bottom bound of the frustum
2482 * @param {number} top Top bound of the frustum
2483 * @param {number} near Near bound of the frustum
2484 * @param {number} far Far bound of the frustum
2485 * @returns {mat4} out
2486 */
2487
2488 function orthoNO(out, left, right, bottom, top, near, far) {
2489 var lr = 1 / (left - right);
2490 var bt = 1 / (bottom - top);
2491 var nf = 1 / (near - far);
2492 out[0] = -2 * lr;
2493 out[1] = 0;
2494 out[2] = 0;
2495 out[3] = 0;
2496 out[4] = 0;
2497 out[5] = -2 * bt;
2498 out[6] = 0;
2499 out[7] = 0;
2500 out[8] = 0;
2501 out[9] = 0;
2502 out[10] = 2 * nf;
2503 out[11] = 0;
2504 out[12] = (left + right) * lr;
2505 out[13] = (top + bottom) * bt;
2506 out[14] = (far + near) * nf;
2507 out[15] = 1;
2508 return out;
2509 }
2510 /**
2511 * Alias for {@link mat4.orthoNO}
2512 * @function
2513 */
2514
2515 var ortho = orthoNO;
2516 /**
2517 * Generates a orthogonal projection matrix with the given bounds.
2518 * The near/far clip planes correspond to a normalized device coordinate Z range of [0, 1],
2519 * which matches WebGPU/Vulkan/DirectX/Metal's clip volume.
2520 *
2521 * @param {mat4} out mat4 frustum matrix will be written into
2522 * @param {number} left Left bound of the frustum
2523 * @param {number} right Right bound of the frustum
2524 * @param {number} bottom Bottom bound of the frustum
2525 * @param {number} top Top bound of the frustum
2526 * @param {number} near Near bound of the frustum
2527 * @param {number} far Far bound of the frustum
2528 * @returns {mat4} out
2529 */
2530
2531 function orthoZO(out, left, right, bottom, top, near, far) {
2532 var lr = 1 / (left - right);
2533 var bt = 1 / (bottom - top);
2534 var nf = 1 / (near - far);
2535 out[0] = -2 * lr;
2536 out[1] = 0;
2537 out[2] = 0;
2538 out[3] = 0;
2539 out[4] = 0;
2540 out[5] = -2 * bt;
2541 out[6] = 0;
2542 out[7] = 0;
2543 out[8] = 0;
2544 out[9] = 0;
2545 out[10] = nf;
2546 out[11] = 0;
2547 out[12] = (left + right) * lr;
2548 out[13] = (top + bottom) * bt;
2549 out[14] = near * nf;
2550 out[15] = 1;
2551 return out;
2552 }
2553 /**
2554 * Generates a look-at matrix with the given eye position, focal point, and up axis.
2555 * If you want a matrix that actually makes an object look at another object, you should use targetTo instead.
2556 *
2557 * @param {mat4} out mat4 frustum matrix will be written into
2558 * @param {ReadonlyVec3} eye Position of the viewer
2559 * @param {ReadonlyVec3} center Point the viewer is looking at
2560 * @param {ReadonlyVec3} up vec3 pointing up
2561 * @returns {mat4} out
2562 */
2563
2564 function lookAt(out, eye, center, up) {
2565 var x0, x1, x2, y0, y1, y2, z0, z1, z2, len;
2566 var eyex = eye[0];
2567 var eyey = eye[1];
2568 var eyez = eye[2];
2569 var upx = up[0];
2570 var upy = up[1];
2571 var upz = up[2];
2572 var centerx = center[0];
2573 var centery = center[1];
2574 var centerz = center[2];
2575
2576 if (Math.abs(eyex - centerx) < EPSILON && Math.abs(eyey - centery) < EPSILON && Math.abs(eyez - centerz) < EPSILON) {
2577 return identity$1(out);
2578 }
2579
2580 z0 = eyex - centerx;
2581 z1 = eyey - centery;
2582 z2 = eyez - centerz;
2583 len = 1 / Math.hypot(z0, z1, z2);
2584 z0 *= len;
2585 z1 *= len;
2586 z2 *= len;
2587 x0 = upy * z2 - upz * z1;
2588 x1 = upz * z0 - upx * z2;
2589 x2 = upx * z1 - upy * z0;
2590 len = Math.hypot(x0, x1, x2);
2591
2592 if (!len) {
2593 x0 = 0;
2594 x1 = 0;
2595 x2 = 0;
2596 } else {
2597 len = 1 / len;
2598 x0 *= len;
2599 x1 *= len;
2600 x2 *= len;
2601 }
2602
2603 y0 = z1 * x2 - z2 * x1;
2604 y1 = z2 * x0 - z0 * x2;
2605 y2 = z0 * x1 - z1 * x0;
2606 len = Math.hypot(y0, y1, y2);
2607
2608 if (!len) {
2609 y0 = 0;
2610 y1 = 0;
2611 y2 = 0;
2612 } else {
2613 len = 1 / len;
2614 y0 *= len;
2615 y1 *= len;
2616 y2 *= len;
2617 }
2618
2619 out[0] = x0;
2620 out[1] = y0;
2621 out[2] = z0;
2622 out[3] = 0;
2623 out[4] = x1;
2624 out[5] = y1;
2625 out[6] = z1;
2626 out[7] = 0;
2627 out[8] = x2;
2628 out[9] = y2;
2629 out[10] = z2;
2630 out[11] = 0;
2631 out[12] = -(x0 * eyex + x1 * eyey + x2 * eyez);
2632 out[13] = -(y0 * eyex + y1 * eyey + y2 * eyez);
2633 out[14] = -(z0 * eyex + z1 * eyey + z2 * eyez);
2634 out[15] = 1;
2635 return out;
2636 }
2637 /**
2638 * Generates a matrix that makes something look at something else.
2639 *
2640 * @param {mat4} out mat4 frustum matrix will be written into
2641 * @param {ReadonlyVec3} eye Position of the viewer
2642 * @param {ReadonlyVec3} center Point the viewer is looking at
2643 * @param {ReadonlyVec3} up vec3 pointing up
2644 * @returns {mat4} out
2645 */
2646
2647 function targetTo(out, eye, target, up) {
2648 var eyex = eye[0],
2649 eyey = eye[1],
2650 eyez = eye[2],
2651 upx = up[0],
2652 upy = up[1],
2653 upz = up[2];
2654 var z0 = eyex - target[0],
2655 z1 = eyey - target[1],
2656 z2 = eyez - target[2];
2657 var len = z0 * z0 + z1 * z1 + z2 * z2;
2658
2659 if (len > 0) {
2660 len = 1 / Math.sqrt(len);
2661 z0 *= len;
2662 z1 *= len;
2663 z2 *= len;
2664 }
2665
2666 var x0 = upy * z2 - upz * z1,
2667 x1 = upz * z0 - upx * z2,
2668 x2 = upx * z1 - upy * z0;
2669 len = x0 * x0 + x1 * x1 + x2 * x2;
2670
2671 if (len > 0) {
2672 len = 1 / Math.sqrt(len);
2673 x0 *= len;
2674 x1 *= len;
2675 x2 *= len;
2676 }
2677
2678 out[0] = x0;
2679 out[1] = x1;
2680 out[2] = x2;
2681 out[3] = 0;
2682 out[4] = z1 * x2 - z2 * x1;
2683 out[5] = z2 * x0 - z0 * x2;
2684 out[6] = z0 * x1 - z1 * x0;
2685 out[7] = 0;
2686 out[8] = z0;
2687 out[9] = z1;
2688 out[10] = z2;
2689 out[11] = 0;
2690 out[12] = eyex;
2691 out[13] = eyey;
2692 out[14] = eyez;
2693 out[15] = 1;
2694 return out;
2695 }
2696 /**
2697 * Returns a string representation of a mat4
2698 *
2699 * @param {ReadonlyMat4} a matrix to represent as a string
2700 * @returns {String} string representation of the matrix
2701 */
2702
2703 function str(a) {
2704 return "mat4(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ", " + a[6] + ", " + a[7] + ", " + a[8] + ", " + a[9] + ", " + a[10] + ", " + a[11] + ", " + a[12] + ", " + a[13] + ", " + a[14] + ", " + a[15] + ")";
2705 }
2706 /**
2707 * Returns Frobenius norm of a mat4
2708 *
2709 * @param {ReadonlyMat4} a the matrix to calculate Frobenius norm of
2710 * @returns {Number} Frobenius norm
2711 */
2712
2713 function frob(a) {
2714 return Math.hypot(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]);
2715 }
2716 /**
2717 * Adds two mat4's
2718 *
2719 * @param {mat4} out the receiving matrix
2720 * @param {ReadonlyMat4} a the first operand
2721 * @param {ReadonlyMat4} b the second operand
2722 * @returns {mat4} out
2723 */
2724
2725 function add(out, a, b) {
2726 out[0] = a[0] + b[0];
2727 out[1] = a[1] + b[1];
2728 out[2] = a[2] + b[2];
2729 out[3] = a[3] + b[3];
2730 out[4] = a[4] + b[4];
2731 out[5] = a[5] + b[5];
2732 out[6] = a[6] + b[6];
2733 out[7] = a[7] + b[7];
2734 out[8] = a[8] + b[8];
2735 out[9] = a[9] + b[9];
2736 out[10] = a[10] + b[10];
2737 out[11] = a[11] + b[11];
2738 out[12] = a[12] + b[12];
2739 out[13] = a[13] + b[13];
2740 out[14] = a[14] + b[14];
2741 out[15] = a[15] + b[15];
2742 return out;
2743 }
2744 /**
2745 * Subtracts matrix b from matrix a
2746 *
2747 * @param {mat4} out the receiving matrix
2748 * @param {ReadonlyMat4} a the first operand
2749 * @param {ReadonlyMat4} b the second operand
2750 * @returns {mat4} out
2751 */
2752
2753 function subtract(out, a, b) {
2754 out[0] = a[0] - b[0];
2755 out[1] = a[1] - b[1];
2756 out[2] = a[2] - b[2];
2757 out[3] = a[3] - b[3];
2758 out[4] = a[4] - b[4];
2759 out[5] = a[5] - b[5];
2760 out[6] = a[6] - b[6];
2761 out[7] = a[7] - b[7];
2762 out[8] = a[8] - b[8];
2763 out[9] = a[9] - b[9];
2764 out[10] = a[10] - b[10];
2765 out[11] = a[11] - b[11];
2766 out[12] = a[12] - b[12];
2767 out[13] = a[13] - b[13];
2768 out[14] = a[14] - b[14];
2769 out[15] = a[15] - b[15];
2770 return out;
2771 }
2772 /**
2773 * Multiply each element of the matrix by a scalar.
2774 *
2775 * @param {mat4} out the receiving matrix
2776 * @param {ReadonlyMat4} a the matrix to scale
2777 * @param {Number} b amount to scale the matrix's elements by
2778 * @returns {mat4} out
2779 */
2780
2781 function multiplyScalar(out, a, b) {
2782 out[0] = a[0] * b;
2783 out[1] = a[1] * b;
2784 out[2] = a[2] * b;
2785 out[3] = a[3] * b;
2786 out[4] = a[4] * b;
2787 out[5] = a[5] * b;
2788 out[6] = a[6] * b;
2789 out[7] = a[7] * b;
2790 out[8] = a[8] * b;
2791 out[9] = a[9] * b;
2792 out[10] = a[10] * b;
2793 out[11] = a[11] * b;
2794 out[12] = a[12] * b;
2795 out[13] = a[13] * b;
2796 out[14] = a[14] * b;
2797 out[15] = a[15] * b;
2798 return out;
2799 }
2800 /**
2801 * Adds two mat4's after multiplying each element of the second operand by a scalar value.
2802 *
2803 * @param {mat4} out the receiving vector
2804 * @param {ReadonlyMat4} a the first operand
2805 * @param {ReadonlyMat4} b the second operand
2806 * @param {Number} scale the amount to scale b's elements by before adding
2807 * @returns {mat4} out
2808 */
2809
2810 function multiplyScalarAndAdd(out, a, b, scale) {
2811 out[0] = a[0] + b[0] * scale;
2812 out[1] = a[1] + b[1] * scale;
2813 out[2] = a[2] + b[2] * scale;
2814 out[3] = a[3] + b[3] * scale;
2815 out[4] = a[4] + b[4] * scale;
2816 out[5] = a[5] + b[5] * scale;
2817 out[6] = a[6] + b[6] * scale;
2818 out[7] = a[7] + b[7] * scale;
2819 out[8] = a[8] + b[8] * scale;
2820 out[9] = a[9] + b[9] * scale;
2821 out[10] = a[10] + b[10] * scale;
2822 out[11] = a[11] + b[11] * scale;
2823 out[12] = a[12] + b[12] * scale;
2824 out[13] = a[13] + b[13] * scale;
2825 out[14] = a[14] + b[14] * scale;
2826 out[15] = a[15] + b[15] * scale;
2827 return out;
2828 }
2829 /**
2830 * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===)
2831 *
2832 * @param {ReadonlyMat4} a The first matrix.
2833 * @param {ReadonlyMat4} b The second matrix.
2834 * @returns {Boolean} True if the matrices are equal, false otherwise.
2835 */
2836
2837 function exactEquals(a, b) {
2838 return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7] && a[8] === b[8] && a[9] === b[9] && a[10] === b[10] && a[11] === b[11] && a[12] === b[12] && a[13] === b[13] && a[14] === b[14] && a[15] === b[15];
2839 }
2840 /**
2841 * Returns whether or not the matrices have approximately the same elements in the same position.
2842 *
2843 * @param {ReadonlyMat4} a The first matrix.
2844 * @param {ReadonlyMat4} b The second matrix.
2845 * @returns {Boolean} True if the matrices are equal, false otherwise.
2846 */
2847
2848 function equals(a, b) {
2849 var a0 = a[0],
2850 a1 = a[1],
2851 a2 = a[2],
2852 a3 = a[3];
2853 var a4 = a[4],
2854 a5 = a[5],
2855 a6 = a[6],
2856 a7 = a[7];
2857 var a8 = a[8],
2858 a9 = a[9],
2859 a10 = a[10],
2860 a11 = a[11];
2861 var a12 = a[12],
2862 a13 = a[13],
2863 a14 = a[14],
2864 a15 = a[15];
2865 var b0 = b[0],
2866 b1 = b[1],
2867 b2 = b[2],
2868 b3 = b[3];
2869 var b4 = b[4],
2870 b5 = b[5],
2871 b6 = b[6],
2872 b7 = b[7];
2873 var b8 = b[8],
2874 b9 = b[9],
2875 b10 = b[10],
2876 b11 = b[11];
2877 var b12 = b[12],
2878 b13 = b[13],
2879 b14 = b[14],
2880 b15 = b[15];
2881 return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= EPSILON * Math.max(1.0, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= EPSILON * Math.max(1.0, Math.abs(a5), Math.abs(b5)) && Math.abs(a6 - b6) <= EPSILON * Math.max(1.0, Math.abs(a6), Math.abs(b6)) && Math.abs(a7 - b7) <= EPSILON * Math.max(1.0, Math.abs(a7), Math.abs(b7)) && Math.abs(a8 - b8) <= EPSILON * Math.max(1.0, Math.abs(a8), Math.abs(b8)) && Math.abs(a9 - b9) <= EPSILON * Math.max(1.0, Math.abs(a9), Math.abs(b9)) && Math.abs(a10 - b10) <= EPSILON * Math.max(1.0, Math.abs(a10), Math.abs(b10)) && Math.abs(a11 - b11) <= EPSILON * Math.max(1.0, Math.abs(a11), Math.abs(b11)) && Math.abs(a12 - b12) <= EPSILON * Math.max(1.0, Math.abs(a12), Math.abs(b12)) && Math.abs(a13 - b13) <= EPSILON * Math.max(1.0, Math.abs(a13), Math.abs(b13)) && Math.abs(a14 - b14) <= EPSILON * Math.max(1.0, Math.abs(a14), Math.abs(b14)) && Math.abs(a15 - b15) <= EPSILON * Math.max(1.0, Math.abs(a15), Math.abs(b15));
2882 }
2883 /**
2884 * Alias for {@link mat4.multiply}
2885 * @function
2886 */
2887
2888 var mul = multiply;
2889 /**
2890 * Alias for {@link mat4.subtract}
2891 * @function
2892 */
2893
2894 var sub = subtract;
2895
2896 var mat4 = /*#__PURE__*/Object.freeze({
2897 __proto__: null,
2898 create: create$1,
2899 clone: clone$1,
2900 copy: copy,
2901 fromValues: fromValues$1,
2902 set: set,
2903 identity: identity$1,
2904 transpose: transpose,
2905 invert: invert,
2906 adjoint: adjoint,
2907 determinant: determinant,
2908 multiply: multiply,
2909 translate: translate,
2910 scale: scale,
2911 rotate: rotate$1,
2912 rotateX: rotateX,
2913 rotateY: rotateY,
2914 rotateZ: rotateZ,
2915 fromTranslation: fromTranslation,
2916 fromScaling: fromScaling,
2917 fromRotation: fromRotation,
2918 fromXRotation: fromXRotation,
2919 fromYRotation: fromYRotation,
2920 fromZRotation: fromZRotation,
2921 fromRotationTranslation: fromRotationTranslation,
2922 fromQuat2: fromQuat2,
2923 getTranslation: getTranslation,
2924 getScaling: getScaling,
2925 getRotation: getRotation,
2926 fromRotationTranslationScale: fromRotationTranslationScale,
2927 fromRotationTranslationScaleOrigin: fromRotationTranslationScaleOrigin,
2928 fromQuat: fromQuat,
2929 frustum: frustum,
2930 perspectiveNO: perspectiveNO,
2931 perspective: perspective,
2932 perspectiveZO: perspectiveZO,
2933 perspectiveFromFieldOfView: perspectiveFromFieldOfView,
2934 orthoNO: orthoNO,
2935 ortho: ortho,
2936 orthoZO: orthoZO,
2937 lookAt: lookAt,
2938 targetTo: targetTo,
2939 str: str,
2940 frob: frob,
2941 add: add,
2942 subtract: subtract,
2943 multiplyScalar: multiplyScalar,
2944 multiplyScalarAndAdd: multiplyScalarAndAdd,
2945 exactEquals: exactEquals,
2946 equals: equals,
2947 mul: mul,
2948 sub: sub
2949 });
2950
2951 /**
2952 * 3 Dimensional Vector
2953 * @module vec3
2954 */
2955
2956 /**
2957 * Creates a new, empty vec3
2958 *
2959 * @returns {vec3} a new 3D vector
2960 */
2961
2962 function create$2() {
2963 var out = new ARRAY_TYPE(3);
2964
2965 if (ARRAY_TYPE != Float32Array) {
2966 out[0] = 0;
2967 out[1] = 0;
2968 out[2] = 0;
2969 }
2970
2971 return out;
2972 }
2973 /**
2974 * Creates a new vec3 initialized with values from an existing vector
2975 *
2976 * @param {ReadonlyVec3} a vector to clone
2977 * @returns {vec3} a new 3D vector
2978 */
2979
2980 function clone$2(a) {
2981 var out = new ARRAY_TYPE(3);
2982 out[0] = a[0];
2983 out[1] = a[1];
2984 out[2] = a[2];
2985 return out;
2986 }
2987 /**
2988 * Calculates the length of a vec3
2989 *
2990 * @param {ReadonlyVec3} a vector to calculate length of
2991 * @returns {Number} length of a
2992 */
2993
2994 function length(a) {
2995 var x = a[0];
2996 var y = a[1];
2997 var z = a[2];
2998 return Math.hypot(x, y, z);
2999 }
3000 /**
3001 * Creates a new vec3 initialized with the given values
3002 *
3003 * @param {Number} x X component
3004 * @param {Number} y Y component
3005 * @param {Number} z Z component
3006 * @returns {vec3} a new 3D vector
3007 */
3008
3009 function fromValues$2(x, y, z) {
3010 var out = new ARRAY_TYPE(3);
3011 out[0] = x;
3012 out[1] = y;
3013 out[2] = z;
3014 return out;
3015 }
3016 /**
3017 * Copy the values from one vec3 to another
3018 *
3019 * @param {vec3} out the receiving vector
3020 * @param {ReadonlyVec3} a the source vector
3021 * @returns {vec3} out
3022 */
3023
3024 function copy$1(out, a) {
3025 out[0] = a[0];
3026 out[1] = a[1];
3027 out[2] = a[2];
3028 return out;
3029 }
3030 /**
3031 * Set the components of a vec3 to the given values
3032 *
3033 * @param {vec3} out the receiving vector
3034 * @param {Number} x X component
3035 * @param {Number} y Y component
3036 * @param {Number} z Z component
3037 * @returns {vec3} out
3038 */
3039
3040 function set$1(out, x, y, z) {
3041 out[0] = x;
3042 out[1] = y;
3043 out[2] = z;
3044 return out;
3045 }
3046 /**
3047 * Adds two vec3's
3048 *
3049 * @param {vec3} out the receiving vector
3050 * @param {ReadonlyVec3} a the first operand
3051 * @param {ReadonlyVec3} b the second operand
3052 * @returns {vec3} out
3053 */
3054
3055 function add$1(out, a, b) {
3056 out[0] = a[0] + b[0];
3057 out[1] = a[1] + b[1];
3058 out[2] = a[2] + b[2];
3059 return out;
3060 }
3061 /**
3062 * Subtracts vector b from vector a
3063 *
3064 * @param {vec3} out the receiving vector
3065 * @param {ReadonlyVec3} a the first operand
3066 * @param {ReadonlyVec3} b the second operand
3067 * @returns {vec3} out
3068 */
3069
3070 function subtract$1(out, a, b) {
3071 out[0] = a[0] - b[0];
3072 out[1] = a[1] - b[1];
3073 out[2] = a[2] - b[2];
3074 return out;
3075 }
3076 /**
3077 * Multiplies two vec3's
3078 *
3079 * @param {vec3} out the receiving vector
3080 * @param {ReadonlyVec3} a the first operand
3081 * @param {ReadonlyVec3} b the second operand
3082 * @returns {vec3} out
3083 */
3084
3085 function multiply$1(out, a, b) {
3086 out[0] = a[0] * b[0];
3087 out[1] = a[1] * b[1];
3088 out[2] = a[2] * b[2];
3089 return out;
3090 }
3091 /**
3092 * Scales a vec3 by a scalar number
3093 *
3094 * @param {vec3} out the receiving vector
3095 * @param {ReadonlyVec3} a the vector to scale
3096 * @param {Number} b amount to scale the vector by
3097 * @returns {vec3} out
3098 */
3099
3100 function scale$1(out, a, b) {
3101 out[0] = a[0] * b;
3102 out[1] = a[1] * b;
3103 out[2] = a[2] * b;
3104 return out;
3105 }
3106 /**
3107 * Normalize a vec3
3108 *
3109 * @param {vec3} out the receiving vector
3110 * @param {ReadonlyVec3} a vector to normalize
3111 * @returns {vec3} out
3112 */
3113
3114 function normalize(out, a) {
3115 var x = a[0];
3116 var y = a[1];
3117 var z = a[2];
3118 var len = x * x + y * y + z * z;
3119
3120 if (len > 0) {
3121 //TODO: evaluate use of glm_invsqrt here?
3122 len = 1 / Math.sqrt(len);
3123 }
3124
3125 out[0] = a[0] * len;
3126 out[1] = a[1] * len;
3127 out[2] = a[2] * len;
3128 return out;
3129 }
3130 /**
3131 * Calculates the dot product of two vec3's
3132 *
3133 * @param {ReadonlyVec3} a the first operand
3134 * @param {ReadonlyVec3} b the second operand
3135 * @returns {Number} dot product of a and b
3136 */
3137
3138 function dot(a, b) {
3139 return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
3140 }
3141 /**
3142 * Computes the cross product of two vec3's
3143 *
3144 * @param {vec3} out the receiving vector
3145 * @param {ReadonlyVec3} a the first operand
3146 * @param {ReadonlyVec3} b the second operand
3147 * @returns {vec3} out
3148 */
3149
3150 function cross(out, a, b) {
3151 var ax = a[0],
3152 ay = a[1],
3153 az = a[2];
3154 var bx = b[0],
3155 by = b[1],
3156 bz = b[2];
3157 out[0] = ay * bz - az * by;
3158 out[1] = az * bx - ax * bz;
3159 out[2] = ax * by - ay * bx;
3160 return out;
3161 }
3162 /**
3163 * Performs a linear interpolation between two vec3's
3164 *
3165 * @param {vec3} out the receiving vector
3166 * @param {ReadonlyVec3} a the first operand
3167 * @param {ReadonlyVec3} b the second operand
3168 * @param {Number} t interpolation amount, in the range [0-1], between the two inputs
3169 * @returns {vec3} out
3170 */
3171
3172 function lerp(out, a, b, t) {
3173 var ax = a[0];
3174 var ay = a[1];
3175 var az = a[2];
3176 out[0] = ax + t * (b[0] - ax);
3177 out[1] = ay + t * (b[1] - ay);
3178 out[2] = az + t * (b[2] - az);
3179 return out;
3180 }
3181 /**
3182 * Transforms the vec3 with a mat4.
3183 * 4th vector component is implicitly '1'
3184 *
3185 * @param {vec3} out the receiving vector
3186 * @param {ReadonlyVec3} a the vector to transform
3187 * @param {ReadonlyMat4} m matrix to transform with
3188 * @returns {vec3} out
3189 */
3190
3191 function transformMat4(out, a, m) {
3192 var x = a[0],
3193 y = a[1],
3194 z = a[2];
3195 var w = m[3] * x + m[7] * y + m[11] * z + m[15];
3196 w = w || 1.0;
3197 out[0] = (m[0] * x + m[4] * y + m[8] * z + m[12]) / w;
3198 out[1] = (m[1] * x + m[5] * y + m[9] * z + m[13]) / w;
3199 out[2] = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w;
3200 return out;
3201 }
3202 /**
3203 * Transforms the vec3 with a mat3.
3204 *
3205 * @param {vec3} out the receiving vector
3206 * @param {ReadonlyVec3} a the vector to transform
3207 * @param {ReadonlyMat3} m the 3x3 matrix to transform with
3208 * @returns {vec3} out
3209 */
3210
3211 function transformMat3(out, a, m) {
3212 var x = a[0],
3213 y = a[1],
3214 z = a[2];
3215 out[0] = x * m[0] + y * m[3] + z * m[6];
3216 out[1] = x * m[1] + y * m[4] + z * m[7];
3217 out[2] = x * m[2] + y * m[5] + z * m[8];
3218 return out;
3219 }
3220 /**
3221 * Transforms the vec3 with a quat
3222 * Can also be used for dual quaternions. (Multiply it with the real part)
3223 *
3224 * @param {vec3} out the receiving vector
3225 * @param {ReadonlyVec3} a the vector to transform
3226 * @param {ReadonlyQuat} q quaternion to transform with
3227 * @returns {vec3} out
3228 */
3229
3230 function transformQuat(out, a, q) {
3231 // benchmarks: https://jsperf.com/quaternion-transform-vec3-implementations-fixed
3232 var qx = q[0],
3233 qy = q[1],
3234 qz = q[2],
3235 qw = q[3];
3236 var x = a[0],
3237 y = a[1],
3238 z = a[2]; // var qvec = [qx, qy, qz];
3239 // var uv = vec3.cross([], qvec, a);
3240
3241 var uvx = qy * z - qz * y,
3242 uvy = qz * x - qx * z,
3243 uvz = qx * y - qy * x; // var uuv = vec3.cross([], qvec, uv);
3244
3245 var uuvx = qy * uvz - qz * uvy,
3246 uuvy = qz * uvx - qx * uvz,
3247 uuvz = qx * uvy - qy * uvx; // vec3.scale(uv, uv, 2 * w);
3248
3249 var w2 = qw * 2;
3250 uvx *= w2;
3251 uvy *= w2;
3252 uvz *= w2; // vec3.scale(uuv, uuv, 2);
3253
3254 uuvx *= 2;
3255 uuvy *= 2;
3256 uuvz *= 2; // return vec3.add(out, a, vec3.add(out, uv, uuv));
3257
3258 out[0] = x + uvx + uuvx;
3259 out[1] = y + uvy + uuvy;
3260 out[2] = z + uvz + uuvz;
3261 return out;
3262 }
3263 /**
3264 * Returns whether or not the vectors have approximately the same elements in the same position.
3265 *
3266 * @param {ReadonlyVec3} a The first vector.
3267 * @param {ReadonlyVec3} b The second vector.
3268 * @returns {Boolean} True if the vectors are equal, false otherwise.
3269 */
3270
3271 function equals$1(a, b) {
3272 var a0 = a[0],
3273 a1 = a[1],
3274 a2 = a[2];
3275 var b0 = b[0],
3276 b1 = b[1],
3277 b2 = b[2];
3278 return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2));
3279 }
3280 /**
3281 * Alias for {@link vec3.length}
3282 * @function
3283 */
3284
3285 var len = length;
3286 /**
3287 * Perform some operation over an array of vec3s.
3288 *
3289 * @param {Array} a the array of vectors to iterate over
3290 * @param {Number} stride Number of elements between the start of each vec3. If 0 assumes tightly packed
3291 * @param {Number} offset Number of elements to skip at the beginning of the array
3292 * @param {Number} count Number of vec3s to iterate over. If 0 iterates over entire array
3293 * @param {Function} fn Function to call for each vector in the array
3294 * @param {Object} [arg] additional argument to pass to fn
3295 * @returns {Array} a
3296 * @function
3297 */
3298
3299 var forEach = function () {
3300 var vec = create$2();
3301 return function (a, stride, offset, count, fn, arg) {
3302 var i, l;
3303
3304 if (!stride) {
3305 stride = 3;
3306 }
3307
3308 if (!offset) {
3309 offset = 0;
3310 }
3311
3312 if (count) {
3313 l = Math.min(count * stride + offset, a.length);
3314 } else {
3315 l = a.length;
3316 }
3317
3318 for (i = offset; i < l; i += stride) {
3319 vec[0] = a[i];
3320 vec[1] = a[i + 1];
3321 vec[2] = a[i + 2];
3322 fn(vec, vec, arg);
3323 a[i] = vec[0];
3324 a[i + 1] = vec[1];
3325 a[i + 2] = vec[2];
3326 }
3327
3328 return a;
3329 };
3330 }();
3331
3332 /**
3333 * 4 Dimensional Vector
3334 * @module vec4
3335 */
3336
3337 /**
3338 * Creates a new, empty vec4
3339 *
3340 * @returns {vec4} a new 4D vector
3341 */
3342
3343 function create$3() {
3344 var out = new ARRAY_TYPE(4);
3345
3346 if (ARRAY_TYPE != Float32Array) {
3347 out[0] = 0;
3348 out[1] = 0;
3349 out[2] = 0;
3350 out[3] = 0;
3351 }
3352
3353 return out;
3354 }
3355 /**
3356 * Creates a new vec4 initialized with the given values
3357 *
3358 * @param {Number} x X component
3359 * @param {Number} y Y component
3360 * @param {Number} z Z component
3361 * @param {Number} w W component
3362 * @returns {vec4} a new 4D vector
3363 */
3364
3365 function fromValues$3(x, y, z, w) {
3366 var out = new ARRAY_TYPE(4);
3367 out[0] = x;
3368 out[1] = y;
3369 out[2] = z;
3370 out[3] = w;
3371 return out;
3372 }
3373 /**
3374 * Copy the values from one vec4 to another
3375 *
3376 * @param {vec4} out the receiving vector
3377 * @param {ReadonlyVec4} a the source vector
3378 * @returns {vec4} out
3379 */
3380
3381 function copy$2(out, a) {
3382 out[0] = a[0];
3383 out[1] = a[1];
3384 out[2] = a[2];
3385 out[3] = a[3];
3386 return out;
3387 }
3388 /**
3389 * Normalize a vec4
3390 *
3391 * @param {vec4} out the receiving vector
3392 * @param {ReadonlyVec4} a vector to normalize
3393 * @returns {vec4} out
3394 */
3395
3396 function normalize$1(out, a) {
3397 var x = a[0];
3398 var y = a[1];
3399 var z = a[2];
3400 var w = a[3];
3401 var len = x * x + y * y + z * z + w * w;
3402
3403 if (len > 0) {
3404 len = 1 / Math.sqrt(len);
3405 }
3406
3407 out[0] = x * len;
3408 out[1] = y * len;
3409 out[2] = z * len;
3410 out[3] = w * len;
3411 return out;
3412 }
3413 /**
3414 * Transforms the vec4 with a mat4.
3415 *
3416 * @param {vec4} out the receiving vector
3417 * @param {ReadonlyVec4} a the vector to transform
3418 * @param {ReadonlyMat4} m matrix to transform with
3419 * @returns {vec4} out
3420 */
3421
3422 function transformMat4$1(out, a, m) {
3423 var x = a[0],
3424 y = a[1],
3425 z = a[2],
3426 w = a[3];
3427 out[0] = m[0] * x + m[4] * y + m[8] * z + m[12] * w;
3428 out[1] = m[1] * x + m[5] * y + m[9] * z + m[13] * w;
3429 out[2] = m[2] * x + m[6] * y + m[10] * z + m[14] * w;
3430 out[3] = m[3] * x + m[7] * y + m[11] * z + m[15] * w;
3431 return out;
3432 }
3433 /**
3434 * Perform some operation over an array of vec4s.
3435 *
3436 * @param {Array} a the array of vectors to iterate over
3437 * @param {Number} stride Number of elements between the start of each vec4. If 0 assumes tightly packed
3438 * @param {Number} offset Number of elements to skip at the beginning of the array
3439 * @param {Number} count Number of vec4s to iterate over. If 0 iterates over entire array
3440 * @param {Function} fn Function to call for each vector in the array
3441 * @param {Object} [arg] additional argument to pass to fn
3442 * @returns {Array} a
3443 * @function
3444 */
3445
3446 var forEach$1 = function () {
3447 var vec = create$3();
3448 return function (a, stride, offset, count, fn, arg) {
3449 var i, l;
3450
3451 if (!stride) {
3452 stride = 4;
3453 }
3454
3455 if (!offset) {
3456 offset = 0;
3457 }
3458
3459 if (count) {
3460 l = Math.min(count * stride + offset, a.length);
3461 } else {
3462 l = a.length;
3463 }
3464
3465 for (i = offset; i < l; i += stride) {
3466 vec[0] = a[i];
3467 vec[1] = a[i + 1];
3468 vec[2] = a[i + 2];
3469 vec[3] = a[i + 3];
3470 fn(vec, vec, arg);
3471 a[i] = vec[0];
3472 a[i + 1] = vec[1];
3473 a[i + 2] = vec[2];
3474 a[i + 3] = vec[3];
3475 }
3476
3477 return a;
3478 };
3479 }();
3480
3481 /**
3482 * Quaternion
3483 * @module quat
3484 */
3485
3486 /**
3487 * Creates a new identity quat
3488 *
3489 * @returns {quat} a new quaternion
3490 */
3491
3492 function create$4() {
3493 var out = new ARRAY_TYPE(4);
3494
3495 if (ARRAY_TYPE != Float32Array) {
3496 out[0] = 0;
3497 out[1] = 0;
3498 out[2] = 0;
3499 }
3500
3501 out[3] = 1;
3502 return out;
3503 }
3504 /**
3505 * Sets a quat from the given angle and rotation axis,
3506 * then returns it.
3507 *
3508 * @param {quat} out the receiving quaternion
3509 * @param {ReadonlyVec3} axis the axis around which to rotate
3510 * @param {Number} rad the angle in radians
3511 * @returns {quat} out
3512 **/
3513
3514 function setAxisAngle(out, axis, rad) {
3515 rad = rad * 0.5;
3516 var s = Math.sin(rad);
3517 out[0] = s * axis[0];
3518 out[1] = s * axis[1];
3519 out[2] = s * axis[2];
3520 out[3] = Math.cos(rad);
3521 return out;
3522 }
3523 /**
3524 * Multiplies two quat's
3525 *
3526 * @param {quat} out the receiving quaternion
3527 * @param {ReadonlyQuat} a the first operand
3528 * @param {ReadonlyQuat} b the second operand
3529 * @returns {quat} out
3530 */
3531
3532 function multiply$2(out, a, b) {
3533 var ax = a[0],
3534 ay = a[1],
3535 az = a[2],
3536 aw = a[3];
3537 var bx = b[0],
3538 by = b[1],
3539 bz = b[2],
3540 bw = b[3];
3541 out[0] = ax * bw + aw * bx + ay * bz - az * by;
3542 out[1] = ay * bw + aw * by + az * bx - ax * bz;
3543 out[2] = az * bw + aw * bz + ax * by - ay * bx;
3544 out[3] = aw * bw - ax * bx - ay * by - az * bz;
3545 return out;
3546 }
3547 /**
3548 * Performs a spherical linear interpolation between two quat
3549 *
3550 * @param {quat} out the receiving quaternion
3551 * @param {ReadonlyQuat} a the first operand
3552 * @param {ReadonlyQuat} b the second operand
3553 * @param {Number} t interpolation amount, in the range [0-1], between the two inputs
3554 * @returns {quat} out
3555 */
3556
3557 function slerp(out, a, b, t) {
3558 // benchmarks:
3559 // http://jsperf.com/quaternion-slerp-implementations
3560 var ax = a[0],
3561 ay = a[1],
3562 az = a[2],
3563 aw = a[3];
3564 var bx = b[0],
3565 by = b[1],
3566 bz = b[2],
3567 bw = b[3];
3568 var omega, cosom, sinom, scale0, scale1; // calc cosine
3569
3570 cosom = ax * bx + ay * by + az * bz + aw * bw; // adjust signs (if necessary)
3571
3572 if (cosom < 0.0) {
3573 cosom = -cosom;
3574 bx = -bx;
3575 by = -by;
3576 bz = -bz;
3577 bw = -bw;
3578 } // calculate coefficients
3579
3580
3581 if (1.0 - cosom > EPSILON) {
3582 // standard case (slerp)
3583 omega = Math.acos(cosom);
3584 sinom = Math.sin(omega);
3585 scale0 = Math.sin((1.0 - t) * omega) / sinom;
3586 scale1 = Math.sin(t * omega) / sinom;
3587 } else {
3588 // "from" and "to" quaternions are very close
3589 // ... so we can do a linear interpolation
3590 scale0 = 1.0 - t;
3591 scale1 = t;
3592 } // calculate final values
3593
3594
3595 out[0] = scale0 * ax + scale1 * bx;
3596 out[1] = scale0 * ay + scale1 * by;
3597 out[2] = scale0 * az + scale1 * bz;
3598 out[3] = scale0 * aw + scale1 * bw;
3599 return out;
3600 }
3601 /**
3602 * Calculates the inverse of a quat
3603 *
3604 * @param {quat} out the receiving quaternion
3605 * @param {ReadonlyQuat} a quat to calculate inverse of
3606 * @returns {quat} out
3607 */
3608
3609 function invert$1(out, a) {
3610 var a0 = a[0],
3611 a1 = a[1],
3612 a2 = a[2],
3613 a3 = a[3];
3614 var dot = a0 * a0 + a1 * a1 + a2 * a2 + a3 * a3;
3615 var invDot = dot ? 1.0 / dot : 0; // TODO: Would be faster to return [0,0,0,0] immediately if dot == 0
3616
3617 out[0] = -a0 * invDot;
3618 out[1] = -a1 * invDot;
3619 out[2] = -a2 * invDot;
3620 out[3] = a3 * invDot;
3621 return out;
3622 }
3623 /**
3624 * Creates a quaternion from the given 3x3 rotation matrix.
3625 *
3626 * NOTE: The resultant quaternion is not normalized, so you should be sure
3627 * to renormalize the quaternion yourself where necessary.
3628 *
3629 * @param {quat} out the receiving quaternion
3630 * @param {ReadonlyMat3} m rotation matrix
3631 * @returns {quat} out
3632 * @function
3633 */
3634
3635 function fromMat3(out, m) {
3636 // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes
3637 // article "Quaternion Calculus and Fast Animation".
3638 var fTrace = m[0] + m[4] + m[8];
3639 var fRoot;
3640
3641 if (fTrace > 0.0) {
3642 // |w| > 1/2, may as well choose w > 1/2
3643 fRoot = Math.sqrt(fTrace + 1.0); // 2w
3644
3645 out[3] = 0.5 * fRoot;
3646 fRoot = 0.5 / fRoot; // 1/(4w)
3647
3648 out[0] = (m[5] - m[7]) * fRoot;
3649 out[1] = (m[6] - m[2]) * fRoot;
3650 out[2] = (m[1] - m[3]) * fRoot;
3651 } else {
3652 // |w| <= 1/2
3653 var i = 0;
3654 if (m[4] > m[0]) i = 1;
3655 if (m[8] > m[i * 3 + i]) i = 2;
3656 var j = (i + 1) % 3;
3657 var k = (i + 2) % 3;
3658 fRoot = Math.sqrt(m[i * 3 + i] - m[j * 3 + j] - m[k * 3 + k] + 1.0);
3659 out[i] = 0.5 * fRoot;
3660 fRoot = 0.5 / fRoot;
3661 out[3] = (m[j * 3 + k] - m[k * 3 + j]) * fRoot;
3662 out[j] = (m[j * 3 + i] + m[i * 3 + j]) * fRoot;
3663 out[k] = (m[k * 3 + i] + m[i * 3 + k]) * fRoot;
3664 }
3665
3666 return out;
3667 }
3668 /**
3669 * Creates a quaternion from the given euler angle x, y, z.
3670 *
3671 * @param {quat} out the receiving quaternion
3672 * @param {x} Angle to rotate around X axis in degrees.
3673 * @param {y} Angle to rotate around Y axis in degrees.
3674 * @param {z} Angle to rotate around Z axis in degrees.
3675 * @returns {quat} out
3676 * @function
3677 */
3678
3679 function fromEuler(out, x, y, z) {
3680 var halfToRad = 0.5 * Math.PI / 180.0;
3681 x *= halfToRad;
3682 y *= halfToRad;
3683 z *= halfToRad;
3684 var sx = Math.sin(x);
3685 var cx = Math.cos(x);
3686 var sy = Math.sin(y);
3687 var cy = Math.cos(y);
3688 var sz = Math.sin(z);
3689 var cz = Math.cos(z);
3690 out[0] = sx * cy * cz - cx * sy * sz;
3691 out[1] = cx * sy * cz + sx * cy * sz;
3692 out[2] = cx * cy * sz - sx * sy * cz;
3693 out[3] = cx * cy * cz + sx * sy * sz;
3694 return out;
3695 }
3696 /**
3697 * Creates a new quat initialized with the given values
3698 *
3699 * @param {Number} x X component
3700 * @param {Number} y Y component
3701 * @param {Number} z Z component
3702 * @param {Number} w W component
3703 * @returns {quat} a new quaternion
3704 * @function
3705 */
3706
3707 var fromValues$4 = fromValues$3;
3708 /**
3709 * Copy the values from one quat to another
3710 *
3711 * @param {quat} out the receiving quaternion
3712 * @param {ReadonlyQuat} a the source quaternion
3713 * @returns {quat} out
3714 * @function
3715 */
3716
3717 var copy$3 = copy$2;
3718 /**
3719 * Alias for {@link quat.multiply}
3720 * @function
3721 */
3722
3723 var mul$1 = multiply$2;
3724 /**
3725 * Normalize a quat
3726 *
3727 * @param {quat} out the receiving quaternion
3728 * @param {ReadonlyQuat} a quaternion to normalize
3729 * @returns {quat} out
3730 * @function
3731 */
3732
3733 var normalize$2 = normalize$1;
3734 /**
3735 * Sets a quaternion to represent the shortest rotation from one
3736 * vector to another.
3737 *
3738 * Both vectors are assumed to be unit length.
3739 *
3740 * @param {quat} out the receiving quaternion.
3741 * @param {ReadonlyVec3} a the initial vector
3742 * @param {ReadonlyVec3} b the destination vector
3743 * @returns {quat} out
3744 */
3745
3746 var rotationTo = function () {
3747 var tmpvec3 = create$2();
3748 var xUnitVec3 = fromValues$2(1, 0, 0);
3749 var yUnitVec3 = fromValues$2(0, 1, 0);
3750 return function (out, a, b) {
3751 var dot$1 = dot(a, b);
3752
3753 if (dot$1 < -0.999999) {
3754 cross(tmpvec3, xUnitVec3, a);
3755 if (len(tmpvec3) < 0.000001) cross(tmpvec3, yUnitVec3, a);
3756 normalize(tmpvec3, tmpvec3);
3757 setAxisAngle(out, tmpvec3, Math.PI);
3758 return out;
3759 } else if (dot$1 > 0.999999) {
3760 out[0] = 0;
3761 out[1] = 0;
3762 out[2] = 0;
3763 out[3] = 1;
3764 return out;
3765 } else {
3766 cross(tmpvec3, a, b);
3767 out[0] = tmpvec3[0];
3768 out[1] = tmpvec3[1];
3769 out[2] = tmpvec3[2];
3770 out[3] = 1 + dot$1;
3771 return normalize$2(out, out);
3772 }
3773 };
3774 }();
3775 /**
3776 * Performs a spherical linear interpolation with two control points
3777 *
3778 * @param {quat} out the receiving quaternion
3779 * @param {ReadonlyQuat} a the first operand
3780 * @param {ReadonlyQuat} b the second operand
3781 * @param {ReadonlyQuat} c the third operand
3782 * @param {ReadonlyQuat} d the fourth operand
3783 * @param {Number} t interpolation amount, in the range [0-1], between the two inputs
3784 * @returns {quat} out
3785 */
3786
3787 var sqlerp = function () {
3788 var temp1 = create$4();
3789 var temp2 = create$4();
3790 return function (out, a, b, c, d, t) {
3791 slerp(temp1, a, d, t);
3792 slerp(temp2, b, c, t);
3793 slerp(out, temp1, temp2, 2 * t * (1 - t));
3794 return out;
3795 };
3796 }();
3797 /**
3798 * Sets the specified quaternion with values corresponding to the given
3799 * axes. Each axis is a vec3 and is expected to be unit length and
3800 * perpendicular to all other specified axes.
3801 *
3802 * @param {ReadonlyVec3} view the vector representing the viewing direction
3803 * @param {ReadonlyVec3} right the vector representing the local "right" direction
3804 * @param {ReadonlyVec3} up the vector representing the local "up" direction
3805 * @returns {quat} out
3806 */
3807
3808 var setAxes = function () {
3809 var matr = create();
3810 return function (out, view, right, up) {
3811 matr[0] = right[0];
3812 matr[3] = right[1];
3813 matr[6] = right[2];
3814 matr[1] = up[0];
3815 matr[4] = up[1];
3816 matr[7] = up[2];
3817 matr[2] = -view[0];
3818 matr[5] = -view[1];
3819 matr[8] = -view[2];
3820 return normalize$2(out, fromMat3(out, matr));
3821 };
3822 }();
3823
3824 /**
3825 * 2 Dimensional Vector
3826 * @module vec2
3827 */
3828
3829 /**
3830 * Creates a new, empty vec2
3831 *
3832 * @returns {vec2} a new 2D vector
3833 */
3834
3835 function create$5() {
3836 var out = new ARRAY_TYPE(2);
3837
3838 if (ARRAY_TYPE != Float32Array) {
3839 out[0] = 0;
3840 out[1] = 0;
3841 }
3842
3843 return out;
3844 }
3845 /**
3846 * Creates a new vec2 initialized with the given values
3847 *
3848 * @param {Number} x X component
3849 * @param {Number} y Y component
3850 * @returns {vec2} a new 2D vector
3851 */
3852
3853 function fromValues$5(x, y) {
3854 var out = new ARRAY_TYPE(2);
3855 out[0] = x;
3856 out[1] = y;
3857 return out;
3858 }
3859 /**
3860 * Copy the values from one vec2 to another
3861 *
3862 * @param {vec2} out the receiving vector
3863 * @param {ReadonlyVec2} a the source vector
3864 * @returns {vec2} out
3865 */
3866
3867 function copy$4(out, a) {
3868 out[0] = a[0];
3869 out[1] = a[1];
3870 return out;
3871 }
3872 /**
3873 * Adds two vec2's
3874 *
3875 * @param {vec2} out the receiving vector
3876 * @param {ReadonlyVec2} a the first operand
3877 * @param {ReadonlyVec2} b the second operand
3878 * @returns {vec2} out
3879 */
3880
3881 function add$2(out, a, b) {
3882 out[0] = a[0] + b[0];
3883 out[1] = a[1] + b[1];
3884 return out;
3885 }
3886 /**
3887 * Subtracts vector b from vector a
3888 *
3889 * @param {vec2} out the receiving vector
3890 * @param {ReadonlyVec2} a the first operand
3891 * @param {ReadonlyVec2} b the second operand
3892 * @returns {vec2} out
3893 */
3894
3895 function subtract$2(out, a, b) {
3896 out[0] = a[0] - b[0];
3897 out[1] = a[1] - b[1];
3898 return out;
3899 }
3900 /**
3901 * Returns the minimum of two vec2's
3902 *
3903 * @param {vec2} out the receiving vector
3904 * @param {ReadonlyVec2} a the first operand
3905 * @param {ReadonlyVec2} b the second operand
3906 * @returns {vec2} out
3907 */
3908
3909 function min$1(out, a, b) {
3910 out[0] = Math.min(a[0], b[0]);
3911 out[1] = Math.min(a[1], b[1]);
3912 return out;
3913 }
3914 /**
3915 * Returns the maximum of two vec2's
3916 *
3917 * @param {vec2} out the receiving vector
3918 * @param {ReadonlyVec2} a the first operand
3919 * @param {ReadonlyVec2} b the second operand
3920 * @returns {vec2} out
3921 */
3922
3923 function max$1(out, a, b) {
3924 out[0] = Math.max(a[0], b[0]);
3925 out[1] = Math.max(a[1], b[1]);
3926 return out;
3927 }
3928 /**
3929 * Scales a vec2 by a scalar number
3930 *
3931 * @param {vec2} out the receiving vector
3932 * @param {ReadonlyVec2} a the vector to scale
3933 * @param {Number} b amount to scale the vector by
3934 * @returns {vec2} out
3935 */
3936
3937 function scale$2(out, a, b) {
3938 out[0] = a[0] * b;
3939 out[1] = a[1] * b;
3940 return out;
3941 }
3942 /**
3943 * Calculates the euclidian distance between two vec2's
3944 *
3945 * @param {ReadonlyVec2} a the first operand
3946 * @param {ReadonlyVec2} b the second operand
3947 * @returns {Number} distance between a and b
3948 */
3949
3950 function distance(a, b) {
3951 var x = b[0] - a[0],
3952 y = b[1] - a[1];
3953 return Math.hypot(x, y);
3954 }
3955 /**
3956 * Calculates the length of a vec2
3957 *
3958 * @param {ReadonlyVec2} a vector to calculate length of
3959 * @returns {Number} length of a
3960 */
3961
3962 function length$1(a) {
3963 var x = a[0],
3964 y = a[1];
3965 return Math.hypot(x, y);
3966 }
3967 /**
3968 * Normalize a vec2
3969 *
3970 * @param {vec2} out the receiving vector
3971 * @param {ReadonlyVec2} a vector to normalize
3972 * @returns {vec2} out
3973 */
3974
3975 function normalize$3(out, a) {
3976 var x = a[0],
3977 y = a[1];
3978 var len = x * x + y * y;
3979
3980 if (len > 0) {
3981 //TODO: evaluate use of glm_invsqrt here?
3982 len = 1 / Math.sqrt(len);
3983 }
3984
3985 out[0] = a[0] * len;
3986 out[1] = a[1] * len;
3987 return out;
3988 }
3989 /**
3990 * Calculates the dot product of two vec2's
3991 *
3992 * @param {ReadonlyVec2} a the first operand
3993 * @param {ReadonlyVec2} b the second operand
3994 * @returns {Number} dot product of a and b
3995 */
3996
3997 function dot$1(a, b) {
3998 return a[0] * b[0] + a[1] * b[1];
3999 }
4000 /**
4001 * Transforms the vec2 with a mat2d
4002 *
4003 * @param {vec2} out the receiving vector
4004 * @param {ReadonlyVec2} a the vector to transform
4005 * @param {ReadonlyMat2d} m matrix to transform with
4006 * @returns {vec2} out
4007 */
4008
4009 function transformMat2d(out, a, m) {
4010 var x = a[0],
4011 y = a[1];
4012 out[0] = m[0] * x + m[2] * y + m[4];
4013 out[1] = m[1] * x + m[3] * y + m[5];
4014 return out;
4015 }
4016 /**
4017 * Get the angle between two 2D vectors
4018 * @param {ReadonlyVec2} a The first operand
4019 * @param {ReadonlyVec2} b The second operand
4020 * @returns {Number} The angle in radians
4021 */
4022
4023 function angle(a, b) {
4024 var x1 = a[0],
4025 y1 = a[1],
4026 x2 = b[0],
4027 y2 = b[1],
4028 // mag is the product of the magnitudes of a and b
4029 mag = Math.sqrt(x1 * x1 + y1 * y1) * Math.sqrt(x2 * x2 + y2 * y2),
4030 // mag &&.. short circuits if mag == 0
4031 cosine = mag && (x1 * x2 + y1 * y2) / mag; // Math.min(Math.max(cosine, -1), 1) clamps the cosine between -1 and 1
4032
4033 return Math.acos(Math.min(Math.max(cosine, -1), 1));
4034 }
4035 /**
4036 * Returns whether or not the vectors exactly have the same elements in the same position (when compared with ===)
4037 *
4038 * @param {ReadonlyVec2} a The first vector.
4039 * @param {ReadonlyVec2} b The second vector.
4040 * @returns {Boolean} True if the vectors are equal, false otherwise.
4041 */
4042
4043 function exactEquals$1(a, b) {
4044 return a[0] === b[0] && a[1] === b[1];
4045 }
4046 /**
4047 * Alias for {@link vec2.subtract}
4048 * @function
4049 */
4050
4051 var sub$1 = subtract$2;
4052 /**
4053 * Perform some operation over an array of vec2s.
4054 *
4055 * @param {Array} a the array of vectors to iterate over
4056 * @param {Number} stride Number of elements between the start of each vec2. If 0 assumes tightly packed
4057 * @param {Number} offset Number of elements to skip at the beginning of the array
4058 * @param {Number} count Number of vec2s to iterate over. If 0 iterates over entire array
4059 * @param {Function} fn Function to call for each vector in the array
4060 * @param {Object} [arg] additional argument to pass to fn
4061 * @returns {Array} a
4062 * @function
4063 */
4064
4065 var forEach$2 = function () {
4066 var vec = create$5();
4067 return function (a, stride, offset, count, fn, arg) {
4068 var i, l;
4069
4070 if (!stride) {
4071 stride = 2;
4072 }
4073
4074 if (!offset) {
4075 offset = 0;
4076 }
4077
4078 if (count) {
4079 l = Math.min(count * stride + offset, a.length);
4080 } else {
4081 l = a.length;
4082 }
4083
4084 for (i = offset; i < l; i += stride) {
4085 vec[0] = a[i];
4086 vec[1] = a[i + 1];
4087 fn(vec, vec, arg);
4088 a[i] = vec[0];
4089 a[i + 1] = vec[1];
4090 }
4091
4092 return a;
4093 };
4094 }();
4095
4096 /**
4097 * Rounds the values of a `PathArray` instance to
4098 * a specified amount of decimals and returns it.
4099 */
4100 function roundPath(path, round) {
4101 if (round === 'off')
4102 return [].concat(path);
4103 // to round values to the power
4104 // the `round` value must be integer
4105 var pow = typeof round === 'number' && round >= 1 ? Math.pow(10, round) : 1;
4106 return path.map(function (pi) {
4107 var values = pi
4108 .slice(1)
4109 .map(Number)
4110 .map(function (n) { return (round ? Math.round(n * pow) / pow : Math.round(n)); });
4111 // @ts-ignore
4112 return [pi[0]].concat(values);
4113 });
4114 }
4115
4116 /**
4117 * Returns a valid `d` attribute string value created
4118 * by rounding values and concatenating the `pathArray` segments.
4119 */
4120 function path2String(path, round) {
4121 if (round === void 0) { round = 'off'; }
4122 return roundPath(path, round)
4123 .map(function (x) { return x[0] + x.slice(1).join(' '); })
4124 .join('');
4125 }
4126
4127 var paramsParser = {
4128 x1: 0,
4129 y1: 0,
4130 x2: 0,
4131 y2: 0,
4132 x: 0,
4133 y: 0,
4134 qx: null,
4135 qy: null,
4136 };
4137
4138 function fixArc(pathArray, allPathCommands, i) {
4139 if (pathArray[i].length > 7) {
4140 pathArray[i].shift();
4141 var pi = pathArray[i];
4142 // const ni = i + 1;
4143 var ni = i;
4144 while (pi.length) {
4145 // if created multiple C:s, their original seg is saved
4146 allPathCommands[i] = 'A';
4147 // @ts-ignore
4148 pathArray.splice((ni += 1), 0, ['C'].concat(pi.splice(0, 6)));
4149 }
4150 pathArray.splice(i, 1);
4151 }
4152 }
4153
4154 var paramsCount = {
4155 a: 7,
4156 c: 6,
4157 h: 1,
4158 l: 2,
4159 m: 2,
4160 r: 4,
4161 q: 4,
4162 s: 4,
4163 t: 2,
4164 v: 1,
4165 z: 0,
4166 };
4167
4168 /**
4169 * Iterates an array to check if it's an actual `PathArray`.
4170 */
4171 function isPathArray(path) {
4172 return (Array.isArray(path) &&
4173 path.every(function (seg) {
4174 var lk = seg[0].toLowerCase();
4175 return paramsCount[lk] === seg.length - 1 && 'achlmqstvz'.includes(lk);
4176 }));
4177 }
4178
4179 /**
4180 * Iterates an array to check if it's a `PathArray`
4181 * with all absolute values.
4182 */
4183 function isAbsoluteArray(path) {
4184 return (isPathArray(path) &&
4185 // @ts-ignore -- `isPathArray` also checks if it's `Array`
4186 path.every(function (_a) {
4187 var x = _a[0];
4188 return x === x.toUpperCase();
4189 }));
4190 }
4191
4192 /**
4193 * Iterates an array to check if it's a `PathArray`
4194 * with all segments are in non-shorthand notation
4195 * with absolute values.
4196 */
4197 function isNormalizedArray(path) {
4198 return isAbsoluteArray(path) && path.every(function (_a) {
4199 var pc = _a[0];
4200 return 'ACLMQZ'.includes(pc);
4201 });
4202 }
4203
4204 /**
4205 * Breaks the parsing of a pathString once a segment is finalized.
4206 */
4207 function finalizeSegment(path) {
4208 var pathCommand = path.pathValue[path.segmentStart];
4209 var LK = pathCommand.toLowerCase();
4210 var data = path.data;
4211 while (data.length >= paramsCount[LK]) {
4212 // overloaded `moveTo`
4213 // https://github.com/rveciana/svg-path-properties/blob/master/src/parse.ts
4214 if (LK === 'm' && data.length > 2) {
4215 // @ts-ignore
4216 path.segments.push([pathCommand].concat(data.splice(0, 2)));
4217 LK = 'l';
4218 pathCommand = pathCommand === 'm' ? 'l' : 'L';
4219 }
4220 else {
4221 // @ts-ignore
4222 path.segments.push([pathCommand].concat(data.splice(0, paramsCount[LK])));
4223 }
4224 if (!paramsCount[LK]) {
4225 break;
4226 }
4227 }
4228 }
4229
4230 /**
4231 * Validates an A (arc-to) specific path command value.
4232 * Usually a `large-arc-flag` or `sweep-flag`.
4233 */
4234 function scanFlag(path) {
4235 var index = path.index, pathValue = path.pathValue;
4236 var code = pathValue.charCodeAt(index);
4237 if (code === 0x30 /* 0 */) {
4238 path.param = 0;
4239 path.index += 1;
4240 return;
4241 }
4242 if (code === 0x31 /* 1 */) {
4243 path.param = 1;
4244 path.index += 1;
4245 return;
4246 }
4247 path.err = "[path-util]: invalid Arc flag \"" + pathValue[index] + "\", expecting 0 or 1 at index " + index;
4248 }
4249
4250 /**
4251 * Checks if the character is or belongs to a number.
4252 * [0-9]|+|-|.
4253 */
4254 function isDigitStart(code) {
4255 return ((code >= 48 && code <= 57) /* 0..9 */ || code === 0x2b /* + */ || code === 0x2d /* - */ || code === 0x2e); /* . */
4256 }
4257 function isDigit(code) {
4258 return code >= 48 && code <= 57; // 0..9
4259 }
4260
4261 /**
4262 * Validates every character of the path string,
4263 * every path command, negative numbers or floating point numbers.
4264 */
4265 function scanParam(path) {
4266 var max = path.max, pathValue = path.pathValue, start = path.index;
4267 var index = start;
4268 var zeroFirst = false;
4269 var hasCeiling = false;
4270 var hasDecimal = false;
4271 var hasDot = false;
4272 var ch;
4273 if (index >= max) {
4274 // path.err = 'SvgPath: missed param (at pos ' + index + ')';
4275 path.err = "[path-util]: Invalid path value at index " + index + ", \"pathValue\" is missing param";
4276 return;
4277 }
4278 ch = pathValue.charCodeAt(index);
4279 if (ch === 0x2b /* + */ || ch === 0x2d /* - */) {
4280 index += 1;
4281 // ch = (index < max) ? pathValue.charCodeAt(index) : 0;
4282 ch = pathValue.charCodeAt(index);
4283 }
4284 // This logic is shamelessly borrowed from Esprima
4285 // https://github.com/ariya/esprimas
4286 if (!isDigit(ch) && ch !== 0x2e /* . */) {
4287 // path.err = 'SvgPath: param should start with 0..9 or `.` (at pos ' + index + ')';
4288 path.err = "[path-util]: Invalid path value at index " + index + ", \"" + pathValue[index] + "\" is not a number";
4289 return;
4290 }
4291 if (ch !== 0x2e /* . */) {
4292 zeroFirst = ch === 0x30 /* 0 */;
4293 index += 1;
4294 ch = pathValue.charCodeAt(index);
4295 if (zeroFirst && index < max) {
4296 // decimal number starts with '0' such as '09' is illegal.
4297 if (ch && isDigit(ch)) {
4298 // path.err = 'SvgPath: numbers started with `0` such as `09`
4299 // are illegal (at pos ' + start + ')';
4300 path.err = "[path-util]: Invalid path value at index " + start + ", \"" + pathValue[start] + "\" illegal number";
4301 return;
4302 }
4303 }
4304 while (index < max && isDigit(pathValue.charCodeAt(index))) {
4305 index += 1;
4306 hasCeiling = true;
4307 }
4308 ch = pathValue.charCodeAt(index);
4309 }
4310 if (ch === 0x2e /* . */) {
4311 hasDot = true;
4312 index += 1;
4313 while (isDigit(pathValue.charCodeAt(index))) {
4314 index += 1;
4315 hasDecimal = true;
4316 }
4317 ch = pathValue.charCodeAt(index);
4318 }
4319 if (ch === 0x65 /* e */ || ch === 0x45 /* E */) {
4320 if (hasDot && !hasCeiling && !hasDecimal) {
4321 path.err = "[path-util]: Invalid path value at index " + index + ", \"" + pathValue[index] + "\" invalid float exponent";
4322 return;
4323 }
4324 index += 1;
4325 ch = pathValue.charCodeAt(index);
4326 if (ch === 0x2b /* + */ || ch === 0x2d /* - */) {
4327 index += 1;
4328 }
4329 if (index < max && isDigit(pathValue.charCodeAt(index))) {
4330 while (index < max && isDigit(pathValue.charCodeAt(index))) {
4331 index += 1;
4332 }
4333 }
4334 else {
4335 path.err = "[path-util]: Invalid path value at index " + index + ", \"" + pathValue[index] + "\" invalid integer exponent";
4336 return;
4337 }
4338 }
4339 path.index = index;
4340 path.param = +path.pathValue.slice(start, index);
4341 }
4342
4343 /**
4344 * Checks if the character is a space.
4345 */
4346 function isSpace(ch) {
4347 var specialSpaces = [
4348 0x1680, 0x180e, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200a, 0x202f,
4349 0x205f, 0x3000, 0xfeff,
4350 ];
4351 /* istanbul ignore next */
4352 return (ch === 0x0a ||
4353 ch === 0x0d ||
4354 ch === 0x2028 ||
4355 ch === 0x2029 || // Line terminators
4356 // White spaces
4357 ch === 0x20 ||
4358 ch === 0x09 ||
4359 ch === 0x0b ||
4360 ch === 0x0c ||
4361 ch === 0xa0 ||
4362 (ch >= 0x1680 && specialSpaces.includes(ch)));
4363 }
4364
4365 /**
4366 * Points the parser to the next character in the
4367 * path string every time it encounters any kind of
4368 * space character.
4369 */
4370 function skipSpaces(path) {
4371 var pathValue = path.pathValue, max = path.max;
4372 while (path.index < max && isSpace(pathValue.charCodeAt(path.index))) {
4373 path.index += 1;
4374 }
4375 }
4376
4377 /**
4378 * Checks if the character is a path command.
4379 */
4380 function isPathCommand(code) {
4381 // eslint-disable-next-line no-bitwise -- Impossible to satisfy
4382 switch (code | 0x20) {
4383 case 0x6d /* m */:
4384 case 0x7a /* z */:
4385 case 0x6c /* l */:
4386 case 0x68 /* h */:
4387 case 0x76 /* v */:
4388 case 0x63 /* c */:
4389 case 0x73 /* s */:
4390 case 0x71 /* q */:
4391 case 0x74 /* t */:
4392 case 0x61 /* a */:
4393 // case 0x72/* r */:
4394 return true;
4395 default:
4396 return false;
4397 }
4398 }
4399
4400 /**
4401 * Checks if the character is an A (arc-to) path command.
4402 */
4403 function isArcCommand(code) {
4404 return (code | 0x20) === 0x61;
4405 }
4406
4407 /**
4408 * Scans every character in the path string to determine
4409 * where a segment starts and where it ends.
4410 */
4411 function scanSegment(path) {
4412 var max = path.max, pathValue = path.pathValue, index = path.index;
4413 var cmdCode = pathValue.charCodeAt(index);
4414 var reqParams = paramsCount[pathValue[index].toLowerCase()];
4415 path.segmentStart = index;
4416 if (!isPathCommand(cmdCode)) {
4417 path.err = "[path-util]: Invalid path value \"" + pathValue[index] + "\" is not a path command";
4418 return;
4419 }
4420 path.index += 1;
4421 skipSpaces(path);
4422 path.data = [];
4423 if (!reqParams) {
4424 // Z
4425 finalizeSegment(path);
4426 return;
4427 }
4428 for (;;) {
4429 for (var i = reqParams; i > 0; i -= 1) {
4430 if (isArcCommand(cmdCode) && (i === 3 || i === 4))
4431 scanFlag(path);
4432 else
4433 scanParam(path);
4434 if (path.err.length) {
4435 return;
4436 }
4437 path.data.push(path.param);
4438 skipSpaces(path);
4439 // after ',' param is mandatory
4440 if (path.index < max && pathValue.charCodeAt(path.index) === 0x2c /* , */) {
4441 path.index += 1;
4442 skipSpaces(path);
4443 }
4444 }
4445 if (path.index >= path.max) {
4446 break;
4447 }
4448 // Stop on next segment
4449 if (!isDigitStart(pathValue.charCodeAt(path.index))) {
4450 break;
4451 }
4452 }
4453 finalizeSegment(path);
4454 }
4455
4456 /**
4457 * The `PathParser` is used by the `parsePathString` static method
4458 * to generate a `pathArray`.
4459 */
4460 var PathParser = /** @class */ (function () {
4461 function PathParser(pathString) {
4462 this.pathValue = pathString;
4463 // @ts-ignore
4464 this.segments = [];
4465 this.max = pathString.length;
4466 this.index = 0;
4467 this.param = 0.0;
4468 this.segmentStart = 0;
4469 this.data = [];
4470 this.err = '';
4471 }
4472 return PathParser;
4473 }());
4474
4475 /**
4476 * Parses a path string value and returns an array
4477 * of segments we like to call `pathArray`.
4478 */
4479 function parsePathString(pathInput) {
4480 if (isPathArray(pathInput)) {
4481 return [].concat(pathInput);
4482 }
4483 var path = new PathParser(pathInput);
4484 skipSpaces(path);
4485 while (path.index < path.max && !path.err.length) {
4486 scanSegment(path);
4487 }
4488 return path.err ? path.err : path.segments;
4489 }
4490
4491 function path2Absolute(pathInput) {
4492 if (isAbsoluteArray(pathInput)) {
4493 return [].concat(pathInput);
4494 }
4495 var path = parsePathString(pathInput);
4496 // if (!path || !path.length) {
4497 // return [['M', 0, 0]];
4498 // }
4499 var x = 0;
4500 var y = 0;
4501 var mx = 0;
4502 var my = 0;
4503 // @ts-ignore
4504 return path.map(function (segment) {
4505 var values = segment.slice(1).map(Number);
4506 var pathCommand = segment[0];
4507 var absCommand = pathCommand.toUpperCase();
4508 if (pathCommand === 'M') {
4509 x = values[0], y = values[1];
4510 mx = x;
4511 my = y;
4512 return ['M', x, y];
4513 }
4514 var absoluteSegment;
4515 if (pathCommand !== absCommand) {
4516 switch (absCommand) {
4517 case 'A':
4518 absoluteSegment = [
4519 absCommand,
4520 values[0],
4521 values[1],
4522 values[2],
4523 values[3],
4524 values[4],
4525 values[5] + x,
4526 values[6] + y,
4527 ];
4528 break;
4529 case 'V':
4530 absoluteSegment = [absCommand, values[0] + y];
4531 break;
4532 case 'H':
4533 absoluteSegment = [absCommand, values[0] + x];
4534 break;
4535 default: {
4536 // use brakets for `eslint: no-case-declaration`
4537 // https://stackoverflow.com/a/50753272/803358
4538 var absValues = values.map(function (n, j) { return n + (j % 2 ? y : x); });
4539 // for n, l, c, s, q, t
4540 // @ts-ignore
4541 absoluteSegment = [absCommand].concat(absValues);
4542 }
4543 }
4544 }
4545 else {
4546 // @ts-ignore
4547 absoluteSegment = [absCommand].concat(values);
4548 }
4549 var segLength = absoluteSegment.length;
4550 switch (absCommand) {
4551 case 'Z':
4552 x = mx;
4553 y = my;
4554 break;
4555 case 'H':
4556 x = absoluteSegment[1];
4557 break;
4558 case 'V':
4559 y = absoluteSegment[1];
4560 break;
4561 default:
4562 x = absoluteSegment[segLength - 2];
4563 y = absoluteSegment[segLength - 1];
4564 if (absCommand === 'M') {
4565 mx = x;
4566 my = y;
4567 }
4568 }
4569 return absoluteSegment;
4570 });
4571 }
4572
4573 /**
4574 * Normalizes a single segment of a `PathArray` object.
4575 * eg. H/V -> L, T -> Q
4576 */
4577 function normalizeSegment(segment, params) {
4578 var pathCommand = segment[0];
4579 var px1 = params.x1, py1 = params.y1, px2 = params.x2, py2 = params.y2;
4580 var values = segment.slice(1).map(Number);
4581 var result = segment;
4582 if (!'TQ'.includes(pathCommand)) {
4583 // optional but good to be cautious
4584 params.qx = null;
4585 params.qy = null;
4586 }
4587 if (pathCommand === 'H') {
4588 result = ['L', segment[1], py1];
4589 }
4590 else if (pathCommand === 'V') {
4591 result = ['L', px1, segment[1]];
4592 }
4593 else if (pathCommand === 'S') {
4594 var x1 = px1 * 2 - px2;
4595 var y1 = py1 * 2 - py2;
4596 params.x1 = x1;
4597 params.y1 = y1;
4598 result = ['C', x1, y1].concat(values);
4599 }
4600 else if (pathCommand === 'T') {
4601 var qx = px1 * 2 - params.qx;
4602 var qy = py1 * 2 - params.qy;
4603 params.qx = qx;
4604 params.qy = qy;
4605 result = ['Q', qx, qy].concat(values);
4606 }
4607 else if (pathCommand === 'Q') {
4608 var nqx = values[0], nqy = values[1];
4609 params.qx = nqx;
4610 params.qy = nqy;
4611 }
4612 return result;
4613 }
4614
4615 /**
4616 * @example
4617 * const path = 'M0 0 H50';
4618 * const normalizedPath = SVGPathCommander.normalizePath(path);
4619 * // result => [['M', 0, 0], ['L', 50, 0]]
4620 */
4621 function normalizePath(pathInput) {
4622 if (isNormalizedArray(pathInput)) {
4623 return [].concat(pathInput);
4624 }
4625 var path = path2Absolute(pathInput);
4626 var params = __assign({}, paramsParser);
4627 for (var i = 0; i < path.length; i += 1) {
4628 // Save current path command
4629 path[i] = normalizeSegment(path[i], params);
4630 var segment = path[i];
4631 var seglen = segment.length;
4632 params.x1 = +segment[seglen - 2];
4633 params.y1 = +segment[seglen - 1];
4634 params.x2 = +segment[seglen - 4] || params.x1;
4635 params.y2 = +segment[seglen - 3] || params.y1;
4636 }
4637 return path;
4638 }
4639
4640 /**
4641 * Iterates an array to check if it's a `PathArray`
4642 * with all C (cubic bezier) segments.
4643 *
4644 * @param {string | PathArray} path the `Array` to be checked
4645 * @returns {boolean} iteration result
4646 */
4647 function isCurveArray(path) {
4648 return isNormalizedArray(path) && path.every(function (_a) {
4649 var pc = _a[0];
4650 return 'MC'.includes(pc);
4651 });
4652 }
4653
4654 function rotateVector(x, y, rad) {
4655 var X = x * Math.cos(rad) - y * Math.sin(rad);
4656 var Y = x * Math.sin(rad) + y * Math.cos(rad);
4657 return { x: X, y: Y };
4658 }
4659
4660 /**
4661 * Converts A (arc-to) segments to C (cubic-bezier-to).
4662 *
4663 * For more information of where this math came from visit:
4664 * http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes
4665 */
4666 function arcToCubic(X1, Y1, RX, RY, angle, LAF, SF, X2, Y2, recursive) {
4667 var x1 = X1;
4668 var y1 = Y1;
4669 var rx = RX;
4670 var ry = RY;
4671 var x2 = X2;
4672 var y2 = Y2;
4673 // for more information of where this Math came from visit:
4674 // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes
4675 var d120 = (Math.PI * 120) / 180;
4676 var rad = (Math.PI / 180) * (+angle || 0);
4677 /** @type {number[]} */
4678 var res = [];
4679 var xy;
4680 var f1;
4681 var f2;
4682 var cx;
4683 var cy;
4684 if (!recursive) {
4685 xy = rotateVector(x1, y1, -rad);
4686 x1 = xy.x;
4687 y1 = xy.y;
4688 xy = rotateVector(x2, y2, -rad);
4689 x2 = xy.x;
4690 y2 = xy.y;
4691 var x = (x1 - x2) / 2;
4692 var y = (y1 - y2) / 2;
4693 var h = (x * x) / (rx * rx) + (y * y) / (ry * ry);
4694 if (h > 1) {
4695 h = Math.sqrt(h);
4696 rx *= h;
4697 ry *= h;
4698 }
4699 var rx2 = rx * rx;
4700 var ry2 = ry * ry;
4701 var k = (LAF === SF ? -1 : 1) *
4702 Math.sqrt(Math.abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x)));
4703 cx = (k * rx * y) / ry + (x1 + x2) / 2;
4704 cy = (k * -ry * x) / rx + (y1 + y2) / 2;
4705 // eslint-disable-next-line no-bitwise -- Impossible to satisfy no-bitwise
4706 f1 = Math.asin(((((y1 - cy) / ry) * Math.pow(10, 9)) >> 0) / Math.pow(10, 9));
4707 // eslint-disable-next-line no-bitwise -- Impossible to satisfy no-bitwise
4708 f2 = Math.asin(((((y2 - cy) / ry) * Math.pow(10, 9)) >> 0) / Math.pow(10, 9));
4709 f1 = x1 < cx ? Math.PI - f1 : f1;
4710 f2 = x2 < cx ? Math.PI - f2 : f2;
4711 if (f1 < 0)
4712 f1 = Math.PI * 2 + f1;
4713 if (f2 < 0)
4714 f2 = Math.PI * 2 + f2;
4715 if (SF && f1 > f2) {
4716 f1 -= Math.PI * 2;
4717 }
4718 if (!SF && f2 > f1) {
4719 f2 -= Math.PI * 2;
4720 }
4721 }
4722 else {
4723 f1 = recursive[0], f2 = recursive[1], cx = recursive[2], cy = recursive[3];
4724 }
4725 var df = f2 - f1;
4726 if (Math.abs(df) > d120) {
4727 var f2old = f2;
4728 var x2old = x2;
4729 var y2old = y2;
4730 f2 = f1 + d120 * (SF && f2 > f1 ? 1 : -1);
4731 x2 = cx + rx * Math.cos(f2);
4732 y2 = cy + ry * Math.sin(f2);
4733 res = arcToCubic(x2, y2, rx, ry, angle, 0, SF, x2old, y2old, [f2, f2old, cx, cy]);
4734 }
4735 df = f2 - f1;
4736 var c1 = Math.cos(f1);
4737 var s1 = Math.sin(f1);
4738 var c2 = Math.cos(f2);
4739 var s2 = Math.sin(f2);
4740 var t = Math.tan(df / 4);
4741 var hx = (4 / 3) * rx * t;
4742 var hy = (4 / 3) * ry * t;
4743 var m1 = [x1, y1];
4744 var m2 = [x1 + hx * s1, y1 - hy * c1];
4745 var m3 = [x2 + hx * s2, y2 - hy * c2];
4746 var m4 = [x2, y2];
4747 m2[0] = 2 * m1[0] - m2[0];
4748 m2[1] = 2 * m1[1] - m2[1];
4749 if (recursive) {
4750 return m2.concat(m3, m4, res);
4751 // return [...m2, ...m3, ...m4, ...res];
4752 }
4753 res = m2.concat(m3, m4, res);
4754 // res = [...m2, ...m3, ...m4, ...res];
4755 var newres = [];
4756 for (var i = 0, ii = res.length; i < ii; i += 1) {
4757 newres[i] = i % 2 ? rotateVector(res[i - 1], res[i], rad).y : rotateVector(res[i], res[i + 1], rad).x;
4758 }
4759 return newres;
4760 }
4761 // const TAU = Math.PI * 2;
4762 // const mapToEllipse = (
4763 // { x, y }: { x: number; y: number },
4764 // rx: number,
4765 // ry: number,
4766 // cosphi: number,
4767 // sinphi: number,
4768 // centerx: number,
4769 // centery: number,
4770 // ) => {
4771 // x *= rx;
4772 // y *= ry;
4773 // const xp = cosphi * x - sinphi * y;
4774 // const yp = sinphi * x + cosphi * y;
4775 // return {
4776 // x: xp + centerx,
4777 // y: yp + centery,
4778 // };
4779 // };
4780 // const approxUnitArc = (ang1: number, ang2: number) => {
4781 // // If 90 degree circular arc, use a constant
4782 // // as derived from http://spencermortensen.com/articles/bezier-circle
4783 // const a =
4784 // ang2 === 1.5707963267948966
4785 // ? 0.551915024494
4786 // : ang2 === -1.5707963267948966
4787 // ? -0.551915024494
4788 // : (4 / 3) * Math.tan(ang2 / 4);
4789 // const x1 = Math.cos(ang1);
4790 // const y1 = Math.sin(ang1);
4791 // const x2 = Math.cos(ang1 + ang2);
4792 // const y2 = Math.sin(ang1 + ang2);
4793 // return [
4794 // {
4795 // x: x1 - y1 * a,
4796 // y: y1 + x1 * a,
4797 // },
4798 // {
4799 // x: x2 + y2 * a,
4800 // y: y2 - x2 * a,
4801 // },
4802 // {
4803 // x: x2,
4804 // y: y2,
4805 // },
4806 // ];
4807 // };
4808 // const vectorAngle = (ux: number, uy: number, vx: number, vy: number) => {
4809 // const sign = ux * vy - uy * vx < 0 ? -1 : 1;
4810 // let dot = ux * vx + uy * vy;
4811 // if (dot > 1) {
4812 // dot = 1;
4813 // }
4814 // if (dot < -1) {
4815 // dot = -1;
4816 // }
4817 // return sign * Math.acos(dot);
4818 // };
4819 // const getArcCenter = (
4820 // px: any,
4821 // py: any,
4822 // cx: any,
4823 // cy: any,
4824 // rx: number,
4825 // ry: number,
4826 // largeArcFlag: number,
4827 // sweepFlag: number,
4828 // sinphi: number,
4829 // cosphi: number,
4830 // pxp: number,
4831 // pyp: number,
4832 // ) => {
4833 // const rxsq = Math.pow(rx, 2);
4834 // const rysq = Math.pow(ry, 2);
4835 // const pxpsq = Math.pow(pxp, 2);
4836 // const pypsq = Math.pow(pyp, 2);
4837 // let radicant = rxsq * rysq - rxsq * pypsq - rysq * pxpsq;
4838 // if (radicant < 0) {
4839 // radicant = 0;
4840 // }
4841 // radicant /= rxsq * pypsq + rysq * pxpsq;
4842 // radicant = Math.sqrt(radicant) * (largeArcFlag === sweepFlag ? -1 : 1);
4843 // const centerxp = ((radicant * rx) / ry) * pyp;
4844 // const centeryp = ((radicant * -ry) / rx) * pxp;
4845 // const centerx = cosphi * centerxp - sinphi * centeryp + (px + cx) / 2;
4846 // const centery = sinphi * centerxp + cosphi * centeryp + (py + cy) / 2;
4847 // const vx1 = (pxp - centerxp) / rx;
4848 // const vy1 = (pyp - centeryp) / ry;
4849 // const vx2 = (-pxp - centerxp) / rx;
4850 // const vy2 = (-pyp - centeryp) / ry;
4851 // const ang1 = vectorAngle(1, 0, vx1, vy1);
4852 // let ang2 = vectorAngle(vx1, vy1, vx2, vy2);
4853 // if (sweepFlag === 0 && ang2 > 0) {
4854 // ang2 -= TAU;
4855 // }
4856 // if (sweepFlag === 1 && ang2 < 0) {
4857 // ang2 += TAU;
4858 // }
4859 // return [centerx, centery, ang1, ang2];
4860 // };
4861 // const arcToBezier = ({ px, py, cx, cy, rx, ry, xAxisRotation = 0, largeArcFlag = 0, sweepFlag = 0 }) => {
4862 // const curves = [];
4863 // if (rx === 0 || ry === 0) {
4864 // return [{ x1: 0, y1: 0, x2: 0, y2: 0, x: cx, y: cy }];
4865 // }
4866 // const sinphi = Math.sin((xAxisRotation * TAU) / 360);
4867 // const cosphi = Math.cos((xAxisRotation * TAU) / 360);
4868 // const pxp = (cosphi * (px - cx)) / 2 + (sinphi * (py - cy)) / 2;
4869 // const pyp = (-sinphi * (px - cx)) / 2 + (cosphi * (py - cy)) / 2;
4870 // if (pxp === 0 && pyp === 0) {
4871 // return [{ x1: 0, y1: 0, x2: 0, y2: 0, x: cx, y: cy }];
4872 // }
4873 // rx = Math.abs(rx);
4874 // ry = Math.abs(ry);
4875 // const lambda = Math.pow(pxp, 2) / Math.pow(rx, 2) + Math.pow(pyp, 2) / Math.pow(ry, 2);
4876 // if (lambda > 1) {
4877 // rx *= Math.sqrt(lambda);
4878 // ry *= Math.sqrt(lambda);
4879 // }
4880 // let [centerx, centery, ang1, ang2] = getArcCenter(
4881 // px,
4882 // py,
4883 // cx,
4884 // cy,
4885 // rx,
4886 // ry,
4887 // largeArcFlag,
4888 // sweepFlag,
4889 // sinphi,
4890 // cosphi,
4891 // pxp,
4892 // pyp,
4893 // );
4894 // // If 'ang2' == 90.0000000001, then `ratio` will evaluate to
4895 // // 1.0000000001. This causes `segments` to be greater than one, which is an
4896 // // unecessary split, and adds extra points to the bezier curve. To alleviate
4897 // // this issue, we round to 1.0 when the ratio is close to 1.0.
4898 // let ratio = Math.abs(ang2) / (TAU / 4);
4899 // if (Math.abs(1.0 - ratio) < 0.0000001) {
4900 // ratio = 1.0;
4901 // }
4902 // const segments = Math.max(Math.ceil(ratio), 1);
4903 // ang2 /= segments;
4904 // for (let i = 0; i < segments; i++) {
4905 // curves.push(approxUnitArc(ang1, ang2));
4906 // ang1 += ang2;
4907 // }
4908 // return curves.map((curve) => {
4909 // const { x: x1, y: y1 } = mapToEllipse(curve[0], rx, ry, cosphi, sinphi, centerx, centery);
4910 // const { x: x2, y: y2 } = mapToEllipse(curve[1], rx, ry, cosphi, sinphi, centerx, centery);
4911 // const { x, y } = mapToEllipse(curve[2], rx, ry, cosphi, sinphi, centerx, centery);
4912 // return { x1, y1, x2, y2, x, y };
4913 // });
4914 // };
4915 // export function arcToCubic(
4916 // x1: number,
4917 // y1: number,
4918 // rx: number,
4919 // ry: number,
4920 // angle: number,
4921 // LAF: number,
4922 // SF: number,
4923 // x2: number,
4924 // y2: number,
4925 // ) {
4926 // const curves = arcToBezier({
4927 // px: x1,
4928 // py: y1,
4929 // cx: x2,
4930 // cy: y2,
4931 // rx,
4932 // ry,
4933 // xAxisRotation: angle,
4934 // largeArcFlag: LAF,
4935 // sweepFlag: SF,
4936 // });
4937 // return curves.reduce((prev, cur) => {
4938 // const { x1, y1, x2, y2, x, y } = cur;
4939 // prev.push(x1, y1, x2, y2, x, y);
4940 // return prev;
4941 // }, [] as number[]);
4942 // }
4943
4944 function quadToCubic(x1, y1, qx, qy, x2, y2) {
4945 var r13 = 1 / 3;
4946 var r23 = 2 / 3;
4947 return [
4948 r13 * x1 + r23 * qx,
4949 r13 * y1 + r23 * qy,
4950 r13 * x2 + r23 * qx,
4951 r13 * y2 + r23 * qy,
4952 x2,
4953 y2, // x,y
4954 ];
4955 }
4956
4957 function midPoint(a, b, t) {
4958 var ax = a[0];
4959 var ay = a[1];
4960 var bx = b[0];
4961 var by = b[1];
4962 return [ax + (bx - ax) * t, ay + (by - ay) * t];
4963 }
4964
4965 var lineToCubic = function (x1, y1, x2, y2) {
4966 var t = 0.5;
4967 var mid = midPoint([x1, y1], [x2, y2], t);
4968 return __spreadArray(__spreadArray([], mid, true), [x2, y2, x2, y2], false);
4969 };
4970
4971 function segmentToCubic(segment, params) {
4972 var pathCommand = segment[0];
4973 var values = segment.slice(1).map(Number);
4974 var x = values[0], y = values[1];
4975 var args;
4976 var px1 = params.x1, py1 = params.y1, px = params.x, py = params.y;
4977 if (!'TQ'.includes(pathCommand)) {
4978 params.qx = null;
4979 params.qy = null;
4980 }
4981 switch (pathCommand) {
4982 case 'M':
4983 params.x = x;
4984 params.y = y;
4985 return segment;
4986 case 'A':
4987 args = [px1, py1].concat(values);
4988 // @ts-ignore
4989 return ['C'].concat(arcToCubic(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9]));
4990 case 'Q':
4991 params.qx = x;
4992 params.qy = y;
4993 args = [px1, py1].concat(values);
4994 // @ts-ignore
4995 return ['C'].concat(quadToCubic(args[0], args[1], args[2], args[3], args[4], args[5]));
4996 case 'L':
4997 // @ts-ignore
4998 return ['C'].concat(lineToCubic(px1, py1, x, y));
4999 case 'Z':
5000 // prevent NaN from divide 0
5001 if (px1 === px && py1 === py) {
5002 return ['C', px1, py1, px, py, px, py];
5003 }
5004 // @ts-ignore
5005 return ['C'].concat(lineToCubic(px1, py1, px, py));
5006 }
5007 return segment;
5008 }
5009
5010 // import { fixPath } from '../process/fix-path';
5011 function path2Curve(pathInput, needZCommandIndexes) {
5012 if (needZCommandIndexes === void 0) { needZCommandIndexes = false; }
5013 if (isCurveArray(pathInput)) {
5014 var cloned = [].concat(pathInput);
5015 if (needZCommandIndexes) {
5016 return [cloned, []];
5017 }
5018 else {
5019 return cloned;
5020 }
5021 }
5022 // fixPath will remove 'Z' command
5023 // const path = fixPath(normalizePath(pathInput));
5024 var path = normalizePath(pathInput);
5025 var params = __assign({}, paramsParser);
5026 var allPathCommands = [];
5027 var pathCommand = '';
5028 var ii = path.length;
5029 var segment;
5030 var seglen;
5031 var zCommandIndexes = [];
5032 for (var i = 0; i < ii; i += 1) {
5033 if (path[i])
5034 pathCommand = path[i][0];
5035 allPathCommands[i] = pathCommand;
5036 var curveSegment = segmentToCubic(path[i], params);
5037 path[i] = curveSegment;
5038 fixArc(path, allPathCommands, i);
5039 ii = path.length; // solves curveArrays ending in Z
5040 // keep Z command account for lineJoin
5041 // @see https://github.com/antvis/util/issues/68
5042 if (pathCommand === 'Z') {
5043 zCommandIndexes.push(i);
5044 }
5045 segment = path[i];
5046 seglen = segment.length;
5047 params.x1 = +segment[seglen - 2];
5048 params.y1 = +segment[seglen - 1];
5049 params.x2 = +segment[seglen - 4] || params.x1;
5050 params.y2 = +segment[seglen - 3] || params.y1;
5051 }
5052 // validate
5053 if (needZCommandIndexes) {
5054 return [path, zCommandIndexes];
5055 }
5056 else {
5057 return path;
5058 }
5059 }
5060
5061 function clonePath(path) {
5062 return path.map(function (x) { return (Array.isArray(x) ? [].concat(x) : x); });
5063 }
5064
5065 // reverse CURVE based pathArray segments only
5066 function reverseCurve(pathArray) {
5067 var rotatedCurve = pathArray
5068 .slice(1)
5069 .map(function (x, i, curveOnly) {
5070 // @ts-ignore
5071 return !i ? pathArray[0].slice(1).concat(x.slice(1)) : curveOnly[i - 1].slice(-2).concat(x.slice(1));
5072 })
5073 // @ts-ignore
5074 .map(function (x) { return x.map(function (y, i) { return x[x.length - i - 2 * (1 - (i % 2))]; }); })
5075 .reverse();
5076 return [['M'].concat(rotatedCurve[0].slice(0, 2))].concat(rotatedCurve.map(function (x) { return ['C'].concat(x.slice(2)); }));
5077 }
5078
5079 function distanceSquareRoot(a, b) {
5080 return Math.sqrt((a[0] - b[0]) * (a[0] - b[0]) + (a[1] - b[1]) * (a[1] - b[1]));
5081 }
5082
5083 /**
5084 * Returns a {x,y} point at a given length, the total length and
5085 * the minimum and maximum {x,y} coordinates of a line (L,V,H,Z) segment.
5086 */
5087 function segmentLineFactory(x1, y1, x2, y2, distance) {
5088 var length = distanceSquareRoot([x1, y1], [x2, y2]);
5089 var point = { x: 0, y: 0 };
5090 if (typeof distance === 'number') {
5091 if (distance <= 0) {
5092 point = { x: x1, y: y1 };
5093 }
5094 else if (distance >= length) {
5095 point = { x: x2, y: y2 };
5096 }
5097 else {
5098 var _a = midPoint([x1, y1], [x2, y2], distance / length), x = _a[0], y = _a[1];
5099 point = { x: x, y: y };
5100 }
5101 }
5102 return {
5103 length: length,
5104 point: point,
5105 min: {
5106 x: Math.min(x1, x2),
5107 y: Math.min(y1, y2),
5108 },
5109 max: {
5110 x: Math.max(x1, x2),
5111 y: Math.max(y1, y2),
5112 },
5113 };
5114 }
5115
5116 function angleBetween(v0, v1) {
5117 var v0x = v0.x, v0y = v0.y;
5118 var v1x = v1.x, v1y = v1.y;
5119 var p = v0x * v1x + v0y * v1y;
5120 var n = Math.sqrt((Math.pow(v0x, 2) + Math.pow(v0y, 2)) * (Math.pow(v1x, 2) + Math.pow(v1y, 2)));
5121 var sign = v0x * v1y - v0y * v1x < 0 ? -1 : 1;
5122 var angle = sign * Math.acos(p / n);
5123 return angle;
5124 }
5125 /**
5126 * Returns a {x,y} point at a given length, the total length and
5127 * the minimum and maximum {x,y} coordinates of a C (cubic-bezier) segment.
5128 * @see https://github.com/MadLittleMods/svg-curve-lib/blob/master/src/js/svg-curve-lib.js
5129 */
5130 function getPointAtArcSegmentLength(x1, y1, RX, RY, angle, LAF, SF, x, y, t) {
5131 var abs = Math.abs, sin = Math.sin, cos = Math.cos, sqrt = Math.sqrt, PI = Math.PI;
5132 var rx = abs(RX);
5133 var ry = abs(RY);
5134 var xRot = ((angle % 360) + 360) % 360;
5135 var xRotRad = xRot * (PI / 180);
5136 if (x1 === x && y1 === y) {
5137 return { x: x1, y: y1 };
5138 }
5139 if (rx === 0 || ry === 0) {
5140 return segmentLineFactory(x1, y1, x, y, t).point;
5141 }
5142 var dx = (x1 - x) / 2;
5143 var dy = (y1 - y) / 2;
5144 var transformedPoint = {
5145 x: cos(xRotRad) * dx + sin(xRotRad) * dy,
5146 y: -sin(xRotRad) * dx + cos(xRotRad) * dy,
5147 };
5148 var radiiCheck = Math.pow(transformedPoint.x, 2) / Math.pow(rx, 2) + Math.pow(transformedPoint.y, 2) / Math.pow(ry, 2);
5149 if (radiiCheck > 1) {
5150 rx *= sqrt(radiiCheck);
5151 ry *= sqrt(radiiCheck);
5152 }
5153 var cSquareNumerator = Math.pow(rx, 2) * Math.pow(ry, 2) - Math.pow(rx, 2) * Math.pow(transformedPoint.y, 2) - Math.pow(ry, 2) * Math.pow(transformedPoint.x, 2);
5154 var cSquareRootDenom = Math.pow(rx, 2) * Math.pow(transformedPoint.y, 2) + Math.pow(ry, 2) * Math.pow(transformedPoint.x, 2);
5155 var cRadicand = cSquareNumerator / cSquareRootDenom;
5156 cRadicand = cRadicand < 0 ? 0 : cRadicand;
5157 var cCoef = (LAF !== SF ? 1 : -1) * sqrt(cRadicand);
5158 var transformedCenter = {
5159 x: cCoef * ((rx * transformedPoint.y) / ry),
5160 y: cCoef * (-(ry * transformedPoint.x) / rx),
5161 };
5162 var center = {
5163 x: cos(xRotRad) * transformedCenter.x - sin(xRotRad) * transformedCenter.y + (x1 + x) / 2,
5164 y: sin(xRotRad) * transformedCenter.x + cos(xRotRad) * transformedCenter.y + (y1 + y) / 2,
5165 };
5166 var startVector = {
5167 x: (transformedPoint.x - transformedCenter.x) / rx,
5168 y: (transformedPoint.y - transformedCenter.y) / ry,
5169 };
5170 var startAngle = angleBetween({ x: 1, y: 0 }, startVector);
5171 var endVector = {
5172 x: (-transformedPoint.x - transformedCenter.x) / rx,
5173 y: (-transformedPoint.y - transformedCenter.y) / ry,
5174 };
5175 var sweepAngle = angleBetween(startVector, endVector);
5176 if (!SF && sweepAngle > 0) {
5177 sweepAngle -= 2 * PI;
5178 }
5179 else if (SF && sweepAngle < 0) {
5180 sweepAngle += 2 * PI;
5181 }
5182 sweepAngle %= 2 * PI;
5183 var alpha = startAngle + sweepAngle * t;
5184 var ellipseComponentX = rx * cos(alpha);
5185 var ellipseComponentY = ry * sin(alpha);
5186 var point = {
5187 x: cos(xRotRad) * ellipseComponentX - sin(xRotRad) * ellipseComponentY + center.x,
5188 y: sin(xRotRad) * ellipseComponentX + cos(xRotRad) * ellipseComponentY + center.y,
5189 };
5190 // to be used later
5191 // point.ellipticalArcStartAngle = startAngle;
5192 // point.ellipticalArcEndAngle = startAngle + sweepAngle;
5193 // point.ellipticalArcAngle = alpha;
5194 // point.ellipticalArcCenter = center;
5195 // point.resultantRx = rx;
5196 // point.resultantRy = ry;
5197 return point;
5198 }
5199 /**
5200 * Returns a {x,y} point at a given length, the total length and
5201 * the shape minimum and maximum {x,y} coordinates of an A (arc-to) segment.
5202 *
5203 * For better performance, it can skip calculate bbox or length in some scenario.
5204 */
5205 function segmentArcFactory(X1, Y1, RX, RY, angle, LAF, SF, X2, Y2, distance, options) {
5206 var _a;
5207 var _b = options.bbox, bbox = _b === void 0 ? true : _b, _c = options.length, length = _c === void 0 ? true : _c, _d = options.sampleSize, sampleSize = _d === void 0 ? 30 : _d;
5208 var distanceIsNumber = typeof distance === 'number';
5209 var x = X1;
5210 var y = Y1;
5211 var LENGTH = 0;
5212 var prev = [x, y, LENGTH];
5213 var cur = [x, y];
5214 var t = 0;
5215 var POINT = { x: 0, y: 0 };
5216 var POINTS = [{ x: x, y: y }];
5217 if (distanceIsNumber && distance <= 0) {
5218 POINT = { x: x, y: y };
5219 }
5220 // bad perf when size > 100
5221 for (var j = 0; j <= sampleSize; j += 1) {
5222 t = j / sampleSize;
5223 (_a = getPointAtArcSegmentLength(X1, Y1, RX, RY, angle, LAF, SF, X2, Y2, t), x = _a.x, y = _a.y);
5224 if (bbox) {
5225 POINTS.push({ x: x, y: y });
5226 }
5227 if (length) {
5228 LENGTH += distanceSquareRoot(cur, [x, y]);
5229 }
5230 cur = [x, y];
5231 if (distanceIsNumber && LENGTH >= distance && distance > prev[2]) {
5232 var dv = (LENGTH - distance) / (LENGTH - prev[2]);
5233 POINT = {
5234 x: cur[0] * (1 - dv) + prev[0] * dv,
5235 y: cur[1] * (1 - dv) + prev[1] * dv,
5236 };
5237 }
5238 prev = [x, y, LENGTH];
5239 }
5240 if (distanceIsNumber && distance >= LENGTH) {
5241 POINT = { x: X2, y: Y2 };
5242 }
5243 return {
5244 length: LENGTH,
5245 point: POINT,
5246 min: {
5247 x: Math.min.apply(null, POINTS.map(function (n) { return n.x; })),
5248 y: Math.min.apply(null, POINTS.map(function (n) { return n.y; })),
5249 },
5250 max: {
5251 x: Math.max.apply(null, POINTS.map(function (n) { return n.x; })),
5252 y: Math.max.apply(null, POINTS.map(function (n) { return n.y; })),
5253 },
5254 };
5255 }
5256
5257 /**
5258 * Returns a {x,y} point at a given length, the total length and
5259 * the minimum and maximum {x,y} coordinates of a C (cubic-bezier) segment.
5260 */
5261 function getPointAtCubicSegmentLength(x1, y1, c1x, c1y, c2x, c2y, x2, y2, t) {
5262 var t1 = 1 - t;
5263 return {
5264 x: Math.pow(t1, 3) * x1 + 3 * Math.pow(t1, 2) * t * c1x + 3 * t1 * Math.pow(t, 2) * c2x + Math.pow(t, 3) * x2,
5265 y: Math.pow(t1, 3) * y1 + 3 * Math.pow(t1, 2) * t * c1y + 3 * t1 * Math.pow(t, 2) * c2y + Math.pow(t, 3) * y2,
5266 };
5267 }
5268 /**
5269 * Returns the length of a C (cubic-bezier) segment
5270 * or an {x,y} point at a given length.
5271 */
5272 function segmentCubicFactory(x1, y1, c1x, c1y, c2x, c2y, x2, y2, distance, options) {
5273 var _a;
5274 var _b = options.bbox, bbox = _b === void 0 ? true : _b, _c = options.length, length = _c === void 0 ? true : _c, _d = options.sampleSize, sampleSize = _d === void 0 ? 10 : _d;
5275 var distanceIsNumber = typeof distance === 'number';
5276 var x = x1;
5277 var y = y1;
5278 var LENGTH = 0;
5279 var prev = [x, y, LENGTH];
5280 var cur = [x, y];
5281 var t = 0;
5282 var POINT = { x: 0, y: 0 };
5283 var POINTS = [{ x: x, y: y }];
5284 if (distanceIsNumber && distance <= 0) {
5285 POINT = { x: x, y: y };
5286 }
5287 // bad perf when size = 300
5288 for (var j = 0; j <= sampleSize; j += 1) {
5289 t = j / sampleSize;
5290 (_a = getPointAtCubicSegmentLength(x1, y1, c1x, c1y, c2x, c2y, x2, y2, t), x = _a.x, y = _a.y);
5291 if (bbox) {
5292 POINTS.push({ x: x, y: y });
5293 }
5294 if (length) {
5295 LENGTH += distanceSquareRoot(cur, [x, y]);
5296 }
5297 cur = [x, y];
5298 if (distanceIsNumber && LENGTH >= distance && distance > prev[2]) {
5299 var dv = (LENGTH - distance) / (LENGTH - prev[2]);
5300 POINT = {
5301 x: cur[0] * (1 - dv) + prev[0] * dv,
5302 y: cur[1] * (1 - dv) + prev[1] * dv,
5303 };
5304 }
5305 prev = [x, y, LENGTH];
5306 }
5307 if (distanceIsNumber && distance >= LENGTH) {
5308 POINT = { x: x2, y: y2 };
5309 }
5310 return {
5311 length: LENGTH,
5312 point: POINT,
5313 min: {
5314 x: Math.min.apply(null, POINTS.map(function (n) { return n.x; })),
5315 y: Math.min.apply(null, POINTS.map(function (n) { return n.y; })),
5316 },
5317 max: {
5318 x: Math.max.apply(null, POINTS.map(function (n) { return n.x; })),
5319 y: Math.max.apply(null, POINTS.map(function (n) { return n.y; })),
5320 },
5321 };
5322 }
5323
5324 /**
5325 * Returns the {x,y} coordinates of a point at a
5326 * given length of a quadratic-bezier segment.
5327 *
5328 * @see https://github.com/substack/point-at-length
5329 */
5330 function getPointAtQuadSegmentLength(x1, y1, cx, cy, x2, y2, t) {
5331 var t1 = 1 - t;
5332 return {
5333 x: Math.pow(t1, 2) * x1 + 2 * t1 * t * cx + Math.pow(t, 2) * x2,
5334 y: Math.pow(t1, 2) * y1 + 2 * t1 * t * cy + Math.pow(t, 2) * y2,
5335 };
5336 }
5337 /**
5338 * Returns a {x,y} point at a given length, the total length and
5339 * the minimum and maximum {x,y} coordinates of a Q (quadratic-bezier) segment.
5340 */
5341 function segmentQuadFactory(x1, y1, qx, qy, x2, y2, distance, options) {
5342 var _a;
5343 var _b = options.bbox, bbox = _b === void 0 ? true : _b, _c = options.length, length = _c === void 0 ? true : _c, _d = options.sampleSize, sampleSize = _d === void 0 ? 10 : _d;
5344 var distanceIsNumber = typeof distance === 'number';
5345 var x = x1;
5346 var y = y1;
5347 var LENGTH = 0;
5348 var prev = [x, y, LENGTH];
5349 var cur = [x, y];
5350 var t = 0;
5351 var POINT = { x: 0, y: 0 };
5352 var POINTS = [{ x: x, y: y }];
5353 if (distanceIsNumber && distance <= 0) {
5354 POINT = { x: x, y: y };
5355 }
5356 for (var j = 0; j <= sampleSize; j += 1) {
5357 t = j / sampleSize;
5358 (_a = getPointAtQuadSegmentLength(x1, y1, qx, qy, x2, y2, t), x = _a.x, y = _a.y);
5359 if (bbox) {
5360 POINTS.push({ x: x, y: y });
5361 }
5362 if (length) {
5363 LENGTH += distanceSquareRoot(cur, [x, y]);
5364 }
5365 cur = [x, y];
5366 if (distanceIsNumber && LENGTH >= distance && distance > prev[2]) {
5367 var dv = (LENGTH - distance) / (LENGTH - prev[2]);
5368 POINT = {
5369 x: cur[0] * (1 - dv) + prev[0] * dv,
5370 y: cur[1] * (1 - dv) + prev[1] * dv,
5371 };
5372 }
5373 prev = [x, y, LENGTH];
5374 }
5375 /* istanbul ignore else */
5376 if (distanceIsNumber && distance >= LENGTH) {
5377 POINT = { x: x2, y: y2 };
5378 }
5379 return {
5380 length: LENGTH,
5381 point: POINT,
5382 min: {
5383 x: Math.min.apply(null, POINTS.map(function (n) { return n.x; })),
5384 y: Math.min.apply(null, POINTS.map(function (n) { return n.y; })),
5385 },
5386 max: {
5387 x: Math.max.apply(null, POINTS.map(function (n) { return n.x; })),
5388 y: Math.max.apply(null, POINTS.map(function (n) { return n.y; })),
5389 },
5390 };
5391 }
5392
5393 /**
5394 * Returns a {x,y} point at a given length
5395 * of a shape, the shape total length and
5396 * the shape minimum and maximum {x,y} coordinates.
5397 */
5398 function pathLengthFactory(pathInput, distance, options) {
5399 var _a, _b, _c, _d, _e, _f;
5400 var path = normalizePath(pathInput);
5401 var distanceIsNumber = typeof distance === 'number';
5402 var isM;
5403 var data = [];
5404 var pathCommand;
5405 var x = 0;
5406 var y = 0;
5407 var mx = 0;
5408 var my = 0;
5409 var seg;
5410 var MIN = [];
5411 var MAX = [];
5412 var length = 0;
5413 var min = { x: 0, y: 0 };
5414 var max = min;
5415 var point = min;
5416 var POINT = min;
5417 var LENGTH = 0;
5418 for (var i = 0, ll = path.length; i < ll; i += 1) {
5419 seg = path[i];
5420 pathCommand = seg[0];
5421 isM = pathCommand === 'M';
5422 data = !isM ? [x, y].concat(seg.slice(1)) : data;
5423 // this segment is always ZERO
5424 /* istanbul ignore else */
5425 if (isM) {
5426 // remember mx, my for Z
5427 mx = seg[1], my = seg[2];
5428 min = { x: mx, y: my };
5429 max = min;
5430 length = 0;
5431 if (distanceIsNumber && distance < 0.001) {
5432 POINT = min;
5433 }
5434 }
5435 else if (pathCommand === 'L') {
5436 (_a = segmentLineFactory(data[0], data[1], data[2], data[3], (distance || 0) - LENGTH), length = _a.length, min = _a.min, max = _a.max, point = _a.point);
5437 }
5438 else if (pathCommand === 'A') {
5439 (_b = segmentArcFactory(data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], (distance || 0) - LENGTH, options || {}), length = _b.length, min = _b.min, max = _b.max, point = _b.point);
5440 }
5441 else if (pathCommand === 'C') {
5442 (_c = segmentCubicFactory(data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], (distance || 0) - LENGTH, options || {}), length = _c.length, min = _c.min, max = _c.max, point = _c.point);
5443 }
5444 else if (pathCommand === 'Q') {
5445 (_d = segmentQuadFactory(data[0], data[1], data[2], data[3], data[4], data[5], (distance || 0) - LENGTH, options || {}), length = _d.length, min = _d.min, max = _d.max, point = _d.point);
5446 }
5447 else if (pathCommand === 'Z') {
5448 data = [x, y, mx, my];
5449 (_e = segmentLineFactory(data[0], data[1], data[2], data[3], (distance || 0) - LENGTH), length = _e.length, min = _e.min, max = _e.max, point = _e.point);
5450 }
5451 if (distanceIsNumber && LENGTH < distance && LENGTH + length >= distance) {
5452 POINT = point;
5453 }
5454 MAX.push(max);
5455 MIN.push(min);
5456 LENGTH += length;
5457 _f = pathCommand !== 'Z' ? seg.slice(-2) : [mx, my], x = _f[0], y = _f[1];
5458 }
5459 // native `getPointAtLength` behavior when the given distance
5460 // is higher than total length
5461 if (distanceIsNumber && distance >= LENGTH) {
5462 POINT = { x: x, y: y };
5463 }
5464 return {
5465 length: LENGTH,
5466 point: POINT,
5467 min: {
5468 x: Math.min.apply(null, MIN.map(function (n) { return n.x; })),
5469 y: Math.min.apply(null, MIN.map(function (n) { return n.y; })),
5470 },
5471 max: {
5472 x: Math.max.apply(null, MAX.map(function (n) { return n.x; })),
5473 y: Math.max.apply(null, MAX.map(function (n) { return n.y; })),
5474 },
5475 };
5476 }
5477
5478 /**
5479 * Returns the shape total length, or the equivalent to `shape.getTotalLength()`.
5480 *
5481 * The `normalizePath` version is lighter, faster, more efficient and more accurate
5482 * with paths that are not `curveArray`.
5483 */
5484 function getTotalLength(pathInput, options) {
5485 return pathLengthFactory(pathInput, undefined, __assign(__assign({}, options), { bbox: false, length: true })).length;
5486 }
5487
5488 function getRotations(a) {
5489 var segCount = a.length;
5490 var pointCount = segCount - 1;
5491 return a.map(function (f, idx) {
5492 return a.map(function (p, i) {
5493 var oldSegIdx = idx + i;
5494 var seg;
5495 if (i === 0 || (a[oldSegIdx] && a[oldSegIdx][0] === 'M')) {
5496 seg = a[oldSegIdx];
5497 return ['M'].concat(seg.slice(-2));
5498 }
5499 if (oldSegIdx >= segCount)
5500 oldSegIdx -= pointCount;
5501 return a[oldSegIdx];
5502 });
5503 });
5504 }
5505 function getRotatedCurve(a, b) {
5506 var segCount = a.length - 1;
5507 var lineLengths = [];
5508 var computedIndex = 0;
5509 var sumLensSqrd = 0;
5510 var rotations = getRotations(a);
5511 rotations.forEach(function (r, i) {
5512 a.slice(1).forEach(function (s, j) {
5513 // @ts-ignore
5514 sumLensSqrd += distanceSquareRoot(a[(i + j) % segCount].slice(-2), b[j % segCount].slice(-2));
5515 });
5516 lineLengths[i] = sumLensSqrd;
5517 sumLensSqrd = 0;
5518 });
5519 computedIndex = lineLengths.indexOf(Math.min.apply(null, lineLengths));
5520 return rotations[computedIndex];
5521 }
5522
5523 /**
5524 * Returns the area of a single cubic-bezier segment.
5525 *
5526 * http://objectmix.com/graphics/133553-area-closed-bezier-curve.html
5527 */
5528 function getCubicSegArea(x1, y1, c1x, c1y, c2x, c2y, x2, y2) {
5529 // https://stackoverflow.com/a/15845996
5530 return ((3 *
5531 ((y2 - y1) * (c1x + c2x) -
5532 (x2 - x1) * (c1y + c2y) +
5533 c1y * (x1 - c2x) -
5534 c1x * (y1 - c2y) +
5535 y2 * (c2x + x1 / 3) -
5536 x2 * (c2y + y1 / 3))) /
5537 20);
5538 }
5539 /**
5540 * Returns the area of a shape.
5541 * @author Jürg Lehni & Jonathan Puckey
5542 *
5543 * @see https://github.com/paperjs/paper.js/blob/develop/src/path/Path.js
5544 */
5545 function getPathArea(path) {
5546 var x = 0;
5547 var y = 0;
5548 var len = 0;
5549 return path2Curve(path)
5550 .map(function (seg) {
5551 var _a;
5552 switch (seg[0]) {
5553 case 'M':
5554 x = seg[1], y = seg[2];
5555 return 0;
5556 default:
5557 // @ts-ignore
5558 var _b = seg.slice(1), c1x = _b[0], c1y = _b[1], c2x = _b[2], c2y = _b[3], x2 = _b[4], y2 = _b[5];
5559 len = getCubicSegArea(x, y, c1x, c1y, c2x, c2y, x2, y2);
5560 _a = seg.slice(-2), x = _a[0], y = _a[1];
5561 return len;
5562 }
5563 })
5564 .reduce(function (a, b) { return a + b; }, 0);
5565 }
5566 // export function getPathArea(pathArray: AbsoluteArray) {
5567 // let x = 0;
5568 // let y = 0;
5569 // let mx = 0;
5570 // let my = 0;
5571 // let len = 0;
5572 // return pathArray
5573 // .map((seg) => {
5574 // switch (seg[0]) {
5575 // case 'M':
5576 // case 'Z':
5577 // mx = seg[0] === 'M' ? seg[1] : mx;
5578 // my = seg[0] === 'M' ? seg[2] : my;
5579 // x = mx;
5580 // y = my;
5581 // return 0;
5582 // default:
5583 // // @ts-ignore
5584 // len = getCubicSegArea.apply(0, [x, y].concat(seg.slice(1)));
5585 // [x, y] = seg.slice(-2) as [number, number];
5586 // return len;
5587 // }
5588 // })
5589 // .reduce((a, b) => a + b, 0);
5590 // }
5591
5592 function getDrawDirection(pathArray) {
5593 return getPathArea(pathArray) >= 0;
5594 }
5595
5596 /**
5597 * Returns [x,y] coordinates of a point at a given length of a shape.
5598 */
5599 function getPointAtLength(pathInput, distance, options) {
5600 return pathLengthFactory(pathInput, distance, __assign(__assign({}, options), { bbox: false, length: true })).point;
5601 }
5602
5603 function splitCubic(pts, t) {
5604 if (t === void 0) { t = 0.5; }
5605 var p0 = pts.slice(0, 2);
5606 var p1 = pts.slice(2, 4);
5607 var p2 = pts.slice(4, 6);
5608 var p3 = pts.slice(6, 8);
5609 var p4 = midPoint(p0, p1, t);
5610 var p5 = midPoint(p1, p2, t);
5611 var p6 = midPoint(p2, p3, t);
5612 var p7 = midPoint(p4, p5, t);
5613 var p8 = midPoint(p5, p6, t);
5614 var p9 = midPoint(p7, p8, t);
5615 return [
5616 // @ts-ignore
5617 ['C'].concat(p4, p7, p9),
5618 // @ts-ignore
5619 ['C'].concat(p8, p6, p3),
5620 ];
5621 }
5622 function getCurveArray(segments) {
5623 return segments.map(function (segment, i, pathArray) {
5624 // @ts-ignore
5625 var segmentData = i && pathArray[i - 1].slice(-2).concat(segment.slice(1));
5626 // @ts-ignore
5627 var curveLength = i
5628 ? segmentCubicFactory(segmentData[0], segmentData[1], segmentData[2], segmentData[3], segmentData[4], segmentData[5], segmentData[6], segmentData[7], segmentData[8], { bbox: false }).length
5629 : 0;
5630 var subsegs;
5631 if (i) {
5632 // must be [segment,segment]
5633 subsegs = curveLength ? splitCubic(segmentData) : [segment, segment];
5634 }
5635 else {
5636 subsegs = [segment];
5637 }
5638 return {
5639 s: segment,
5640 ss: subsegs,
5641 l: curveLength,
5642 };
5643 });
5644 }
5645 function equalizeSegments(path1, path2, TL) {
5646 var c1 = getCurveArray(path1);
5647 var c2 = getCurveArray(path2);
5648 var L1 = c1.length;
5649 var L2 = c2.length;
5650 var l1 = c1.filter(function (x) { return x.l; }).length;
5651 var l2 = c2.filter(function (x) { return x.l; }).length;
5652 var m1 = c1.filter(function (x) { return x.l; }).reduce(function (a, _a) {
5653 var l = _a.l;
5654 return a + l;
5655 }, 0) / l1 || 0;
5656 var m2 = c2.filter(function (x) { return x.l; }).reduce(function (a, _a) {
5657 var l = _a.l;
5658 return a + l;
5659 }, 0) / l2 || 0;
5660 var tl = TL || Math.max(L1, L2);
5661 var mm = [m1, m2];
5662 var dif = [tl - L1, tl - L2];
5663 var canSplit = 0;
5664 var result = [c1, c2].map(function (x, i) {
5665 // @ts-ignore
5666 return x.l === tl
5667 ? x.map(function (y) { return y.s; })
5668 : x
5669 .map(function (y, j) {
5670 canSplit = j && dif[i] && y.l >= mm[i];
5671 dif[i] -= canSplit ? 1 : 0;
5672 return canSplit ? y.ss : [y.s];
5673 })
5674 .flat();
5675 });
5676 return result[0].length === result[1].length ? result : equalizeSegments(result[0], result[1], tl);
5677 }
5678
5679 var Component = /** @class */function () {
5680 function Component(props, context, updater) {
5681 this.isMounted = false;
5682 // State 内部私有属性
5683 this.destroyed = false;
5684 this.props = props;
5685 this.state = {};
5686 this.context = context;
5687 this.updater = updater;
5688 }
5689 Component.prototype.willMount = function () {};
5690 Component.prototype.didMount = function () {};
5691 Component.prototype.shouldUpdate = function (_nextProps) {
5692 return true;
5693 };
5694 Component.prototype.willReceiveProps = function (_props, _context) {};
5695 Component.prototype.willUpdate = function () {};
5696 Component.prototype.didUpdate = function () {};
5697 Component.prototype.render = function () {
5698 return null;
5699 };
5700 Component.prototype.willUnmount = function () {};
5701 Component.prototype.didUnmount = function () {};
5702 Component.prototype.setState = function (partialState, callback) {
5703 if (this.destroyed) {
5704 return;
5705 }
5706 this.updater.enqueueSetState(this, partialState, callback);
5707 };
5708 Component.prototype.forceUpdate = function (callback) {
5709 if (this.destroyed) {
5710 return;
5711 }
5712 this.updater.enqueueForceUpdate(this, {}, callback);
5713 };
5714 Component.prototype.setAnimate = function (animate) {
5715 this.animate = animate;
5716 this._vNode.animate = animate;
5717 };
5718 Component.prototype.destroy = function () {
5719 this.destroyed = true;
5720 this.animator = null;
5721 };
5722 return Component;
5723 }();
5724 // 标识是否是组件
5725 // @ts-ignore
5726 Component.prototype.isF2Component = true;
5727
5728 function cloneElement(element, props) {
5729 if (!element) return element;
5730 return __assign(__assign({}, element), {
5731 props: __assign(__assign({}, element.props), props)
5732 });
5733 }
5734 function map$1(children, fn) {
5735 if (!children) {
5736 return fn(children);
5737 }
5738 if (isArray(children)) {
5739 return children.map(function (child) {
5740 return map$1(child, fn);
5741 });
5742 }
5743 return fn(children);
5744 }
5745 function compareArray(nextElements, lastElements, callback) {
5746 var keyed = {};
5747 var nextLength = nextElements.length;
5748 var lastLength = lastElements.length;
5749 for (var i = 0, len = lastLength; i < len; i++) {
5750 var element = lastElements[i];
5751 if (element && !isNil(element.key)) {
5752 var key = element.key;
5753 keyed[key] = element;
5754 }
5755 }
5756 var result = [];
5757 // 比较元素
5758 for (var i = 0, len = nextLength; i < len; i++) {
5759 var element = nextElements[i];
5760 if (!element) {
5761 continue;
5762 }
5763 var key = element.key;
5764 var lastElement = void 0;
5765 // 有key值定义
5766 if (!isNil(element.key)) {
5767 lastElement = keyed[key];
5768 if (lastElement) delete keyed[key];
5769 } else {
5770 // 取相同位置的元素
5771 lastElement = lastElements[i];
5772 }
5773 // 没有直接返回
5774 if (!lastElement) {
5775 result.push(compare(element, null, callback));
5776 continue;
5777 }
5778 // 如果 lastElement 已经被处理过, next 处理成新增
5779 if (lastElement === null || lastElement === void 0 ? void 0 : lastElement.__processed) {
5780 result.push(compare(element, null, callback));
5781 continue;
5782 }
5783 // 标记 element 已经被处理过
5784 lastElement.__processed = true;
5785 result.push(compare(element, lastElement, callback));
5786 }
5787 // 处理 lastElements 里面还未被处理的元素
5788 for (var i = 0, len = lastLength; i < len; i++) {
5789 var lastElement = lastElements[i];
5790 if (!lastElement) {
5791 continue;
5792 }
5793 if (!(lastElement === null || lastElement === void 0 ? void 0 : lastElement.__processed)) {
5794 result.push(compare(null, lastElement, callback));
5795 } else {
5796 delete lastElement.__processed;
5797 }
5798 }
5799 return result;
5800 }
5801 // 比较2棵树
5802 function compare(nextElement, lastElement, callback) {
5803 // 有一个为空
5804 if (!nextElement || !lastElement) {
5805 return callback(nextElement, lastElement);
5806 }
5807 if (isArray(nextElement) || isArray(lastElement)) {
5808 var nextElementArray = isArray(nextElement) ? nextElement : [nextElement];
5809 var lastElementArray = isArray(lastElement) ? lastElement : [lastElement];
5810 return compareArray(nextElementArray, lastElementArray, callback);
5811 }
5812 return callback(nextElement, lastElement);
5813 }
5814 function toArray(element) {
5815 if (!element) {
5816 return element;
5817 }
5818 if (!isArray(element)) {
5819 return [element];
5820 }
5821 var newArray = [];
5822 for (var i = 0, len = element.length; i < len; i++) {
5823 var item = element[i];
5824 if (isArray(item)) {
5825 newArray = newArray.concat(toArray(item));
5826 } else {
5827 newArray.push(item);
5828 }
5829 }
5830 return newArray;
5831 }
5832 var Children = {
5833 cloneElement: cloneElement,
5834 map: map$1,
5835 toArray: toArray,
5836 compare: compare
5837 };
5838
5839 function getDefaultExportFromCjs (x) {
5840 return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
5841 }
5842
5843 function createCommonjsModule(fn, basedir, module) {
5844 return module = {
5845 path: basedir,
5846 exports: {},
5847 require: function (path, base) {
5848 return commonjsRequire(path, (base === undefined || base === null) ? module.path : base);
5849 }
5850 }, fn(module, module.exports), module.exports;
5851 }
5852
5853 function commonjsRequire () {
5854 throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs');
5855 }
5856
5857 var eventemitter3 = createCommonjsModule(function (module) {
5858
5859 var has = Object.prototype.hasOwnProperty
5860 , prefix = '~';
5861
5862 /**
5863 * Constructor to create a storage for our `EE` objects.
5864 * An `Events` instance is a plain object whose properties are event names.
5865 *
5866 * @constructor
5867 * @private
5868 */
5869 function Events() {}
5870
5871 //
5872 // We try to not inherit from `Object.prototype`. In some engines creating an
5873 // instance in this way is faster than calling `Object.create(null)` directly.
5874 // If `Object.create(null)` is not supported we prefix the event names with a
5875 // character to make sure that the built-in object properties are not
5876 // overridden or used as an attack vector.
5877 //
5878 if (Object.create) {
5879 Events.prototype = Object.create(null);
5880
5881 //
5882 // This hack is needed because the `__proto__` property is still inherited in
5883 // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.
5884 //
5885 if (!new Events().__proto__) prefix = false;
5886 }
5887
5888 /**
5889 * Representation of a single event listener.
5890 *
5891 * @param {Function} fn The listener function.
5892 * @param {*} context The context to invoke the listener with.
5893 * @param {Boolean} [once=false] Specify if the listener is a one-time listener.
5894 * @constructor
5895 * @private
5896 */
5897 function EE(fn, context, once) {
5898 this.fn = fn;
5899 this.context = context;
5900 this.once = once || false;
5901 }
5902
5903 /**
5904 * Add a listener for a given event.
5905 *
5906 * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
5907 * @param {(String|Symbol)} event The event name.
5908 * @param {Function} fn The listener function.
5909 * @param {*} context The context to invoke the listener with.
5910 * @param {Boolean} once Specify if the listener is a one-time listener.
5911 * @returns {EventEmitter}
5912 * @private
5913 */
5914 function addListener(emitter, event, fn, context, once) {
5915 if (typeof fn !== 'function') {
5916 throw new TypeError('The listener must be a function');
5917 }
5918
5919 var listener = new EE(fn, context || emitter, once)
5920 , evt = prefix ? prefix + event : event;
5921
5922 if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;
5923 else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);
5924 else emitter._events[evt] = [emitter._events[evt], listener];
5925
5926 return emitter;
5927 }
5928
5929 /**
5930 * Clear event by name.
5931 *
5932 * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
5933 * @param {(String|Symbol)} evt The Event name.
5934 * @private
5935 */
5936 function clearEvent(emitter, evt) {
5937 if (--emitter._eventsCount === 0) emitter._events = new Events();
5938 else delete emitter._events[evt];
5939 }
5940
5941 /**
5942 * Minimal `EventEmitter` interface that is molded against the Node.js
5943 * `EventEmitter` interface.
5944 *
5945 * @constructor
5946 * @public
5947 */
5948 function EventEmitter() {
5949 this._events = new Events();
5950 this._eventsCount = 0;
5951 }
5952
5953 /**
5954 * Return an array listing the events for which the emitter has registered
5955 * listeners.
5956 *
5957 * @returns {Array}
5958 * @public
5959 */
5960 EventEmitter.prototype.eventNames = function eventNames() {
5961 var names = []
5962 , events
5963 , name;
5964
5965 if (this._eventsCount === 0) return names;
5966
5967 for (name in (events = this._events)) {
5968 if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
5969 }
5970
5971 if (Object.getOwnPropertySymbols) {
5972 return names.concat(Object.getOwnPropertySymbols(events));
5973 }
5974
5975 return names;
5976 };
5977
5978 /**
5979 * Return the listeners registered for a given event.
5980 *
5981 * @param {(String|Symbol)} event The event name.
5982 * @returns {Array} The registered listeners.
5983 * @public
5984 */
5985 EventEmitter.prototype.listeners = function listeners(event) {
5986 var evt = prefix ? prefix + event : event
5987 , handlers = this._events[evt];
5988
5989 if (!handlers) return [];
5990 if (handlers.fn) return [handlers.fn];
5991
5992 for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {
5993 ee[i] = handlers[i].fn;
5994 }
5995
5996 return ee;
5997 };
5998
5999 /**
6000 * Return the number of listeners listening to a given event.
6001 *
6002 * @param {(String|Symbol)} event The event name.
6003 * @returns {Number} The number of listeners.
6004 * @public
6005 */
6006 EventEmitter.prototype.listenerCount = function listenerCount(event) {
6007 var evt = prefix ? prefix + event : event
6008 , listeners = this._events[evt];
6009
6010 if (!listeners) return 0;
6011 if (listeners.fn) return 1;
6012 return listeners.length;
6013 };
6014
6015 /**
6016 * Calls each of the listeners registered for a given event.
6017 *
6018 * @param {(String|Symbol)} event The event name.
6019 * @returns {Boolean} `true` if the event had listeners, else `false`.
6020 * @public
6021 */
6022 EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
6023 var evt = prefix ? prefix + event : event;
6024
6025 if (!this._events[evt]) return false;
6026
6027 var listeners = this._events[evt]
6028 , len = arguments.length
6029 , args
6030 , i;
6031
6032 if (listeners.fn) {
6033 if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);
6034
6035 switch (len) {
6036 case 1: return listeners.fn.call(listeners.context), true;
6037 case 2: return listeners.fn.call(listeners.context, a1), true;
6038 case 3: return listeners.fn.call(listeners.context, a1, a2), true;
6039 case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;
6040 case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
6041 case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
6042 }
6043
6044 for (i = 1, args = new Array(len -1); i < len; i++) {
6045 args[i - 1] = arguments[i];
6046 }
6047
6048 listeners.fn.apply(listeners.context, args);
6049 } else {
6050 var length = listeners.length
6051 , j;
6052
6053 for (i = 0; i < length; i++) {
6054 if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);
6055
6056 switch (len) {
6057 case 1: listeners[i].fn.call(listeners[i].context); break;
6058 case 2: listeners[i].fn.call(listeners[i].context, a1); break;
6059 case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;
6060 case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;
6061 default:
6062 if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {
6063 args[j - 1] = arguments[j];
6064 }
6065
6066 listeners[i].fn.apply(listeners[i].context, args);
6067 }
6068 }
6069 }
6070
6071 return true;
6072 };
6073
6074 /**
6075 * Add a listener for a given event.
6076 *
6077 * @param {(String|Symbol)} event The event name.
6078 * @param {Function} fn The listener function.
6079 * @param {*} [context=this] The context to invoke the listener with.
6080 * @returns {EventEmitter} `this`.
6081 * @public
6082 */
6083 EventEmitter.prototype.on = function on(event, fn, context) {
6084 return addListener(this, event, fn, context, false);
6085 };
6086
6087 /**
6088 * Add a one-time listener for a given event.
6089 *
6090 * @param {(String|Symbol)} event The event name.
6091 * @param {Function} fn The listener function.
6092 * @param {*} [context=this] The context to invoke the listener with.
6093 * @returns {EventEmitter} `this`.
6094 * @public
6095 */
6096 EventEmitter.prototype.once = function once(event, fn, context) {
6097 return addListener(this, event, fn, context, true);
6098 };
6099
6100 /**
6101 * Remove the listeners of a given event.
6102 *
6103 * @param {(String|Symbol)} event The event name.
6104 * @param {Function} fn Only remove the listeners that match this function.
6105 * @param {*} context Only remove the listeners that have this context.
6106 * @param {Boolean} once Only remove one-time listeners.
6107 * @returns {EventEmitter} `this`.
6108 * @public
6109 */
6110 EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
6111 var evt = prefix ? prefix + event : event;
6112
6113 if (!this._events[evt]) return this;
6114 if (!fn) {
6115 clearEvent(this, evt);
6116 return this;
6117 }
6118
6119 var listeners = this._events[evt];
6120
6121 if (listeners.fn) {
6122 if (
6123 listeners.fn === fn &&
6124 (!once || listeners.once) &&
6125 (!context || listeners.context === context)
6126 ) {
6127 clearEvent(this, evt);
6128 }
6129 } else {
6130 for (var i = 0, events = [], length = listeners.length; i < length; i++) {
6131 if (
6132 listeners[i].fn !== fn ||
6133 (once && !listeners[i].once) ||
6134 (context && listeners[i].context !== context)
6135 ) {
6136 events.push(listeners[i]);
6137 }
6138 }
6139
6140 //
6141 // Reset the array, or remove it completely if we have no more listeners.
6142 //
6143 if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;
6144 else clearEvent(this, evt);
6145 }
6146
6147 return this;
6148 };
6149
6150 /**
6151 * Remove all listeners, or those of the specified event.
6152 *
6153 * @param {(String|Symbol)} [event] The event name.
6154 * @returns {EventEmitter} `this`.
6155 * @public
6156 */
6157 EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
6158 var evt;
6159
6160 if (event) {
6161 evt = prefix ? prefix + event : event;
6162 if (this._events[evt]) clearEvent(this, evt);
6163 } else {
6164 this._events = new Events();
6165 this._eventsCount = 0;
6166 }
6167
6168 return this;
6169 };
6170
6171 //
6172 // Alias methods names because people roll like that.
6173 //
6174 EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
6175 EventEmitter.prototype.addListener = EventEmitter.prototype.on;
6176
6177 //
6178 // Expose the prefix.
6179 //
6180 EventEmitter.prefixed = prefix;
6181
6182 //
6183 // Allow `EventEmitter` to be imported as module namespace.
6184 //
6185 EventEmitter.EventEmitter = EventEmitter;
6186
6187 //
6188 // Expose the module.
6189 //
6190 {
6191 module.exports = EventEmitter;
6192 }
6193 });
6194
6195 function define(constructor, factory, prototype) {
6196 constructor.prototype = factory.prototype = prototype;
6197 prototype.constructor = constructor;
6198 }
6199
6200 function extend(parent, definition) {
6201 var prototype = Object.create(parent.prototype);
6202 for (var key in definition) prototype[key] = definition[key];
6203 return prototype;
6204 }
6205
6206 function Color() {}
6207
6208 var darker = 0.7;
6209 var brighter = 1 / darker;
6210
6211 var reI = "\\s*([+-]?\\d+)\\s*",
6212 reN = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*",
6213 reP = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*",
6214 reHex = /^#([0-9a-f]{3,8})$/,
6215 reRgbInteger = new RegExp("^rgb\\(" + [reI, reI, reI] + "\\)$"),
6216 reRgbPercent = new RegExp("^rgb\\(" + [reP, reP, reP] + "\\)$"),
6217 reRgbaInteger = new RegExp("^rgba\\(" + [reI, reI, reI, reN] + "\\)$"),
6218 reRgbaPercent = new RegExp("^rgba\\(" + [reP, reP, reP, reN] + "\\)$"),
6219 reHslPercent = new RegExp("^hsl\\(" + [reN, reP, reP] + "\\)$"),
6220 reHslaPercent = new RegExp("^hsla\\(" + [reN, reP, reP, reN] + "\\)$");
6221
6222 var named = {
6223 aliceblue: 0xf0f8ff,
6224 antiquewhite: 0xfaebd7,
6225 aqua: 0x00ffff,
6226 aquamarine: 0x7fffd4,
6227 azure: 0xf0ffff,
6228 beige: 0xf5f5dc,
6229 bisque: 0xffe4c4,
6230 black: 0x000000,
6231 blanchedalmond: 0xffebcd,
6232 blue: 0x0000ff,
6233 blueviolet: 0x8a2be2,
6234 brown: 0xa52a2a,
6235 burlywood: 0xdeb887,
6236 cadetblue: 0x5f9ea0,
6237 chartreuse: 0x7fff00,
6238 chocolate: 0xd2691e,
6239 coral: 0xff7f50,
6240 cornflowerblue: 0x6495ed,
6241 cornsilk: 0xfff8dc,
6242 crimson: 0xdc143c,
6243 cyan: 0x00ffff,
6244 darkblue: 0x00008b,
6245 darkcyan: 0x008b8b,
6246 darkgoldenrod: 0xb8860b,
6247 darkgray: 0xa9a9a9,
6248 darkgreen: 0x006400,
6249 darkgrey: 0xa9a9a9,
6250 darkkhaki: 0xbdb76b,
6251 darkmagenta: 0x8b008b,
6252 darkolivegreen: 0x556b2f,
6253 darkorange: 0xff8c00,
6254 darkorchid: 0x9932cc,
6255 darkred: 0x8b0000,
6256 darksalmon: 0xe9967a,
6257 darkseagreen: 0x8fbc8f,
6258 darkslateblue: 0x483d8b,
6259 darkslategray: 0x2f4f4f,
6260 darkslategrey: 0x2f4f4f,
6261 darkturquoise: 0x00ced1,
6262 darkviolet: 0x9400d3,
6263 deeppink: 0xff1493,
6264 deepskyblue: 0x00bfff,
6265 dimgray: 0x696969,
6266 dimgrey: 0x696969,
6267 dodgerblue: 0x1e90ff,
6268 firebrick: 0xb22222,
6269 floralwhite: 0xfffaf0,
6270 forestgreen: 0x228b22,
6271 fuchsia: 0xff00ff,
6272 gainsboro: 0xdcdcdc,
6273 ghostwhite: 0xf8f8ff,
6274 gold: 0xffd700,
6275 goldenrod: 0xdaa520,
6276 gray: 0x808080,
6277 green: 0x008000,
6278 greenyellow: 0xadff2f,
6279 grey: 0x808080,
6280 honeydew: 0xf0fff0,
6281 hotpink: 0xff69b4,
6282 indianred: 0xcd5c5c,
6283 indigo: 0x4b0082,
6284 ivory: 0xfffff0,
6285 khaki: 0xf0e68c,
6286 lavender: 0xe6e6fa,
6287 lavenderblush: 0xfff0f5,
6288 lawngreen: 0x7cfc00,
6289 lemonchiffon: 0xfffacd,
6290 lightblue: 0xadd8e6,
6291 lightcoral: 0xf08080,
6292 lightcyan: 0xe0ffff,
6293 lightgoldenrodyellow: 0xfafad2,
6294 lightgray: 0xd3d3d3,
6295 lightgreen: 0x90ee90,
6296 lightgrey: 0xd3d3d3,
6297 lightpink: 0xffb6c1,
6298 lightsalmon: 0xffa07a,
6299 lightseagreen: 0x20b2aa,
6300 lightskyblue: 0x87cefa,
6301 lightslategray: 0x778899,
6302 lightslategrey: 0x778899,
6303 lightsteelblue: 0xb0c4de,
6304 lightyellow: 0xffffe0,
6305 lime: 0x00ff00,
6306 limegreen: 0x32cd32,
6307 linen: 0xfaf0e6,
6308 magenta: 0xff00ff,
6309 maroon: 0x800000,
6310 mediumaquamarine: 0x66cdaa,
6311 mediumblue: 0x0000cd,
6312 mediumorchid: 0xba55d3,
6313 mediumpurple: 0x9370db,
6314 mediumseagreen: 0x3cb371,
6315 mediumslateblue: 0x7b68ee,
6316 mediumspringgreen: 0x00fa9a,
6317 mediumturquoise: 0x48d1cc,
6318 mediumvioletred: 0xc71585,
6319 midnightblue: 0x191970,
6320 mintcream: 0xf5fffa,
6321 mistyrose: 0xffe4e1,
6322 moccasin: 0xffe4b5,
6323 navajowhite: 0xffdead,
6324 navy: 0x000080,
6325 oldlace: 0xfdf5e6,
6326 olive: 0x808000,
6327 olivedrab: 0x6b8e23,
6328 orange: 0xffa500,
6329 orangered: 0xff4500,
6330 orchid: 0xda70d6,
6331 palegoldenrod: 0xeee8aa,
6332 palegreen: 0x98fb98,
6333 paleturquoise: 0xafeeee,
6334 palevioletred: 0xdb7093,
6335 papayawhip: 0xffefd5,
6336 peachpuff: 0xffdab9,
6337 peru: 0xcd853f,
6338 pink: 0xffc0cb,
6339 plum: 0xdda0dd,
6340 powderblue: 0xb0e0e6,
6341 purple: 0x800080,
6342 rebeccapurple: 0x663399,
6343 red: 0xff0000,
6344 rosybrown: 0xbc8f8f,
6345 royalblue: 0x4169e1,
6346 saddlebrown: 0x8b4513,
6347 salmon: 0xfa8072,
6348 sandybrown: 0xf4a460,
6349 seagreen: 0x2e8b57,
6350 seashell: 0xfff5ee,
6351 sienna: 0xa0522d,
6352 silver: 0xc0c0c0,
6353 skyblue: 0x87ceeb,
6354 slateblue: 0x6a5acd,
6355 slategray: 0x708090,
6356 slategrey: 0x708090,
6357 snow: 0xfffafa,
6358 springgreen: 0x00ff7f,
6359 steelblue: 0x4682b4,
6360 tan: 0xd2b48c,
6361 teal: 0x008080,
6362 thistle: 0xd8bfd8,
6363 tomato: 0xff6347,
6364 turquoise: 0x40e0d0,
6365 violet: 0xee82ee,
6366 wheat: 0xf5deb3,
6367 white: 0xffffff,
6368 whitesmoke: 0xf5f5f5,
6369 yellow: 0xffff00,
6370 yellowgreen: 0x9acd32
6371 };
6372
6373 define(Color, color, {
6374 copy: function(channels) {
6375 return Object.assign(new this.constructor, this, channels);
6376 },
6377 displayable: function() {
6378 return this.rgb().displayable();
6379 },
6380 hex: color_formatHex, // Deprecated! Use color.formatHex.
6381 formatHex: color_formatHex,
6382 formatHsl: color_formatHsl,
6383 formatRgb: color_formatRgb,
6384 toString: color_formatRgb
6385 });
6386
6387 function color_formatHex() {
6388 return this.rgb().formatHex();
6389 }
6390
6391 function color_formatHsl() {
6392 return hslConvert(this).formatHsl();
6393 }
6394
6395 function color_formatRgb() {
6396 return this.rgb().formatRgb();
6397 }
6398
6399 function color(format) {
6400 var m, l;
6401 format = (format + "").trim().toLowerCase();
6402 return (m = reHex.exec(format)) ? (l = m[1].length, m = parseInt(m[1], 16), l === 6 ? rgbn(m) // #ff0000
6403 : l === 3 ? new Rgb((m >> 8 & 0xf) | (m >> 4 & 0xf0), (m >> 4 & 0xf) | (m & 0xf0), ((m & 0xf) << 4) | (m & 0xf), 1) // #f00
6404 : l === 8 ? rgba(m >> 24 & 0xff, m >> 16 & 0xff, m >> 8 & 0xff, (m & 0xff) / 0xff) // #ff000000
6405 : l === 4 ? rgba((m >> 12 & 0xf) | (m >> 8 & 0xf0), (m >> 8 & 0xf) | (m >> 4 & 0xf0), (m >> 4 & 0xf) | (m & 0xf0), (((m & 0xf) << 4) | (m & 0xf)) / 0xff) // #f000
6406 : null) // invalid hex
6407 : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0)
6408 : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%)
6409 : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1)
6410 : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1)
6411 : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%)
6412 : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1)
6413 : named.hasOwnProperty(format) ? rgbn(named[format]) // eslint-disable-line no-prototype-builtins
6414 : format === "transparent" ? new Rgb(NaN, NaN, NaN, 0)
6415 : null;
6416 }
6417
6418 function rgbn(n) {
6419 return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1);
6420 }
6421
6422 function rgba(r, g, b, a) {
6423 if (a <= 0) r = g = b = NaN;
6424 return new Rgb(r, g, b, a);
6425 }
6426
6427 function rgbConvert(o) {
6428 if (!(o instanceof Color)) o = color(o);
6429 if (!o) return new Rgb;
6430 o = o.rgb();
6431 return new Rgb(o.r, o.g, o.b, o.opacity);
6432 }
6433
6434 function rgb(r, g, b, opacity) {
6435 return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity);
6436 }
6437
6438 function Rgb(r, g, b, opacity) {
6439 this.r = +r;
6440 this.g = +g;
6441 this.b = +b;
6442 this.opacity = +opacity;
6443 }
6444
6445 define(Rgb, rgb, extend(Color, {
6446 brighter: function(k) {
6447 k = k == null ? brighter : Math.pow(brighter, k);
6448 return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
6449 },
6450 darker: function(k) {
6451 k = k == null ? darker : Math.pow(darker, k);
6452 return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
6453 },
6454 rgb: function() {
6455 return this;
6456 },
6457 displayable: function() {
6458 return (-0.5 <= this.r && this.r < 255.5)
6459 && (-0.5 <= this.g && this.g < 255.5)
6460 && (-0.5 <= this.b && this.b < 255.5)
6461 && (0 <= this.opacity && this.opacity <= 1);
6462 },
6463 hex: rgb_formatHex, // Deprecated! Use color.formatHex.
6464 formatHex: rgb_formatHex,
6465 formatRgb: rgb_formatRgb,
6466 toString: rgb_formatRgb
6467 }));
6468
6469 function rgb_formatHex() {
6470 return "#" + hex(this.r) + hex(this.g) + hex(this.b);
6471 }
6472
6473 function rgb_formatRgb() {
6474 var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a));
6475 return (a === 1 ? "rgb(" : "rgba(")
6476 + Math.max(0, Math.min(255, Math.round(this.r) || 0)) + ", "
6477 + Math.max(0, Math.min(255, Math.round(this.g) || 0)) + ", "
6478 + Math.max(0, Math.min(255, Math.round(this.b) || 0))
6479 + (a === 1 ? ")" : ", " + a + ")");
6480 }
6481
6482 function hex(value) {
6483 value = Math.max(0, Math.min(255, Math.round(value) || 0));
6484 return (value < 16 ? "0" : "") + value.toString(16);
6485 }
6486
6487 function hsla(h, s, l, a) {
6488 if (a <= 0) h = s = l = NaN;
6489 else if (l <= 0 || l >= 1) h = s = NaN;
6490 else if (s <= 0) h = NaN;
6491 return new Hsl(h, s, l, a);
6492 }
6493
6494 function hslConvert(o) {
6495 if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity);
6496 if (!(o instanceof Color)) o = color(o);
6497 if (!o) return new Hsl;
6498 if (o instanceof Hsl) return o;
6499 o = o.rgb();
6500 var r = o.r / 255,
6501 g = o.g / 255,
6502 b = o.b / 255,
6503 min = Math.min(r, g, b),
6504 max = Math.max(r, g, b),
6505 h = NaN,
6506 s = max - min,
6507 l = (max + min) / 2;
6508 if (s) {
6509 if (r === max) h = (g - b) / s + (g < b) * 6;
6510 else if (g === max) h = (b - r) / s + 2;
6511 else h = (r - g) / s + 4;
6512 s /= l < 0.5 ? max + min : 2 - max - min;
6513 h *= 60;
6514 } else {
6515 s = l > 0 && l < 1 ? 0 : h;
6516 }
6517 return new Hsl(h, s, l, o.opacity);
6518 }
6519
6520 function hsl(h, s, l, opacity) {
6521 return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity);
6522 }
6523
6524 function Hsl(h, s, l, opacity) {
6525 this.h = +h;
6526 this.s = +s;
6527 this.l = +l;
6528 this.opacity = +opacity;
6529 }
6530
6531 define(Hsl, hsl, extend(Color, {
6532 brighter: function(k) {
6533 k = k == null ? brighter : Math.pow(brighter, k);
6534 return new Hsl(this.h, this.s, this.l * k, this.opacity);
6535 },
6536 darker: function(k) {
6537 k = k == null ? darker : Math.pow(darker, k);
6538 return new Hsl(this.h, this.s, this.l * k, this.opacity);
6539 },
6540 rgb: function() {
6541 var h = this.h % 360 + (this.h < 0) * 360,
6542 s = isNaN(h) || isNaN(this.s) ? 0 : this.s,
6543 l = this.l,
6544 m2 = l + (l < 0.5 ? l : 1 - l) * s,
6545 m1 = 2 * l - m2;
6546 return new Rgb(
6547 hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2),
6548 hsl2rgb(h, m1, m2),
6549 hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2),
6550 this.opacity
6551 );
6552 },
6553 displayable: function() {
6554 return (0 <= this.s && this.s <= 1 || isNaN(this.s))
6555 && (0 <= this.l && this.l <= 1)
6556 && (0 <= this.opacity && this.opacity <= 1);
6557 },
6558 formatHsl: function() {
6559 var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a));
6560 return (a === 1 ? "hsl(" : "hsla(")
6561 + (this.h || 0) + ", "
6562 + (this.s || 0) * 100 + "%, "
6563 + (this.l || 0) * 100 + "%"
6564 + (a === 1 ? ")" : ", " + a + ")");
6565 }
6566 }));
6567
6568 /* From FvD 13.37, CSS Color Module Level 3 */
6569 function hsl2rgb(h, m1, m2) {
6570 return (h < 60 ? m1 + (m2 - m1) * h / 60
6571 : h < 180 ? m2
6572 : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60
6573 : m1) * 255;
6574 }
6575
6576 function distance$1(x1, y1, x2, y2) {
6577 var dx = x1 - x2;
6578 var dy = y1 - y2;
6579 return Math.sqrt(dx * dx + dy * dy);
6580 }
6581 function getBBoxByArray(xArr, yArr) {
6582 var minX = Math.min.apply(Math, __spreadArray([], __read(xArr), false));
6583 var minY = Math.min.apply(Math, __spreadArray([], __read(yArr), false));
6584 var maxX = Math.max.apply(Math, __spreadArray([], __read(xArr), false));
6585 var maxY = Math.max.apply(Math, __spreadArray([], __read(yArr), false));
6586 return {
6587 x: minX,
6588 y: minY,
6589 width: maxX - minX,
6590 height: maxY - minY,
6591 };
6592 }
6593 // x 的极值
6594 function xExtrema(rx, ry, xRotation) {
6595 return Math.atan((-ry / rx) * Math.tan(xRotation));
6596 }
6597 // y 的极值
6598 function yExtrema(rx, ry, xRotation) {
6599 return Math.atan(ry / (rx * Math.tan(xRotation)));
6600 }
6601 // 根据角度求 x 坐标
6602 function xAt(cx, cy, rx, ry, xRotation, angle) {
6603 return (rx * Math.cos(xRotation) * Math.cos(angle) -
6604 ry * Math.sin(xRotation) * Math.sin(angle) +
6605 cx);
6606 }
6607 // 根据角度求 y 坐标
6608 function yAt(cx, cy, rx, ry, xRotation, angle) {
6609 return (rx * Math.sin(xRotation) * Math.cos(angle) +
6610 ry * Math.cos(xRotation) * Math.sin(angle) +
6611 cy);
6612 }
6613 function box$5(cx, cy, rx, ry, xRotation, startAngle, endAngle) {
6614 var xDim = xExtrema(rx, ry, xRotation);
6615 var minX = Infinity;
6616 var maxX = -Infinity;
6617 var xs = [startAngle, endAngle];
6618 for (var i = -Math.PI * 2; i <= Math.PI * 2; i += Math.PI) {
6619 var xAngle = xDim + i;
6620 if (startAngle < endAngle) {
6621 if (startAngle < xAngle && xAngle < endAngle) {
6622 xs.push(xAngle);
6623 }
6624 }
6625 else {
6626 if (endAngle < xAngle && xAngle < startAngle) {
6627 xs.push(xAngle);
6628 }
6629 }
6630 }
6631 for (var i = 0; i < xs.length; i++) {
6632 var x = xAt(cx, cy, rx, ry, xRotation, xs[i]);
6633 if (x < minX) {
6634 minX = x;
6635 }
6636 if (x > maxX) {
6637 maxX = x;
6638 }
6639 }
6640 var yDim = yExtrema(rx, ry, xRotation);
6641 var minY = Infinity;
6642 var maxY = -Infinity;
6643 var ys = [startAngle, endAngle];
6644 for (var i = -Math.PI * 2; i <= Math.PI * 2; i += Math.PI) {
6645 var yAngle = yDim + i;
6646 if (startAngle < endAngle) {
6647 if (startAngle < yAngle && yAngle < endAngle) {
6648 ys.push(yAngle);
6649 }
6650 }
6651 else {
6652 if (endAngle < yAngle && yAngle < startAngle) {
6653 ys.push(yAngle);
6654 }
6655 }
6656 }
6657 for (var i = 0; i < ys.length; i++) {
6658 var y = yAt(cx, cy, rx, ry, xRotation, ys[i]);
6659 if (y < minY) {
6660 minY = y;
6661 }
6662 if (y > maxY) {
6663 maxY = y;
6664 }
6665 }
6666 return {
6667 x: minX,
6668 y: minY,
6669 width: maxX - minX,
6670 height: maxY - minY,
6671 };
6672 }
6673
6674 var EPSILON$1 = 0.0001;
6675 /**
6676 * 使用牛顿切割法求最近的点
6677 * @param {number[]} xArr 点的 x 数组
6678 * @param {number[]} yArr 点的 y 数组
6679 * @param {number} x 指定的点 x
6680 * @param {number} y 指定的点 y
6681 * @param {Function} tCallback 差值函数
6682 */
6683 function nearestPoint$2(xArr, yArr, x, y, tCallback, length) {
6684 var t = -1;
6685 var d = Infinity;
6686 var v0 = [x, y];
6687 var segNum = 20;
6688 if (length && length > 200) {
6689 segNum = length / 10;
6690 }
6691 var increaseRate = 1 / segNum;
6692 var interval = increaseRate / 10;
6693 for (var i = 0; i <= segNum; i++) {
6694 var _t = i * increaseRate;
6695 var v1 = [
6696 tCallback.apply(void 0, __spreadArray([], __read(xArr.concat([_t])), false)),
6697 tCallback.apply(void 0, __spreadArray([], __read(yArr.concat([_t])), false)),
6698 ];
6699 var d1 = distance$1(v0[0], v0[1], v1[0], v1[1]);
6700 if (d1 < d) {
6701 t = _t;
6702 d = d1;
6703 }
6704 }
6705 // 提前终止
6706 if (t === 0) {
6707 return {
6708 x: xArr[0],
6709 y: yArr[0],
6710 };
6711 }
6712 if (t === 1) {
6713 var count = xArr.length;
6714 return {
6715 x: xArr[count - 1],
6716 y: yArr[count - 1],
6717 };
6718 }
6719 d = Infinity;
6720 for (var i = 0; i < 32; i++) {
6721 if (interval < EPSILON$1) {
6722 break;
6723 }
6724 var prev = t - interval;
6725 var next = t + interval;
6726 var v1 = [
6727 tCallback.apply(void 0, __spreadArray([], __read(xArr.concat([prev])), false)),
6728 tCallback.apply(void 0, __spreadArray([], __read(yArr.concat([prev])), false)),
6729 ];
6730 var d1 = distance$1(v0[0], v0[1], v1[0], v1[1]);
6731 if (prev >= 0 && d1 < d) {
6732 t = prev;
6733 d = d1;
6734 }
6735 else {
6736 var v2 = [
6737 tCallback.apply(void 0, __spreadArray([], __read(xArr.concat([next])), false)),
6738 tCallback.apply(void 0, __spreadArray([], __read(yArr.concat([next])), false)),
6739 ];
6740 var d2 = distance$1(v0[0], v0[1], v2[0], v2[1]);
6741 if (next <= 1 && d2 < d) {
6742 t = next;
6743 d = d2;
6744 }
6745 else {
6746 interval *= 0.5;
6747 }
6748 }
6749 }
6750 return {
6751 x: tCallback.apply(void 0, __spreadArray([], __read(xArr.concat([t])), false)),
6752 y: tCallback.apply(void 0, __spreadArray([], __read(yArr.concat([t])), false)),
6753 };
6754 }
6755 function length$4(x1, y1, x2, y2) {
6756 return distance$1(x1, y1, x2, y2);
6757 }
6758 function pointAt$3(x1, y1, x2, y2, t) {
6759 return {
6760 x: (1 - t) * x1 + t * x2,
6761 y: (1 - t) * y1 + t * y2,
6762 };
6763 }
6764 function pointToLine(x1, y1, x2, y2, x, y) {
6765 var d = [x2 - x1, y2 - y1];
6766 // 如果端点相等,则判定点到点的距离
6767 if (exactEquals$1(d, [0, 0])) {
6768 return Math.sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1));
6769 }
6770 var u = [-d[1], d[0]];
6771 normalize$3(u, u);
6772 var a = [x - x1, y - y1];
6773 return Math.abs(dot$1(a, u));
6774 }
6775
6776 function cubicAt(p0, p1, p2, p3, t) {
6777 var onet = 1 - t; // t * t * t 的性能大概是 Math.pow(t, 3) 的三倍
6778 return (onet * onet * onet * p0 +
6779 3 * p1 * t * onet * onet +
6780 3 * p2 * t * t * onet +
6781 p3 * t * t * t);
6782 }
6783 function extrema$1(p0, p1, p2, p3) {
6784 var a = -3 * p0 + 9 * p1 - 9 * p2 + 3 * p3;
6785 var b = 6 * p0 - 12 * p1 + 6 * p2;
6786 var c = 3 * p1 - 3 * p0;
6787 var extremas = [];
6788 var t1;
6789 var t2;
6790 var discSqrt;
6791 if (isNumberEqual(a, 0)) {
6792 if (!isNumberEqual(b, 0)) {
6793 t1 = -c / b;
6794 if (t1 >= 0 && t1 <= 1) {
6795 extremas.push(t1);
6796 }
6797 }
6798 }
6799 else {
6800 var disc = b * b - 4 * a * c;
6801 if (isNumberEqual(disc, 0)) {
6802 extremas.push(-b / (2 * a));
6803 }
6804 else if (disc > 0) {
6805 discSqrt = Math.sqrt(disc);
6806 t1 = (-b + discSqrt) / (2 * a);
6807 t2 = (-b - discSqrt) / (2 * a);
6808 if (t1 >= 0 && t1 <= 1) {
6809 extremas.push(t1);
6810 }
6811 if (t2 >= 0 && t2 <= 1) {
6812 extremas.push(t2);
6813 }
6814 }
6815 }
6816 return extremas;
6817 }
6818 function box$3(x1, y1, x2, y2, x3, y3, x4, y4) {
6819 var xArr = [x1, x4];
6820 var yArr = [y1, y4];
6821 var xExtrema = extrema$1(x1, x2, x3, x4);
6822 var yExtrema = extrema$1(y1, y2, y3, y4);
6823 for (var i = 0; i < xExtrema.length; i++) {
6824 xArr.push(cubicAt(x1, x2, x3, x4, xExtrema[i]));
6825 }
6826 for (var i = 0; i < yExtrema.length; i++) {
6827 yArr.push(cubicAt(y1, y2, y3, y4, yExtrema[i]));
6828 }
6829 return getBBoxByArray(xArr, yArr);
6830 }
6831 function nearestPoint$1(x1, y1, x2, y2, x3, y3, x4, y4, x0, y0, length) {
6832 return nearestPoint$2([x1, x2, x3, x4], [y1, y2, y3, y4], x0, y0, cubicAt, length);
6833 }
6834 function pointDistance$3(x1, y1, x2, y2, x3, y3, x4, y4, x0, y0, length) {
6835 var point = nearestPoint$1(x1, y1, x2, y2, x3, y3, x4, y4, x0, y0, length);
6836 return distance$1(point.x, point.y, x0, y0);
6837 }
6838 function lengthOfSegment(points) {
6839 if (points.length < 2) {
6840 return 0;
6841 }
6842 var totalLength = 0;
6843 for (var i = 0; i < points.length - 1; i++) {
6844 var from = points[i];
6845 var to = points[i + 1];
6846 totalLength += distance$1(from[0], from[1], to[0], to[1]);
6847 }
6848 return totalLength;
6849 }
6850 function length$2(points) {
6851 return lengthOfSegment(points);
6852 }
6853
6854 // 差值公式
6855 function quadraticAt(p0, p1, p2, t) {
6856 var onet = 1 - t;
6857 return onet * onet * p0 + 2 * t * onet * p1 + t * t * p2;
6858 }
6859 // 求极值
6860 function extrema(p0, p1, p2) {
6861 var a = p0 + p2 - 2 * p1;
6862 if (isNumberEqual(a, 0)) {
6863 return [0.5];
6864 }
6865 var rst = (p0 - p1) / a;
6866 if (rst <= 1 && rst >= 0) {
6867 return [rst];
6868 }
6869 return [];
6870 }
6871 function box(x1, y1, x2, y2, x3, y3) {
6872 var xExtrema = extrema(x1, x2, x3)[0];
6873 var yExtrema = extrema(y1, y2, y3)[0];
6874 // 控制点不加入 box 的计算
6875 var xArr = [x1, x3];
6876 var yArr = [y1, y3];
6877 if (xExtrema !== undefined) {
6878 xArr.push(quadraticAt(x1, x2, x3, xExtrema));
6879 }
6880 if (yExtrema !== undefined) {
6881 yArr.push(quadraticAt(y1, y2, y3, yExtrema));
6882 }
6883 return getBBoxByArray(xArr, yArr);
6884 }
6885 function nearestPoint(x1, y1, x2, y2, x3, y3, x0, y0) {
6886 return nearestPoint$2([x1, x2, x3], [y1, y2, y3], x0, y0, quadraticAt);
6887 }
6888 function pointDistance(x1, y1, x2, y2, x3, y3, x0, y0) {
6889 var point = nearestPoint(x1, y1, x2, y2, x3, y3, x0, y0);
6890 return distance$1(point.x, point.y, x0, y0);
6891 }
6892
6893 var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
6894
6895 var rbush = {exports: {}};
6896
6897 (function (module, exports) {
6898 (function (global, factory) {
6899 module.exports = factory() ;
6900 }(commonjsGlobal, function () {
6901 function quickselect(arr, k, left, right, compare) {
6902 quickselectStep(arr, k, left || 0, right || (arr.length - 1), compare || defaultCompare);
6903 }
6904
6905 function quickselectStep(arr, k, left, right, compare) {
6906
6907 while (right > left) {
6908 if (right - left > 600) {
6909 var n = right - left + 1;
6910 var m = k - left + 1;
6911 var z = Math.log(n);
6912 var s = 0.5 * Math.exp(2 * z / 3);
6913 var sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1);
6914 var newLeft = Math.max(left, Math.floor(k - m * s / n + sd));
6915 var newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd));
6916 quickselectStep(arr, k, newLeft, newRight, compare);
6917 }
6918
6919 var t = arr[k];
6920 var i = left;
6921 var j = right;
6922
6923 swap(arr, left, k);
6924 if (compare(arr[right], t) > 0) { swap(arr, left, right); }
6925
6926 while (i < j) {
6927 swap(arr, i, j);
6928 i++;
6929 j--;
6930 while (compare(arr[i], t) < 0) { i++; }
6931 while (compare(arr[j], t) > 0) { j--; }
6932 }
6933
6934 if (compare(arr[left], t) === 0) { swap(arr, left, j); }
6935 else {
6936 j++;
6937 swap(arr, j, right);
6938 }
6939
6940 if (j <= k) { left = j + 1; }
6941 if (k <= j) { right = j - 1; }
6942 }
6943 }
6944
6945 function swap(arr, i, j) {
6946 var tmp = arr[i];
6947 arr[i] = arr[j];
6948 arr[j] = tmp;
6949 }
6950
6951 function defaultCompare(a, b) {
6952 return a < b ? -1 : a > b ? 1 : 0;
6953 }
6954
6955 var RBush = function RBush(maxEntries) {
6956 if ( maxEntries === void 0 ) maxEntries = 9;
6957
6958 // max entries in a node is 9 by default; min node fill is 40% for best performance
6959 this._maxEntries = Math.max(4, maxEntries);
6960 this._minEntries = Math.max(2, Math.ceil(this._maxEntries * 0.4));
6961 this.clear();
6962 };
6963
6964 RBush.prototype.all = function all () {
6965 return this._all(this.data, []);
6966 };
6967
6968 RBush.prototype.search = function search (bbox) {
6969 var node = this.data;
6970 var result = [];
6971
6972 if (!intersects(bbox, node)) { return result; }
6973
6974 var toBBox = this.toBBox;
6975 var nodesToSearch = [];
6976
6977 while (node) {
6978 for (var i = 0; i < node.children.length; i++) {
6979 var child = node.children[i];
6980 var childBBox = node.leaf ? toBBox(child) : child;
6981
6982 if (intersects(bbox, childBBox)) {
6983 if (node.leaf) { result.push(child); }
6984 else if (contains(bbox, childBBox)) { this._all(child, result); }
6985 else { nodesToSearch.push(child); }
6986 }
6987 }
6988 node = nodesToSearch.pop();
6989 }
6990
6991 return result;
6992 };
6993
6994 RBush.prototype.collides = function collides (bbox) {
6995 var node = this.data;
6996
6997 if (!intersects(bbox, node)) { return false; }
6998
6999 var nodesToSearch = [];
7000 while (node) {
7001 for (var i = 0; i < node.children.length; i++) {
7002 var child = node.children[i];
7003 var childBBox = node.leaf ? this.toBBox(child) : child;
7004
7005 if (intersects(bbox, childBBox)) {
7006 if (node.leaf || contains(bbox, childBBox)) { return true; }
7007 nodesToSearch.push(child);
7008 }
7009 }
7010 node = nodesToSearch.pop();
7011 }
7012
7013 return false;
7014 };
7015
7016 RBush.prototype.load = function load (data) {
7017 if (!(data && data.length)) { return this; }
7018
7019 if (data.length < this._minEntries) {
7020 for (var i = 0; i < data.length; i++) {
7021 this.insert(data[i]);
7022 }
7023 return this;
7024 }
7025
7026 // recursively build the tree with the given data from scratch using OMT algorithm
7027 var node = this._build(data.slice(), 0, data.length - 1, 0);
7028
7029 if (!this.data.children.length) {
7030 // save as is if tree is empty
7031 this.data = node;
7032
7033 } else if (this.data.height === node.height) {
7034 // split root if trees have the same height
7035 this._splitRoot(this.data, node);
7036
7037 } else {
7038 if (this.data.height < node.height) {
7039 // swap trees if inserted one is bigger
7040 var tmpNode = this.data;
7041 this.data = node;
7042 node = tmpNode;
7043 }
7044
7045 // insert the small tree into the large tree at appropriate level
7046 this._insert(node, this.data.height - node.height - 1, true);
7047 }
7048
7049 return this;
7050 };
7051
7052 RBush.prototype.insert = function insert (item) {
7053 if (item) { this._insert(item, this.data.height - 1); }
7054 return this;
7055 };
7056
7057 RBush.prototype.clear = function clear () {
7058 this.data = createNode([]);
7059 return this;
7060 };
7061
7062 RBush.prototype.remove = function remove (item, equalsFn) {
7063 if (!item) { return this; }
7064
7065 var node = this.data;
7066 var bbox = this.toBBox(item);
7067 var path = [];
7068 var indexes = [];
7069 var i, parent, goingUp;
7070
7071 // depth-first iterative tree traversal
7072 while (node || path.length) {
7073
7074 if (!node) { // go up
7075 node = path.pop();
7076 parent = path[path.length - 1];
7077 i = indexes.pop();
7078 goingUp = true;
7079 }
7080
7081 if (node.leaf) { // check current node
7082 var index = findItem(item, node.children, equalsFn);
7083
7084 if (index !== -1) {
7085 // item found, remove the item and condense tree upwards
7086 node.children.splice(index, 1);
7087 path.push(node);
7088 this._condense(path);
7089 return this;
7090 }
7091 }
7092
7093 if (!goingUp && !node.leaf && contains(node, bbox)) { // go down
7094 path.push(node);
7095 indexes.push(i);
7096 i = 0;
7097 parent = node;
7098 node = node.children[0];
7099
7100 } else if (parent) { // go right
7101 i++;
7102 node = parent.children[i];
7103 goingUp = false;
7104
7105 } else { node = null; } // nothing found
7106 }
7107
7108 return this;
7109 };
7110
7111 RBush.prototype.toBBox = function toBBox (item) { return item; };
7112
7113 RBush.prototype.compareMinX = function compareMinX (a, b) { return a.minX - b.minX; };
7114 RBush.prototype.compareMinY = function compareMinY (a, b) { return a.minY - b.minY; };
7115
7116 RBush.prototype.toJSON = function toJSON () { return this.data; };
7117
7118 RBush.prototype.fromJSON = function fromJSON (data) {
7119 this.data = data;
7120 return this;
7121 };
7122
7123 RBush.prototype._all = function _all (node, result) {
7124 var nodesToSearch = [];
7125 while (node) {
7126 if (node.leaf) { result.push.apply(result, node.children); }
7127 else { nodesToSearch.push.apply(nodesToSearch, node.children); }
7128
7129 node = nodesToSearch.pop();
7130 }
7131 return result;
7132 };
7133
7134 RBush.prototype._build = function _build (items, left, right, height) {
7135
7136 var N = right - left + 1;
7137 var M = this._maxEntries;
7138 var node;
7139
7140 if (N <= M) {
7141 // reached leaf level; return leaf
7142 node = createNode(items.slice(left, right + 1));
7143 calcBBox(node, this.toBBox);
7144 return node;
7145 }
7146
7147 if (!height) {
7148 // target height of the bulk-loaded tree
7149 height = Math.ceil(Math.log(N) / Math.log(M));
7150
7151 // target number of root entries to maximize storage utilization
7152 M = Math.ceil(N / Math.pow(M, height - 1));
7153 }
7154
7155 node = createNode([]);
7156 node.leaf = false;
7157 node.height = height;
7158
7159 // split the items into M mostly square tiles
7160
7161 var N2 = Math.ceil(N / M);
7162 var N1 = N2 * Math.ceil(Math.sqrt(M));
7163
7164 multiSelect(items, left, right, N1, this.compareMinX);
7165
7166 for (var i = left; i <= right; i += N1) {
7167
7168 var right2 = Math.min(i + N1 - 1, right);
7169
7170 multiSelect(items, i, right2, N2, this.compareMinY);
7171
7172 for (var j = i; j <= right2; j += N2) {
7173
7174 var right3 = Math.min(j + N2 - 1, right2);
7175
7176 // pack each entry recursively
7177 node.children.push(this._build(items, j, right3, height - 1));
7178 }
7179 }
7180
7181 calcBBox(node, this.toBBox);
7182
7183 return node;
7184 };
7185
7186 RBush.prototype._chooseSubtree = function _chooseSubtree (bbox, node, level, path) {
7187 while (true) {
7188 path.push(node);
7189
7190 if (node.leaf || path.length - 1 === level) { break; }
7191
7192 var minArea = Infinity;
7193 var minEnlargement = Infinity;
7194 var targetNode = (void 0);
7195
7196 for (var i = 0; i < node.children.length; i++) {
7197 var child = node.children[i];
7198 var area = bboxArea(child);
7199 var enlargement = enlargedArea(bbox, child) - area;
7200
7201 // choose entry with the least area enlargement
7202 if (enlargement < minEnlargement) {
7203 minEnlargement = enlargement;
7204 minArea = area < minArea ? area : minArea;
7205 targetNode = child;
7206
7207 } else if (enlargement === minEnlargement) {
7208 // otherwise choose one with the smallest area
7209 if (area < minArea) {
7210 minArea = area;
7211 targetNode = child;
7212 }
7213 }
7214 }
7215
7216 node = targetNode || node.children[0];
7217 }
7218
7219 return node;
7220 };
7221
7222 RBush.prototype._insert = function _insert (item, level, isNode) {
7223 var bbox = isNode ? item : this.toBBox(item);
7224 var insertPath = [];
7225
7226 // find the best node for accommodating the item, saving all nodes along the path too
7227 var node = this._chooseSubtree(bbox, this.data, level, insertPath);
7228
7229 // put the item into the node
7230 node.children.push(item);
7231 extend(node, bbox);
7232
7233 // split on node overflow; propagate upwards if necessary
7234 while (level >= 0) {
7235 if (insertPath[level].children.length > this._maxEntries) {
7236 this._split(insertPath, level);
7237 level--;
7238 } else { break; }
7239 }
7240
7241 // adjust bboxes along the insertion path
7242 this._adjustParentBBoxes(bbox, insertPath, level);
7243 };
7244
7245 // split overflowed node into two
7246 RBush.prototype._split = function _split (insertPath, level) {
7247 var node = insertPath[level];
7248 var M = node.children.length;
7249 var m = this._minEntries;
7250
7251 this._chooseSplitAxis(node, m, M);
7252
7253 var splitIndex = this._chooseSplitIndex(node, m, M);
7254
7255 var newNode = createNode(node.children.splice(splitIndex, node.children.length - splitIndex));
7256 newNode.height = node.height;
7257 newNode.leaf = node.leaf;
7258
7259 calcBBox(node, this.toBBox);
7260 calcBBox(newNode, this.toBBox);
7261
7262 if (level) { insertPath[level - 1].children.push(newNode); }
7263 else { this._splitRoot(node, newNode); }
7264 };
7265
7266 RBush.prototype._splitRoot = function _splitRoot (node, newNode) {
7267 // split root node
7268 this.data = createNode([node, newNode]);
7269 this.data.height = node.height + 1;
7270 this.data.leaf = false;
7271 calcBBox(this.data, this.toBBox);
7272 };
7273
7274 RBush.prototype._chooseSplitIndex = function _chooseSplitIndex (node, m, M) {
7275 var index;
7276 var minOverlap = Infinity;
7277 var minArea = Infinity;
7278
7279 for (var i = m; i <= M - m; i++) {
7280 var bbox1 = distBBox(node, 0, i, this.toBBox);
7281 var bbox2 = distBBox(node, i, M, this.toBBox);
7282
7283 var overlap = intersectionArea(bbox1, bbox2);
7284 var area = bboxArea(bbox1) + bboxArea(bbox2);
7285
7286 // choose distribution with minimum overlap
7287 if (overlap < minOverlap) {
7288 minOverlap = overlap;
7289 index = i;
7290
7291 minArea = area < minArea ? area : minArea;
7292
7293 } else if (overlap === minOverlap) {
7294 // otherwise choose distribution with minimum area
7295 if (area < minArea) {
7296 minArea = area;
7297 index = i;
7298 }
7299 }
7300 }
7301
7302 return index || M - m;
7303 };
7304
7305 // sorts node children by the best axis for split
7306 RBush.prototype._chooseSplitAxis = function _chooseSplitAxis (node, m, M) {
7307 var compareMinX = node.leaf ? this.compareMinX : compareNodeMinX;
7308 var compareMinY = node.leaf ? this.compareMinY : compareNodeMinY;
7309 var xMargin = this._allDistMargin(node, m, M, compareMinX);
7310 var yMargin = this._allDistMargin(node, m, M, compareMinY);
7311
7312 // if total distributions margin value is minimal for x, sort by minX,
7313 // otherwise it's already sorted by minY
7314 if (xMargin < yMargin) { node.children.sort(compareMinX); }
7315 };
7316
7317 // total margin of all possible split distributions where each node is at least m full
7318 RBush.prototype._allDistMargin = function _allDistMargin (node, m, M, compare) {
7319 node.children.sort(compare);
7320
7321 var toBBox = this.toBBox;
7322 var leftBBox = distBBox(node, 0, m, toBBox);
7323 var rightBBox = distBBox(node, M - m, M, toBBox);
7324 var margin = bboxMargin(leftBBox) + bboxMargin(rightBBox);
7325
7326 for (var i = m; i < M - m; i++) {
7327 var child = node.children[i];
7328 extend(leftBBox, node.leaf ? toBBox(child) : child);
7329 margin += bboxMargin(leftBBox);
7330 }
7331
7332 for (var i$1 = M - m - 1; i$1 >= m; i$1--) {
7333 var child$1 = node.children[i$1];
7334 extend(rightBBox, node.leaf ? toBBox(child$1) : child$1);
7335 margin += bboxMargin(rightBBox);
7336 }
7337
7338 return margin;
7339 };
7340
7341 RBush.prototype._adjustParentBBoxes = function _adjustParentBBoxes (bbox, path, level) {
7342 // adjust bboxes along the given tree path
7343 for (var i = level; i >= 0; i--) {
7344 extend(path[i], bbox);
7345 }
7346 };
7347
7348 RBush.prototype._condense = function _condense (path) {
7349 // go through the path, removing empty nodes and updating bboxes
7350 for (var i = path.length - 1, siblings = (void 0); i >= 0; i--) {
7351 if (path[i].children.length === 0) {
7352 if (i > 0) {
7353 siblings = path[i - 1].children;
7354 siblings.splice(siblings.indexOf(path[i]), 1);
7355
7356 } else { this.clear(); }
7357
7358 } else { calcBBox(path[i], this.toBBox); }
7359 }
7360 };
7361
7362 function findItem(item, items, equalsFn) {
7363 if (!equalsFn) { return items.indexOf(item); }
7364
7365 for (var i = 0; i < items.length; i++) {
7366 if (equalsFn(item, items[i])) { return i; }
7367 }
7368 return -1;
7369 }
7370
7371 // calculate node's bbox from bboxes of its children
7372 function calcBBox(node, toBBox) {
7373 distBBox(node, 0, node.children.length, toBBox, node);
7374 }
7375
7376 // min bounding rectangle of node children from k to p-1
7377 function distBBox(node, k, p, toBBox, destNode) {
7378 if (!destNode) { destNode = createNode(null); }
7379 destNode.minX = Infinity;
7380 destNode.minY = Infinity;
7381 destNode.maxX = -Infinity;
7382 destNode.maxY = -Infinity;
7383
7384 for (var i = k; i < p; i++) {
7385 var child = node.children[i];
7386 extend(destNode, node.leaf ? toBBox(child) : child);
7387 }
7388
7389 return destNode;
7390 }
7391
7392 function extend(a, b) {
7393 a.minX = Math.min(a.minX, b.minX);
7394 a.minY = Math.min(a.minY, b.minY);
7395 a.maxX = Math.max(a.maxX, b.maxX);
7396 a.maxY = Math.max(a.maxY, b.maxY);
7397 return a;
7398 }
7399
7400 function compareNodeMinX(a, b) { return a.minX - b.minX; }
7401 function compareNodeMinY(a, b) { return a.minY - b.minY; }
7402
7403 function bboxArea(a) { return (a.maxX - a.minX) * (a.maxY - a.minY); }
7404 function bboxMargin(a) { return (a.maxX - a.minX) + (a.maxY - a.minY); }
7405
7406 function enlargedArea(a, b) {
7407 return (Math.max(b.maxX, a.maxX) - Math.min(b.minX, a.minX)) *
7408 (Math.max(b.maxY, a.maxY) - Math.min(b.minY, a.minY));
7409 }
7410
7411 function intersectionArea(a, b) {
7412 var minX = Math.max(a.minX, b.minX);
7413 var minY = Math.max(a.minY, b.minY);
7414 var maxX = Math.min(a.maxX, b.maxX);
7415 var maxY = Math.min(a.maxY, b.maxY);
7416
7417 return Math.max(0, maxX - minX) *
7418 Math.max(0, maxY - minY);
7419 }
7420
7421 function contains(a, b) {
7422 return a.minX <= b.minX &&
7423 a.minY <= b.minY &&
7424 b.maxX <= a.maxX &&
7425 b.maxY <= a.maxY;
7426 }
7427
7428 function intersects(a, b) {
7429 return b.minX <= a.maxX &&
7430 b.minY <= a.maxY &&
7431 b.maxX >= a.minX &&
7432 b.maxY >= a.minY;
7433 }
7434
7435 function createNode(children) {
7436 return {
7437 children: children,
7438 height: 1,
7439 leaf: true,
7440 minX: Infinity,
7441 minY: Infinity,
7442 maxX: -Infinity,
7443 maxY: -Infinity
7444 };
7445 }
7446
7447 // sort an array so that items come in groups of n unsorted items, with groups sorted between each other;
7448 // combines selection algorithm with binary divide & conquer approach
7449
7450 function multiSelect(arr, left, right, n, compare) {
7451 var stack = [left, right];
7452
7453 while (stack.length) {
7454 right = stack.pop();
7455 left = stack.pop();
7456
7457 if (right - left <= n) { continue; }
7458
7459 var mid = left + Math.ceil((right - left) / n / 2) * n;
7460 quickselect(arr, mid, left, right, compare);
7461
7462 stack.push(left, mid, mid, right);
7463 }
7464 }
7465
7466 return RBush;
7467
7468 }));
7469 }(rbush));
7470
7471 var RBush = rbush.exports;
7472
7473 var Shape;
7474 (function (Shape) {
7475 Shape["GROUP"] = "g";
7476 Shape["CIRCLE"] = "circle";
7477 Shape["ELLIPSE"] = "ellipse";
7478 Shape["IMAGE"] = "image";
7479 Shape["RECT"] = "rect";
7480 Shape["LINE"] = "line";
7481 Shape["POLYLINE"] = "polyline";
7482 Shape["POLYGON"] = "polygon";
7483 Shape["TEXT"] = "text";
7484 Shape["PATH"] = "path";
7485 Shape["HTML"] = "html";
7486 Shape["MESH"] = "mesh";
7487 })(Shape || (Shape = {}));
7488 var ClipSpaceNearZ;
7489 (function (ClipSpaceNearZ) {
7490 ClipSpaceNearZ[ClipSpaceNearZ["ZERO"] = 0] = "ZERO";
7491 ClipSpaceNearZ[ClipSpaceNearZ["NEGATIVE_ONE"] = 1] = "NEGATIVE_ONE";
7492 })(ClipSpaceNearZ || (ClipSpaceNearZ = {}));
7493
7494 var AbstractRendererPlugin = /** @class */ (function () {
7495 function AbstractRendererPlugin() {
7496 this.plugins = [];
7497 }
7498 AbstractRendererPlugin.prototype.addRenderingPlugin = function (plugin) {
7499 this.plugins.push(plugin);
7500 this.context.renderingPlugins.push(plugin);
7501 };
7502 AbstractRendererPlugin.prototype.removeAllRenderingPlugins = function () {
7503 var _this = this;
7504 this.plugins.forEach(function (plugin) {
7505 var index = _this.context.renderingPlugins.indexOf(plugin);
7506 if (index >= 0) {
7507 _this.context.renderingPlugins.splice(index, 1);
7508 }
7509 });
7510 };
7511 return AbstractRendererPlugin;
7512 }());
7513 var AbstractRenderer = /** @class */ (function () {
7514 function AbstractRenderer(config) {
7515 this.clipSpaceNearZ = ClipSpaceNearZ.NEGATIVE_ONE;
7516 this.plugins = [];
7517 this.config = __assign({
7518 /**
7519 * only dirty object will cause re-render
7520 */
7521 enableDirtyCheck: true, enableCulling: false,
7522 /**
7523 * enable auto rendering by default
7524 */
7525 enableAutoRendering: true,
7526 /**
7527 * enable dirty rectangle rendering by default
7528 */
7529 enableDirtyRectangleRendering: true, enableDirtyRectangleRenderingDebug: false, enableSizeAttenuation: true }, config);
7530 }
7531 AbstractRenderer.prototype.registerPlugin = function (plugin) {
7532 var index = this.plugins.findIndex(function (p) { return p === plugin; });
7533 if (index === -1) {
7534 this.plugins.push(plugin);
7535 }
7536 };
7537 AbstractRenderer.prototype.unregisterPlugin = function (plugin) {
7538 var index = this.plugins.findIndex(function (p) { return p === plugin; });
7539 if (index > -1) {
7540 this.plugins.splice(index, 1);
7541 }
7542 };
7543 AbstractRenderer.prototype.getPlugins = function () {
7544 return this.plugins;
7545 };
7546 AbstractRenderer.prototype.getPlugin = function (name) {
7547 return this.plugins.find(function (plugin) { return plugin.name === name; });
7548 };
7549 AbstractRenderer.prototype.getConfig = function () {
7550 return this.config;
7551 };
7552 AbstractRenderer.prototype.setConfig = function (config) {
7553 Object.assign(this.config, config);
7554 };
7555 return AbstractRenderer;
7556 }());
7557
7558 function copyVec3(a, b) {
7559 a[0] = b[0];
7560 a[1] = b[1];
7561 a[2] = b[2];
7562 return a;
7563 }
7564 function subVec3(o, a, b) {
7565 o[0] = a[0] - b[0];
7566 o[1] = a[1] - b[1];
7567 o[2] = a[2] - b[2];
7568 return o;
7569 }
7570 function addVec3(o, a, b) {
7571 o[0] = a[0] + b[0];
7572 o[1] = a[1] + b[1];
7573 o[2] = a[2] + b[2];
7574 return o;
7575 }
7576 function scaleVec3(o, a, b) {
7577 o[0] = a[0] * b;
7578 o[1] = a[1] * b;
7579 o[2] = a[2] * b;
7580 return o;
7581 }
7582 function maxVec3(o, a, b) {
7583 o[0] = Math.max(a[0], b[0]);
7584 o[1] = Math.max(a[1], b[1]);
7585 o[2] = Math.max(a[2], b[2]);
7586 return o;
7587 }
7588 function minVec3(o, a, b) {
7589 o[0] = Math.min(a[0], b[0]);
7590 o[1] = Math.min(a[1], b[1]);
7591 o[2] = Math.min(a[2], b[2]);
7592 return o;
7593 }
7594 function getAngle(angle) {
7595 if (angle === undefined) {
7596 return 0;
7597 }
7598 else if (angle > 360 || angle < -360) {
7599 return angle % 360;
7600 }
7601 return angle;
7602 }
7603 function createVec3(x, y, z) {
7604 if (y === void 0) { y = 0; }
7605 if (z === void 0) { z = 0; }
7606 if (Array.isArray(x) && x.length === 3) {
7607 return clone$2(x);
7608 }
7609 if (isNumber(x)) {
7610 return fromValues$2(x, y, z);
7611 }
7612 return fromValues$2(x[0], x[1] || y, x[2] || z);
7613 }
7614 function deg2rad(deg) {
7615 return deg * (Math.PI / 180);
7616 }
7617 function rad2deg(rad) {
7618 return rad * (180 / Math.PI);
7619 }
7620 function turn2deg(turn) {
7621 return 360 * turn;
7622 }
7623 function getEulerFromQuat(out, quat) {
7624 var x = quat[0];
7625 var y = quat[1];
7626 var z = quat[2];
7627 var w = quat[3];
7628 var x2 = x * x;
7629 var y2 = y * y;
7630 var z2 = z * z;
7631 var w2 = w * w;
7632 var unit = x2 + y2 + z2 + w2;
7633 var test = x * w - y * z;
7634 if (test > 0.499995 * unit) {
7635 // TODO: Use glmatrix.EPSILON
7636 // singularity at the north pole
7637 out[0] = Math.PI / 2;
7638 out[1] = 2 * Math.atan2(y, x);
7639 out[2] = 0;
7640 }
7641 else if (test < -0.499995 * unit) {
7642 //TODO: Use glmatrix.EPSILON
7643 // singularity at the south pole
7644 out[0] = -Math.PI / 2;
7645 out[1] = 2 * Math.atan2(y, x);
7646 out[2] = 0;
7647 }
7648 else {
7649 out[0] = Math.asin(2 * (x * z - w * y));
7650 out[1] = Math.atan2(2 * (x * w + y * z), 1 - 2 * (z2 + w2));
7651 out[2] = Math.atan2(2 * (x * y + z * w), 1 - 2 * (y2 + z2));
7652 }
7653 // TODO: Return them as degrees and not as radians
7654 return out;
7655 }
7656 function getEulerFromMat4(out, m) {
7657 var x;
7658 var z;
7659 var halfPi = Math.PI * 0.5;
7660 var _a = __read(getScaling(create$2(), m), 3), sx = _a[0], sy = _a[1], sz = _a[2];
7661 var y = Math.asin(-m[2] / sx);
7662 if (y < halfPi) {
7663 if (y > -halfPi) {
7664 x = Math.atan2(m[6] / sy, m[10] / sz);
7665 z = Math.atan2(m[1] / sx, m[0] / sx);
7666 }
7667 else {
7668 // Not a unique solution
7669 z = 0;
7670 x = -Math.atan2(m[4] / sy, m[5] / sy);
7671 }
7672 }
7673 else {
7674 // Not a unique solution
7675 z = 0;
7676 x = Math.atan2(m[4] / sy, m[5] / sy);
7677 }
7678 out[0] = x;
7679 out[1] = y;
7680 out[2] = z;
7681 return out;
7682 }
7683 /**
7684 * @see https://github.com/toji/gl-matrix/issues/329
7685 * @see https://doc.babylonjs.com/divingDeeper/mesh/transforms/center_origin/rotation_conventions
7686 */
7687 function getEuler(out, quat) {
7688 if (quat.length === 16) {
7689 return getEulerFromMat4(out, quat);
7690 }
7691 else {
7692 return getEulerFromQuat(out, quat);
7693 }
7694 }
7695 function fromRotationTranslationScale$1(rotation, x, y, scaleX, scaleY) {
7696 var cos = Math.cos(rotation);
7697 var sin = Math.sin(rotation);
7698 return fromValues(scaleX * cos, scaleY * sin, 0, -scaleX * sin, scaleY * cos, 0, x, y, 1);
7699 }
7700 function makePerspective(out, left, right, top, bottom, near, far, zero) {
7701 if (zero === void 0) { zero = false; }
7702 var x = (2 * near) / (right - left);
7703 var y = (2 * near) / (top - bottom);
7704 var a = (right + left) / (right - left);
7705 var b = (top + bottom) / (top - bottom);
7706 var c;
7707 var d;
7708 if (zero) {
7709 c = -far / (far - near);
7710 d = (-far * near) / (far - near);
7711 }
7712 else {
7713 c = -(far + near) / (far - near);
7714 d = (-2 * far * near) / (far - near);
7715 }
7716 out[0] = x;
7717 out[1] = 0;
7718 out[2] = 0;
7719 out[3] = 0;
7720 out[4] = 0;
7721 out[5] = y;
7722 out[6] = 0;
7723 out[7] = 0;
7724 out[8] = a;
7725 out[9] = b;
7726 out[10] = c;
7727 out[11] = -1;
7728 out[12] = 0;
7729 out[13] = 0;
7730 out[14] = d;
7731 out[15] = 0;
7732 return out;
7733 }
7734 function decompose(mat) {
7735 var row0x = mat[0];
7736 var row0y = mat[1];
7737 var row1x = mat[3];
7738 var row1y = mat[4];
7739 // decompose 3x3 matrix
7740 // @see https://www.w3.org/TR/css-transforms-1/#decomposing-a-2d-matrix
7741 var scalingX = Math.sqrt(row0x * row0x + row0y * row0y);
7742 var scalingY = Math.sqrt(row1x * row1x + row1y * row1y);
7743 // If determinant is negative, one axis was flipped.
7744 var determinant = row0x * row1y - row0y * row1x;
7745 if (determinant < 0) {
7746 // Flip axis with minimum unit vector dot product.
7747 if (row0x < row1y) {
7748 scalingX = -scalingX;
7749 }
7750 else {
7751 scalingY = -scalingY;
7752 }
7753 }
7754 // Renormalize matrix to remove scale.
7755 if (scalingX) {
7756 row0x *= 1 / scalingX;
7757 row0y *= 1 / scalingX;
7758 }
7759 if (scalingY) {
7760 row1x *= 1 / scalingY;
7761 row1y *= 1 / scalingY;
7762 }
7763 // Compute rotation and renormalize matrix.
7764 var rotation = Math.atan2(row0y, row0x);
7765 var angle = rad2deg(rotation);
7766 return [mat[6], mat[7], scalingX, scalingY, angle];
7767 }
7768 var tmp = create$1();
7769 var perspectiveMatrix = create$1();
7770 var tmpVec4 = create$3();
7771 var row = [create$2(), create$2(), create$2()];
7772 var pdum3 = create$2();
7773 /*
7774 Input: matrix ; a 4x4 matrix
7775 Output: translation ; a 3 component vector
7776 scale ; a 3 component vector
7777 skew ; skew factors XY,XZ,YZ represented as a 3 component vector
7778 perspective ; a 4 component vector
7779 quaternion ; a 4 component vector
7780 Returns false if the matrix cannot be decomposed, true if it can
7781
7782
7783 References:
7784 https://github.com/kamicane/matrix3d/blob/master/lib/Matrix3d.js
7785 https://github.com/ChromiumWebApps/chromium/blob/master/ui/gfx/transform_util.cc
7786 http://www.w3.org/TR/css3-transforms/#decomposing-a-3d-matrix
7787 */
7788 function decomposeMat4(matrix, translation, scale, skew, perspective, quaternion) {
7789 //normalize, if not possible then bail out early
7790 if (!normalize$4(tmp, matrix))
7791 return false;
7792 // perspectiveMatrix is used to solve for perspective, but it also provides
7793 // an easy way to test for singularity of the upper 3x3 component.
7794 copy(perspectiveMatrix, tmp);
7795 perspectiveMatrix[3] = 0;
7796 perspectiveMatrix[7] = 0;
7797 perspectiveMatrix[11] = 0;
7798 perspectiveMatrix[15] = 1;
7799 // If the perspectiveMatrix is not invertible, we are also unable to
7800 // decompose, so we'll bail early. Constant taken from SkMatrix44::invert.
7801 if (Math.abs(determinant(perspectiveMatrix)) < 1e-8)
7802 return false;
7803 var a03 = tmp[3], a13 = tmp[7], a23 = tmp[11], a30 = tmp[12], a31 = tmp[13], a32 = tmp[14], a33 = tmp[15];
7804 // First, isolate perspective.
7805 if (a03 !== 0 || a13 !== 0 || a23 !== 0) {
7806 tmpVec4[0] = a03;
7807 tmpVec4[1] = a13;
7808 tmpVec4[2] = a23;
7809 tmpVec4[3] = a33;
7810 // Solve the equation by inverting perspectiveMatrix and multiplying
7811 // rightHandSide by the inverse.
7812 // resuing the perspectiveMatrix here since it's no longer needed
7813 var ret = invert(perspectiveMatrix, perspectiveMatrix);
7814 if (!ret)
7815 return false;
7816 transpose(perspectiveMatrix, perspectiveMatrix);
7817 //multiply by transposed inverse perspective matrix, into perspective vec4
7818 transformMat4$1(perspective, tmpVec4, perspectiveMatrix);
7819 }
7820 else {
7821 //no perspective
7822 perspective[0] = perspective[1] = perspective[2] = 0;
7823 perspective[3] = 1;
7824 }
7825 // Next take care of translation
7826 translation[0] = a30;
7827 translation[1] = a31;
7828 translation[2] = a32;
7829 // Now get scale and shear. 'row' is a 3 element array of 3 component vectors
7830 mat3from4(row, tmp);
7831 // Compute X scale factor and normalize first row.
7832 scale[0] = length(row[0]);
7833 normalize(row[0], row[0]);
7834 // Compute XY shear factor and make 2nd row orthogonal to 1st.
7835 skew[0] = dot(row[0], row[1]);
7836 combine(row[1], row[1], row[0], 1.0, -skew[0]);
7837 // Now, compute Y scale and normalize 2nd row.
7838 scale[1] = length(row[1]);
7839 normalize(row[1], row[1]);
7840 skew[0] /= scale[1];
7841 // Compute XZ and YZ shears, orthogonalize 3rd row
7842 skew[1] = dot(row[0], row[2]);
7843 combine(row[2], row[2], row[0], 1.0, -skew[1]);
7844 skew[2] = dot(row[1], row[2]);
7845 combine(row[2], row[2], row[1], 1.0, -skew[2]);
7846 // Next, get Z scale and normalize 3rd row.
7847 scale[2] = length(row[2]);
7848 normalize(row[2], row[2]);
7849 skew[1] /= scale[2];
7850 skew[2] /= scale[2];
7851 // At this point, the matrix (in rows) is orthonormal.
7852 // Check for a coordinate system flip. If the determinant
7853 // is -1, then negate the matrix and the scaling factors.
7854 cross(pdum3, row[1], row[2]);
7855 if (dot(row[0], pdum3) < 0) {
7856 for (var i = 0; i < 3; i++) {
7857 scale[i] *= -1;
7858 row[i][0] *= -1;
7859 row[i][1] *= -1;
7860 row[i][2] *= -1;
7861 }
7862 }
7863 // Now, get the rotations out
7864 quaternion[0] =
7865 0.5 * Math.sqrt(Math.max(1 + row[0][0] - row[1][1] - row[2][2], 0));
7866 quaternion[1] =
7867 0.5 * Math.sqrt(Math.max(1 - row[0][0] + row[1][1] - row[2][2], 0));
7868 quaternion[2] =
7869 0.5 * Math.sqrt(Math.max(1 - row[0][0] - row[1][1] + row[2][2], 0));
7870 quaternion[3] =
7871 0.5 * Math.sqrt(Math.max(1 + row[0][0] + row[1][1] + row[2][2], 0));
7872 if (row[2][1] > row[1][2])
7873 quaternion[0] = -quaternion[0];
7874 if (row[0][2] > row[2][0])
7875 quaternion[1] = -quaternion[1];
7876 if (row[1][0] > row[0][1])
7877 quaternion[2] = -quaternion[2];
7878 return true;
7879 }
7880 function normalize$4(out, mat) {
7881 var m44 = mat[15];
7882 // Cannot normalize.
7883 if (m44 === 0)
7884 return false;
7885 var scale = 1 / m44;
7886 for (var i = 0; i < 16; i++)
7887 out[i] = mat[i] * scale;
7888 return true;
7889 }
7890 //gets upper-left of a 4x4 matrix into a 3x3 of vectors
7891 function mat3from4(out, mat4x4) {
7892 out[0][0] = mat4x4[0];
7893 out[0][1] = mat4x4[1];
7894 out[0][2] = mat4x4[2];
7895 out[1][0] = mat4x4[4];
7896 out[1][1] = mat4x4[5];
7897 out[1][2] = mat4x4[6];
7898 out[2][0] = mat4x4[8];
7899 out[2][1] = mat4x4[9];
7900 out[2][2] = mat4x4[10];
7901 }
7902 function combine(out, a, b, scale1, scale2) {
7903 out[0] = a[0] * scale1 + b[0] * scale2;
7904 out[1] = a[1] * scale1 + b[1] * scale2;
7905 out[2] = a[2] * scale1 + b[2] * scale2;
7906 }
7907
7908 /**
7909 * Axis-Aligned Bounding Box
7910 * 为了便于后续 Frustum Culling,通过查找表定义 p-vertex 和 n-vertex
7911 * @see https://github.com/antvis/GWebGPUEngine/issues/3
7912 */
7913 var AABB = /** @class */ (function () {
7914 function AABB() {
7915 this.center = [0, 0, 0];
7916 this.halfExtents = [0, 0, 0];
7917 this.min = [0, 0, 0];
7918 this.max = [0, 0, 0];
7919 }
7920 AABB.isEmpty = function (aabb) {
7921 return (!aabb ||
7922 (aabb.halfExtents[0] === 0 &&
7923 aabb.halfExtents[1] === 0 &&
7924 aabb.halfExtents[2] === 0));
7925 };
7926 // center: vec3 = vec3.create();
7927 // halfExtents: vec3 = vec3.create();
7928 // min: vec3 = vec3.create();
7929 // max: vec3 = vec3.create();
7930 AABB.prototype.update = function (center, halfExtents) {
7931 copyVec3(this.center, center);
7932 copyVec3(this.halfExtents, halfExtents);
7933 subVec3(this.min, this.center, this.halfExtents);
7934 addVec3(this.max, this.center, this.halfExtents);
7935 // vec3.copy(this.center, center);
7936 // vec3.copy(this.halfExtents, halfExtents);
7937 // vec3.sub(this.min, this.center, this.halfExtents);
7938 // vec3.add(this.max, this.center, this.halfExtents);
7939 };
7940 AABB.prototype.setMinMax = function (min, max) {
7941 // vec3.add(this.center, max, min);
7942 // vec3.scale(this.center, this.center, 0.5);
7943 // vec3.sub(this.halfExtents, max, min);
7944 // vec3.scale(this.halfExtents, this.halfExtents, 0.5);
7945 // vec3.copy(this.min, min);
7946 // vec3.copy(this.max, max);
7947 addVec3(this.center, max, min);
7948 scaleVec3(this.center, this.center, 0.5);
7949 subVec3(this.halfExtents, max, min);
7950 scaleVec3(this.halfExtents, this.halfExtents, 0.5);
7951 copyVec3(this.min, min);
7952 copyVec3(this.max, max);
7953 };
7954 AABB.prototype.getMin = function () {
7955 return this.min;
7956 };
7957 AABB.prototype.getMax = function () {
7958 return this.max;
7959 };
7960 AABB.prototype.add = function (aabb) {
7961 if (AABB.isEmpty(aabb)) {
7962 return;
7963 }
7964 if (AABB.isEmpty(this)) {
7965 this.setMinMax(aabb.getMin(), aabb.getMax());
7966 return;
7967 }
7968 var tc = this.center;
7969 var tcx = tc[0];
7970 var tcy = tc[1];
7971 var tcz = tc[2];
7972 var th = this.halfExtents;
7973 var thx = th[0];
7974 var thy = th[1];
7975 var thz = th[2];
7976 var tminx = tcx - thx;
7977 var tmaxx = tcx + thx;
7978 var tminy = tcy - thy;
7979 var tmaxy = tcy + thy;
7980 var tminz = tcz - thz;
7981 var tmaxz = tcz + thz;
7982 var oc = aabb.center;
7983 var ocx = oc[0];
7984 var ocy = oc[1];
7985 var ocz = oc[2];
7986 var oh = aabb.halfExtents;
7987 var ohx = oh[0];
7988 var ohy = oh[1];
7989 var ohz = oh[2];
7990 var ominx = ocx - ohx;
7991 var omaxx = ocx + ohx;
7992 var ominy = ocy - ohy;
7993 var omaxy = ocy + ohy;
7994 var ominz = ocz - ohz;
7995 var omaxz = ocz + ohz;
7996 if (ominx < tminx) {
7997 tminx = ominx;
7998 }
7999 if (omaxx > tmaxx) {
8000 tmaxx = omaxx;
8001 }
8002 if (ominy < tminy) {
8003 tminy = ominy;
8004 }
8005 if (omaxy > tmaxy) {
8006 tmaxy = omaxy;
8007 }
8008 if (ominz < tminz) {
8009 tminz = ominz;
8010 }
8011 if (omaxz > tmaxz) {
8012 tmaxz = omaxz;
8013 }
8014 tc[0] = (tminx + tmaxx) * 0.5;
8015 tc[1] = (tminy + tmaxy) * 0.5;
8016 tc[2] = (tminz + tmaxz) * 0.5;
8017 th[0] = (tmaxx - tminx) * 0.5;
8018 th[1] = (tmaxy - tminy) * 0.5;
8019 th[2] = (tmaxz - tminz) * 0.5;
8020 this.min[0] = tminx;
8021 this.min[1] = tminy;
8022 this.min[2] = tminz;
8023 this.max[0] = tmaxx;
8024 this.max[1] = tmaxy;
8025 this.max[2] = tmaxz;
8026 };
8027 AABB.prototype.setFromTransformedAABB = function (aabb, m) {
8028 var bc = this.center;
8029 var br = this.halfExtents;
8030 var ac = aabb.center;
8031 var ar = aabb.halfExtents;
8032 var mx0 = m[0];
8033 var mx1 = m[4];
8034 var mx2 = m[8];
8035 var my0 = m[1];
8036 var my1 = m[5];
8037 var my2 = m[9];
8038 var mz0 = m[2];
8039 var mz1 = m[6];
8040 var mz2 = m[10];
8041 var mx0a = Math.abs(mx0);
8042 var mx1a = Math.abs(mx1);
8043 var mx2a = Math.abs(mx2);
8044 var my0a = Math.abs(my0);
8045 var my1a = Math.abs(my1);
8046 var my2a = Math.abs(my2);
8047 var mz0a = Math.abs(mz0);
8048 var mz1a = Math.abs(mz1);
8049 var mz2a = Math.abs(mz2);
8050 bc[0] = m[12] + mx0 * ac[0] + mx1 * ac[1] + mx2 * ac[2];
8051 bc[1] = m[13] + my0 * ac[0] + my1 * ac[1] + my2 * ac[2];
8052 bc[2] = m[14] + mz0 * ac[0] + mz1 * ac[1] + mz2 * ac[2];
8053 // vec3.set(
8054 // bc,
8055 // m[12] + mx0 * ac[0] + mx1 * ac[1] + mx2 * ac[2],
8056 // m[13] + my0 * ac[0] + my1 * ac[1] + my2 * ac[2],
8057 // m[14] + mz0 * ac[0] + mz1 * ac[1] + mz2 * ac[2],
8058 // );
8059 br[0] = mx0a * ar[0] + mx1a * ar[1] + mx2a * ar[2];
8060 br[1] = my0a * ar[0] + my1a * ar[1] + my2a * ar[2];
8061 br[2] = mz0a * ar[0] + mz1a * ar[1] + mz2a * ar[2];
8062 // vec3.set(
8063 // br,
8064 // mx0a * ar[0] + mx1a * ar[1] + mx2a * ar[2],
8065 // my0a * ar[0] + my1a * ar[1] + my2a * ar[2],
8066 // mz0a * ar[0] + mz1a * ar[1] + mz2a * ar[2],
8067 // );
8068 // this.min = vec3.sub(this.min, bc, br);
8069 // this.max = vec3.add(this.max, bc, br);
8070 subVec3(this.min, bc, br);
8071 addVec3(this.max, bc, br);
8072 };
8073 AABB.prototype.intersects = function (aabb) {
8074 var aMax = this.getMax();
8075 var aMin = this.getMin();
8076 var bMax = aabb.getMax();
8077 var bMin = aabb.getMin();
8078 return (aMin[0] <= bMax[0] &&
8079 aMax[0] >= bMin[0] &&
8080 aMin[1] <= bMax[1] &&
8081 aMax[1] >= bMin[1] &&
8082 aMin[2] <= bMax[2] &&
8083 aMax[2] >= bMin[2]);
8084 };
8085 AABB.prototype.intersection = function (aabb) {
8086 if (!this.intersects(aabb)) {
8087 return null;
8088 }
8089 var intersection = new AABB();
8090 // const min = vec3.max(vec3.create(), this.getMin(), aabb.getMin());
8091 // const max = vec3.min(vec3.create(), this.getMax(), aabb.getMax());
8092 var min = maxVec3([0, 0, 0], this.getMin(), aabb.getMin());
8093 var max = minVec3([0, 0, 0], this.getMax(), aabb.getMax());
8094 intersection.setMinMax(min, max);
8095 return intersection;
8096 };
8097 // containsPoint(point: vec3) {
8098 // const min = this.getMin();
8099 // const max = this.getMax();
8100 // return !(
8101 // point[0] < min[0] ||
8102 // point[0] > max[0] ||
8103 // point[1] < min[1] ||
8104 // point[1] > max[1] ||
8105 // point[2] < min[2] ||
8106 // point[2] > max[2]
8107 // );
8108 // }
8109 /**
8110 * get n-vertex
8111 * @param plane plane of CullingVolume
8112 */
8113 AABB.prototype.getNegativeFarPoint = function (plane) {
8114 if (plane.pnVertexFlag === 0x111) {
8115 return copyVec3([0, 0, 0], this.min);
8116 // return vec3.copy(vec3.create(), this.min);
8117 }
8118 else if (plane.pnVertexFlag === 0x110) {
8119 return [this.min[0], this.min[1], this.max[2]];
8120 // return vec3.fromValues(this.min[0], this.min[1], this.max[2]);
8121 }
8122 else if (plane.pnVertexFlag === 0x101) {
8123 return [this.min[0], this.max[1], this.min[2]];
8124 // return vec3.fromValues(this.min[0], this.max[1], this.min[2]);
8125 }
8126 else if (plane.pnVertexFlag === 0x100) {
8127 return [this.min[0], this.max[1], this.max[2]];
8128 // return vec3.fromValues(this.min[0], this.max[1], this.max[2]);
8129 }
8130 else if (plane.pnVertexFlag === 0x011) {
8131 return [this.max[0], this.min[1], this.min[2]];
8132 // return vec3.fromValues(this.max[0], this.min[1], this.min[2]);
8133 }
8134 else if (plane.pnVertexFlag === 0x010) {
8135 return [this.max[0], this.min[1], this.max[2]];
8136 // return vec3.fromValues(this.max[0], this.min[1], this.max[2]);
8137 }
8138 else if (plane.pnVertexFlag === 0x001) {
8139 return [this.max[0], this.max[1], this.min[2]];
8140 // return vec3.fromValues(this.max[0], this.max[1], this.min[2]);
8141 }
8142 else {
8143 return [this.max[0], this.max[1], this.max[2]];
8144 // return vec3.fromValues(this.max[0], this.max[1], this.max[2]);
8145 }
8146 };
8147 /**
8148 * get p-vertex
8149 * @param plane plane of CullingVolume
8150 */
8151 AABB.prototype.getPositiveFarPoint = function (plane) {
8152 if (plane.pnVertexFlag === 0x111) {
8153 return copyVec3([0, 0, 0], this.max);
8154 // return vec3.copy(vec3.create(), this.max);
8155 }
8156 else if (plane.pnVertexFlag === 0x110) {
8157 return [this.max[0], this.max[1], this.min[2]];
8158 // return vec3.fromValues(this.max[0], this.max[1], this.min[2]);
8159 }
8160 else if (plane.pnVertexFlag === 0x101) {
8161 return [this.max[0], this.min[1], this.max[2]];
8162 // return vec3.fromValues(this.max[0], this.min[1], this.max[2]);
8163 }
8164 else if (plane.pnVertexFlag === 0x100) {
8165 return [this.max[0], this.min[1], this.min[2]];
8166 // return vec3.fromValues(this.max[0], this.min[1], this.min[2]);
8167 }
8168 else if (plane.pnVertexFlag === 0x011) {
8169 return [this.min[0], this.max[1], this.max[2]];
8170 // return vec3.fromValues(this.min[0], this.max[1], this.max[2]);
8171 }
8172 else if (plane.pnVertexFlag === 0x010) {
8173 return [this.min[0], this.max[1], this.min[2]];
8174 // return vec3.fromValues(this.min[0], this.max[1], this.min[2]);
8175 }
8176 else if (plane.pnVertexFlag === 0x001) {
8177 return [this.min[0], this.min[1], this.max[2]];
8178 // return vec3.fromValues(this.min[0], this.min[1], this.max[2]);
8179 }
8180 else {
8181 return [this.min[0], this.min[1], this.min[2]];
8182 // return vec3.fromValues(this.min[0], this.min[1], this.min[2]);
8183 }
8184 };
8185 return AABB;
8186 }());
8187
8188 var Plane = /** @class */ (function () {
8189 function Plane(distance, normal) {
8190 this.distance = distance || 0;
8191 this.normal = normal || fromValues$2(0, 1, 0);
8192 this.updatePNVertexFlag();
8193 }
8194 Plane.prototype.updatePNVertexFlag = function () {
8195 this.pnVertexFlag =
8196 (Number(this.normal[0] >= 0) << 8) +
8197 (Number(this.normal[1] >= 0) << 4) +
8198 Number(this.normal[2] >= 0);
8199 };
8200 Plane.prototype.distanceToPoint = function (point) {
8201 return dot(point, this.normal) - this.distance;
8202 };
8203 Plane.prototype.normalize = function () {
8204 var invLen = 1 / len(this.normal);
8205 scale$1(this.normal, this.normal, invLen);
8206 this.distance *= invLen;
8207 };
8208 Plane.prototype.intersectsLine = function (start, end, point) {
8209 var d0 = this.distanceToPoint(start);
8210 var d1 = this.distanceToPoint(end);
8211 var t = d0 / (d0 - d1);
8212 var intersects = t >= 0 && t <= 1;
8213 if (intersects && point) {
8214 lerp(point, start, end, t);
8215 }
8216 return intersects;
8217 };
8218 return Plane;
8219 }());
8220
8221 var Mask;
8222 (function (Mask) {
8223 Mask[Mask["OUTSIDE"] = 4294967295] = "OUTSIDE";
8224 Mask[Mask["INSIDE"] = 0] = "INSIDE";
8225 Mask[Mask["INDETERMINATE"] = 2147483647] = "INDETERMINATE";
8226 })(Mask || (Mask = {}));
8227 var Frustum = /** @class */ (function () {
8228 function Frustum(planes) {
8229 this.planes = [];
8230 if (planes) {
8231 this.planes = planes;
8232 }
8233 else {
8234 for (var i = 0; i < 6; i++) {
8235 this.planes.push(new Plane());
8236 }
8237 }
8238 }
8239 /**
8240 * extract 6 planes from projectionMatrix
8241 * @see http://www8.cs.umu.se/kurser/5DV051/HT12/lab/plane_extraction.pdf
8242 */
8243 Frustum.prototype.extractFromVPMatrix = function (projectionMatrix) {
8244 // @ts-ignore
8245 var _a = __read(projectionMatrix, 16), m0 = _a[0], m1 = _a[1], m2 = _a[2], m3 = _a[3], m4 = _a[4], m5 = _a[5], m6 = _a[6], m7 = _a[7], m8 = _a[8], m9 = _a[9], m10 = _a[10], m11 = _a[11], m12 = _a[12], m13 = _a[13], m14 = _a[14], m15 = _a[15];
8246 // right
8247 set$1(this.planes[0].normal, m3 - m0, m7 - m4, m11 - m8);
8248 this.planes[0].distance = m15 - m12;
8249 // left
8250 set$1(this.planes[1].normal, m3 + m0, m7 + m4, m11 + m8);
8251 this.planes[1].distance = m15 + m12;
8252 // bottom
8253 set$1(this.planes[2].normal, m3 + m1, m7 + m5, m11 + m9);
8254 this.planes[2].distance = m15 + m13;
8255 // top
8256 set$1(this.planes[3].normal, m3 - m1, m7 - m5, m11 - m9);
8257 this.planes[3].distance = m15 - m13;
8258 // far
8259 set$1(this.planes[4].normal, m3 - m2, m7 - m6, m11 - m10);
8260 this.planes[4].distance = m15 - m14;
8261 // near
8262 set$1(this.planes[5].normal, m3 + m2, m7 + m6, m11 + m10);
8263 this.planes[5].distance = m15 + m14;
8264 this.planes.forEach(function (plane) {
8265 plane.normalize();
8266 plane.updatePNVertexFlag();
8267 });
8268 };
8269 return Frustum;
8270 }());
8271
8272 var Point = /** @class */ (function () {
8273 function Point(x, y) {
8274 if (x === void 0) { x = 0; }
8275 if (y === void 0) { y = 0; }
8276 this.x = 0;
8277 this.y = 0;
8278 this.x = x;
8279 this.y = y;
8280 }
8281 Point.prototype.clone = function () {
8282 return new Point(this.x, this.y);
8283 };
8284 Point.prototype.copyFrom = function (p) {
8285 this.x = p.x;
8286 this.y = p.y;
8287 };
8288 return Point;
8289 }());
8290
8291 var Rectangle = /** @class */ (function () {
8292 function Rectangle(x, y, width, height) {
8293 this.x = x;
8294 this.y = y;
8295 this.width = width;
8296 this.height = height;
8297 this.left = x;
8298 this.right = x + width;
8299 this.top = y;
8300 this.bottom = y + height;
8301 }
8302 Rectangle.prototype.toJSON = function () { };
8303 return Rectangle;
8304 }());
8305
8306 var ERROR_MSG_METHOD_NOT_IMPLEMENTED = 'Method not implemented.';
8307 var ERROR_MSG_USE_DOCUMENT_ELEMENT = 'Use document.documentElement instead.';
8308 var ERROR_MSG_APPEND_DESTROYED_ELEMENT = 'Cannot append a destroyed element.';
8309
8310 /**
8311 * Different type of cameras, eg. simple camera used in 2D scene or
8312 * advanced camera which can do actions & switch between landmarks.
8313 */
8314 var CameraType;
8315 (function (CameraType) {
8316 /**
8317 * Performs all the rotational operations with the focal point instead of the camera position.
8318 * This type of camera is useful in applications(like CAD) where 3D objects are being designed or explored.
8319 * Camera cannot orbits over the north & south poles.
8320 * @see http://voxelent.com/tutorial-cameras/
8321 *
8322 * In Three.js it's used in OrbitControls.
8323 * @see https://threejs.org/docs/#examples/zh/controls/OrbitControls
8324 */
8325 CameraType[CameraType["ORBITING"] = 0] = "ORBITING";
8326 /**
8327 * It's similar to the ORBITING camera, but it allows the camera to orbit over the north or south poles.
8328 *
8329 * In Three.js it's used in OrbitControls.
8330 * @see https://threejs.org/docs/#examples/en/controls/TrackballControls
8331 */
8332 CameraType[CameraType["EXPLORING"] = 1] = "EXPLORING";
8333 /**
8334 * Performs all the rotational operations with the camera position.
8335 * It's useful in first person shooting games.
8336 * Camera cannot orbits over the north & south poles.
8337 *
8338 * In Three.js it's used in FirstPersonControls.
8339 * @see https://threejs.org/docs/#examples/en/controls/FirstPersonControls
8340 */
8341 CameraType[CameraType["TRACKING"] = 2] = "TRACKING";
8342 })(CameraType || (CameraType = {}));
8343 /**
8344 * CameraType must be TRACKING
8345 */
8346 var CameraTrackingMode;
8347 (function (CameraTrackingMode) {
8348 CameraTrackingMode[CameraTrackingMode["DEFAULT"] = 0] = "DEFAULT";
8349 CameraTrackingMode[CameraTrackingMode["ROTATIONAL"] = 1] = "ROTATIONAL";
8350 CameraTrackingMode[CameraTrackingMode["TRANSLATIONAL"] = 2] = "TRANSLATIONAL";
8351 CameraTrackingMode[CameraTrackingMode["CINEMATIC"] = 3] = "CINEMATIC";
8352 })(CameraTrackingMode || (CameraTrackingMode = {}));
8353 var CameraProjectionMode;
8354 (function (CameraProjectionMode) {
8355 CameraProjectionMode[CameraProjectionMode["ORTHOGRAPHIC"] = 0] = "ORTHOGRAPHIC";
8356 CameraProjectionMode[CameraProjectionMode["PERSPECTIVE"] = 1] = "PERSPECTIVE";
8357 })(CameraProjectionMode || (CameraProjectionMode = {}));
8358 var CameraEvent = {
8359 UPDATED: 'updated',
8360 };
8361
8362 var MIN_DISTANCE = 0.0002;
8363 /**
8364 * 参考「WebGL Insights - 23.Designing Cameras for WebGL Applications」,基于 Responsible Camera 思路设计
8365 * @see https://github.com/d13g0/nucleo.js/blob/master/source/camera/Camera.js
8366 *
8367 * 保存相机参数,定义相机动作:
8368 * 1. dolly 沿 n 轴移动
8369 * 2. pan 沿 u v 轴移动
8370 * 3. rotate 以方位角旋转
8371 * 4. 移动到 Landmark,具有平滑的动画效果,其间禁止其他用户交互
8372 */
8373 var Camera = /** @class */ (function () {
8374 function Camera() {
8375 /**
8376 * Clip space near Z, default to range `[-1, 1]`
8377 */
8378 this.clipSpaceNearZ = ClipSpaceNearZ.NEGATIVE_ONE;
8379 this.eventEmitter = new eventemitter3();
8380 /**
8381 * Matrix of camera
8382 */
8383 this.matrix = create$1();
8384 /**
8385 * u axis +X is right
8386 * @see http://learnwebgl.brown37.net/07_cameras/camera_introduction.html#a-camera-definition
8387 */
8388 this.right = fromValues$2(1, 0, 0);
8389 /**
8390 * v axis +Y is up
8391 */
8392 this.up = fromValues$2(0, 1, 0);
8393 /**
8394 * n axis +Z is inside
8395 */
8396 this.forward = fromValues$2(0, 0, 1);
8397 /**
8398 * Position of camera.
8399 */
8400 this.position = fromValues$2(0, 0, 1);
8401 /**
8402 * Position of focal point.
8403 */
8404 this.focalPoint = fromValues$2(0, 0, 0);
8405 /**
8406 * vector from focalPoint to position
8407 */
8408 this.distanceVector = fromValues$2(0, 0, -1);
8409 /**
8410 * length(focalPoint - position)
8411 */
8412 this.distance = 1;
8413 /**
8414 * @see https://en.wikipedia.org/wiki/Azimuth
8415 */
8416 this.azimuth = 0;
8417 this.elevation = 0;
8418 this.roll = 0;
8419 this.relAzimuth = 0;
8420 this.relElevation = 0;
8421 this.relRoll = 0;
8422 /**
8423 * 沿 n 轴移动时,保证移动速度从快到慢
8424 */
8425 this.dollyingStep = 0;
8426 this.maxDistance = Infinity;
8427 this.minDistance = -Infinity;
8428 /**
8429 * zoom factor of the camera, default is 1
8430 * eg. https://threejs.org/docs/#api/en/cameras/OrthographicCamera.zoom
8431 */
8432 this.zoom = 1;
8433 /**
8434 * invert the horizontal coordinate system HCS
8435 */
8436 this.rotateWorld = false;
8437 /**
8438 * 投影矩阵参数
8439 */
8440 /**
8441 * field of view [0-360]
8442 * @see http://en.wikipedia.org/wiki/Angle_of_view
8443 */
8444 this.fov = 30;
8445 this.near = 0.1;
8446 this.far = 1000;
8447 this.aspect = 1;
8448 this.projectionMatrix = create$1();
8449 this.projectionMatrixInverse = create$1();
8450 this.jitteredProjectionMatrix = undefined;
8451 this.enableUpdate = true;
8452 // protected following = undefined;
8453 this.type = CameraType.EXPLORING;
8454 this.trackingMode = CameraTrackingMode.DEFAULT;
8455 this.projectionMode = CameraProjectionMode.PERSPECTIVE;
8456 /**
8457 * for culling use
8458 */
8459 this.frustum = new Frustum();
8460 /**
8461 * ortho matrix for Canvas2D & SVG
8462 */
8463 this.orthoMatrix = create$1();
8464 }
8465 // constructor(type = CameraType.EXPLORING, trackingMode = CameraTrackingMode.DEFAULT) {
8466 // this.setType(type, trackingMode);
8467 // }
8468 Camera.prototype.isOrtho = function () {
8469 return this.projectionMode === CameraProjectionMode.ORTHOGRAPHIC;
8470 };
8471 Camera.prototype.getProjectionMode = function () {
8472 return this.projectionMode;
8473 };
8474 Camera.prototype.getPerspective = function () {
8475 // account for TAA
8476 return this.jitteredProjectionMatrix || this.projectionMatrix;
8477 };
8478 Camera.prototype.getPerspectiveInverse = function () {
8479 return this.projectionMatrixInverse;
8480 };
8481 Camera.prototype.getFrustum = function () {
8482 return this.frustum;
8483 };
8484 Camera.prototype.getPosition = function () {
8485 return this.position;
8486 };
8487 Camera.prototype.getFocalPoint = function () {
8488 return this.focalPoint;
8489 };
8490 Camera.prototype.getDollyingStep = function () {
8491 return this.dollyingStep;
8492 };
8493 Camera.prototype.getNear = function () {
8494 return this.near;
8495 };
8496 Camera.prototype.getFar = function () {
8497 return this.far;
8498 };
8499 Camera.prototype.getZoom = function () {
8500 return this.zoom;
8501 };
8502 Camera.prototype.getOrthoMatrix = function () {
8503 return this.orthoMatrix;
8504 };
8505 Camera.prototype.getView = function () {
8506 return this.view;
8507 };
8508 Camera.prototype.setEnableUpdate = function (enabled) {
8509 this.enableUpdate = enabled;
8510 };
8511 Camera.prototype.setType = function (type, trackingMode) {
8512 this.type = type;
8513 if (this.type === CameraType.EXPLORING) {
8514 this.setWorldRotation(true);
8515 }
8516 else {
8517 this.setWorldRotation(false);
8518 }
8519 this._getAngles();
8520 if (this.type === CameraType.TRACKING && trackingMode !== undefined) {
8521 this.setTrackingMode(trackingMode);
8522 }
8523 return this;
8524 };
8525 Camera.prototype.setProjectionMode = function (projectionMode) {
8526 this.projectionMode = projectionMode;
8527 return this;
8528 };
8529 Camera.prototype.setTrackingMode = function (trackingMode) {
8530 if (this.type !== CameraType.TRACKING) {
8531 throw new Error('Impossible to set a tracking mode if the camera is not of tracking type');
8532 }
8533 this.trackingMode = trackingMode;
8534 return this;
8535 };
8536 /**
8537 * If flag is true, it reverses the azimuth and elevation angles.
8538 * Subsequent calls to rotate, setAzimuth, setElevation,
8539 * changeAzimuth or changeElevation will cause the inverted effect.
8540 * setRoll or changeRoll is not affected by this method.
8541 *
8542 * This inversion is useful when one wants to simulate that the world
8543 * is moving, instead of the camera.
8544 *
8545 * By default the camera angles are not reversed.
8546 * @param {Boolean} flag the boolean flag to reverse the angles.
8547 */
8548 Camera.prototype.setWorldRotation = function (flag) {
8549 this.rotateWorld = flag;
8550 this._getAngles();
8551 return this;
8552 };
8553 /**
8554 * 计算 MV 矩阵,为相机矩阵的逆矩阵
8555 */
8556 Camera.prototype.getViewTransform = function () {
8557 return invert(create$1(), this.matrix);
8558 };
8559 Camera.prototype.getWorldTransform = function () {
8560 return this.matrix;
8561 };
8562 Camera.prototype.jitterProjectionMatrix = function (x, y) {
8563 var translation = fromTranslation(create$1(), [x, y, 0]);
8564 this.jitteredProjectionMatrix = multiply(create$1(), translation, this.projectionMatrix);
8565 };
8566 Camera.prototype.clearJitterProjectionMatrix = function () {
8567 this.jitteredProjectionMatrix = undefined;
8568 };
8569 /**
8570 * 设置相机矩阵
8571 */
8572 Camera.prototype.setMatrix = function (matrix) {
8573 this.matrix = matrix;
8574 this._update();
8575 return this;
8576 };
8577 Camera.prototype.setFov = function (fov) {
8578 this.setPerspective(this.near, this.far, fov, this.aspect);
8579 return this;
8580 };
8581 Camera.prototype.setAspect = function (aspect) {
8582 this.setPerspective(this.near, this.far, this.fov, aspect);
8583 return this;
8584 };
8585 Camera.prototype.setNear = function (near) {
8586 if (this.projectionMode === CameraProjectionMode.PERSPECTIVE) {
8587 this.setPerspective(near, this.far, this.fov, this.aspect);
8588 }
8589 else {
8590 this.setOrthographic(this.left, this.rright, this.top, this.bottom, near, this.far);
8591 }
8592 return this;
8593 };
8594 Camera.prototype.setFar = function (far) {
8595 if (this.projectionMode === CameraProjectionMode.PERSPECTIVE) {
8596 this.setPerspective(this.near, far, this.fov, this.aspect);
8597 }
8598 else {
8599 this.setOrthographic(this.left, this.rright, this.top, this.bottom, this.near, far);
8600 }
8601 return this;
8602 };
8603 /**
8604 * Sets an offset in a larger frustum, used in PixelPicking
8605 */
8606 Camera.prototype.setViewOffset = function (fullWidth, fullHeight, x, y, width, height) {
8607 this.aspect = fullWidth / fullHeight;
8608 if (this.view === undefined) {
8609 this.view = {
8610 enabled: true,
8611 fullWidth: 1,
8612 fullHeight: 1,
8613 offsetX: 0,
8614 offsetY: 0,
8615 width: 1,
8616 height: 1,
8617 };
8618 }
8619 this.view.enabled = true;
8620 this.view.fullWidth = fullWidth;
8621 this.view.fullHeight = fullHeight;
8622 this.view.offsetX = x;
8623 this.view.offsetY = y;
8624 this.view.width = width;
8625 this.view.height = height;
8626 if (this.projectionMode === CameraProjectionMode.PERSPECTIVE) {
8627 this.setPerspective(this.near, this.far, this.fov, this.aspect);
8628 }
8629 else {
8630 this.setOrthographic(this.left, this.rright, this.top, this.bottom, this.near, this.far);
8631 }
8632 return this;
8633 };
8634 Camera.prototype.clearViewOffset = function () {
8635 if (this.view !== undefined) {
8636 this.view.enabled = false;
8637 }
8638 if (this.projectionMode === CameraProjectionMode.PERSPECTIVE) {
8639 this.setPerspective(this.near, this.far, this.fov, this.aspect);
8640 }
8641 else {
8642 this.setOrthographic(this.left, this.rright, this.top, this.bottom, this.near, this.far);
8643 }
8644 return this;
8645 };
8646 Camera.prototype.setZoom = function (zoom) {
8647 this.zoom = zoom;
8648 if (this.projectionMode === CameraProjectionMode.ORTHOGRAPHIC) {
8649 this.setOrthographic(this.left, this.rright, this.top, this.bottom, this.near, this.far);
8650 }
8651 else if (this.projectionMode === CameraProjectionMode.PERSPECTIVE) {
8652 this.setPerspective(this.near, this.far, this.fov, this.aspect);
8653 }
8654 return this;
8655 };
8656 /**
8657 * Zoom by specified point in viewport coordinates.
8658 */
8659 Camera.prototype.setZoomByViewportPoint = function (zoom, viewportPoint) {
8660 var _a = this.canvas.viewport2Canvas({
8661 x: viewportPoint[0],
8662 y: viewportPoint[1],
8663 }), ox = _a.x, oy = _a.y;
8664 var roll = this.roll;
8665 this.rotate(0, 0, -roll);
8666 this.setPosition(ox, oy);
8667 this.setFocalPoint(ox, oy);
8668 this.setZoom(zoom);
8669 this.rotate(0, 0, roll);
8670 var _b = this.canvas.viewport2Canvas({
8671 x: viewportPoint[0],
8672 y: viewportPoint[1],
8673 }), cx = _b.x, cy = _b.y;
8674 // project to rotated axis
8675 var dvec = fromValues$2(cx - ox, cy - oy, 0);
8676 var dx = dot(dvec, this.right) / length(this.right);
8677 var dy = dot(dvec, this.up) / length(this.up);
8678 this.pan(-dx, -dy);
8679 return this;
8680 };
8681 Camera.prototype.setPerspective = function (near, far, fov, aspect) {
8682 var _a;
8683 this.projectionMode = CameraProjectionMode.PERSPECTIVE;
8684 this.fov = fov;
8685 this.near = near;
8686 this.far = far;
8687 this.aspect = aspect;
8688 var top = (this.near * Math.tan(deg2rad(0.5 * this.fov))) / this.zoom;
8689 var height = 2 * top;
8690 var width = this.aspect * height;
8691 var left = -0.5 * width;
8692 if ((_a = this.view) === null || _a === void 0 ? void 0 : _a.enabled) {
8693 var fullWidth = this.view.fullWidth;
8694 var fullHeight = this.view.fullHeight;
8695 left += (this.view.offsetX * width) / fullWidth;
8696 top -= (this.view.offsetY * height) / fullHeight;
8697 width *= this.view.width / fullWidth;
8698 height *= this.view.height / fullHeight;
8699 }
8700 makePerspective(this.projectionMatrix, left, left + width, top, top - height, near, this.far, this.clipSpaceNearZ === ClipSpaceNearZ.ZERO);
8701 // flipY since the origin of OpenGL/WebGL is bottom-left compared with top-left in Canvas2D
8702 scale(this.projectionMatrix, this.projectionMatrix, fromValues$2(1, -1, 1));
8703 invert(this.projectionMatrixInverse, this.projectionMatrix);
8704 this.triggerUpdate();
8705 return this;
8706 };
8707 Camera.prototype.setOrthographic = function (l, r, t, b, near, far) {
8708 var _a;
8709 this.projectionMode = CameraProjectionMode.ORTHOGRAPHIC;
8710 this.rright = r;
8711 this.left = l;
8712 this.top = t;
8713 this.bottom = b;
8714 this.near = near;
8715 this.far = far;
8716 var dx = (this.rright - this.left) / (2 * this.zoom);
8717 var dy = (this.top - this.bottom) / (2 * this.zoom);
8718 var cx = (this.rright + this.left) / 2;
8719 var cy = (this.top + this.bottom) / 2;
8720 var left = cx - dx;
8721 var right = cx + dx;
8722 var top = cy + dy;
8723 var bottom = cy - dy;
8724 if ((_a = this.view) === null || _a === void 0 ? void 0 : _a.enabled) {
8725 var scaleW = (this.rright - this.left) / this.view.fullWidth / this.zoom;
8726 var scaleH = (this.top - this.bottom) / this.view.fullHeight / this.zoom;
8727 left += scaleW * this.view.offsetX;
8728 right = left + scaleW * this.view.width;
8729 top -= scaleH * this.view.offsetY;
8730 bottom = top - scaleH * this.view.height;
8731 }
8732 if (this.clipSpaceNearZ === ClipSpaceNearZ.NEGATIVE_ONE) {
8733 ortho(this.projectionMatrix, left, right, bottom, top, near, far);
8734 }
8735 else {
8736 orthoZO(this.projectionMatrix, left, right, bottom, top, near, far);
8737 }
8738 // flipY since the origin of OpenGL/WebGL is bottom-left compared with top-left in Canvas2D
8739 scale(this.projectionMatrix, this.projectionMatrix, fromValues$2(1, -1, 1));
8740 invert(this.projectionMatrixInverse, this.projectionMatrix);
8741 this._getOrthoMatrix();
8742 this.triggerUpdate();
8743 return this;
8744 };
8745 /**
8746 * Move the camera in world coordinates.
8747 * It will keep looking at the current focal point.
8748 *
8749 * support scalars or vectors.
8750 * @example
8751 * setPosition(1, 2, 3);
8752 * setPosition([1, 2, 3]);
8753 */
8754 Camera.prototype.setPosition = function (x, y, z) {
8755 if (y === void 0) { y = this.position[1]; }
8756 if (z === void 0) { z = this.position[2]; }
8757 var position = createVec3(x, y, z);
8758 this._setPosition(position);
8759 this.setFocalPoint(this.focalPoint);
8760 this.triggerUpdate();
8761 return this;
8762 };
8763 /**
8764 * Sets the focal point of this camera in world coordinates.
8765 *
8766 * support scalars or vectors.
8767 * @example
8768 * setFocalPoint(1, 2, 3);
8769 * setFocalPoint([1, 2, 3]);
8770 */
8771 Camera.prototype.setFocalPoint = function (x, y, z) {
8772 if (y === void 0) { y = this.focalPoint[1]; }
8773 if (z === void 0) { z = this.focalPoint[2]; }
8774 var up = fromValues$2(0, 1, 0);
8775 this.focalPoint = createVec3(x, y, z);
8776 if (this.trackingMode === CameraTrackingMode.CINEMATIC) {
8777 var d = subtract$1(create$2(), this.focalPoint, this.position);
8778 x = d[0];
8779 y = d[1];
8780 z = d[2];
8781 var r = length(d);
8782 var el = rad2deg(Math.asin(y / r));
8783 var az = 90 + rad2deg(Math.atan2(z, x));
8784 var m = create$1();
8785 rotateY(m, m, deg2rad(az));
8786 rotateX(m, m, deg2rad(el));
8787 up = transformMat4(create$2(), [0, 1, 0], m);
8788 }
8789 invert(this.matrix, lookAt(create$1(), this.position, this.focalPoint, up));
8790 this._getAxes();
8791 this._getDistance();
8792 this._getAngles();
8793 this.triggerUpdate();
8794 return this;
8795 };
8796 Camera.prototype.getDistance = function () {
8797 return this.distance;
8798 };
8799 Camera.prototype.getDistanceVector = function () {
8800 return this.distanceVector;
8801 };
8802 /**
8803 * Moves the camera towards/from the focal point.
8804 */
8805 Camera.prototype.setDistance = function (d) {
8806 if (this.distance === d || d < 0) {
8807 return this;
8808 }
8809 this.distance = d;
8810 if (this.distance < MIN_DISTANCE) {
8811 this.distance = MIN_DISTANCE;
8812 }
8813 this.dollyingStep = this.distance / 100;
8814 var pos = create$2();
8815 d = this.distance;
8816 var n = this.forward;
8817 var f = this.focalPoint;
8818 pos[0] = d * n[0] + f[0];
8819 pos[1] = d * n[1] + f[1];
8820 pos[2] = d * n[2] + f[2];
8821 this._setPosition(pos);
8822 this.triggerUpdate();
8823 return this;
8824 };
8825 Camera.prototype.setMaxDistance = function (d) {
8826 this.maxDistance = d;
8827 return this;
8828 };
8829 Camera.prototype.setMinDistance = function (d) {
8830 this.minDistance = d;
8831 return this;
8832 };
8833 /**
8834 * 设置相机方位角,不同相机模式下需要重新计算相机位置或者是视点位置
8835 * the azimuth in degrees
8836 */
8837 Camera.prototype.setAzimuth = function (az) {
8838 this.azimuth = getAngle(az);
8839 this.computeMatrix();
8840 this._getAxes();
8841 if (this.type === CameraType.ORBITING ||
8842 this.type === CameraType.EXPLORING) {
8843 this._getPosition();
8844 }
8845 else if (this.type === CameraType.TRACKING) {
8846 this._getFocalPoint();
8847 }
8848 this.triggerUpdate();
8849 return this;
8850 };
8851 Camera.prototype.getAzimuth = function () {
8852 return this.azimuth;
8853 };
8854 /**
8855 * 设置相机方位角,不同相机模式下需要重新计算相机位置或者是视点位置
8856 */
8857 Camera.prototype.setElevation = function (el) {
8858 this.elevation = getAngle(el);
8859 this.computeMatrix();
8860 this._getAxes();
8861 if (this.type === CameraType.ORBITING ||
8862 this.type === CameraType.EXPLORING) {
8863 this._getPosition();
8864 }
8865 else if (this.type === CameraType.TRACKING) {
8866 this._getFocalPoint();
8867 }
8868 this.triggerUpdate();
8869 return this;
8870 };
8871 Camera.prototype.getElevation = function () {
8872 return this.elevation;
8873 };
8874 /**
8875 * 设置相机方位角,不同相机模式下需要重新计算相机位置或者是视点位置
8876 */
8877 Camera.prototype.setRoll = function (angle) {
8878 this.roll = getAngle(angle);
8879 this.computeMatrix();
8880 this._getAxes();
8881 if (this.type === CameraType.ORBITING ||
8882 this.type === CameraType.EXPLORING) {
8883 this._getPosition();
8884 }
8885 else if (this.type === CameraType.TRACKING) {
8886 this._getFocalPoint();
8887 }
8888 this.triggerUpdate();
8889 return this;
8890 };
8891 Camera.prototype.getRoll = function () {
8892 return this.roll;
8893 };
8894 /**
8895 * 根据相机矩阵重新计算各种相机参数
8896 */
8897 Camera.prototype._update = function () {
8898 this._getAxes();
8899 this._getPosition();
8900 this._getDistance();
8901 this._getAngles();
8902 this._getOrthoMatrix();
8903 this.triggerUpdate();
8904 };
8905 /**
8906 * 计算相机矩阵
8907 */
8908 Camera.prototype.computeMatrix = function () {
8909 // 使用四元数描述 3D 旋转
8910 // @see https://xiaoiver.github.io/coding/2018/12/28/Camera-%E8%AE%BE%E8%AE%A1-%E4%B8%80.html
8911 var rotZ = setAxisAngle(create$4(), [0, 0, 1], deg2rad(this.roll));
8912 identity$1(this.matrix);
8913 // only consider HCS for EXPLORING and ORBITING cameras
8914 var rotX = setAxisAngle(create$4(), [1, 0, 0], deg2rad(((this.rotateWorld && this.type !== CameraType.TRACKING) ||
8915 this.type === CameraType.TRACKING
8916 ? 1
8917 : -1) * this.elevation));
8918 var rotY = setAxisAngle(create$4(), [0, 1, 0], deg2rad(((this.rotateWorld && this.type !== CameraType.TRACKING) ||
8919 this.type === CameraType.TRACKING
8920 ? 1
8921 : -1) * this.azimuth));
8922 var rotQ = multiply$2(create$4(), rotY, rotX);
8923 rotQ = multiply$2(create$4(), rotQ, rotZ);
8924 var rotMatrix = fromQuat(create$1(), rotQ);
8925 if (this.type === CameraType.ORBITING ||
8926 this.type === CameraType.EXPLORING) {
8927 translate(this.matrix, this.matrix, this.focalPoint);
8928 multiply(this.matrix, this.matrix, rotMatrix);
8929 translate(this.matrix, this.matrix, [0, 0, this.distance]);
8930 }
8931 else if (this.type === CameraType.TRACKING) {
8932 translate(this.matrix, this.matrix, this.position);
8933 multiply(this.matrix, this.matrix, rotMatrix);
8934 }
8935 };
8936 /**
8937 * Sets the camera position in the camera matrix
8938 */
8939 Camera.prototype._setPosition = function (x, y, z) {
8940 this.position = createVec3(x, y, z);
8941 var m = this.matrix;
8942 m[12] = this.position[0];
8943 m[13] = this.position[1];
8944 m[14] = this.position[2];
8945 m[15] = 1;
8946 this._getOrthoMatrix();
8947 };
8948 /**
8949 * Recalculates axes based on the current matrix
8950 */
8951 Camera.prototype._getAxes = function () {
8952 copy$1(this.right, createVec3(transformMat4$1(create$3(), [1, 0, 0, 0], this.matrix)));
8953 copy$1(this.up, createVec3(transformMat4$1(create$3(), [0, 1, 0, 0], this.matrix)));
8954 copy$1(this.forward, createVec3(transformMat4$1(create$3(), [0, 0, 1, 0], this.matrix)));
8955 normalize(this.right, this.right);
8956 normalize(this.up, this.up);
8957 normalize(this.forward, this.forward);
8958 };
8959 /**
8960 * Recalculates euler angles based on the current state
8961 */
8962 Camera.prototype._getAngles = function () {
8963 // Recalculates angles
8964 var x = this.distanceVector[0];
8965 var y = this.distanceVector[1];
8966 var z = this.distanceVector[2];
8967 var r = length(this.distanceVector);
8968 // FAST FAIL: If there is no distance we cannot compute angles
8969 if (r === 0) {
8970 this.elevation = 0;
8971 this.azimuth = 0;
8972 return;
8973 }
8974 if (this.type === CameraType.TRACKING) {
8975 this.elevation = rad2deg(Math.asin(y / r));
8976 this.azimuth = rad2deg(Math.atan2(-x, -z));
8977 }
8978 else {
8979 if (this.rotateWorld) {
8980 this.elevation = rad2deg(Math.asin(y / r));
8981 this.azimuth = rad2deg(Math.atan2(-x, -z));
8982 }
8983 else {
8984 this.elevation = -rad2deg(Math.asin(y / r));
8985 this.azimuth = -rad2deg(Math.atan2(-x, -z));
8986 }
8987 }
8988 };
8989 /**
8990 * 重新计算相机位置,只有 ORBITING 模式相机位置才会发生变化
8991 */
8992 Camera.prototype._getPosition = function () {
8993 copy$1(this.position, createVec3(transformMat4$1(create$3(), [0, 0, 0, 1], this.matrix)));
8994 // 相机位置变化,需要重新计算视距
8995 this._getDistance();
8996 };
8997 /**
8998 * 重新计算视点,只有 TRACKING 模式视点才会发生变化
8999 */
9000 Camera.prototype._getFocalPoint = function () {
9001 transformMat3(this.distanceVector, [0, 0, -this.distance], fromMat4(create(), this.matrix));
9002 add$1(this.focalPoint, this.position, this.distanceVector);
9003 // 视点变化,需要重新计算视距
9004 this._getDistance();
9005 };
9006 /**
9007 * 重新计算视距
9008 */
9009 Camera.prototype._getDistance = function () {
9010 this.distanceVector = subtract$1(create$2(), this.focalPoint, this.position);
9011 this.distance = length(this.distanceVector);
9012 this.dollyingStep = this.distance / 100;
9013 };
9014 Camera.prototype._getOrthoMatrix = function () {
9015 if (this.projectionMode !== CameraProjectionMode.ORTHOGRAPHIC) {
9016 return;
9017 }
9018 var position = this.position;
9019 var rotZ = setAxisAngle(create$4(), [0, 0, 1], (-this.roll * Math.PI) / 180);
9020 fromRotationTranslationScaleOrigin(this.orthoMatrix, rotZ, fromValues$2((this.rright - this.left) / 2 - position[0], (this.top - this.bottom) / 2 - position[1], 0), fromValues$2(this.zoom, this.zoom, 1), position);
9021 };
9022 Camera.prototype.triggerUpdate = function () {
9023 if (this.enableUpdate) {
9024 // update frustum
9025 var viewMatrix = this.getViewTransform();
9026 var vpMatrix = multiply(create$1(), this.getPerspective(), viewMatrix);
9027 this.getFrustum().extractFromVPMatrix(vpMatrix);
9028 this.eventEmitter.emit(CameraEvent.UPDATED);
9029 }
9030 };
9031 Camera.prototype.rotate = function (azimuth, elevation, roll) {
9032 throw new Error(ERROR_MSG_METHOD_NOT_IMPLEMENTED);
9033 };
9034 Camera.prototype.pan = function (tx, ty) {
9035 throw new Error(ERROR_MSG_METHOD_NOT_IMPLEMENTED);
9036 };
9037 Camera.prototype.dolly = function (value) {
9038 throw new Error(ERROR_MSG_METHOD_NOT_IMPLEMENTED);
9039 };
9040 Camera.prototype.createLandmark = function (name, params) {
9041 throw new Error(ERROR_MSG_METHOD_NOT_IMPLEMENTED);
9042 };
9043 Camera.prototype.gotoLandmark = function (name, options) {
9044 throw new Error(ERROR_MSG_METHOD_NOT_IMPLEMENTED);
9045 };
9046 Camera.prototype.cancelLandmarkAnimation = function () {
9047 throw new Error(ERROR_MSG_METHOD_NOT_IMPLEMENTED);
9048 };
9049 return Camera;
9050 }());
9051
9052 function memoize(func, resolver) {
9053 if (typeof func !== 'function' ||
9054 (resolver != null && typeof resolver !== 'function')) {
9055 throw new TypeError('Expected a function');
9056 }
9057 var memoized = function () {
9058 var args = [];
9059 for (var _i = 0; _i < arguments.length; _i++) {
9060 args[_i] = arguments[_i];
9061 }
9062 var key = resolver ? resolver.apply(this, args) : args[0];
9063 var cache = memoized.cache;
9064 if (cache.has(key)) {
9065 return cache.get(key);
9066 }
9067 var result = func.apply(this, args);
9068 memoized.cache = cache.set(key, result) || cache;
9069 return result;
9070 };
9071 memoized.cache = new (memoize.Cache || Map)();
9072 return memoized;
9073 }
9074 memoize.Cache = Map;
9075
9076 // These units are iterated through, so be careful when adding or changing the
9077 // order.
9078 var UnitType;
9079 (function (UnitType) {
9080 UnitType[UnitType["kUnknown"] = 0] = "kUnknown";
9081 UnitType[UnitType["kNumber"] = 1] = "kNumber";
9082 UnitType[UnitType["kPercentage"] = 2] = "kPercentage";
9083 // Length units
9084 UnitType[UnitType["kEms"] = 3] = "kEms";
9085 // kExs,
9086 UnitType[UnitType["kPixels"] = 4] = "kPixels";
9087 // kCentimeters,
9088 // kMillimeters,
9089 // kInches,
9090 // kPoints,
9091 // kPicas,
9092 // kQuarterMillimeters,
9093 // https://drafts.csswg.org/css-values-4/#viewport-relative-lengths
9094 //
9095 // See also IsViewportPercentageLength.
9096 // kViewportWidth,
9097 // kViewportHeight,
9098 // kViewportInlineSize,
9099 // kViewportBlockSize,
9100 // kViewportMin,
9101 // kViewportMax,
9102 // kSmallViewportWidth,
9103 // kSmallViewportHeight,
9104 // kSmallViewportInlineSize,
9105 // kSmallViewportBlockSize,
9106 // kSmallViewportMin,
9107 // kSmallViewportMax,
9108 // kLargeViewportWidth,
9109 // kLargeViewportHeight,
9110 // kLargeViewportInlineSize,
9111 // kLargeViewportBlockSize,
9112 // kLargeViewportMin,
9113 // kLargeViewportMax,
9114 // kDynamicViewportWidth,
9115 // kDynamicViewportHeight,
9116 // kDynamicViewportInlineSize,
9117 // kDynamicViewportBlockSize,
9118 // kDynamicViewportMin,
9119 // kDynamicViewportMax,
9120 // https://drafts.csswg.org/css-contain-3/#container-lengths
9121 //
9122 // See also IsContainerPercentageLength.
9123 // kContainerWidth,
9124 // kContainerHeight,
9125 // kContainerInlineSize,
9126 // kContainerBlockSize,
9127 // kContainerMin,
9128 // kContainerMax,
9129 UnitType[UnitType["kRems"] = 5] = "kRems";
9130 // kChs,
9131 // kUserUnits, // The SVG term for unitless lengths
9132 // Angle units
9133 UnitType[UnitType["kDegrees"] = 6] = "kDegrees";
9134 UnitType[UnitType["kRadians"] = 7] = "kRadians";
9135 UnitType[UnitType["kGradians"] = 8] = "kGradians";
9136 UnitType[UnitType["kTurns"] = 9] = "kTurns";
9137 // Time units
9138 UnitType[UnitType["kMilliseconds"] = 10] = "kMilliseconds";
9139 UnitType[UnitType["kSeconds"] = 11] = "kSeconds";
9140 // kHertz,
9141 // kKilohertz,
9142 // Resolution
9143 // kDotsPerPixel,
9144 // kDotsPerInch,
9145 // kDotsPerCentimeter,
9146 // Other units
9147 // kFraction,
9148 UnitType[UnitType["kInteger"] = 12] = "kInteger";
9149 // This value is used to handle quirky margins in reflow roots (body, td,
9150 // and th) like WinIE. The basic idea is that a stylesheet can use the value
9151 // __qem (for quirky em) instead of em. When the quirky value is used, if
9152 // you're in quirks mode, the margin will collapse away inside a table cell.
9153 // This quirk is specified in the HTML spec but our impl is different.
9154 // TODO: Remove this. crbug.com/443952
9155 // kQuirkyEms,
9156 })(UnitType || (UnitType = {}));
9157 var UnitCategory;
9158 (function (UnitCategory) {
9159 UnitCategory[UnitCategory["kUNumber"] = 0] = "kUNumber";
9160 UnitCategory[UnitCategory["kUPercent"] = 1] = "kUPercent";
9161 UnitCategory[UnitCategory["kULength"] = 2] = "kULength";
9162 UnitCategory[UnitCategory["kUAngle"] = 3] = "kUAngle";
9163 UnitCategory[UnitCategory["kUTime"] = 4] = "kUTime";
9164 // kUFrequency,
9165 // kUResolution,
9166 UnitCategory[UnitCategory["kUOther"] = 5] = "kUOther";
9167 })(UnitCategory || (UnitCategory = {}));
9168 var ValueRange;
9169 (function (ValueRange) {
9170 ValueRange[ValueRange["kAll"] = 0] = "kAll";
9171 ValueRange[ValueRange["kNonNegative"] = 1] = "kNonNegative";
9172 ValueRange[ValueRange["kInteger"] = 2] = "kInteger";
9173 ValueRange[ValueRange["kNonNegativeInteger"] = 3] = "kNonNegativeInteger";
9174 ValueRange[ValueRange["kPositiveInteger"] = 4] = "kPositiveInteger";
9175 })(ValueRange || (ValueRange = {}));
9176 var Nested;
9177 (function (Nested) {
9178 Nested[Nested["kYes"] = 0] = "kYes";
9179 Nested[Nested["kNo"] = 1] = "kNo";
9180 })(Nested || (Nested = {}));
9181 var ParenLess;
9182 (function (ParenLess) {
9183 ParenLess[ParenLess["kYes"] = 0] = "kYes";
9184 ParenLess[ParenLess["kNo"] = 1] = "kNo";
9185 })(ParenLess || (ParenLess = {}));
9186
9187 // This file specifies the unit strings used in CSSPrimitiveValues.
9188 var data = [
9189 {
9190 name: 'em',
9191 unit_type: UnitType.kEms,
9192 },
9193 // {
9194 // name: 'ex',
9195 // unit_type: UnitType.kExs,
9196 // },
9197 {
9198 name: 'px',
9199 unit_type: UnitType.kPixels,
9200 },
9201 // {
9202 // name: "cm",
9203 // unit_type: UnitType.kCentimeters,
9204 // },
9205 // {
9206 // name: "mm",
9207 // unit_type: UnitType.kMillimeters,
9208 // },
9209 // {
9210 // name: "q",
9211 // unit_type: UnitType.kQuarterMillimeters,
9212 // },
9213 // {
9214 // name: "in",
9215 // unit_type: UnitType.kInches,
9216 // },
9217 // {
9218 // name: "pt",
9219 // unit_type: UnitType.kPoints,
9220 // },
9221 // {
9222 // name: "pc",
9223 // unit_type: UnitType.kPicas,
9224 // },
9225 {
9226 name: 'deg',
9227 unit_type: UnitType.kDegrees,
9228 },
9229 {
9230 name: 'rad',
9231 unit_type: UnitType.kRadians,
9232 },
9233 {
9234 name: 'grad',
9235 unit_type: UnitType.kGradians,
9236 },
9237 {
9238 name: 'ms',
9239 unit_type: UnitType.kMilliseconds,
9240 },
9241 {
9242 name: 's',
9243 unit_type: UnitType.kSeconds,
9244 },
9245 // {
9246 // name: "hz",
9247 // unit_type: UnitType.kHertz,
9248 // },
9249 // {
9250 // name: "khz",
9251 // unit_type: UnitType.kKilohertz,
9252 // },
9253 // {
9254 // name: "dpi",
9255 // unit_type: "kDotsPerInch",
9256 // },
9257 // {
9258 // name: "dpcm",
9259 // unit_type: "kDotsPerCentimeter",
9260 // },
9261 // {
9262 // name: "dppx",
9263 // unit_type: "kDotsPerPixel",
9264 // },
9265 // {
9266 // name: "x",
9267 // unit_type: "kDotsPerPixel",
9268 // },
9269 // {
9270 // name: "vw",
9271 // unit_type: "kViewportWidth",
9272 // },
9273 // {
9274 // name: "vh",
9275 // unit_type: "kViewportHeight",
9276 // },
9277 // {
9278 // name: "vi",
9279 // unit_type: "kViewportInlineSize",
9280 // },
9281 // {
9282 // name: "vb",
9283 // unit_type: "kViewportBlockSize",
9284 // },
9285 // {
9286 // name: "vmin",
9287 // unit_type: UnitType.kViewportMin,
9288 // },
9289 // {
9290 // name: "vmax",
9291 // unit_type: UnitType.kViewportMax,
9292 // },
9293 // {
9294 // name: "svw",
9295 // unit_type: "kSmallViewportWidth",
9296 // },
9297 // {
9298 // name: "svh",
9299 // unit_type: "kSmallViewportHeight",
9300 // },
9301 // {
9302 // name: "svi",
9303 // unit_type: "kSmallViewportInlineSize",
9304 // },
9305 // {
9306 // name: "svb",
9307 // unit_type: "kSmallViewportBlockSize",
9308 // },
9309 // {
9310 // name: "svmin",
9311 // unit_type: "kSmallViewportMin",
9312 // },
9313 // {
9314 // name: "svmax",
9315 // unit_type: "kSmallViewportMax",
9316 // },
9317 // {
9318 // name: "lvw",
9319 // unit_type: "kLargeViewportWidth",
9320 // },
9321 // {
9322 // name: "lvh",
9323 // unit_type: "kLargeViewportHeight",
9324 // },
9325 // {
9326 // name: "lvi",
9327 // unit_type: "kLargeViewportInlineSize",
9328 // },
9329 // {
9330 // name: "lvb",
9331 // unit_type: "kLargeViewportBlockSize",
9332 // },
9333 // {
9334 // name: "lvmin",
9335 // unit_type: UnitType.kLargeViewportMin,
9336 // },
9337 // {
9338 // name: "lvmax",
9339 // unit_type: UnitType.kLargeViewportMax,
9340 // },
9341 // {
9342 // name: "dvw",
9343 // unit_type: UnitType.kDynamicViewportWidth,
9344 // },
9345 // {
9346 // name: "dvh",
9347 // unit_type: UnitType.kDynamicViewportHeight,
9348 // },
9349 // {
9350 // name: "dvi",
9351 // unit_type: UnitType.kDynamicViewportInlineSize,
9352 // },
9353 // {
9354 // name: "dvb",
9355 // unit_type: UnitType.kDynamicViewportBlockSize,
9356 // },
9357 // {
9358 // name: "dvmin",
9359 // unit_type: UnitType.kDynamicViewportMin,
9360 // },
9361 // {
9362 // name: "dvmax",
9363 // unit_type: UnitType.kDynamicViewportMax,
9364 // },
9365 // {
9366 // name: "cqw",
9367 // unit_type: UnitType.kContainerWidth,
9368 // },
9369 // {
9370 // name: "cqh",
9371 // unit_type: UnitType.kContainerHeight,
9372 // },
9373 // {
9374 // name: "cqi",
9375 // unit_type: UnitType.kContainerInlineSize,
9376 // },
9377 // {
9378 // name: "cqb",
9379 // unit_type: UnitType.kContainerBlockSize,
9380 // },
9381 // {
9382 // name: "cqmin",
9383 // unit_type: UnitType.kContainerMin,
9384 // },
9385 // {
9386 // name: "cqmax",
9387 // unit_type: UnitType.kContainerMax,
9388 // },
9389 {
9390 name: 'rem',
9391 unit_type: UnitType.kRems,
9392 },
9393 // {
9394 // name: 'fr',
9395 // unit_type: UnitType.kFraction,
9396 // },
9397 {
9398 name: 'turn',
9399 unit_type: UnitType.kTurns,
9400 },
9401 // {
9402 // name: 'ch',
9403 // unit_type: UnitType.kChs,
9404 // },
9405 // {
9406 // name: '__qem',
9407 // unit_type: UnitType.kQuirkyEms,
9408 // },
9409 ];
9410 var CSSStyleValueType;
9411 (function (CSSStyleValueType) {
9412 CSSStyleValueType[CSSStyleValueType["kUnknownType"] = 0] = "kUnknownType";
9413 CSSStyleValueType[CSSStyleValueType["kUnparsedType"] = 1] = "kUnparsedType";
9414 CSSStyleValueType[CSSStyleValueType["kKeywordType"] = 2] = "kKeywordType";
9415 // Start of CSSNumericValue subclasses
9416 CSSStyleValueType[CSSStyleValueType["kUnitType"] = 3] = "kUnitType";
9417 CSSStyleValueType[CSSStyleValueType["kSumType"] = 4] = "kSumType";
9418 CSSStyleValueType[CSSStyleValueType["kProductType"] = 5] = "kProductType";
9419 CSSStyleValueType[CSSStyleValueType["kNegateType"] = 6] = "kNegateType";
9420 CSSStyleValueType[CSSStyleValueType["kInvertType"] = 7] = "kInvertType";
9421 CSSStyleValueType[CSSStyleValueType["kMinType"] = 8] = "kMinType";
9422 CSSStyleValueType[CSSStyleValueType["kMaxType"] = 9] = "kMaxType";
9423 CSSStyleValueType[CSSStyleValueType["kClampType"] = 10] = "kClampType";
9424 // End of CSSNumericValue subclasses
9425 CSSStyleValueType[CSSStyleValueType["kTransformType"] = 11] = "kTransformType";
9426 CSSStyleValueType[CSSStyleValueType["kPositionType"] = 12] = "kPositionType";
9427 CSSStyleValueType[CSSStyleValueType["kURLImageType"] = 13] = "kURLImageType";
9428 CSSStyleValueType[CSSStyleValueType["kColorType"] = 14] = "kColorType";
9429 CSSStyleValueType[CSSStyleValueType["kUnsupportedColorType"] = 15] = "kUnsupportedColorType";
9430 })(CSSStyleValueType || (CSSStyleValueType = {}));
9431 // function parseCSSStyleValue(propertyName: string, value: string): CSSStyleValue[] {
9432 // // const propertyId = cssPropertyID(propertyName);
9433 // // if (propertyId === CSSPropertyID.kInvalid) {
9434 // // return [];
9435 // // }
9436 // // const customPropertyName = propertyId === CSSPropertyID.kVariable ? propertyName : null;
9437 // // return fromString(propertyId, customPropertyName, value);
9438 // return [];
9439 // }
9440 var stringToUnitType = function (name) {
9441 return data.find(function (item) { return item.name === name; }).unit_type;
9442 };
9443 var unitFromName = function (name) {
9444 if (!name) {
9445 return UnitType.kUnknown;
9446 }
9447 if (name === 'number') {
9448 return UnitType.kNumber;
9449 }
9450 if (name === 'percent' || name === '%') {
9451 return UnitType.kPercentage;
9452 }
9453 return stringToUnitType(name);
9454 };
9455 var unitTypeToUnitCategory = function (type) {
9456 switch (type) {
9457 case UnitType.kNumber:
9458 case UnitType.kInteger:
9459 return UnitCategory.kUNumber;
9460 case UnitType.kPercentage:
9461 return UnitCategory.kUPercent;
9462 case UnitType.kPixels:
9463 // case UnitType.kCentimeters:
9464 // case UnitType.kMillimeters:
9465 // case UnitType.kQuarterMillimeters:
9466 // case UnitType.kInches:
9467 // case UnitType.kPoints:
9468 // case UnitType.kPicas:
9469 // case UnitType.kUserUnits:
9470 return UnitCategory.kULength;
9471 case UnitType.kMilliseconds:
9472 case UnitType.kSeconds:
9473 return UnitCategory.kUTime;
9474 case UnitType.kDegrees:
9475 case UnitType.kRadians:
9476 case UnitType.kGradians:
9477 case UnitType.kTurns:
9478 return UnitCategory.kUAngle;
9479 // case UnitType.kHertz:
9480 // case UnitType.kKilohertz:
9481 // return UnitCategory.kUFrequency;
9482 // case UnitType.kDotsPerPixel:
9483 // case UnitType.kDotsPerInch:
9484 // case UnitType.kDotsPerCentimeter:
9485 // return UnitCategory.kUResolution;
9486 default:
9487 return UnitCategory.kUOther;
9488 }
9489 };
9490 var canonicalUnitTypeForCategory = function (category) {
9491 // The canonical unit type is chosen according to the way
9492 // CSSPropertyParser.ValidUnit() chooses the default unit in each category
9493 // (based on unitflags).
9494 switch (category) {
9495 case UnitCategory.kUNumber:
9496 return UnitType.kNumber;
9497 case UnitCategory.kULength:
9498 return UnitType.kPixels;
9499 case UnitCategory.kUPercent:
9500 return UnitType.kPercentage;
9501 // return UnitType.kUnknown; // Cannot convert between numbers and percent.
9502 case UnitCategory.kUTime:
9503 return UnitType.kSeconds;
9504 case UnitCategory.kUAngle:
9505 return UnitType.kDegrees;
9506 // case UnitCategory.kUFrequency:
9507 // return UnitType.kHertz;
9508 // case UnitCategory.kUResolution:
9509 // return UnitType.kDotsPerPixel;
9510 default:
9511 return UnitType.kUnknown;
9512 }
9513 };
9514 /**
9515 * @see https://chromium.googlesource.com/chromium/src/+/refs/heads/main/third_party/blink/renderer/core/css/css_primitive_value.cc#353
9516 */
9517 var conversionToCanonicalUnitsScaleFactor = function (unit_type) {
9518 var factor = 1.0;
9519 // FIXME: the switch can be replaced by an array of scale factors.
9520 switch (unit_type) {
9521 // These are "canonical" units in their respective categories.
9522 case UnitType.kPixels:
9523 // case UnitType.kUserUnits:
9524 case UnitType.kDegrees:
9525 case UnitType.kSeconds:
9526 // case UnitType.kHertz:
9527 break;
9528 case UnitType.kMilliseconds:
9529 factor = 0.001;
9530 break;
9531 // case UnitType.kCentimeters:
9532 // // factor = kCssPixelsPerCentimeter;
9533 // break;
9534 // case UnitType.kDotsPerCentimeter:
9535 // // factor = 1 / kCssPixelsPerCentimeter;
9536 // break;
9537 // case UnitType.kMillimeters:
9538 // // factor = kCssPixelsPerMillimeter;
9539 // break;
9540 // case UnitType.kQuarterMillimeters:
9541 // // factor = kCssPixelsPerQuarterMillimeter;
9542 // break;
9543 // case UnitType.kInches:
9544 // // factor = kCssPixelsPerInch;
9545 // break;
9546 // case UnitType.kDotsPerInch:
9547 // // factor = 1 / kCssPixelsPerInch;
9548 // break;
9549 // case UnitType.kPoints:
9550 // // factor = kCssPixelsPerPoint;
9551 // break;
9552 // case UnitType.kPicas:
9553 // // factor = kCssPixelsPerPica;
9554 // break;
9555 case UnitType.kRadians:
9556 factor = 180 / Math.PI;
9557 break;
9558 case UnitType.kGradians:
9559 factor = 0.9;
9560 break;
9561 case UnitType.kTurns:
9562 factor = 360;
9563 break;
9564 }
9565 return factor;
9566 };
9567 var unitTypeToString = function (type) {
9568 switch (type) {
9569 case UnitType.kNumber:
9570 case UnitType.kInteger:
9571 // case UnitType.kUserUnits:
9572 return '';
9573 case UnitType.kPercentage:
9574 return '%';
9575 case UnitType.kEms:
9576 // case UnitType.kQuirkyEms:
9577 return 'em';
9578 // case UnitType.kExs:
9579 // return 'ex';
9580 case UnitType.kRems:
9581 return 'rem';
9582 // case UnitType.kChs:
9583 // return 'ch';
9584 case UnitType.kPixels:
9585 return 'px';
9586 // case UnitType.kCentimeters:
9587 // return 'cm';
9588 // case UnitType.kDotsPerPixel:
9589 // return 'dppx';
9590 // case UnitType.kDotsPerInch:
9591 // return 'dpi';
9592 // case UnitType.kDotsPerCentimeter:
9593 // return 'dpcm';
9594 // case UnitType.kMillimeters:
9595 // return 'mm';
9596 // case UnitType.kQuarterMillimeters:
9597 // return 'q';
9598 // case UnitType.kInches:
9599 // return 'in';
9600 // case UnitType.kPoints:
9601 // return 'pt';
9602 // case UnitType.kPicas:
9603 // return 'pc';
9604 case UnitType.kDegrees:
9605 return 'deg';
9606 case UnitType.kRadians:
9607 return 'rad';
9608 case UnitType.kGradians:
9609 return 'grad';
9610 case UnitType.kMilliseconds:
9611 return 'ms';
9612 case UnitType.kSeconds:
9613 return 's';
9614 // case UnitType.kHertz:
9615 // return 'hz';
9616 // case UnitType.kKilohertz:
9617 // return 'khz';
9618 case UnitType.kTurns:
9619 return 'turn';
9620 }
9621 return '';
9622 };
9623 /**
9624 * CSSStyleValue is the base class for all CSS values accessible from Typed OM.
9625 * Values that are not yet supported as specific types are also returned as base CSSStyleValues.
9626 *
9627 * Spec @see https://drafts.css-houdini.org/css-typed-om/#stylevalue-objects
9628 * Docs @see https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleValue
9629 */
9630 var CSSStyleValue = /** @class */ (function () {
9631 function CSSStyleValue() {
9632 }
9633 // static parse(propertyName: string, value: string): CSSStyleValue {
9634 // return parseCSSStyleValue(propertyName, value)[0];
9635 // }
9636 // static parseAll(propertyName: string, value: string): CSSStyleValue[] {
9637 // return parseCSSStyleValue(propertyName, value);
9638 // }
9639 CSSStyleValue.isAngle = function (unit) {
9640 return (unit === UnitType.kDegrees ||
9641 unit === UnitType.kRadians ||
9642 unit === UnitType.kGradians ||
9643 unit === UnitType.kTurns);
9644 };
9645 // static isViewportPercentageLength(type: UnitType) {
9646 // return type >= UnitType.kViewportWidth && type <= UnitType.kDynamicViewportMax;
9647 // }
9648 // static isContainerPercentageLength(type: UnitType) {
9649 // return type >= UnitType.kContainerWidth && type <= UnitType.kContainerMax;
9650 // }
9651 CSSStyleValue.isLength = function (type) {
9652 // return (type >= UnitType.kEms && type <= UnitType.kUserUnits) || type == UnitType.kQuirkyEms;
9653 return type >= UnitType.kEms && type < UnitType.kDegrees;
9654 };
9655 CSSStyleValue.isRelativeUnit = function (type) {
9656 return (type === UnitType.kPercentage ||
9657 type === UnitType.kEms ||
9658 // type === UnitType.kExs ||
9659 type === UnitType.kRems
9660 // type === UnitType.kChs ||
9661 // this.isViewportPercentageLength(type) ||
9662 // this.isContainerPercentageLength(type)
9663 );
9664 };
9665 CSSStyleValue.isTime = function (unit) {
9666 return unit === UnitType.kSeconds || unit === UnitType.kMilliseconds;
9667 };
9668 // protected abstract toCSSValue(): CSSValue;
9669 CSSStyleValue.prototype.toString = function () {
9670 return this.buildCSSText(Nested.kNo, ParenLess.kNo, '');
9671 };
9672 CSSStyleValue.prototype.isNumericValue = function () {
9673 return (this.getType() >= CSSStyleValueType.kUnitType &&
9674 this.getType() <= CSSStyleValueType.kClampType);
9675 };
9676 return CSSStyleValue;
9677 }());
9678
9679 /**
9680 * CSSColorValue is the base class used for the various CSS color interfaces.
9681 *
9682 * @see https://drafts.css-houdini.org/css-typed-om-1/#colorvalue-objects
9683 */
9684 var CSSColorValue = /** @class */ (function (_super) {
9685 __extends(CSSColorValue, _super);
9686 function CSSColorValue(colorSpace) {
9687 var _this = _super.call(this) || this;
9688 _this.colorSpace = colorSpace;
9689 return _this;
9690 }
9691 CSSColorValue.prototype.getType = function () {
9692 return CSSStyleValueType.kColorType;
9693 };
9694 // buildCSSText(n: Nested, p: ParenLess, result: string): string {
9695 // let text = '';
9696 // if (this.colorSpace === 'rgb') {
9697 // text = `rgba(${this.channels.join(',')},${this.alpha})`;
9698 // }
9699 // return (result += text);
9700 // }
9701 /**
9702 * @see https://drafts.css-houdini.org/css-typed-om-1/#dom-csscolorvalue-to
9703 */
9704 CSSColorValue.prototype.to = function (colorSpace) {
9705 return this;
9706 };
9707 return CSSColorValue;
9708 }(CSSStyleValue));
9709
9710 var GradientType;
9711 (function (GradientType) {
9712 GradientType[GradientType["Constant"] = 0] = "Constant";
9713 GradientType[GradientType["LinearGradient"] = 1] = "LinearGradient";
9714 GradientType[GradientType["RadialGradient"] = 2] = "RadialGradient";
9715 })(GradientType || (GradientType = {}));
9716 var CSSGradientValue = /** @class */ (function (_super) {
9717 __extends(CSSGradientValue, _super);
9718 function CSSGradientValue(type, value) {
9719 var _this = _super.call(this) || this;
9720 _this.type = type;
9721 _this.value = value;
9722 return _this;
9723 }
9724 CSSGradientValue.prototype.clone = function () {
9725 return new CSSGradientValue(this.type, this.value);
9726 };
9727 CSSGradientValue.prototype.buildCSSText = function (n, p, result) {
9728 return result;
9729 };
9730 CSSGradientValue.prototype.getType = function () {
9731 return CSSStyleValueType.kColorType;
9732 };
9733 return CSSGradientValue;
9734 }(CSSStyleValue));
9735
9736 /**
9737 * CSSKeywordValue represents CSS Values that are specified as keywords
9738 * eg. 'initial'
9739 * @see https://developer.mozilla.org/en-US/docs/Web/API/CSSKeywordValue
9740 * @see https://chromium.googlesource.com/chromium/src/+/refs/heads/main/third_party/blink/renderer/core/css/cssom/css_keyword_value.idl
9741 */
9742 var CSSKeywordValue = /** @class */ (function (_super) {
9743 __extends(CSSKeywordValue, _super);
9744 function CSSKeywordValue(value) {
9745 var _this = _super.call(this) || this;
9746 _this.value = value;
9747 return _this;
9748 }
9749 CSSKeywordValue.prototype.clone = function () {
9750 return new CSSKeywordValue(this.value);
9751 };
9752 CSSKeywordValue.prototype.getType = function () {
9753 return CSSStyleValueType.kKeywordType;
9754 };
9755 CSSKeywordValue.prototype.buildCSSText = function (n, p, result) {
9756 return result + this.value;
9757 };
9758 return CSSKeywordValue;
9759 }(CSSStyleValue));
9760
9761 var camelCase = memoize(function (str) {
9762 if (str === void 0) { str = ''; }
9763 return str.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); });
9764 });
9765 var kebabize = function (str) {
9766 return str
9767 .split('')
9768 .map(function (letter, idx) {
9769 return letter.toUpperCase() === letter
9770 ? "".concat(idx !== 0 ? '-' : '').concat(letter.toLowerCase())
9771 : letter;
9772 })
9773 .join('');
9774 };
9775
9776 function DCHECK(bool) {
9777 if (!bool) {
9778 throw new Error();
9779 }
9780 }
9781 function isFunction$1(func) {
9782 return typeof func === 'function';
9783 }
9784 function isSymbol(value) {
9785 // @see https://github.com/lodash/lodash/blob/master/isSymbol.js
9786 return typeof value === 'symbol';
9787 }
9788 var definedProps = function (obj) {
9789 return Object.fromEntries(Object.entries(obj).filter(function (_a) {
9790 var _b = __read(_a, 2), v = _b[1];
9791 return v !== undefined;
9792 }));
9793 };
9794 var FORMAT_ATTR_MAP = {
9795 d: {
9796 alias: 'path',
9797 },
9798 strokeDasharray: {
9799 alias: 'lineDash',
9800 },
9801 strokeWidth: {
9802 alias: 'lineWidth',
9803 },
9804 textAnchor: {
9805 alias: 'textAlign',
9806 },
9807 src: {
9808 alias: 'img',
9809 },
9810 };
9811 var formatAttributeName = memoize(function (name) {
9812 var attributeName = camelCase(name);
9813 var map = FORMAT_ATTR_MAP[attributeName];
9814 attributeName = (map === null || map === void 0 ? void 0 : map.alias) || attributeName;
9815 return attributeName;
9816 });
9817
9818 // type CSSNumericBaseType =
9819 // | 'length'
9820 // | 'angle'
9821 // | 'time'
9822 // | 'frequency'
9823 // | 'resolution'
9824 // | 'flex'
9825 // | 'percent';
9826 // https://drafts.css-houdini.org/css-typed-om/#dictdef-cssnumerictype
9827 // interface CSSNumericType {
9828 // length: number;
9829 // angle: number;
9830 // time: number;
9831 // frequency: number;
9832 // resolution: number;
9833 // flex: number;
9834 // percent: number;
9835 // percentHint: CSSNumericBaseType;
9836 // }
9837 var formatInfinityOrNaN = function (number, suffix) {
9838 if (suffix === void 0) { suffix = ''; }
9839 var result = '';
9840 if (!Number.isFinite(number)) {
9841 if (number > 0)
9842 result = 'infinity';
9843 else
9844 result = '-infinity';
9845 }
9846 else {
9847 DCHECK(Number.isNaN(number));
9848 result = 'NaN';
9849 }
9850 return (result += suffix);
9851 };
9852 var toCanonicalUnit = function (unit) {
9853 return canonicalUnitTypeForCategory(unitTypeToUnitCategory(unit));
9854 };
9855 /**
9856 * CSSNumericValue is the base class for numeric and length typed CSS Values.
9857 * @see https://drafts.css-houdini.org/css-typed-om/#numeric-objects
9858 * @see https://developer.mozilla.org/en-US/docs/Web/API/CSSNumericValue
9859 * @see https://chromium.googlesource.com/chromium/src/+/refs/heads/main/third_party/blink/renderer/core/css/cssom/css_numeric_value.idl
9860 */
9861 /**
9862 * Represents numeric values that can be expressed as a single number plus a
9863 * unit (or a naked number or percentage).
9864 * @see https://drafts.css-houdini.org/css-typed-om/#cssunitvalue
9865 */
9866 var CSSUnitValue = /** @class */ (function (_super) {
9867 __extends(CSSUnitValue, _super);
9868 function CSSUnitValue(value, unitOrName) {
9869 if (unitOrName === void 0) { unitOrName = UnitType.kNumber; }
9870 var _this = _super.call(this) || this;
9871 var unit;
9872 if (typeof unitOrName === 'string') {
9873 unit = unitFromName(unitOrName);
9874 }
9875 else {
9876 unit = unitOrName;
9877 }
9878 _this.unit = unit;
9879 _this.value = value;
9880 return _this;
9881 }
9882 CSSUnitValue.prototype.clone = function () {
9883 return new CSSUnitValue(this.value, this.unit);
9884 };
9885 CSSUnitValue.prototype.equals = function (other) {
9886 var other_unit_value = other;
9887 return (this.value === other_unit_value.value &&
9888 this.unit === other_unit_value.unit);
9889 };
9890 CSSUnitValue.prototype.getType = function () {
9891 return CSSStyleValueType.kUnitType;
9892 };
9893 CSSUnitValue.prototype.convertTo = function (target_unit) {
9894 if (this.unit === target_unit) {
9895 return new CSSUnitValue(this.value, this.unit);
9896 }
9897 // Instead of defining the scale factors for every unit to every other unit,
9898 // we simply convert to the canonical unit and back since we already have
9899 // the scale factors for canonical units.
9900 var canonical_unit = toCanonicalUnit(this.unit);
9901 if (canonical_unit !== toCanonicalUnit(target_unit) ||
9902 canonical_unit === UnitType.kUnknown) {
9903 return null;
9904 }
9905 var scale_factor = conversionToCanonicalUnitsScaleFactor(this.unit) /
9906 conversionToCanonicalUnitsScaleFactor(target_unit);
9907 return new CSSUnitValue(this.value * scale_factor, target_unit);
9908 };
9909 CSSUnitValue.prototype.buildCSSText = function (n, p, result) {
9910 var text;
9911 switch (this.unit) {
9912 case UnitType.kUnknown:
9913 // FIXME
9914 break;
9915 case UnitType.kInteger:
9916 text = Number(this.value).toFixed(0);
9917 break;
9918 case UnitType.kNumber:
9919 case UnitType.kPercentage:
9920 case UnitType.kEms:
9921 // case UnitType.kQuirkyEms:
9922 // case UnitType.kExs:
9923 case UnitType.kRems:
9924 // case UnitType.kChs:
9925 case UnitType.kPixels:
9926 // case UnitType.kCentimeters:
9927 // case UnitType.kDotsPerPixel:
9928 // case UnitType.kDotsPerInch:
9929 // case UnitType.kDotsPerCentimeter:
9930 // case UnitType.kMillimeters:
9931 // case UnitType.kQuarterMillimeters:
9932 // case UnitType.kInches:
9933 // case UnitType.kPoints:
9934 // case UnitType.kPicas:
9935 // case UnitType.kUserUnits:
9936 case UnitType.kDegrees:
9937 case UnitType.kRadians:
9938 case UnitType.kGradians:
9939 case UnitType.kMilliseconds:
9940 case UnitType.kSeconds:
9941 // case UnitType.kHertz:
9942 // case UnitType.kKilohertz:
9943 case UnitType.kTurns: // case UnitType.kContainerMax: { // case UnitType.kContainerMin: // case UnitType.kContainerBlockSize: // case UnitType.kContainerInlineSize: // case UnitType.kContainerHeight: // case UnitType.kContainerWidth: // case UnitType.kDynamicViewportMax: // case UnitType.kDynamicViewportMin: // case UnitType.kDynamicViewportBlockSize: // case UnitType.kDynamicViewportInlineSize: // case UnitType.kDynamicViewportHeight: // case UnitType.kDynamicViewportWidth: // case UnitType.kLargeViewportMax: // case UnitType.kLargeViewportMin: // case UnitType.kLargeViewportBlockSize: // case UnitType.kLargeViewportInlineSize: // case UnitType.kLargeViewportHeight: // case UnitType.kLargeViewportWidth: // case UnitType.kSmallViewportMax: // case UnitType.kSmallViewportMin: // case UnitType.kSmallViewportBlockSize: // case UnitType.kSmallViewportInlineSize: // case UnitType.kSmallViewportHeight: // case UnitType.kSmallViewportWidth: // case UnitType.kViewportMax: // case UnitType.kViewportMin: // case UnitType.kViewportBlockSize: // case UnitType.kViewportInlineSize: // case UnitType.kViewportHeight: // case UnitType.kViewportWidth: // case UnitType.kFraction:
9944 {
9945 var kMinInteger = -999999;
9946 var kMaxInteger = 999999;
9947 var value = this.value;
9948 var unit = unitTypeToString(this.unit);
9949 if (value < kMinInteger || value > kMaxInteger) {
9950 var unit_1 = unitTypeToString(this.unit);
9951 if (!Number.isFinite(value) || Number.isNaN(value)) {
9952 text = formatInfinityOrNaN(value, unit_1);
9953 }
9954 else {
9955 text = value + (unit_1 || '');
9956 }
9957 }
9958 else {
9959 text = "".concat(value).concat(unit);
9960 }
9961 }
9962 }
9963 result += text;
9964 return result;
9965 };
9966 return CSSUnitValue;
9967 }(CSSStyleValue));
9968 var Opx = new CSSUnitValue(0, 'px');
9969 new CSSUnitValue(1, 'px');
9970 var Odeg = new CSSUnitValue(0, 'deg');
9971
9972 /**
9973 * The CSSRGB class represents the CSS rgb()/rgba() functions.
9974 *
9975 * @see https://drafts.css-houdini.org/css-typed-om-1/#cssrgb
9976 */
9977 var CSSRGB = /** @class */ (function (_super) {
9978 __extends(CSSRGB, _super);
9979 function CSSRGB(r, g, b, alpha,
9980 /**
9981 * 'transparent' & 'none' has the same rgba data
9982 */
9983 isNone) {
9984 if (alpha === void 0) { alpha = 1; }
9985 if (isNone === void 0) { isNone = false; }
9986 var _this = _super.call(this, 'rgb') || this;
9987 _this.r = r;
9988 _this.g = g;
9989 _this.b = b;
9990 _this.alpha = alpha;
9991 _this.isNone = isNone;
9992 return _this;
9993 }
9994 CSSRGB.prototype.clone = function () {
9995 return new CSSRGB(this.r, this.g, this.b, this.alpha);
9996 };
9997 CSSRGB.prototype.buildCSSText = function (n, p, result) {
9998 return result + "rgba(".concat(this.r, ",").concat(this.g, ",").concat(this.b, ",").concat(this.alpha, ")");
9999 };
10000 return CSSRGB;
10001 }(CSSColorValue));
10002
10003 /**
10004 * CSSKeywordValue
10005 */
10006 var unsetKeywordValue = new CSSKeywordValue('unset');
10007 var initialKeywordValue = new CSSKeywordValue('initial');
10008 var inheritKeywordValue = new CSSKeywordValue('inherit');
10009 var keywordCache = {
10010 '': unsetKeywordValue,
10011 unset: unsetKeywordValue,
10012 initial: initialKeywordValue,
10013 inherit: inheritKeywordValue,
10014 };
10015 var getOrCreateKeyword = function (name) {
10016 if (!keywordCache[name]) {
10017 keywordCache[name] = new CSSKeywordValue(name);
10018 }
10019 return keywordCache[name];
10020 };
10021 /**
10022 * CSSColor
10023 */
10024 var noneColor = new CSSRGB(0, 0, 0, 0, true);
10025 var transparentColor = new CSSRGB(0, 0, 0, 0);
10026 var getOrCreateRGBA = memoize(function (r, g, b, a) {
10027 return new CSSRGB(r, g, b, a);
10028 }, function (r, g, b, a) {
10029 return "rgba(".concat(r, ",").concat(g, ",").concat(b, ",").concat(a, ")");
10030 });
10031 // export const getOrCreateUnitValue = memoize(
10032 // (value: number, unitOrName: UnitType | string = UnitType.kNumber) => {
10033 // return new CSSUnitValue(value, unitOrName);
10034 // },
10035 // (value: number, unitOrName: UnitType | string = UnitType.kNumber) => {
10036 // return `${value}${unitOrName}`;
10037 // },
10038 // );
10039 var getOrCreateUnitValue = function (value, unitOrName) {
10040 if (unitOrName === void 0) { unitOrName = UnitType.kNumber; }
10041 return new CSSUnitValue(value, unitOrName);
10042 };
10043 var PECENTAGE_50 = new CSSUnitValue(50, '%');
10044
10045 /**
10046 * @see https://doc.babylonjs.com/how_to/optimizing_your_scene#changing-mesh-culling-strategy
10047 */
10048 var Strategy;
10049 (function (Strategy) {
10050 Strategy[Strategy["Standard"] = 0] = "Standard";
10051 })(Strategy || (Strategy = {}));
10052
10053 var SortReason;
10054 (function (SortReason) {
10055 SortReason[SortReason["ADDED"] = 0] = "ADDED";
10056 SortReason[SortReason["REMOVED"] = 1] = "REMOVED";
10057 SortReason[SortReason["Z_INDEX_CHANGED"] = 2] = "Z_INDEX_CHANGED";
10058 })(SortReason || (SortReason = {}));
10059
10060 var EMPTY_PARSED_PATH = {
10061 absolutePath: [],
10062 hasArc: false,
10063 segments: [],
10064 polygons: [],
10065 polylines: [],
10066 curve: null,
10067 totalLength: 0,
10068 rect: new Rectangle(0, 0, 0, 0),
10069 };
10070
10071 /**
10072 * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Content_type
10073 */
10074 var PropertySyntax;
10075 (function (PropertySyntax) {
10076 /**
10077 * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Content_type#coordinate
10078 */
10079 PropertySyntax["COORDINATE"] = "<coordinate>";
10080 /**
10081 * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Content_type#color
10082 */
10083 PropertySyntax["COLOR"] = "<color>";
10084 /**
10085 * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Content_type#paint
10086 */
10087 PropertySyntax["PAINT"] = "<paint>";
10088 /**
10089 * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Content_type#number
10090 */
10091 PropertySyntax["NUMBER"] = "<number>";
10092 /**
10093 * @see https://developer.mozilla.org/zh-CN/docs/Web/CSS/angle
10094 */
10095 PropertySyntax["ANGLE"] = "<angle>";
10096 /**
10097 * <number> with range 0..1
10098 * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Content_type#opacity_value
10099 */
10100 PropertySyntax["OPACITY_VALUE"] = "<opacity-value>";
10101 /**
10102 * <number> with range 0..Infinity
10103 */
10104 PropertySyntax["SHADOW_BLUR"] = "<shadow-blur>";
10105 /**
10106 * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Content_type#length
10107 */
10108 PropertySyntax["LENGTH"] = "<length>";
10109 /**
10110 * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Content_type#percentage
10111 */
10112 PropertySyntax["PERCENTAGE"] = "<percentage>";
10113 PropertySyntax["LENGTH_PERCENTAGE"] = "<length> | <percentage>";
10114 PropertySyntax["LENGTH_PERCENTAGE_12"] = "[<length> | <percentage>]{1,2}";
10115 /**
10116 * @see https://developer.mozilla.org/en-US/docs/Web/CSS/margin#formal_syntax
10117 */
10118 PropertySyntax["LENGTH_PERCENTAGE_14"] = "[<length> | <percentage>]{1,4}";
10119 /**
10120 * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Content_type#list-of-ts
10121 */
10122 PropertySyntax["LIST_OF_POINTS"] = "<list-of-points>";
10123 PropertySyntax["PATH"] = "<path>";
10124 /**
10125 * @see https://developer.mozilla.org/en-US/docs/Web/CSS/filter#formal_syntax
10126 */
10127 PropertySyntax["FILTER"] = "<filter>";
10128 PropertySyntax["Z_INDEX"] = "<z-index>";
10129 PropertySyntax["OFFSET_DISTANCE"] = "<offset-distance>";
10130 PropertySyntax["DEFINED_PATH"] = "<defined-path>";
10131 PropertySyntax["MARKER"] = "<marker>";
10132 PropertySyntax["TRANSFORM"] = "<transform>";
10133 PropertySyntax["TRANSFORM_ORIGIN"] = "<transform-origin>";
10134 PropertySyntax["TEXT"] = "<text>";
10135 PropertySyntax["TEXT_TRANSFORM"] = "<text-transform>";
10136 })(PropertySyntax || (PropertySyntax = {}));
10137
10138 /**
10139 * borrow from gradient-parser, but we delete some browser compatible prefix such as `-webkit-`
10140 * @see https://github.com/rafaelcaricio/gradient-parser
10141 */
10142 function colorStopToString(colorStop) {
10143 var type = colorStop.type, value = colorStop.value;
10144 if (type === 'hex') {
10145 return "#".concat(value);
10146 }
10147 else if (type === 'literal') {
10148 return value;
10149 }
10150 else if (type === 'rgb') {
10151 return "rgb(".concat(value.join(','), ")");
10152 }
10153 else {
10154 return "rgba(".concat(value.join(','), ")");
10155 }
10156 }
10157 var parseGradient$1 = (function () {
10158 var tokens = {
10159 linearGradient: /^(linear\-gradient)/i,
10160 repeatingLinearGradient: /^(repeating\-linear\-gradient)/i,
10161 radialGradient: /^(radial\-gradient)/i,
10162 repeatingRadialGradient: /^(repeating\-radial\-gradient)/i,
10163 /**
10164 * @see https://projects.verou.me/conic-gradient/
10165 */
10166 conicGradient: /^(conic\-gradient)/i,
10167 sideOrCorner: /^to (left (top|bottom)|right (top|bottom)|top (left|right)|bottom (left|right)|left|right|top|bottom)/i,
10168 extentKeywords: /^(closest\-side|closest\-corner|farthest\-side|farthest\-corner|contain|cover)/,
10169 positionKeywords: /^(left|center|right|top|bottom)/i,
10170 pixelValue: /^(-?(([0-9]*\.[0-9]+)|([0-9]+\.?)))px/,
10171 percentageValue: /^(-?(([0-9]*\.[0-9]+)|([0-9]+\.?)))\%/,
10172 emValue: /^(-?(([0-9]*\.[0-9]+)|([0-9]+\.?)))em/,
10173 angleValue: /^(-?(([0-9]*\.[0-9]+)|([0-9]+\.?)))deg/,
10174 startCall: /^\(/,
10175 endCall: /^\)/,
10176 comma: /^,/,
10177 hexColor: /^\#([0-9a-fA-F]+)/,
10178 literalColor: /^([a-zA-Z]+)/,
10179 rgbColor: /^rgb/i,
10180 rgbaColor: /^rgba/i,
10181 number: /^(([0-9]*\.[0-9]+)|([0-9]+\.?))/,
10182 };
10183 var input = '';
10184 function error(msg) {
10185 throw new Error(input + ': ' + msg);
10186 }
10187 function getAST() {
10188 var ast = matchListDefinitions();
10189 if (input.length > 0) {
10190 error('Invalid input not EOF');
10191 }
10192 return ast;
10193 }
10194 function matchListDefinitions() {
10195 return matchListing(matchDefinition);
10196 }
10197 function matchDefinition() {
10198 return (matchGradient('linear-gradient', tokens.linearGradient, matchLinearOrientation) ||
10199 matchGradient('repeating-linear-gradient', tokens.repeatingLinearGradient, matchLinearOrientation) ||
10200 matchGradient('radial-gradient', tokens.radialGradient, matchListRadialOrientations) ||
10201 matchGradient('repeating-radial-gradient', tokens.repeatingRadialGradient, matchListRadialOrientations) ||
10202 matchGradient('conic-gradient', tokens.conicGradient, matchListRadialOrientations));
10203 }
10204 function matchGradient(gradientType, pattern, orientationMatcher) {
10205 return matchCall(pattern, function (captures) {
10206 var orientation = orientationMatcher();
10207 if (orientation) {
10208 if (!scan(tokens.comma)) {
10209 error('Missing comma before color stops');
10210 }
10211 }
10212 return {
10213 type: gradientType,
10214 orientation: orientation,
10215 colorStops: matchListing(matchColorStop),
10216 };
10217 });
10218 }
10219 function matchCall(pattern, callback) {
10220 var captures = scan(pattern);
10221 if (captures) {
10222 if (!scan(tokens.startCall)) {
10223 error('Missing (');
10224 }
10225 var result = callback(captures);
10226 if (!scan(tokens.endCall)) {
10227 error('Missing )');
10228 }
10229 return result;
10230 }
10231 }
10232 function matchLinearOrientation() {
10233 return matchSideOrCorner() || matchAngle();
10234 }
10235 function matchSideOrCorner() {
10236 return match('directional', tokens.sideOrCorner, 1);
10237 }
10238 function matchAngle() {
10239 return match('angular', tokens.angleValue, 1);
10240 }
10241 function matchListRadialOrientations() {
10242 var radialOrientations, radialOrientation = matchRadialOrientation(), lookaheadCache;
10243 if (radialOrientation) {
10244 radialOrientations = [];
10245 radialOrientations.push(radialOrientation);
10246 lookaheadCache = input;
10247 if (scan(tokens.comma)) {
10248 radialOrientation = matchRadialOrientation();
10249 if (radialOrientation) {
10250 radialOrientations.push(radialOrientation);
10251 }
10252 else {
10253 input = lookaheadCache;
10254 }
10255 }
10256 }
10257 return radialOrientations;
10258 }
10259 function matchRadialOrientation() {
10260 var radialType = matchCircle() || matchEllipse();
10261 if (radialType) {
10262 // @ts-ignore
10263 radialType.at = matchAtPosition();
10264 }
10265 else {
10266 var extent = matchExtentKeyword();
10267 if (extent) {
10268 radialType = extent;
10269 var positionAt = matchAtPosition();
10270 if (positionAt) {
10271 // @ts-ignore
10272 radialType.at = positionAt;
10273 }
10274 }
10275 else {
10276 var defaultPosition = matchPositioning();
10277 if (defaultPosition) {
10278 radialType = {
10279 type: 'default-radial',
10280 // @ts-ignore
10281 at: defaultPosition,
10282 };
10283 }
10284 }
10285 }
10286 return radialType;
10287 }
10288 function matchCircle() {
10289 var circle = match('shape', /^(circle)/i, 0);
10290 if (circle) {
10291 // @ts-ignore
10292 circle.style = matchLength() || matchExtentKeyword();
10293 }
10294 return circle;
10295 }
10296 function matchEllipse() {
10297 var ellipse = match('shape', /^(ellipse)/i, 0);
10298 if (ellipse) {
10299 // @ts-ignore
10300 ellipse.style = matchDistance() || matchExtentKeyword();
10301 }
10302 return ellipse;
10303 }
10304 function matchExtentKeyword() {
10305 return match('extent-keyword', tokens.extentKeywords, 1);
10306 }
10307 function matchAtPosition() {
10308 if (match('position', /^at/, 0)) {
10309 var positioning = matchPositioning();
10310 if (!positioning) {
10311 error('Missing positioning value');
10312 }
10313 return positioning;
10314 }
10315 }
10316 function matchPositioning() {
10317 var location = matchCoordinates();
10318 if (location.x || location.y) {
10319 return {
10320 type: 'position',
10321 value: location,
10322 };
10323 }
10324 }
10325 function matchCoordinates() {
10326 return {
10327 x: matchDistance(),
10328 y: matchDistance(),
10329 };
10330 }
10331 function matchListing(matcher) {
10332 var captures = matcher();
10333 var result = [];
10334 if (captures) {
10335 result.push(captures);
10336 while (scan(tokens.comma)) {
10337 captures = matcher();
10338 if (captures) {
10339 result.push(captures);
10340 }
10341 else {
10342 error('One extra comma');
10343 }
10344 }
10345 }
10346 return result;
10347 }
10348 function matchColorStop() {
10349 var color = matchColor();
10350 if (!color) {
10351 error('Expected color definition');
10352 }
10353 color.length = matchDistance();
10354 return color;
10355 }
10356 function matchColor() {
10357 return (matchHexColor() ||
10358 matchRGBAColor() ||
10359 matchRGBColor() ||
10360 matchLiteralColor());
10361 }
10362 function matchLiteralColor() {
10363 return match('literal', tokens.literalColor, 0);
10364 }
10365 function matchHexColor() {
10366 return match('hex', tokens.hexColor, 1);
10367 }
10368 function matchRGBColor() {
10369 return matchCall(tokens.rgbColor, function () {
10370 return {
10371 type: 'rgb',
10372 value: matchListing(matchNumber),
10373 };
10374 });
10375 }
10376 function matchRGBAColor() {
10377 return matchCall(tokens.rgbaColor, function () {
10378 return {
10379 type: 'rgba',
10380 value: matchListing(matchNumber),
10381 };
10382 });
10383 }
10384 function matchNumber() {
10385 return scan(tokens.number)[1];
10386 }
10387 function matchDistance() {
10388 return (match('%', tokens.percentageValue, 1) ||
10389 matchPositionKeyword() ||
10390 matchLength());
10391 }
10392 function matchPositionKeyword() {
10393 return match('position-keyword', tokens.positionKeywords, 1);
10394 }
10395 function matchLength() {
10396 return match('px', tokens.pixelValue, 1) || match('em', tokens.emValue, 1);
10397 }
10398 function match(type, pattern, captureIndex) {
10399 var captures = scan(pattern);
10400 if (captures) {
10401 return {
10402 type: type,
10403 value: captures[captureIndex],
10404 };
10405 }
10406 }
10407 function scan(regexp) {
10408 var blankCaptures = /^[\n\r\t\s]+/.exec(input);
10409 if (blankCaptures) {
10410 consume(blankCaptures[0].length);
10411 }
10412 var captures = regexp.exec(input);
10413 if (captures) {
10414 consume(captures[0].length);
10415 }
10416 return captures;
10417 }
10418 function consume(size) {
10419 input = input.substring(size);
10420 }
10421 return function (code) {
10422 input = code;
10423 return getAST();
10424 };
10425 })();
10426 function computeLinearGradient(width, height, angle) {
10427 var rad = deg2rad(angle.value);
10428 var rx = 0;
10429 var ry = 0;
10430 var rcx = rx + width / 2;
10431 var rcy = ry + height / 2;
10432 // get the length of gradient line
10433 // @see https://observablehq.com/@danburzo/css-gradient-line
10434 var length = Math.abs(width * Math.cos(rad)) + Math.abs(height * Math.sin(rad));
10435 var x1 = rcx - (Math.cos(rad) * length) / 2;
10436 var y1 = rcy - (Math.sin(rad) * length) / 2;
10437 var x2 = rcx + (Math.cos(rad) * length) / 2;
10438 var y2 = rcy + (Math.sin(rad) * length) / 2;
10439 return { x1: x1, y1: y1, x2: x2, y2: y2 };
10440 }
10441 function computeRadialGradient(width, height, cx, cy, size) {
10442 // 'px'
10443 var x = cx.value;
10444 var y = cy.value;
10445 // TODO: 'em'
10446 // '%'
10447 if (cx.unit === UnitType.kPercentage) {
10448 x = (cx.value / 100) * width;
10449 }
10450 if (cy.unit === UnitType.kPercentage) {
10451 y = (cy.value / 100) * height;
10452 }
10453 // default to farthest-side
10454 var r = Math.max(distanceSquareRoot([0, 0], [x, y]), distanceSquareRoot([0, height], [x, y]), distanceSquareRoot([width, height], [x, y]), distanceSquareRoot([width, 0], [x, y]));
10455 if (size) {
10456 if (size instanceof CSSUnitValue) {
10457 r = size.value;
10458 }
10459 else if (size instanceof CSSKeywordValue) {
10460 // @see https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Images/Using_CSS_gradients#example_closest-side_for_circles
10461 if (size.value === 'closest-side') {
10462 r = Math.min(x, width - x, y, height - y);
10463 }
10464 else if (size.value === 'farthest-side') {
10465 r = Math.max(x, width - x, y, height - y);
10466 }
10467 else if (size.value === 'closest-corner') {
10468 r = Math.min(distanceSquareRoot([0, 0], [x, y]), distanceSquareRoot([0, height], [x, y]), distanceSquareRoot([width, height], [x, y]), distanceSquareRoot([width, 0], [x, y]));
10469 }
10470 }
10471 }
10472 return { x: x, y: y, r: r };
10473 }
10474
10475 var regexLG = /^l\s*\(\s*([\d.]+)\s*\)\s*(.*)/i;
10476 var regexRG = /^r\s*\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)\s*\)\s*(.*)/i;
10477 var regexPR = /^p\s*\(\s*([axyn])\s*\)\s*(.*)/i;
10478 var regexColorStop = /[\d.]+:(#[^\s]+|[^\)]+\))/gi;
10479 function spaceColorStops(colorStops) {
10480 var _a, _b, _c;
10481 var length = colorStops.length;
10482 colorStops[length - 1].length = (_a = colorStops[length - 1].length) !== null && _a !== void 0 ? _a : {
10483 type: '%',
10484 value: '100',
10485 };
10486 if (length > 1) {
10487 colorStops[0].length = (_b = colorStops[0].length) !== null && _b !== void 0 ? _b : {
10488 type: '%',
10489 value: '0',
10490 };
10491 }
10492 var previousIndex = 0;
10493 var previousOffset = Number(colorStops[0].length.value);
10494 for (var i = 1; i < length; i++) {
10495 // support '%' & 'px'
10496 var offset = (_c = colorStops[i].length) === null || _c === void 0 ? void 0 : _c.value;
10497 if (!isNil(offset) && !isNil(previousOffset)) {
10498 for (var j = 1; j < i - previousIndex; j++)
10499 colorStops[previousIndex + j].length = {
10500 type: '%',
10501 value: "".concat(previousOffset +
10502 ((Number(offset) - previousOffset) * j) / (i - previousIndex)),
10503 };
10504 previousIndex = i;
10505 previousOffset = Number(offset);
10506 }
10507 }
10508 }
10509 // The position of the gradient line's starting point.
10510 // different from CSS side(to top) @see https://developer.mozilla.org/en-US/docs/Web/CSS/gradient/linear-gradient#values
10511 var SideOrCornerToDegMap = {
10512 left: 270 - 90,
10513 top: 0 - 90,
10514 bottom: 180 - 90,
10515 right: 90 - 90,
10516 'left top': 315 - 90,
10517 'top left': 315 - 90,
10518 'left bottom': 225 - 90,
10519 'bottom left': 225 - 90,
10520 'right top': 45 - 90,
10521 'top right': 45 - 90,
10522 'right bottom': 135 - 90,
10523 'bottom right': 135 - 90,
10524 };
10525 var angleToDeg = memoize(function (orientation) {
10526 var angle;
10527 if (orientation.type === 'angular') {
10528 angle = Number(orientation.value);
10529 }
10530 else {
10531 angle = SideOrCornerToDegMap[orientation.value] || 0;
10532 }
10533 return getOrCreateUnitValue(angle, 'deg');
10534 });
10535 var positonToCSSUnitValue = memoize(function (position) {
10536 var cx = 50;
10537 var cy = 50;
10538 var unitX = '%';
10539 var unitY = '%';
10540 if ((position === null || position === void 0 ? void 0 : position.type) === 'position') {
10541 var _a = position.value, x = _a.x, y = _a.y;
10542 if ((x === null || x === void 0 ? void 0 : x.type) === 'position-keyword') {
10543 if (x.value === 'left') {
10544 cx = 0;
10545 }
10546 else if (x.value === 'center') {
10547 cx = 50;
10548 }
10549 else if (x.value === 'right') {
10550 cx = 100;
10551 }
10552 else if (x.value === 'top') {
10553 cy = 0;
10554 }
10555 else if (x.value === 'bottom') {
10556 cy = 100;
10557 }
10558 }
10559 if ((y === null || y === void 0 ? void 0 : y.type) === 'position-keyword') {
10560 if (y.value === 'left') {
10561 cx = 0;
10562 }
10563 else if (y.value === 'center') {
10564 cy = 50;
10565 }
10566 else if (y.value === 'right') {
10567 cx = 100;
10568 }
10569 else if (y.value === 'top') {
10570 cy = 0;
10571 }
10572 else if (y.value === 'bottom') {
10573 cy = 100;
10574 }
10575 }
10576 if ((x === null || x === void 0 ? void 0 : x.type) === 'px' || (x === null || x === void 0 ? void 0 : x.type) === '%' || (x === null || x === void 0 ? void 0 : x.type) === 'em') {
10577 unitX = x === null || x === void 0 ? void 0 : x.type;
10578 cx = Number(x.value);
10579 }
10580 if ((y === null || y === void 0 ? void 0 : y.type) === 'px' || (y === null || y === void 0 ? void 0 : y.type) === '%' || (y === null || y === void 0 ? void 0 : y.type) === 'em') {
10581 unitY = y === null || y === void 0 ? void 0 : y.type;
10582 cy = Number(y.value);
10583 }
10584 }
10585 return {
10586 cx: getOrCreateUnitValue(cx, unitX),
10587 cy: getOrCreateUnitValue(cy, unitY),
10588 };
10589 });
10590 var parseGradient = memoize(function (colorStr) {
10591 var _a;
10592 if (colorStr.indexOf('linear') > -1 || colorStr.indexOf('radial') > -1) {
10593 var ast = parseGradient$1(colorStr);
10594 return ast.map(function (_a) {
10595 var type = _a.type, orientation = _a.orientation, colorStops = _a.colorStops;
10596 spaceColorStops(colorStops);
10597 var steps = colorStops.map(function (colorStop) {
10598 // TODO: only support % for now, should calc percentage of axis length when using px/em
10599 return {
10600 offset: getOrCreateUnitValue(Number(colorStop.length.value), '%'),
10601 color: colorStopToString(colorStop),
10602 };
10603 });
10604 if (type === 'linear-gradient') {
10605 return new CSSGradientValue(GradientType.LinearGradient, {
10606 angle: orientation
10607 ? angleToDeg(orientation)
10608 : Odeg,
10609 steps: steps,
10610 });
10611 }
10612 else if (type === 'radial-gradient') {
10613 if (!orientation) {
10614 orientation = [
10615 {
10616 type: 'shape',
10617 value: 'circle',
10618 },
10619 ];
10620 }
10621 if (orientation[0].type === 'shape' &&
10622 orientation[0].value === 'circle') {
10623 var _b = positonToCSSUnitValue(orientation[0].at), cx = _b.cx, cy = _b.cy;
10624 var size = void 0;
10625 if (orientation[0].style) {
10626 var _c = orientation[0].style, type_1 = _c.type, value = _c.value;
10627 if (type_1 === 'extent-keyword') {
10628 size = getOrCreateKeyword(value);
10629 }
10630 else {
10631 size = getOrCreateUnitValue(value, type_1);
10632 }
10633 }
10634 return new CSSGradientValue(GradientType.RadialGradient, {
10635 cx: cx,
10636 cy: cy,
10637 size: size,
10638 steps: steps,
10639 });
10640 }
10641 // TODO: support ellipse shape
10642 // TODO: repeating-linear-gradient & repeating-radial-gradient
10643 // } else if (type === 'repeating-linear-gradient') {
10644 // } else if (type === 'repeating-radial-gradient') {
10645 }
10646 });
10647 }
10648 // legacy format, should be deprecated later
10649 var type = colorStr[0];
10650 if (colorStr[1] === '(' || colorStr[2] === '(') {
10651 if (type === 'l') {
10652 var arr = regexLG.exec(colorStr);
10653 if (arr) {
10654 var steps = ((_a = arr[2].match(regexColorStop)) === null || _a === void 0 ? void 0 : _a.map(function (stop) { return stop.split(':'); })) || [];
10655 return [
10656 new CSSGradientValue(GradientType.LinearGradient, {
10657 angle: getOrCreateUnitValue(parseFloat(arr[1]), 'deg'),
10658 steps: steps.map(function (_a) {
10659 var _b = __read(_a, 2), offset = _b[0], color = _b[1];
10660 return ({
10661 offset: getOrCreateUnitValue(Number(offset) * 100, '%'),
10662 color: color,
10663 });
10664 }),
10665 }),
10666 ];
10667 }
10668 }
10669 else if (type === 'r') {
10670 var parsedRadialGradient = parseRadialGradient(colorStr);
10671 if (parsedRadialGradient) {
10672 if (isString(parsedRadialGradient)) {
10673 colorStr = parsedRadialGradient;
10674 }
10675 else {
10676 return [
10677 new CSSGradientValue(GradientType.RadialGradient, parsedRadialGradient),
10678 ];
10679 }
10680 }
10681 }
10682 else if (type === 'p') {
10683 return parsePattern(colorStr);
10684 }
10685 }
10686 });
10687 function parseRadialGradient(gradientStr) {
10688 var _a;
10689 var arr = regexRG.exec(gradientStr);
10690 if (arr) {
10691 var steps = ((_a = arr[4].match(regexColorStop)) === null || _a === void 0 ? void 0 : _a.map(function (stop) { return stop.split(':'); })) || [];
10692 return {
10693 cx: getOrCreateUnitValue(50, '%'),
10694 cy: getOrCreateUnitValue(50, '%'),
10695 steps: steps.map(function (_a) {
10696 var _b = __read(_a, 2), offset = _b[0], color = _b[1];
10697 return ({
10698 offset: getOrCreateUnitValue(Number(offset) * 100, '%'),
10699 color: color,
10700 });
10701 }),
10702 };
10703 }
10704 return null;
10705 }
10706 function parsePattern(patternStr) {
10707 var arr = regexPR.exec(patternStr);
10708 if (arr) {
10709 var repetition = arr[1];
10710 var src = arr[2];
10711 switch (repetition) {
10712 case 'a':
10713 repetition = 'repeat';
10714 break;
10715 case 'x':
10716 repetition = 'repeat-x';
10717 break;
10718 case 'y':
10719 repetition = 'repeat-y';
10720 break;
10721 case 'n':
10722 repetition = 'no-repeat';
10723 break;
10724 default:
10725 repetition = 'no-repeat';
10726 }
10727 return {
10728 image: src,
10729 // @ts-ignore
10730 repetition: repetition,
10731 };
10732 }
10733 return null;
10734 }
10735 function isPattern(object) {
10736 return object && !!object.image;
10737 }
10738 function isCSSRGB(object) {
10739 return (object &&
10740 !isNil(object.r) &&
10741 !isNil(object.g) &&
10742 !isNil(object.b));
10743 }
10744 /**
10745 * @see https://github.com/WebKit/WebKit/blob/main/Source/WebCore/css/parser/CSSParser.cpp#L97
10746 */
10747 var parseColor = memoize(function (colorStr) {
10748 if (isPattern(colorStr)) {
10749 return __assign({ repetition: 'repeat' }, colorStr);
10750 }
10751 if (isNil(colorStr)) {
10752 colorStr = '';
10753 }
10754 if (colorStr === 'transparent') {
10755 // transparent black
10756 return transparentColor;
10757 }
10758 else if (colorStr === 'currentColor') {
10759 // @see https://github.com/adobe-webplatform/Snap.svg/issues/526
10760 colorStr = 'black';
10761 }
10762 // support CSS gradient syntax
10763 var g = parseGradient(colorStr);
10764 if (g) {
10765 return g;
10766 }
10767 // constants
10768 var color$1 = color(colorStr);
10769 var rgba = [0, 0, 0, 0];
10770 if (color$1 !== null) {
10771 rgba[0] = color$1.r || 0;
10772 rgba[1] = color$1.g || 0;
10773 rgba[2] = color$1.b || 0;
10774 rgba[3] = color$1.opacity;
10775 }
10776 // return new CSSRGB(...rgba);
10777 return getOrCreateRGBA.apply(void 0, __spreadArray([], __read(rgba), false));
10778 });
10779 function mergeColors(left, right) {
10780 // only support constant value, exclude gradient & pattern
10781 if (!isCSSRGB(left) || !isCSSRGB(right)) {
10782 return;
10783 }
10784 return [
10785 [Number(left.r), Number(left.g), Number(left.b), Number(left.alpha)],
10786 [Number(right.r), Number(right.g), Number(right.b), Number(right.alpha)],
10787 function (color) {
10788 var rgba = color.slice();
10789 if (rgba[3]) {
10790 for (var i = 0; i < 3; i++)
10791 rgba[i] = Math.round(clamp(rgba[i], 0, 255));
10792 }
10793 rgba[3] = clamp(rgba[3], 0, 1);
10794 return "rgba(".concat(rgba.join(','), ")");
10795 },
10796 ];
10797 }
10798
10799 function parseDimension(unitRegExp, string) {
10800 if (isNil(string)) {
10801 return getOrCreateUnitValue(0, 'px');
10802 }
10803 string = "".concat(string).trim().toLowerCase();
10804 if (isFinite(Number(string))) {
10805 if ('px'.search(unitRegExp) >= 0) {
10806 return getOrCreateUnitValue(Number(string), 'px');
10807 }
10808 else if ('deg'.search(unitRegExp) >= 0) {
10809 return getOrCreateUnitValue(Number(string), 'deg');
10810 }
10811 }
10812 var matchedUnits = [];
10813 string = string.replace(unitRegExp, function (match) {
10814 matchedUnits.push(match);
10815 return 'U' + match;
10816 });
10817 var taggedUnitRegExp = 'U(' + unitRegExp.source + ')';
10818 return matchedUnits.map(function (unit) {
10819 return getOrCreateUnitValue(Number(string
10820 .replace(new RegExp('U' + unit, 'g'), '')
10821 .replace(new RegExp(taggedUnitRegExp, 'g'), '*0')), unit);
10822 })[0];
10823 }
10824 /**
10825 * <length>
10826 * @see https://developer.mozilla.org/zh-CN/docs/Web/CSS/length
10827 * length with only absolute unit, eg. 1px
10828 */
10829 var parseLengthUnmemoize = function (css) {
10830 return parseDimension(new RegExp('px', 'g'), css);
10831 };
10832 var parseLength = memoize(parseLengthUnmemoize);
10833 /**
10834 * <percentage>
10835 * @see https://developer.mozilla.org/zh-CN/docs/Web/CSS/percentage
10836 */
10837 var parserPercentageUnmemoize = function (css) {
10838 return parseDimension(new RegExp('%', 'g'), css);
10839 };
10840 memoize(parserPercentageUnmemoize);
10841 /**
10842 * length with absolute or relative unit,
10843 * eg. 1px, 0.7em, 50%, calc(100% - 200px);
10844 *
10845 * @see https://developer.mozilla.org/zh-CN/docs/Web/CSS/length-percentage
10846 */
10847 var parseLengthOrPercentageUnmemoize = function (css) {
10848 if (isNumber(css) || isFinite(Number(css))) {
10849 // Number(css) is NaN
10850 return getOrCreateUnitValue(Number(css) || 0, 'px');
10851 // return Number(css);
10852 }
10853 return parseDimension(new RegExp('px|%|em|rem', 'g'), css);
10854 };
10855 var parseLengthOrPercentage = memoize(parseLengthOrPercentageUnmemoize);
10856 var parseAngleUnmemoize = function (css) {
10857 return parseDimension(new RegExp('deg|rad|grad|turn', 'g'), css);
10858 };
10859 var parseAngle = memoize(parseAngleUnmemoize);
10860 /**
10861 * merge CSSUnitValue
10862 *
10863 * @example
10864 * 10px + 20px = 30px
10865 * 10deg + 10rad
10866 * 10% + 20% = 30%
10867 */
10868 function mergeDimensions(left, right, target, nonNegative, index) {
10869 if (index === void 0) { index = 0; }
10870 var unit = '';
10871 var leftValue = left.value || 0;
10872 var rightValue = right.value || 0;
10873 var canonicalUnit = toCanonicalUnit(left.unit);
10874 var leftCanonicalUnitValue = left.convertTo(canonicalUnit);
10875 var rightCanonicalUnitValue = right.convertTo(canonicalUnit);
10876 if (leftCanonicalUnitValue && rightCanonicalUnitValue) {
10877 leftValue = leftCanonicalUnitValue.value;
10878 rightValue = rightCanonicalUnitValue.value;
10879 unit = unitTypeToString(left.unit);
10880 }
10881 else {
10882 // format '%' to 'px'
10883 if (CSSUnitValue.isLength(left.unit) || CSSUnitValue.isLength(right.unit)) {
10884 leftValue = convertPercentUnit(left, index, target);
10885 rightValue = convertPercentUnit(right, index, target);
10886 unit = 'px';
10887 }
10888 }
10889 // // format 'rad' 'turn' to 'deg'
10890 // if (CSSUnitValue.isAngle(left.unit) || CSSUnitValue.isAngle(right.unit)) {
10891 // leftValue = convertAngleUnit(left);
10892 // rightValue = convertAngleUnit(right);
10893 // unit = 'deg';
10894 // }
10895 return [
10896 leftValue,
10897 rightValue,
10898 function (value) {
10899 if (nonNegative) {
10900 value = Math.max(value, 0);
10901 }
10902 return value + unit;
10903 },
10904 ];
10905 }
10906 function convertAngleUnit(value) {
10907 var deg = 0;
10908 if (value.unit === UnitType.kDegrees) {
10909 deg = value.value;
10910 }
10911 else if (value.unit === UnitType.kRadians) {
10912 deg = rad2deg(Number(value.value));
10913 }
10914 else if (value.unit === UnitType.kTurns) {
10915 deg = turn2deg(Number(value.value));
10916 }
10917 return deg;
10918 }
10919 function parseDimensionArrayFormat(string, size) {
10920 var parsed;
10921 if (Array.isArray(string)) {
10922 // [1, '2px', 3]
10923 parsed = string.map(function (segment) { return Number(segment); });
10924 }
10925 else if (isString(string)) {
10926 parsed = string.split(' ').map(function (segment) { return Number(segment); });
10927 }
10928 else if (isNumber(string)) {
10929 parsed = [string];
10930 }
10931 if (size === 2) {
10932 if (parsed.length === 1) {
10933 return [parsed[0], parsed[0]];
10934 }
10935 else {
10936 return [parsed[0], parsed[1]];
10937 }
10938 }
10939 else {
10940 if (parsed.length === 1) {
10941 return [parsed[0], parsed[0], parsed[0], parsed[0]];
10942 }
10943 else if (parsed.length === 2) {
10944 return [parsed[0], parsed[1], parsed[0], parsed[1]];
10945 }
10946 else if (parsed.length === 3) {
10947 return [parsed[0], parsed[1], parsed[2], parsed[1]];
10948 }
10949 else {
10950 return [parsed[0], parsed[1], parsed[2], parsed[3]];
10951 }
10952 }
10953 }
10954 function parseDimensionArray(string) {
10955 if (isString(string)) {
10956 // "1px 2px 3px"
10957 return string.split(' ').map(function (segment) { return parseLengthOrPercentage(segment); });
10958 }
10959 else {
10960 // [1, '2px', 3]
10961 return string.map(function (segment) { return parseLengthOrPercentage(segment.toString()); });
10962 }
10963 }
10964 // export function mergeDimensionList(
10965 // left: CSSUnitValue[],
10966 // right: CSSUnitValue[],
10967 // target: IElement | null,
10968 // ): [number[], number[], (list: number[]) => string] | undefined {
10969 // if (left.length !== right.length) {
10970 // return;
10971 // }
10972 // const unit = left[0].unit;
10973 // return [
10974 // left.map((l) => l.value),
10975 // right.map((l) => l.value),
10976 // (values: number[]) => {
10977 // return values.map((n) => new CSSUnitValue(n, unit)).join(' ');
10978 // },
10979 // ];
10980 // }
10981 function convertPercentUnit(valueWithUnit, vec3Index, target) {
10982 if (valueWithUnit.value === 0) {
10983 return 0;
10984 }
10985 if (valueWithUnit.unit === UnitType.kPixels) {
10986 return Number(valueWithUnit.value);
10987 }
10988 else if (valueWithUnit.unit === UnitType.kPercentage && target) {
10989 var bounds = target.nodeName === Shape.GROUP
10990 ? target.getLocalBounds()
10991 : // : target.getGeometryBounds();
10992 target.geometry.contentBounds;
10993 return (valueWithUnit.value / 100) * bounds.halfExtents[vec3Index] * 2;
10994 }
10995 return 0;
10996 }
10997
10998 var parseParam = function (css) {
10999 return parseDimension(/deg|rad|grad|turn|px|%/g, css);
11000 };
11001 var supportedFilters = [
11002 'blur',
11003 'brightness',
11004 'drop-shadow',
11005 'contrast',
11006 'grayscale',
11007 'sepia',
11008 'saturate',
11009 'hue-rotate',
11010 'invert',
11011 ];
11012 function parseFilter(filterStr) {
11013 if (filterStr === void 0) { filterStr = ''; }
11014 filterStr = filterStr.toLowerCase().trim();
11015 if (filterStr === 'none') {
11016 return [];
11017 }
11018 var filterRegExp = /\s*([\w-]+)\(([^)]*)\)/g;
11019 var result = [];
11020 var match;
11021 var prevLastIndex = 0;
11022 while ((match = filterRegExp.exec(filterStr))) {
11023 if (match.index !== prevLastIndex) {
11024 return [];
11025 }
11026 prevLastIndex = match.index + match[0].length;
11027 if (supportedFilters.indexOf(match[1]) > -1) {
11028 result.push({
11029 name: match[1],
11030 params: match[2].split(' ').map(function (p) { return parseParam(p) || parseColor(p); }),
11031 });
11032 }
11033 if (filterRegExp.lastIndex === filterStr.length) {
11034 return result;
11035 }
11036 }
11037 return [];
11038 }
11039
11040 function numberToString(x) {
11041 // scale(0.00000001) -> scale(0)
11042 // return x.toFixed(6).replace(/0+$/, '').replace(/\.$/, '');
11043 return x.toString();
11044 }
11045 /**
11046 * parse string or number to CSSUnitValue(numeric)
11047 *
11048 * eg.
11049 * * 0 -> CSSUnitValue(0)
11050 * * '2' -> CSSUnitValue(2)
11051 */
11052 var parseNumberUnmemoize = function (string) {
11053 if (typeof string === 'number') {
11054 return getOrCreateUnitValue(string);
11055 }
11056 if (/^\s*[-+]?(\d*\.)?\d+\s*$/.test(string)) {
11057 return getOrCreateUnitValue(Number(string));
11058 }
11059 else {
11060 return getOrCreateUnitValue(0);
11061 }
11062 };
11063 var parseNumber = memoize(parseNumberUnmemoize);
11064 memoize(function (string) {
11065 if (isString(string)) {
11066 return string.split(' ').map(parseNumber);
11067 }
11068 else {
11069 return string.map(parseNumber);
11070 }
11071 });
11072 function mergeNumbers(left, right) {
11073 return [left, right, numberToString];
11074 }
11075 function clampedMergeNumbers(min, max) {
11076 return function (left, right) { return [
11077 left,
11078 right,
11079 function (x) { return numberToString(clamp(x, min, max)); },
11080 ]; };
11081 }
11082 function mergeNumberLists(left, right) {
11083 if (left.length !== right.length) {
11084 return;
11085 }
11086 return [
11087 left,
11088 right,
11089 function (numberList) {
11090 return numberList;
11091 },
11092 ];
11093 }
11094
11095 function getOrCalculatePathTotalLength(path) {
11096 if (path.parsedStyle.path.totalLength === 0) {
11097 path.parsedStyle.path.totalLength = getTotalLength(path.parsedStyle.path.absolutePath);
11098 }
11099 return path.parsedStyle.path.totalLength;
11100 }
11101 function removeRedundantMCommand(path) {
11102 for (var i = 0; i < path.length; i++) {
11103 var prevSegment = path[i - 1];
11104 var segment = path[i];
11105 var cmd = segment[0];
11106 if (cmd === 'M') {
11107 if (prevSegment) {
11108 var prevCmd = prevSegment[0];
11109 var srcPoint = [segment[1], segment[2]];
11110 var destPoint = void 0;
11111 if (prevCmd === 'L' || prevCmd === 'M') {
11112 destPoint = [prevSegment[1], prevSegment[2]];
11113 }
11114 else if (prevCmd === 'C' || prevCmd === 'A' || prevCmd === 'Q') {
11115 destPoint = [
11116 prevSegment[prevSegment.length - 2],
11117 prevSegment[prevSegment.length - 1],
11118 ];
11119 }
11120 if (destPoint && isSamePoint(srcPoint, destPoint)) {
11121 path.splice(i, 1);
11122 i--;
11123 }
11124 }
11125 }
11126 }
11127 }
11128 function hasArcOrBezier(path) {
11129 var hasArc = false;
11130 var count = path.length;
11131 for (var i = 0; i < count; i++) {
11132 var params = path[i];
11133 var cmd = params[0];
11134 if (cmd === 'C' || cmd === 'A' || cmd === 'Q') {
11135 hasArc = true;
11136 break;
11137 }
11138 }
11139 return hasArc;
11140 }
11141 function extractPolygons(pathArray) {
11142 var polygons = [];
11143 var polylines = [];
11144 var points = []; // 防止第一个命令不是 'M'
11145 for (var i = 0; i < pathArray.length; i++) {
11146 var params = pathArray[i];
11147 var cmd = params[0];
11148 if (cmd === 'M') {
11149 // 遇到 'M' 判定是否是新数组,新数组中没有点
11150 if (points.length) {
11151 // 如果存在点,则说明没有遇到 'Z',开始了一个新的多边形
11152 polylines.push(points);
11153 points = []; // 创建新的点
11154 }
11155 points.push([params[1], params[2]]);
11156 }
11157 else if (cmd === 'Z') {
11158 if (points.length) {
11159 // 存在点
11160 polygons.push(points);
11161 points = []; // 开始新的点集合
11162 }
11163 // 如果不存在点,同时 'Z',则说明是错误,不处理
11164 }
11165 else {
11166 points.push([params[1], params[2]]);
11167 }
11168 }
11169 // 说明 points 未放入 polygons 或者 polyline
11170 // 仅当只有一个 M,没有 Z 时会发生这种情况
11171 if (points.length > 0) {
11172 polylines.push(points);
11173 }
11174 return {
11175 polygons: polygons,
11176 polylines: polylines,
11177 };
11178 }
11179 function isSamePoint(point1, point2) {
11180 return point1[0] === point2[0] && point1[1] === point2[1];
11181 }
11182 function getPathBBox(segments, lineWidth) {
11183 var xArr = [];
11184 var yArr = [];
11185 var segmentsWithAngle = [];
11186 for (var i = 0; i < segments.length; i++) {
11187 var segment = segments[i];
11188 var currentPoint = segment.currentPoint, params = segment.params, prePoint = segment.prePoint;
11189 var box$1 = void 0;
11190 switch (segment.command) {
11191 case 'Q':
11192 box$1 = box(prePoint[0], prePoint[1], params[1], params[2], params[3], params[4]);
11193 break;
11194 case 'C':
11195 box$1 = box$3(prePoint[0], prePoint[1], params[1], params[2], params[3], params[4], params[5], params[6]);
11196 break;
11197 case 'A':
11198 var arcParams = segment.arcParams;
11199 box$1 = box$5(arcParams.cx, arcParams.cy, arcParams.rx, arcParams.ry, arcParams.xRotation, arcParams.startAngle, arcParams.endAngle);
11200 break;
11201 default:
11202 xArr.push(currentPoint[0]);
11203 yArr.push(currentPoint[1]);
11204 break;
11205 }
11206 if (box$1) {
11207 segment.box = box$1;
11208 xArr.push(box$1.x, box$1.x + box$1.width);
11209 yArr.push(box$1.y, box$1.y + box$1.height);
11210 }
11211 if (lineWidth &&
11212 (segment.command === 'L' || segment.command === 'M') &&
11213 segment.prePoint &&
11214 segment.nextPoint) {
11215 segmentsWithAngle.push(segment);
11216 }
11217 }
11218 // bbox calculation should ignore NaN for path attribute
11219 // ref: https://github.com/antvis/g/issues/210
11220 // ref: https://github.com/antvis/G2/issues/3109
11221 xArr = xArr.filter(function (item) { return !Number.isNaN(item) && item !== Infinity && item !== -Infinity; });
11222 yArr = yArr.filter(function (item) { return !Number.isNaN(item) && item !== Infinity && item !== -Infinity; });
11223 var minX = min(xArr);
11224 var minY = min(yArr);
11225 var maxX = max(xArr);
11226 var maxY = max(yArr);
11227 if (segmentsWithAngle.length === 0) {
11228 return {
11229 x: minX,
11230 y: minY,
11231 width: maxX - minX,
11232 height: maxY - minY,
11233 };
11234 }
11235 for (var i = 0; i < segmentsWithAngle.length; i++) {
11236 var segment = segmentsWithAngle[i];
11237 var currentPoint = segment.currentPoint;
11238 var extra = void 0;
11239 if (currentPoint[0] === minX) {
11240 extra = getExtraFromSegmentWithAngle(segment, lineWidth);
11241 minX = minX - extra.xExtra;
11242 }
11243 else if (currentPoint[0] === maxX) {
11244 extra = getExtraFromSegmentWithAngle(segment, lineWidth);
11245 maxX = maxX + extra.xExtra;
11246 }
11247 if (currentPoint[1] === minY) {
11248 extra = getExtraFromSegmentWithAngle(segment, lineWidth);
11249 minY = minY - extra.yExtra;
11250 }
11251 else if (currentPoint[1] === maxY) {
11252 extra = getExtraFromSegmentWithAngle(segment, lineWidth);
11253 maxY = maxY + extra.yExtra;
11254 }
11255 }
11256 return {
11257 x: minX,
11258 y: minY,
11259 width: maxX - minX,
11260 height: maxY - minY,
11261 };
11262 }
11263 function getExtraFromSegmentWithAngle(segment, lineWidth) {
11264 var prePoint = segment.prePoint, currentPoint = segment.currentPoint, nextPoint = segment.nextPoint;
11265 var currentAndPre = Math.pow(currentPoint[0] - prePoint[0], 2) +
11266 Math.pow(currentPoint[1] - prePoint[1], 2);
11267 var currentAndNext = Math.pow(currentPoint[0] - nextPoint[0], 2) +
11268 Math.pow(currentPoint[1] - nextPoint[1], 2);
11269 var preAndNext = Math.pow(prePoint[0] - nextPoint[0], 2) +
11270 Math.pow(prePoint[1] - nextPoint[1], 2);
11271 // 以 currentPoint 为顶点的夹角
11272 var currentAngle = Math.acos((currentAndPre + currentAndNext - preAndNext) /
11273 (2 * Math.sqrt(currentAndPre) * Math.sqrt(currentAndNext)));
11274 // 夹角为空、 0 或 PI 时,不需要计算夹角处的额外宽度
11275 // 注意: 由于计算精度问题,夹角为 0 的情况计算出来的角度可能是一个很小的值,还需要判断其与 0 是否近似相等
11276 if (!currentAngle ||
11277 Math.sin(currentAngle) === 0 ||
11278 isNumberEqual(currentAngle, 0)) {
11279 return {
11280 xExtra: 0,
11281 yExtra: 0,
11282 };
11283 }
11284 var xAngle = Math.abs(Math.atan2(nextPoint[1] - currentPoint[1], nextPoint[0] - currentPoint[0]));
11285 var yAngle = Math.abs(Math.atan2(nextPoint[0] - currentPoint[0], nextPoint[1] - currentPoint[1]));
11286 // 将夹角转为锐角
11287 xAngle = xAngle > Math.PI / 2 ? Math.PI - xAngle : xAngle;
11288 yAngle = yAngle > Math.PI / 2 ? Math.PI - yAngle : yAngle;
11289 // 这里不考虑在水平和垂直方向的投影,直接使用最大差值
11290 // 由于上层统一加减了二分之一线宽,这里需要进行弥补
11291 var extra = {
11292 // 水平方向投影
11293 xExtra: Math.cos(currentAngle / 2 - xAngle) *
11294 ((lineWidth / 2) * (1 / Math.sin(currentAngle / 2))) -
11295 lineWidth / 2 || 0,
11296 // 垂直方向投影
11297 yExtra: Math.cos(yAngle - currentAngle / 2) *
11298 ((lineWidth / 2) * (1 / Math.sin(currentAngle / 2))) -
11299 lineWidth / 2 || 0,
11300 };
11301 return extra;
11302 }
11303 // 点对称
11304 function toSymmetry(point, center) {
11305 return [
11306 center[0] + (center[0] - point[0]),
11307 center[1] + (center[1] - point[1]),
11308 ];
11309 }
11310 var angleBetween$1 = function (v0, v1) {
11311 var p = v0.x * v1.x + v0.y * v1.y;
11312 var n = Math.sqrt((Math.pow(v0.x, 2) + Math.pow(v0.y, 2)) *
11313 (Math.pow(v1.x, 2) + Math.pow(v1.y, 2)));
11314 var sign = v0.x * v1.y - v0.y * v1.x < 0 ? -1 : 1;
11315 var angle = sign * Math.acos(p / n);
11316 return angle;
11317 };
11318 /**
11319 * @see https://github.com/rveciana/svg-path-properties/blob/b6bd9a322966f6ef7a311872d80c56e3718de861/src/arc.ts#L121
11320 */
11321 var pointOnEllipticalArc = function (p0, rx, ry, xAxisRotation, largeArcFlag, sweepFlag, p1, t) {
11322 // In accordance to: http://www.w3.org/TR/SVG/implnote.html#ArcOutOfRangeParameters
11323 rx = Math.abs(rx);
11324 ry = Math.abs(ry);
11325 xAxisRotation = mod(xAxisRotation, 360);
11326 var xAxisRotationRadians = deg2rad(xAxisRotation);
11327 // If the endpoints are identical, then this is equivalent to omitting the elliptical arc segment entirely.
11328 if (p0.x === p1.x && p0.y === p1.y) {
11329 return { x: p0.x, y: p0.y, ellipticalArcAngle: 0 }; // Check if angle is correct
11330 }
11331 // If rx = 0 or ry = 0 then this arc is treated as a straight line segment joining the endpoints.
11332 if (rx === 0 || ry === 0) {
11333 //return this.pointOnLine(p0, p1, t);
11334 return { x: 0, y: 0, ellipticalArcAngle: 0 }; // Check if angle is correct
11335 }
11336 // Following "Conversion from endpoint to center parameterization"
11337 // http://www.w3.org/TR/SVG/implnote.html#ArcConversionEndpointToCenter
11338 // Step #1: Compute transformedPoint
11339 var dx = (p0.x - p1.x) / 2;
11340 var dy = (p0.y - p1.y) / 2;
11341 var transformedPoint = {
11342 x: Math.cos(xAxisRotationRadians) * dx + Math.sin(xAxisRotationRadians) * dy,
11343 y: -Math.sin(xAxisRotationRadians) * dx +
11344 Math.cos(xAxisRotationRadians) * dy,
11345 };
11346 // Ensure radii are large enough
11347 var radiiCheck = Math.pow(transformedPoint.x, 2) / Math.pow(rx, 2) +
11348 Math.pow(transformedPoint.y, 2) / Math.pow(ry, 2);
11349 if (radiiCheck > 1) {
11350 rx = Math.sqrt(radiiCheck) * rx;
11351 ry = Math.sqrt(radiiCheck) * ry;
11352 }
11353 // Step #2: Compute transformedCenter
11354 var cSquareNumerator = Math.pow(rx, 2) * Math.pow(ry, 2) -
11355 Math.pow(rx, 2) * Math.pow(transformedPoint.y, 2) -
11356 Math.pow(ry, 2) * Math.pow(transformedPoint.x, 2);
11357 var cSquareRootDenom = Math.pow(rx, 2) * Math.pow(transformedPoint.y, 2) +
11358 Math.pow(ry, 2) * Math.pow(transformedPoint.x, 2);
11359 var cRadicand = cSquareNumerator / cSquareRootDenom;
11360 // Make sure this never drops below zero because of precision
11361 cRadicand = cRadicand < 0 ? 0 : cRadicand;
11362 var cCoef = (largeArcFlag !== sweepFlag ? 1 : -1) * Math.sqrt(cRadicand);
11363 var transformedCenter = {
11364 x: cCoef * ((rx * transformedPoint.y) / ry),
11365 y: cCoef * (-(ry * transformedPoint.x) / rx),
11366 };
11367 // Step #3: Compute center
11368 var center = {
11369 x: Math.cos(xAxisRotationRadians) * transformedCenter.x -
11370 Math.sin(xAxisRotationRadians) * transformedCenter.y +
11371 (p0.x + p1.x) / 2,
11372 y: Math.sin(xAxisRotationRadians) * transformedCenter.x +
11373 Math.cos(xAxisRotationRadians) * transformedCenter.y +
11374 (p0.y + p1.y) / 2,
11375 };
11376 // Step #4: Compute start/sweep angles
11377 // Start angle of the elliptical arc prior to the stretch and rotate operations.
11378 // Difference between the start and end angles
11379 var startVector = {
11380 x: (transformedPoint.x - transformedCenter.x) / rx,
11381 y: (transformedPoint.y - transformedCenter.y) / ry,
11382 };
11383 var startAngle = angleBetween$1({
11384 x: 1,
11385 y: 0,
11386 }, startVector);
11387 var endVector = {
11388 x: (-transformedPoint.x - transformedCenter.x) / rx,
11389 y: (-transformedPoint.y - transformedCenter.y) / ry,
11390 };
11391 var sweepAngle = angleBetween$1(startVector, endVector);
11392 if (!sweepFlag && sweepAngle > 0) {
11393 sweepAngle -= 2 * Math.PI;
11394 }
11395 else if (sweepFlag && sweepAngle < 0) {
11396 sweepAngle += 2 * Math.PI;
11397 }
11398 // We use % instead of `mod(..)` because we want it to be -360deg to 360deg(but actually in radians)
11399 sweepAngle %= 2 * Math.PI;
11400 // From http://www.w3.org/TR/SVG/implnote.html#ArcParameterizationAlternatives
11401 var angle = startAngle + sweepAngle * t;
11402 var ellipseComponentX = rx * Math.cos(angle);
11403 var ellipseComponentY = ry * Math.sin(angle);
11404 var point = {
11405 x: Math.cos(xAxisRotationRadians) * ellipseComponentX -
11406 Math.sin(xAxisRotationRadians) * ellipseComponentY +
11407 center.x,
11408 y: Math.sin(xAxisRotationRadians) * ellipseComponentX +
11409 Math.cos(xAxisRotationRadians) * ellipseComponentY +
11410 center.y,
11411 ellipticalArcStartAngle: startAngle,
11412 ellipticalArcEndAngle: startAngle + sweepAngle,
11413 ellipticalArcAngle: angle,
11414 ellipticalArcCenter: center,
11415 resultantRx: rx,
11416 resultantRy: ry,
11417 };
11418 return point;
11419 };
11420 function path2Segments(path) {
11421 var segments = [];
11422 var currentPoint = null; // 当前图形
11423 var nextParams = null; // 下一节点的 path 参数
11424 var startMovePoint = null; // 开始 M 的点,可能会有多个
11425 var lastStartMovePointIndex = 0; // 最近一个开始点 M 的索引
11426 var count = path.length;
11427 for (var i = 0; i < count; i++) {
11428 var params = path[i];
11429 nextParams = path[i + 1];
11430 var command = params[0];
11431 // 数学定义上的参数,便于后面的计算
11432 var segment = {
11433 command: command,
11434 prePoint: currentPoint,
11435 params: params,
11436 startTangent: null,
11437 endTangent: null,
11438 currentPoint: null,
11439 nextPoint: null,
11440 arcParams: null,
11441 box: null,
11442 cubicParams: null,
11443 };
11444 switch (command) {
11445 case 'M':
11446 startMovePoint = [params[1], params[2]];
11447 lastStartMovePointIndex = i;
11448 break;
11449 case 'A':
11450 var arcParams = getArcParams(currentPoint, params);
11451 segment.arcParams = arcParams;
11452 break;
11453 }
11454 if (command === 'Z') {
11455 // 有了 Z 后,当前节点从开始 M 的点开始
11456 currentPoint = startMovePoint;
11457 // 如果当前点的命令为 Z,相当于当前点为最近一个 M 点,则下一个点直接指向最近一个 M 点的下一个点
11458 nextParams = path[lastStartMovePointIndex + 1];
11459 }
11460 else {
11461 var len = params.length;
11462 currentPoint = [params[len - 2], params[len - 1]];
11463 }
11464 if (nextParams && nextParams[0] === 'Z') {
11465 // 如果下一个点的命令为 Z,则下一个点直接指向最近一个 M 点
11466 nextParams = path[lastStartMovePointIndex];
11467 if (segments[lastStartMovePointIndex]) {
11468 // 如果下一个点的命令为 Z,则最近一个 M 点的前一个点为当前点
11469 segments[lastStartMovePointIndex].prePoint = currentPoint;
11470 }
11471 }
11472 segment.currentPoint = currentPoint;
11473 // 如果当前点与最近一个 M 点相同,则最近一个 M 点的前一个点为当前点的前一个点
11474 if (segments[lastStartMovePointIndex] &&
11475 isSamePoint(currentPoint, segments[lastStartMovePointIndex].currentPoint)) {
11476 segments[lastStartMovePointIndex].prePoint = segment.prePoint;
11477 }
11478 var nextPoint = nextParams
11479 ? [nextParams[nextParams.length - 2], nextParams[nextParams.length - 1]]
11480 : null;
11481 segment.nextPoint = nextPoint;
11482 // Add startTangent and endTangent
11483 var prePoint = segment.prePoint;
11484 if (['L', 'H', 'V'].includes(command)) {
11485 segment.startTangent = [
11486 prePoint[0] - currentPoint[0],
11487 prePoint[1] - currentPoint[1],
11488 ];
11489 segment.endTangent = [
11490 currentPoint[0] - prePoint[0],
11491 currentPoint[1] - prePoint[1],
11492 ];
11493 }
11494 else if (command === 'Q') {
11495 // 二次贝塞尔曲线只有一个控制点
11496 var cp = [params[1], params[2]];
11497 // 二次贝塞尔曲线的终点为 currentPoint
11498 segment.startTangent = [prePoint[0] - cp[0], prePoint[1] - cp[1]];
11499 segment.endTangent = [currentPoint[0] - cp[0], currentPoint[1] - cp[1]];
11500 }
11501 else if (command === 'T') {
11502 var preSegment = segments[i - 1];
11503 var cp = toSymmetry(preSegment.currentPoint, prePoint);
11504 if (preSegment.command === 'Q') {
11505 segment.command = 'Q';
11506 segment.startTangent = [prePoint[0] - cp[0], prePoint[1] - cp[1]];
11507 segment.endTangent = [currentPoint[0] - cp[0], currentPoint[1] - cp[1]];
11508 }
11509 else {
11510 // @ts-ignore
11511 segment.command = 'TL';
11512 segment.startTangent = [
11513 prePoint[0] - currentPoint[0],
11514 prePoint[1] - currentPoint[1],
11515 ];
11516 segment.endTangent = [
11517 currentPoint[0] - prePoint[0],
11518 currentPoint[1] - prePoint[1],
11519 ];
11520 }
11521 }
11522 else if (command === 'C') {
11523 // 三次贝塞尔曲线有两个控制点
11524 var cp1 = [params[1], params[2]];
11525 var cp2 = [params[3], params[4]];
11526 segment.startTangent = [prePoint[0] - cp1[0], prePoint[1] - cp1[1]];
11527 segment.endTangent = [currentPoint[0] - cp2[0], currentPoint[1] - cp2[1]];
11528 // horizontal line, eg. ['C', 100, 100, 100, 100, 200, 200]
11529 if (segment.startTangent[0] === 0 && segment.startTangent[1] === 0) {
11530 segment.startTangent = [cp1[0] - cp2[0], cp1[1] - cp2[1]];
11531 }
11532 if (segment.endTangent[0] === 0 && segment.endTangent[1] === 0) {
11533 segment.endTangent = [cp2[0] - cp1[0], cp2[1] - cp1[1]];
11534 }
11535 }
11536 else if (command === 'S') {
11537 var preSegment = segments[i - 1];
11538 var cp1 = toSymmetry(preSegment.currentPoint, prePoint);
11539 var cp2 = [params[1], params[2]];
11540 if (preSegment.command === 'C') {
11541 segment.command = 'C'; // 将 S 命令变换为 C 命令
11542 segment.startTangent = [prePoint[0] - cp1[0], prePoint[1] - cp1[1]];
11543 segment.endTangent = [
11544 currentPoint[0] - cp2[0],
11545 currentPoint[1] - cp2[1],
11546 ];
11547 }
11548 else {
11549 // @ts-ignore
11550 segment.command = 'SQ'; // 将 S 命令变换为 SQ 命令
11551 segment.startTangent = [prePoint[0] - cp2[0], prePoint[1] - cp2[1]];
11552 segment.endTangent = [
11553 currentPoint[0] - cp2[0],
11554 currentPoint[1] - cp2[1],
11555 ];
11556 }
11557 }
11558 else if (command === 'A') {
11559 var _a = getTangentAtRatio(segment, 0), dx1 = _a.x, dy1 = _a.y;
11560 var _b = getTangentAtRatio(segment, 1, false), dx2 = _b.x, dy2 = _b.y;
11561 segment.startTangent = [dx1, dy1];
11562 segment.endTangent = [dx2, dy2];
11563 }
11564 segments.push(segment);
11565 }
11566 return segments;
11567 }
11568 /**
11569 * Use length instead of ratio
11570 */
11571 function getTangentAtRatio(segment, ratio, sign) {
11572 if (sign === void 0) { sign = true; }
11573 var _a = segment.arcParams, _b = _a.rx, rx = _b === void 0 ? 0 : _b, _c = _a.ry, ry = _c === void 0 ? 0 : _c, xRotation = _a.xRotation, arcFlag = _a.arcFlag, sweepFlag = _a.sweepFlag;
11574 var p1 = pointOnEllipticalArc({ x: segment.prePoint[0], y: segment.prePoint[1] }, rx, ry, xRotation, !!arcFlag, !!sweepFlag, { x: segment.currentPoint[0], y: segment.currentPoint[1] }, ratio);
11575 var p2 = pointOnEllipticalArc({ x: segment.prePoint[0], y: segment.prePoint[1] }, rx, ry, xRotation, !!arcFlag, !!sweepFlag, { x: segment.currentPoint[0], y: segment.currentPoint[1] }, sign ? ratio + 0.005 : ratio - 0.005);
11576 var xDist = p2.x - p1.x;
11577 var yDist = p2.y - p1.y;
11578 var dist = Math.sqrt(xDist * xDist + yDist * yDist);
11579 return { x: -xDist / dist, y: -yDist / dist };
11580 }
11581 // 向量长度
11582 function vMag(v) {
11583 return Math.sqrt(v[0] * v[0] + v[1] * v[1]);
11584 }
11585 // u.v/|u||v|,计算夹角的余弦值
11586 function vRatio(u, v) {
11587 // 当存在一个向量的长度为 0 时,夹角也为 0,即夹角的余弦值为 1
11588 return vMag(u) * vMag(v)
11589 ? (u[0] * v[0] + u[1] * v[1]) / (vMag(u) * vMag(v))
11590 : 1;
11591 }
11592 // 向量角度
11593 function vAngle(u, v) {
11594 return (u[0] * v[1] < u[1] * v[0] ? -1 : 1) * Math.acos(vRatio(u, v));
11595 }
11596 function getArcParams(startPoint, params) {
11597 var rx = params[1];
11598 var ry = params[2];
11599 var xRotation = mod(deg2rad(params[3]), Math.PI * 2);
11600 var arcFlag = params[4];
11601 var sweepFlag = params[5];
11602 // 弧形起点坐标
11603 var x1 = startPoint[0];
11604 var y1 = startPoint[1];
11605 // 弧形终点坐标
11606 var x2 = params[6];
11607 var y2 = params[7];
11608 var xp = (Math.cos(xRotation) * (x1 - x2)) / 2.0 +
11609 (Math.sin(xRotation) * (y1 - y2)) / 2.0;
11610 var yp = (-1 * Math.sin(xRotation) * (x1 - x2)) / 2.0 +
11611 (Math.cos(xRotation) * (y1 - y2)) / 2.0;
11612 var lambda = (xp * xp) / (rx * rx) + (yp * yp) / (ry * ry);
11613 if (lambda > 1) {
11614 rx *= Math.sqrt(lambda);
11615 ry *= Math.sqrt(lambda);
11616 }
11617 var diff = rx * rx * (yp * yp) + ry * ry * (xp * xp);
11618 var f = diff ? Math.sqrt((rx * rx * (ry * ry) - diff) / diff) : 1;
11619 if (arcFlag === sweepFlag) {
11620 f *= -1;
11621 }
11622 if (isNaN(f)) {
11623 f = 0;
11624 }
11625 // 旋转前的起点坐标,且当长半轴和短半轴的长度为 0 时,坐标按 (0, 0) 处理
11626 var cxp = ry ? (f * rx * yp) / ry : 0;
11627 var cyp = rx ? (f * -ry * xp) / rx : 0;
11628 // 椭圆圆心坐标
11629 var cx = (x1 + x2) / 2.0 + Math.cos(xRotation) * cxp - Math.sin(xRotation) * cyp;
11630 var cy = (y1 + y2) / 2.0 + Math.sin(xRotation) * cxp + Math.cos(xRotation) * cyp;
11631 // 起始点的单位向量
11632 var u = [(xp - cxp) / rx, (yp - cyp) / ry];
11633 // 终止点的单位向量
11634 var v = [(-1 * xp - cxp) / rx, (-1 * yp - cyp) / ry];
11635 // 计算起始点和圆心的连线,与 x 轴正方向的夹角
11636 var theta = vAngle([1, 0], u);
11637 // 计算圆弧起始点和终止点与椭圆圆心连线的夹角
11638 var dTheta = vAngle(u, v);
11639 if (vRatio(u, v) <= -1) {
11640 dTheta = Math.PI;
11641 }
11642 if (vRatio(u, v) >= 1) {
11643 dTheta = 0;
11644 }
11645 if (sweepFlag === 0 && dTheta > 0) {
11646 dTheta = dTheta - 2 * Math.PI;
11647 }
11648 if (sweepFlag === 1 && dTheta < 0) {
11649 dTheta = dTheta + 2 * Math.PI;
11650 }
11651 return {
11652 cx: cx,
11653 cy: cy,
11654 // 弧形的起点和终点相同时,长轴和短轴的长度按 0 处理
11655 rx: isSamePoint(startPoint, [x2, y2]) ? 0 : rx,
11656 ry: isSamePoint(startPoint, [x2, y2]) ? 0 : ry,
11657 startAngle: theta,
11658 endAngle: theta + dTheta,
11659 xRotation: xRotation,
11660 arcFlag: arcFlag,
11661 sweepFlag: sweepFlag,
11662 };
11663 }
11664 function commandsToPathString(commands, object, transform) {
11665 var _a = object.parsedStyle, _b = _a.defX, defX = _b === void 0 ? 0 : _b, _c = _a.defY, defY = _c === void 0 ? 0 : _c;
11666 return commands.reduce(function (prev, cur) {
11667 var path = '';
11668 if (cur[0] === 'M' || cur[0] === 'L') {
11669 var p = fromValues$2(cur[1] - defX, cur[2] - defY, 0);
11670 if (transform) {
11671 transformMat4(p, p, transform);
11672 }
11673 path = "".concat(cur[0]).concat(p[0], ",").concat(p[1]);
11674 }
11675 else if (cur[0] === 'Z') {
11676 path = cur[0];
11677 }
11678 else if (cur[0] === 'C') {
11679 var p1 = fromValues$2(cur[1] - defX, cur[2] - defY, 0);
11680 var p2 = fromValues$2(cur[3] - defX, cur[4] - defY, 0);
11681 var p3 = fromValues$2(cur[5] - defX, cur[6] - defY, 0);
11682 if (transform) {
11683 transformMat4(p1, p1, transform);
11684 transformMat4(p2, p2, transform);
11685 transformMat4(p3, p3, transform);
11686 }
11687 path = "".concat(cur[0]).concat(p1[0], ",").concat(p1[1], ",").concat(p2[0], ",").concat(p2[1], ",").concat(p3[0], ",").concat(p3[1]);
11688 }
11689 else if (cur[0] === 'A') {
11690 var c = fromValues$2(cur[6] - defX, cur[7] - defY, 0);
11691 if (transform) {
11692 transformMat4(c, c, transform);
11693 }
11694 path = "".concat(cur[0]).concat(cur[1], ",").concat(cur[2], ",").concat(cur[3], ",").concat(cur[4], ",").concat(cur[5], ",").concat(c[0], ",").concat(c[1]);
11695 }
11696 else if (cur[0] === 'Q') {
11697 var p1 = fromValues$2(cur[1] - defX, cur[2] - defY, 0);
11698 var p2 = fromValues$2(cur[3] - defX, cur[4] - defY, 0);
11699 if (transform) {
11700 transformMat4(p1, p1, transform);
11701 transformMat4(p2, p2, transform);
11702 }
11703 path = "".concat(cur[0]).concat(cur[1], ",").concat(cur[2], ",").concat(cur[3], ",").concat(cur[4], "}");
11704 }
11705 return (prev += path);
11706 }, '');
11707 }
11708 function lineToCommands(x1, y1, x2, y2) {
11709 return [
11710 ['M', x1, y1],
11711 ['L', x2, y2],
11712 ];
11713 }
11714 function ellipseToCommands(rx, ry, cx, cy) {
11715 var factor = ((-1 + Math.sqrt(2)) / 3) * 4;
11716 var dx = rx * factor;
11717 var dy = ry * factor;
11718 var left = cx - rx;
11719 var right = cx + rx;
11720 var top = cy - ry;
11721 var bottom = cy + ry;
11722 return [
11723 ['M', left, cy],
11724 ['C', left, cy - dy, cx - dx, top, cx, top],
11725 ['C', cx + dx, top, right, cy - dy, right, cy],
11726 ['C', right, cy + dy, cx + dx, bottom, cx, bottom],
11727 ['C', cx - dx, bottom, left, cy + dy, left, cy],
11728 ['Z'],
11729 ];
11730 }
11731 function polygonToCommands(points, closed) {
11732 var result = points.map(function (point, i) {
11733 return [i === 0 ? 'M' : 'L', point[0], point[1]];
11734 });
11735 if (closed) {
11736 result.push(['Z']);
11737 }
11738 return result;
11739 }
11740 function rectToCommands(width, height, x, y, radius) {
11741 // @see https://gist.github.com/danielpquinn/dd966af424030d47e476
11742 if (radius) {
11743 var _a = __read(radius, 4), tlr = _a[0], trr = _a[1], brr = _a[2], blr = _a[3];
11744 var signX = width > 0 ? 1 : -1;
11745 var signY = height > 0 ? 1 : -1;
11746 // sweep-flag @see https://developer.mozilla.org/zh-CN/docs/Web/SVG/Tutorial/Paths#arcs
11747 var sweepFlag = signX + signY !== 0 ? 1 : 0;
11748 return [
11749 ['M', signX * tlr + x, y],
11750 ['L', width - signX * trr + x, y],
11751 trr ? ['A', trr, trr, 0, 0, sweepFlag, width + x, signY * trr + y] : null,
11752 ['L', width + x, height - signY * brr + y],
11753 brr
11754 ? ['A', brr, brr, 0, 0, sweepFlag, width + x - signX * brr, height + y]
11755 : null,
11756 ['L', x + signX * blr, height + y],
11757 blr
11758 ? ['A', blr, blr, 0, 0, sweepFlag, x, height + y - signY * blr]
11759 : null,
11760 ['L', x, signY * tlr + y],
11761 tlr ? ['A', tlr, tlr, 0, 0, sweepFlag, signX * tlr + x, y] : null,
11762 ['Z'],
11763 ].filter(function (command) { return command; });
11764 }
11765 return [
11766 ['M', x, y],
11767 ['L', x + width, y],
11768 ['L', x + width, y + height],
11769 ['L', x, y + height],
11770 ['Z'],
11771 ];
11772 }
11773 /**
11774 * convert object to path, should account for:
11775 * * transform & origin
11776 * * anchor
11777 * * lineWidth
11778 */
11779 function convertToPath(object, transform) {
11780 if (transform === void 0) { transform = object.getLocalTransform(); }
11781 var commands = [];
11782 switch (object.nodeName) {
11783 case Shape.LINE:
11784 var _a = object.parsedStyle, _b = _a.x1, x1 = _b === void 0 ? 0 : _b, _c = _a.y1, y1 = _c === void 0 ? 0 : _c, _d = _a.x2, x2 = _d === void 0 ? 0 : _d, _e = _a.y2, y2 = _e === void 0 ? 0 : _e;
11785 commands = lineToCommands(x1, y1, x2, y2);
11786 break;
11787 case Shape.CIRCLE: {
11788 var _f = object.parsedStyle, _g = _f.r, r = _g === void 0 ? 0 : _g, _h = _f.cx, cx = _h === void 0 ? 0 : _h, _j = _f.cy, cy = _j === void 0 ? 0 : _j;
11789 commands = ellipseToCommands(r, r, cx, cy);
11790 break;
11791 }
11792 case Shape.ELLIPSE: {
11793 var _k = object.parsedStyle, _l = _k.rx, rx = _l === void 0 ? 0 : _l, _m = _k.ry, ry = _m === void 0 ? 0 : _m, _o = _k.cx, cx = _o === void 0 ? 0 : _o, _p = _k.cy, cy = _p === void 0 ? 0 : _p;
11794 commands = ellipseToCommands(rx, ry, cx, cy);
11795 break;
11796 }
11797 case Shape.POLYLINE:
11798 case Shape.POLYGON:
11799 var points = object.parsedStyle.points;
11800 commands = polygonToCommands(points.points, object.nodeName === Shape.POLYGON);
11801 break;
11802 case Shape.RECT:
11803 var _q = object.parsedStyle, _r = _q.width, width_1 = _r === void 0 ? 0 : _r, _s = _q.height, height_1 = _s === void 0 ? 0 : _s, _t = _q.x, x = _t === void 0 ? 0 : _t, _u = _q.y, y = _u === void 0 ? 0 : _u, radius = _q.radius;
11804 var hasRadius = radius && radius.some(function (r) { return r !== 0; });
11805 commands = rectToCommands(width_1, height_1, x, y, hasRadius &&
11806 radius.map(function (r) {
11807 return clamp(r, 0, Math.min(Math.abs(width_1) / 2, Math.abs(height_1) / 2));
11808 }));
11809 break;
11810 case Shape.PATH:
11811 var absolutePath = object.parsedStyle.path.absolutePath;
11812 commands = __spreadArray([], __read(absolutePath), false);
11813 break;
11814 }
11815 if (commands.length) {
11816 return commandsToPathString(commands, object, transform);
11817 }
11818 }
11819
11820 var internalParsePath = function (path) {
11821 // empty path
11822 if (path === '' || (Array.isArray(path) && path.length === 0)) {
11823 return {
11824 absolutePath: [],
11825 hasArc: false,
11826 segments: [],
11827 polygons: [],
11828 polylines: [],
11829 curve: null,
11830 totalLength: 0,
11831 rect: {
11832 x: 0,
11833 y: 0,
11834 width: 0,
11835 height: 0,
11836 },
11837 };
11838 }
11839 var absolutePath;
11840 try {
11841 absolutePath = normalizePath(path);
11842 }
11843 catch (e) {
11844 absolutePath = normalizePath('');
11845 console.error("[g]: Invalid SVG Path definition: ".concat(path));
11846 }
11847 removeRedundantMCommand(absolutePath);
11848 var hasArc = hasArcOrBezier(absolutePath);
11849 var _a = extractPolygons(absolutePath), polygons = _a.polygons, polylines = _a.polylines;
11850 // for later use
11851 var segments = path2Segments(absolutePath);
11852 // Only calculate bbox here since we don't need length now.
11853 var _b = getPathBBox(segments, 0), x = _b.x, y = _b.y, width = _b.width, height = _b.height;
11854 return {
11855 absolutePath: absolutePath,
11856 hasArc: hasArc,
11857 segments: segments,
11858 polygons: polygons,
11859 polylines: polylines,
11860 // curve,
11861 // Delay the calculation of length.
11862 totalLength: 0,
11863 rect: {
11864 x: Number.isFinite(x) ? x : 0,
11865 y: Number.isFinite(y) ? y : 0,
11866 width: Number.isFinite(width) ? width : 0,
11867 height: Number.isFinite(height) ? height : 0,
11868 },
11869 };
11870 };
11871 var memoizedParsePath = memoize(internalParsePath);
11872 function parsePath(path) {
11873 return (isString(path) ? memoizedParsePath(path) : internalParsePath(path));
11874 }
11875 function mergePaths(left, right, object) {
11876 var curve1 = left.curve;
11877 var curve2 = right.curve;
11878 if (!curve1 || curve1.length === 0) {
11879 // convert to curves to do morphing & picking later
11880 // @see http://thednp.github.io/kute.js/svgCubicMorph.html
11881 curve1 = path2Curve(left.absolutePath, false);
11882 left.curve = curve1;
11883 }
11884 if (!curve2 || curve2.length === 0) {
11885 curve2 = path2Curve(right.absolutePath, false);
11886 right.curve = curve2;
11887 }
11888 var curves = [curve1, curve2];
11889 if (curve1.length !== curve2.length) {
11890 curves = equalizeSegments(curve1, curve2);
11891 }
11892 var curve0 = getDrawDirection(curves[0]) !== getDrawDirection(curves[1])
11893 ? reverseCurve(curves[0])
11894 : clonePath(curves[0]);
11895 return [
11896 curve0,
11897 getRotatedCurve(curves[1], curve0),
11898 function (pathArray) {
11899 // need converting to path string?
11900 return pathArray;
11901 },
11902 ];
11903 }
11904
11905 /**
11906 * @see https://developer.mozilla.org/zh-CN/docs/Web/SVG/Attribute/points
11907 *
11908 * @example
11909 * points="100,10 250,150 200,110"
11910 */
11911 function parsePoints(pointsOrStr, object) {
11912 var points;
11913 if (isString(pointsOrStr)) {
11914 points = pointsOrStr.split(' ').map(function (pointStr) {
11915 var _a = __read(pointStr.split(','), 2), x = _a[0], y = _a[1];
11916 return [Number(x), Number(y)];
11917 });
11918 }
11919 else {
11920 points = pointsOrStr;
11921 }
11922 var segments = [];
11923 var tempLength = 0;
11924 var segmentT;
11925 var segmentL;
11926 var totalLength = length$2(points);
11927 points.forEach(function (p, i) {
11928 if (points[i + 1]) {
11929 segmentT = [0, 0];
11930 segmentT[0] = tempLength / totalLength;
11931 segmentL = length$4(p[0], p[1], points[i + 1][0], points[i + 1][1]);
11932 tempLength += segmentL;
11933 segmentT[1] = tempLength / totalLength;
11934 segments.push(segmentT);
11935 }
11936 });
11937 var minX = Math.min.apply(Math, __spreadArray([], __read(points.map(function (point) { return point[0]; })), false));
11938 var minY = Math.min.apply(Math, __spreadArray([], __read(points.map(function (point) { return point[1]; })), false));
11939 if (object) {
11940 object.parsedStyle.defX = minX;
11941 object.parsedStyle.defY = minY;
11942 }
11943 return {
11944 points: points,
11945 totalLength: totalLength,
11946 segments: segments,
11947 };
11948 }
11949 function mergePoints(left, right) {
11950 return [
11951 left.points,
11952 right.points,
11953 function (points) {
11954 return points;
11955 },
11956 ];
11957 }
11958
11959 var _ = null;
11960 function cast(pattern) {
11961 return function (contents) {
11962 var i = 0;
11963 return pattern.map(function (x) {
11964 return x === _ ? contents[i++] : x;
11965 });
11966 };
11967 }
11968 function id(x) {
11969 return x;
11970 }
11971 // type: [argTypes, convertTo3D, convertTo2D]
11972 // In the argument types string, lowercase characters represent optional arguments
11973 var transformFunctions = {
11974 // @ts-ignore
11975 matrix: ['NNNNNN', [_, _, 0, 0, _, _, 0, 0, 0, 0, 1, 0, _, _, 0, 1], id],
11976 matrix3d: ['NNNNNNNNNNNNNNNN', id],
11977 rotate: ['A'],
11978 rotatex: ['A'],
11979 rotatey: ['A'],
11980 rotatez: ['A'],
11981 rotate3d: ['NNNA'],
11982 perspective: ['L'],
11983 scale: ['Nn', cast([_, _, new CSSUnitValue(1)]), id],
11984 scalex: [
11985 'N',
11986 cast([_, new CSSUnitValue(1), new CSSUnitValue(1)]),
11987 cast([_, new CSSUnitValue(1)]),
11988 ],
11989 scaley: [
11990 'N',
11991 cast([new CSSUnitValue(1), _, new CSSUnitValue(1)]),
11992 cast([new CSSUnitValue(1), _]),
11993 ],
11994 scalez: ['N', cast([new CSSUnitValue(1), new CSSUnitValue(1), _])],
11995 scale3d: ['NNN', id],
11996 skew: ['Aa', null, id],
11997 skewx: ['A', null, cast([_, Odeg])],
11998 skewy: ['A', null, cast([Odeg, _])],
11999 translate: ['Tt', cast([_, _, Opx]), id],
12000 translatex: ['T', cast([_, Opx, Opx]), cast([_, Opx])],
12001 translatey: ['T', cast([Opx, _, Opx]), cast([Opx, _])],
12002 translatez: ['L', cast([Opx, Opx, _])],
12003 translate3d: ['TTL', id],
12004 };
12005 /**
12006 * none
12007 * scale(1) scale(1, 2)
12008 * scaleX(1)
12009 */
12010 function parseTransform(string) {
12011 string = (string || 'none').toLowerCase().trim();
12012 if (string === 'none') {
12013 return [];
12014 }
12015 var transformRegExp = /\s*(\w+)\(([^)]*)\)/g;
12016 var result = [];
12017 var match;
12018 var prevLastIndex = 0;
12019 while ((match = transformRegExp.exec(string))) {
12020 if (match.index !== prevLastIndex) {
12021 return [];
12022 }
12023 prevLastIndex = match.index + match[0].length;
12024 var functionName = match[1]; // scale
12025 var functionData = transformFunctions[functionName]; // scale(1, 2)
12026 if (!functionData) {
12027 // invalid, eg. scale()
12028 return [];
12029 }
12030 var args = match[2].split(','); // 1,2
12031 var argTypes = functionData[0]; // Nn
12032 if (argTypes.length < args.length) {
12033 // scale(N, n)
12034 return [];
12035 }
12036 var parsedArgs = [];
12037 for (var i = 0; i < argTypes.length; i++) {
12038 var arg = args[i];
12039 var type = argTypes[i];
12040 var parsedArg = void 0;
12041 if (!arg) {
12042 // @ts-ignore
12043 parsedArg = {
12044 a: Odeg,
12045 n: parsedArgs[0],
12046 t: Opx,
12047 }[type];
12048 }
12049 else {
12050 // @ts-ignore
12051 parsedArg = {
12052 A: function (s) {
12053 return s.trim() === '0' ? Odeg : parseAngle(s);
12054 },
12055 N: parseNumber,
12056 T: parseLengthOrPercentage,
12057 L: parseLength,
12058 }[type.toUpperCase()](arg);
12059 }
12060 if (parsedArg === undefined) {
12061 return [];
12062 }
12063 parsedArgs.push(parsedArg);
12064 }
12065 result.push({ t: functionName, d: parsedArgs }); // { t: scale, d: [1, 2] }
12066 if (transformRegExp.lastIndex === string.length) {
12067 return result;
12068 }
12069 }
12070 return [];
12071 }
12072 function parseTransformUnmemoize(string) {
12073 string = (string || 'none').toLowerCase().trim();
12074 if (string === 'none') {
12075 return [];
12076 }
12077 var transformRegExp = /\s*(\w+)\(([^)]*)\)/g;
12078 var result = [];
12079 var match;
12080 var prevLastIndex = 0;
12081 while ((match = transformRegExp.exec(string))) {
12082 if (match.index !== prevLastIndex) {
12083 return [];
12084 }
12085 prevLastIndex = match.index + match[0].length;
12086 var functionName = match[1]; // scale
12087 var functionData = transformFunctions[functionName]; // scale(1, 2)
12088 if (!functionData) {
12089 // invalid, eg. scale()
12090 return [];
12091 }
12092 var args = match[2].split(','); // 1,2
12093 var argTypes = functionData[0]; // Nn
12094 if (argTypes.length < args.length) {
12095 // scale(N, n)
12096 return [];
12097 }
12098 var parsedArgs = [];
12099 for (var i = 0; i < argTypes.length; i++) {
12100 var arg = args[i];
12101 var type = argTypes[i];
12102 var parsedArg = void 0;
12103 if (!arg) {
12104 // @ts-ignore
12105 parsedArg = {
12106 a: Odeg,
12107 n: parsedArgs[0],
12108 t: Opx,
12109 }[type];
12110 }
12111 else {
12112 // @ts-ignore
12113 parsedArg = {
12114 A: function (s) {
12115 return s.trim() === '0' ? Odeg : parseAngleUnmemoize(s);
12116 },
12117 N: parseNumberUnmemoize,
12118 T: parseLengthOrPercentageUnmemoize,
12119 L: parseLengthUnmemoize,
12120 }[type.toUpperCase()](arg);
12121 }
12122 if (parsedArg === undefined) {
12123 return [];
12124 }
12125 parsedArgs.push(parsedArg);
12126 }
12127 result.push({ t: functionName, d: parsedArgs }); // { t: scale, d: [1, 2] }
12128 if (transformRegExp.lastIndex === string.length) {
12129 return result;
12130 }
12131 }
12132 return [];
12133 }
12134 function convertItemToMatrix(item) {
12135 var x;
12136 var y;
12137 var z;
12138 var angle;
12139 switch (item.t) {
12140 case 'rotatex':
12141 angle = deg2rad(convertAngleUnit(item.d[0]));
12142 return [
12143 1,
12144 0,
12145 0,
12146 0,
12147 0,
12148 Math.cos(angle),
12149 Math.sin(angle),
12150 0,
12151 0,
12152 -Math.sin(angle),
12153 Math.cos(angle),
12154 0,
12155 0,
12156 0,
12157 0,
12158 1,
12159 ];
12160 case 'rotatey':
12161 angle = deg2rad(convertAngleUnit(item.d[0]));
12162 return [
12163 Math.cos(angle),
12164 0,
12165 -Math.sin(angle),
12166 0,
12167 0,
12168 1,
12169 0,
12170 0,
12171 Math.sin(angle),
12172 0,
12173 Math.cos(angle),
12174 0,
12175 0,
12176 0,
12177 0,
12178 1,
12179 ];
12180 case 'rotate':
12181 case 'rotatez':
12182 angle = deg2rad(convertAngleUnit(item.d[0]));
12183 return [
12184 Math.cos(angle),
12185 Math.sin(angle),
12186 0,
12187 0,
12188 -Math.sin(angle),
12189 Math.cos(angle),
12190 0,
12191 0,
12192 0,
12193 0,
12194 1,
12195 0,
12196 0,
12197 0,
12198 0,
12199 1,
12200 ];
12201 case 'rotate3d':
12202 x = item.d[0].value;
12203 y = item.d[1].value;
12204 z = item.d[2].value;
12205 angle = deg2rad(convertAngleUnit(item.d[3]));
12206 var sqrLength = x * x + y * y + z * z;
12207 if (sqrLength === 0) {
12208 x = 1;
12209 y = 0;
12210 z = 0;
12211 }
12212 else if (sqrLength !== 1) {
12213 var length_1 = Math.sqrt(sqrLength);
12214 x /= length_1;
12215 y /= length_1;
12216 z /= length_1;
12217 }
12218 var s = Math.sin(angle / 2);
12219 var sc = s * Math.cos(angle / 2);
12220 var sq = s * s;
12221 return [
12222 1 - 2 * (y * y + z * z) * sq,
12223 2 * (x * y * sq + z * sc),
12224 2 * (x * z * sq - y * sc),
12225 0,
12226 2 * (x * y * sq - z * sc),
12227 1 - 2 * (x * x + z * z) * sq,
12228 2 * (y * z * sq + x * sc),
12229 0,
12230 2 * (x * z * sq + y * sc),
12231 2 * (y * z * sq - x * sc),
12232 1 - 2 * (x * x + y * y) * sq,
12233 0,
12234 0,
12235 0,
12236 0,
12237 1,
12238 ];
12239 case 'scale':
12240 return [
12241 item.d[0].value,
12242 0,
12243 0,
12244 0,
12245 0,
12246 item.d[1].value,
12247 0,
12248 0,
12249 0,
12250 0,
12251 1,
12252 0,
12253 0,
12254 0,
12255 0,
12256 1,
12257 ];
12258 case 'scalex':
12259 return [item.d[0].value, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
12260 case 'scaley':
12261 return [1, 0, 0, 0, 0, item.d[0].value, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
12262 case 'scalez':
12263 return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, item.d[0].value, 0, 0, 0, 0, 1];
12264 case 'scale3d':
12265 return [
12266 item.d[0].value,
12267 0,
12268 0,
12269 0,
12270 0,
12271 item.d[1].value,
12272 0,
12273 0,
12274 0,
12275 0,
12276 item.d[2].value,
12277 0,
12278 0,
12279 0,
12280 0,
12281 1,
12282 ];
12283 case 'skew':
12284 var xAngle = deg2rad(convertAngleUnit(item.d[0]));
12285 var yAngle = deg2rad(convertAngleUnit(item.d[1]));
12286 return [
12287 1,
12288 Math.tan(yAngle),
12289 0,
12290 0,
12291 Math.tan(xAngle),
12292 1,
12293 0,
12294 0,
12295 0,
12296 0,
12297 1,
12298 0,
12299 0,
12300 0,
12301 0,
12302 1,
12303 ];
12304 case 'skewx':
12305 angle = deg2rad(convertAngleUnit(item.d[0]));
12306 return [1, 0, 0, 0, Math.tan(angle), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
12307 case 'skewy':
12308 angle = deg2rad(convertAngleUnit(item.d[0]));
12309 return [1, Math.tan(angle), 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
12310 case 'translate':
12311 // TODO: pass target
12312 x = convertPercentUnit(item.d[0], 0, null) || 0;
12313 y = convertPercentUnit(item.d[1], 0, null) || 0;
12314 return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, 0, 1];
12315 case 'translatex':
12316 x = convertPercentUnit(item.d[0], 0, null) || 0;
12317 return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, 0, 0, 1];
12318 case 'translatey':
12319 y = convertPercentUnit(item.d[0], 0, null) || 0;
12320 return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, y, 0, 1];
12321 case 'translatez':
12322 z = convertPercentUnit(item.d[0], 0, null) || 0;
12323 return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, z, 1];
12324 case 'translate3d':
12325 x = convertPercentUnit(item.d[0], 0, null) || 0;
12326 y = convertPercentUnit(item.d[1], 0, null) || 0;
12327 z = convertPercentUnit(item.d[2], 0, null) || 0;
12328 return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, z, 1];
12329 case 'perspective':
12330 var t = convertPercentUnit(item.d[0], 0, null) || 0;
12331 var p = t ? -1 / t : 0;
12332 return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, p, 0, 0, 0, 1];
12333 case 'matrix':
12334 return [
12335 item.d[0].value,
12336 item.d[1].value,
12337 0,
12338 0,
12339 item.d[2].value,
12340 item.d[3].value,
12341 0,
12342 0,
12343 0,
12344 0,
12345 1,
12346 0,
12347 item.d[4].value,
12348 item.d[5].value,
12349 0,
12350 1,
12351 ];
12352 case 'matrix3d':
12353 return item.d.map(function (d) { return d.value; });
12354 }
12355 }
12356 function multiplyMatrices(a, b) {
12357 return [
12358 a[0] * b[0] + a[4] * b[1] + a[8] * b[2] + a[12] * b[3],
12359 a[1] * b[0] + a[5] * b[1] + a[9] * b[2] + a[13] * b[3],
12360 a[2] * b[0] + a[6] * b[1] + a[10] * b[2] + a[14] * b[3],
12361 a[3] * b[0] + a[7] * b[1] + a[11] * b[2] + a[15] * b[3],
12362 a[0] * b[4] + a[4] * b[5] + a[8] * b[6] + a[12] * b[7],
12363 a[1] * b[4] + a[5] * b[5] + a[9] * b[6] + a[13] * b[7],
12364 a[2] * b[4] + a[6] * b[5] + a[10] * b[6] + a[14] * b[7],
12365 a[3] * b[4] + a[7] * b[5] + a[11] * b[6] + a[15] * b[7],
12366 a[0] * b[8] + a[4] * b[9] + a[8] * b[10] + a[12] * b[11],
12367 a[1] * b[8] + a[5] * b[9] + a[9] * b[10] + a[13] * b[11],
12368 a[2] * b[8] + a[6] * b[9] + a[10] * b[10] + a[14] * b[11],
12369 a[3] * b[8] + a[7] * b[9] + a[11] * b[10] + a[15] * b[11],
12370 a[0] * b[12] + a[4] * b[13] + a[8] * b[14] + a[12] * b[15],
12371 a[1] * b[12] + a[5] * b[13] + a[9] * b[14] + a[13] * b[15],
12372 a[2] * b[12] + a[6] * b[13] + a[10] * b[14] + a[14] * b[15],
12373 a[3] * b[12] + a[7] * b[13] + a[11] * b[14] + a[15] * b[15],
12374 ];
12375 }
12376 function convertToMatrix(transformList) {
12377 if (transformList.length === 0) {
12378 return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
12379 }
12380 return transformList.map(convertItemToMatrix).reduce(multiplyMatrices);
12381 }
12382 function makeMatrixDecomposition(transformList) {
12383 var translate = [0, 0, 0];
12384 var scale = [1, 1, 1];
12385 var skew = [0, 0, 0];
12386 var perspective = [0, 0, 0, 1];
12387 var quaternion = [0, 0, 0, 1];
12388 decomposeMat4(
12389 // @ts-ignore
12390 convertToMatrix(transformList), translate, scale, skew, perspective, quaternion);
12391 return [[translate, scale, skew, quaternion, perspective]];
12392 }
12393 var composeMatrix = (function () {
12394 function multiply(a, b) {
12395 var result = [
12396 [0, 0, 0, 0],
12397 [0, 0, 0, 0],
12398 [0, 0, 0, 0],
12399 [0, 0, 0, 0],
12400 ];
12401 for (var i = 0; i < 4; i++) {
12402 for (var j = 0; j < 4; j++) {
12403 for (var k = 0; k < 4; k++) {
12404 result[i][j] += b[i][k] * a[k][j];
12405 }
12406 }
12407 }
12408 return result;
12409 }
12410 function is2D(m) {
12411 return (m[0][2] == 0 &&
12412 m[0][3] == 0 &&
12413 m[1][2] == 0 &&
12414 m[1][3] == 0 &&
12415 m[2][0] == 0 &&
12416 m[2][1] == 0 &&
12417 m[2][2] == 1 &&
12418 m[2][3] == 0 &&
12419 m[3][2] == 0 &&
12420 m[3][3] == 1);
12421 }
12422 function composeMatrix(translate, scale, skew, quat, perspective) {
12423 var matrix = [
12424 [1, 0, 0, 0],
12425 [0, 1, 0, 0],
12426 [0, 0, 1, 0],
12427 [0, 0, 0, 1],
12428 ];
12429 for (var i = 0; i < 4; i++) {
12430 matrix[i][3] = perspective[i];
12431 }
12432 for (var i = 0; i < 3; i++) {
12433 for (var j = 0; j < 3; j++) {
12434 matrix[3][i] += translate[j] * matrix[j][i];
12435 }
12436 }
12437 var x = quat[0], y = quat[1], z = quat[2], w = quat[3];
12438 var rotMatrix = [
12439 [1, 0, 0, 0],
12440 [0, 1, 0, 0],
12441 [0, 0, 1, 0],
12442 [0, 0, 0, 1],
12443 ];
12444 rotMatrix[0][0] = 1 - 2 * (y * y + z * z);
12445 rotMatrix[0][1] = 2 * (x * y - z * w);
12446 rotMatrix[0][2] = 2 * (x * z + y * w);
12447 rotMatrix[1][0] = 2 * (x * y + z * w);
12448 rotMatrix[1][1] = 1 - 2 * (x * x + z * z);
12449 rotMatrix[1][2] = 2 * (y * z - x * w);
12450 rotMatrix[2][0] = 2 * (x * z - y * w);
12451 rotMatrix[2][1] = 2 * (y * z + x * w);
12452 rotMatrix[2][2] = 1 - 2 * (x * x + y * y);
12453 matrix = multiply(matrix, rotMatrix);
12454 var temp = [
12455 [1, 0, 0, 0],
12456 [0, 1, 0, 0],
12457 [0, 0, 1, 0],
12458 [0, 0, 0, 1],
12459 ];
12460 if (skew[2]) {
12461 temp[2][1] = skew[2];
12462 matrix = multiply(matrix, temp);
12463 }
12464 if (skew[1]) {
12465 temp[2][1] = 0;
12466 temp[2][0] = skew[0];
12467 matrix = multiply(matrix, temp);
12468 }
12469 if (skew[0]) {
12470 temp[2][0] = 0;
12471 temp[1][0] = skew[0];
12472 matrix = multiply(matrix, temp);
12473 }
12474 for (var i = 0; i < 3; i++) {
12475 for (var j = 0; j < 3; j++) {
12476 matrix[i][j] *= scale[i];
12477 }
12478 }
12479 if (is2D(matrix)) {
12480 return [
12481 matrix[0][0],
12482 matrix[0][1],
12483 matrix[1][0],
12484 matrix[1][1],
12485 matrix[3][0],
12486 matrix[3][1],
12487 ];
12488 }
12489 return matrix[0].concat(matrix[1], matrix[2], matrix[3]);
12490 }
12491 return composeMatrix;
12492 })();
12493 function numberToLongString(x) {
12494 return x.toFixed(6).replace('.000000', '');
12495 }
12496 function mergeMatrices(left, right) {
12497 var leftArgs;
12498 var rightArgs;
12499 // @ts-ignore
12500 if (left.decompositionPair !== right) {
12501 // @ts-ignore
12502 left.decompositionPair = right;
12503 // @ts-ignore
12504 leftArgs = makeMatrixDecomposition(left);
12505 }
12506 // @ts-ignore
12507 if (right.decompositionPair !== left) {
12508 // @ts-ignore
12509 right.decompositionPair = left;
12510 // @ts-ignore
12511 rightArgs = makeMatrixDecomposition(right);
12512 }
12513 if (leftArgs[0] === null || rightArgs[0] === null)
12514 return [
12515 // @ts-ignore
12516 [false],
12517 // @ts-ignore
12518 [true],
12519 // @ts-ignore
12520 function (x) {
12521 return x ? right[0].d : left[0].d;
12522 },
12523 ];
12524 leftArgs[0].push(0);
12525 rightArgs[0].push(1);
12526 return [
12527 leftArgs,
12528 rightArgs,
12529 // @ts-ignore
12530 function (list) {
12531 // @ts-ignore
12532 var q = quat(leftArgs[0][3], rightArgs[0][3], list[5]);
12533 var mat = composeMatrix(list[0], list[1], list[2], q, list[4]);
12534 var stringifiedArgs = mat.map(numberToLongString).join(',');
12535 return stringifiedArgs;
12536 },
12537 ];
12538 }
12539 function dot$2(v1, v2) {
12540 var result = 0;
12541 for (var i = 0; i < v1.length; i++) {
12542 result += v1[i] * v2[i];
12543 }
12544 return result;
12545 }
12546 function quat(fromQ, toQ, f) {
12547 var product = dot$2(fromQ, toQ);
12548 product = clamp(product, -1.0, 1.0);
12549 var quat = [];
12550 if (product === 1.0) {
12551 quat = fromQ;
12552 }
12553 else {
12554 var theta = Math.acos(product);
12555 var w = (Math.sin(f * theta) * 1) / Math.sqrt(1 - product * product);
12556 for (var i = 0; i < 4; i++) {
12557 quat.push(fromQ[i] * (Math.cos(f * theta) - product * w) + toQ[i] * w);
12558 }
12559 }
12560 return quat;
12561 }
12562 // scalex/y/z -> scale
12563 function typeTo2D(type) {
12564 return type.replace(/[xy]/, '');
12565 }
12566 // scalex/y/z -> scale3d
12567 function typeTo3D(type) {
12568 return type.replace(/(x|y|z|3d)?$/, '3d');
12569 }
12570 var isMatrixOrPerspective = function (lt, rt) {
12571 return ((lt === 'perspective' && rt === 'perspective') ||
12572 ((lt === 'matrix' || lt === 'matrix3d') &&
12573 (rt === 'matrix' || rt === 'matrix3d')));
12574 };
12575 function mergeTransforms(left, right, target) {
12576 var flipResults = false;
12577 // padding empty transform, eg. merge 'scale(10)' with 'none' -> scale(1)
12578 if (!left.length || !right.length) {
12579 if (!left.length) {
12580 flipResults = true;
12581 left = right;
12582 right = [];
12583 }
12584 var _loop_1 = function (i) {
12585 var _a = left[i], type = _a.t, args = _a.d;
12586 // none -> scale(1)/translateX(0)
12587 var defaultValue = type.substring(0, 5) === 'scale' ? 1 : 0;
12588 right.push({
12589 t: type,
12590 d: args.map(function (arg) {
12591 if (typeof arg === 'number') {
12592 return getOrCreateUnitValue(defaultValue);
12593 }
12594 return getOrCreateUnitValue(defaultValue, arg.unit);
12595 // {
12596 // unit: arg.unit,
12597 // value: defaultValue,
12598 // };
12599 }),
12600 });
12601 };
12602 for (var i = 0; i < left.length; i++) {
12603 _loop_1(i);
12604 }
12605 }
12606 var leftResult = [];
12607 var rightResult = [];
12608 var types = [];
12609 // merge matrix() with matrix3d()
12610 if (left.length !== right.length) {
12611 var merged = mergeMatrices(left, right);
12612 // @ts-ignore
12613 leftResult = [merged[0]];
12614 // @ts-ignore
12615 rightResult = [merged[1]];
12616 types = [['matrix', [merged[2]]]];
12617 }
12618 else {
12619 for (var i = 0; i < left.length; i++) {
12620 var leftType = left[i].t;
12621 var rightType = right[i].t;
12622 var leftArgs = left[i].d;
12623 var rightArgs = right[i].d;
12624 var leftFunctionData = transformFunctions[leftType];
12625 var rightFunctionData = transformFunctions[rightType];
12626 var type = void 0;
12627 if (isMatrixOrPerspective(leftType, rightType)) {
12628 var merged = mergeMatrices([left[i]], [right[i]]);
12629 // @ts-ignore
12630 leftResult.push(merged[0]);
12631 // @ts-ignore
12632 rightResult.push(merged[1]);
12633 types.push(['matrix', [merged[2]]]);
12634 continue;
12635 }
12636 else if (leftType === rightType) {
12637 type = leftType;
12638 }
12639 else if (leftFunctionData[2] &&
12640 rightFunctionData[2] &&
12641 typeTo2D(leftType) === typeTo2D(rightType)) {
12642 type = typeTo2D(leftType);
12643 // @ts-ignore
12644 leftArgs = leftFunctionData[2](leftArgs);
12645 // @ts-ignore
12646 rightArgs = rightFunctionData[2](rightArgs);
12647 }
12648 else if (leftFunctionData[1] &&
12649 rightFunctionData[1] &&
12650 typeTo3D(leftType) === typeTo3D(rightType)) {
12651 type = typeTo3D(leftType);
12652 // @ts-ignore
12653 leftArgs = leftFunctionData[1](leftArgs);
12654 // @ts-ignore
12655 rightArgs = rightFunctionData[1](rightArgs);
12656 }
12657 else {
12658 var merged = mergeMatrices(left, right);
12659 // @ts-ignore
12660 leftResult = [merged[0]];
12661 // @ts-ignore
12662 rightResult = [merged[1]];
12663 types = [['matrix', [merged[2]]]];
12664 break;
12665 }
12666 var leftArgsCopy = [];
12667 var rightArgsCopy = [];
12668 var stringConversions = [];
12669 for (var j = 0; j < leftArgs.length; j++) {
12670 // const merge = leftArgs[j].unit === UnitType.kNumber ? mergeDimensions : mergeDimensions;
12671 var merged = mergeDimensions(leftArgs[j], rightArgs[j], target, false, j);
12672 leftArgsCopy[j] = merged[0];
12673 rightArgsCopy[j] = merged[1];
12674 stringConversions.push(merged[2]);
12675 }
12676 leftResult.push(leftArgsCopy);
12677 rightResult.push(rightArgsCopy);
12678 types.push([type, stringConversions]);
12679 }
12680 }
12681 if (flipResults) {
12682 var tmp = leftResult;
12683 leftResult = rightResult;
12684 rightResult = tmp;
12685 }
12686 return [
12687 leftResult,
12688 rightResult,
12689 function (list) {
12690 return list
12691 .map(function (args, i) {
12692 var stringifiedArgs = args
12693 .map(function (arg, j) {
12694 return types[i][1][j](arg);
12695 })
12696 .join(',');
12697 if (types[i][0] === 'matrix' &&
12698 stringifiedArgs.split(',').length === 16) {
12699 types[i][0] = 'matrix3d';
12700 }
12701 if (types[i][0] === 'matrix3d' &&
12702 stringifiedArgs.split(',').length === 6) {
12703 types[i][0] = 'matrix';
12704 }
12705 return types[i][0] + '(' + stringifiedArgs + ')';
12706 })
12707 .join(' ');
12708 },
12709 ];
12710 }
12711
12712 /**
12713 * @see https://developer.mozilla.org/zh-CN/docs/Web/CSS/transform-origin
12714 * eg. 'center' 'top left' '50px 50px'
12715 */
12716 var parseTransformOrigin = memoize(function (value) {
12717 if (isString(value)) {
12718 if (value === 'text-anchor') {
12719 return [getOrCreateUnitValue(0, 'px'), getOrCreateUnitValue(0, 'px')];
12720 }
12721 var values = value.split(' ');
12722 if (values.length === 1) {
12723 if (values[0] === 'top' || values[0] === 'bottom') {
12724 // 'top' -> 'center top'
12725 values[1] = values[0];
12726 values[0] = 'center';
12727 }
12728 else {
12729 // '50px' -> '50px center'
12730 values[1] = 'center';
12731 }
12732 }
12733 if (values.length !== 2) {
12734 return null;
12735 }
12736 // eg. center bottom
12737 return [
12738 parseLengthOrPercentage(convertKeyword2Percent(values[0])),
12739 parseLengthOrPercentage(convertKeyword2Percent(values[1])),
12740 ];
12741 }
12742 else {
12743 return [
12744 getOrCreateUnitValue(value[0] || 0, 'px'),
12745 getOrCreateUnitValue(value[1] || 0, 'px'),
12746 ];
12747 }
12748 });
12749 var parseTransformOriginUnmemoize = function (value) {
12750 if (isString(value)) {
12751 if (value === 'text-anchor') {
12752 return [getOrCreateUnitValue(0, 'px'), getOrCreateUnitValue(0, 'px')];
12753 }
12754 var values = value.split(' ');
12755 if (values.length === 1) {
12756 if (values[0] === 'top' || values[0] === 'bottom') {
12757 // 'top' -> 'center top'
12758 values[1] = values[0];
12759 values[0] = 'center';
12760 }
12761 else {
12762 // '50px' -> '50px center'
12763 values[1] = 'center';
12764 }
12765 }
12766 if (values.length !== 2) {
12767 return null;
12768 }
12769 // eg. center bottom
12770 return [
12771 parseLengthOrPercentageUnmemoize(convertKeyword2Percent(values[0])),
12772 parseLengthOrPercentageUnmemoize(convertKeyword2Percent(values[1])),
12773 ];
12774 }
12775 else {
12776 return [
12777 getOrCreateUnitValue(value[0] || 0, 'px'),
12778 getOrCreateUnitValue(value[1] || 0, 'px'),
12779 ];
12780 }
12781 };
12782 function convertKeyword2Percent(keyword) {
12783 if (keyword === 'center') {
12784 return '50%';
12785 }
12786 else if (keyword === 'left' || keyword === 'top') {
12787 return '0';
12788 }
12789 else if (keyword === 'right' || keyword === 'bottom') {
12790 return '100%';
12791 }
12792 return keyword;
12793 }
12794
12795 /**
12796 * Blink used them in code generation(css_properties.json5)
12797 */
12798 var BUILT_IN_PROPERTIES = [
12799 {
12800 /**
12801 * used in CSS Layout API
12802 * eg. `display: 'flex'`
12803 */
12804 n: 'display',
12805 k: ['none'],
12806 },
12807 {
12808 /**
12809 * range [0.0, 1.0]
12810 * @see https://developer.mozilla.org/en-US/docs/Web/CSS/opacity
12811 */
12812 n: 'opacity',
12813 int: true,
12814 inh: true,
12815 d: '1',
12816 syntax: PropertySyntax.OPACITY_VALUE,
12817 },
12818 {
12819 /**
12820 * inheritable, range [0.0, 1.0]
12821 * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/fill-opacity
12822 * @see https://svgwg.org/svg2-draft/painting.html#FillOpacity
12823 */
12824 n: 'fillOpacity',
12825 int: true,
12826 inh: true,
12827 d: '1',
12828 syntax: PropertySyntax.OPACITY_VALUE,
12829 },
12830 {
12831 /**
12832 * inheritable, range [0.0, 1.0]
12833 * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-opacity
12834 * @see https://svgwg.org/svg2-draft/painting.html#StrokeOpacity
12835 */
12836 n: 'strokeOpacity',
12837 int: true,
12838 inh: true,
12839 d: '1',
12840 syntax: PropertySyntax.OPACITY_VALUE,
12841 },
12842 {
12843 /**
12844 * background-color is not inheritable
12845 * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Fills_and_Strokes
12846 */
12847 n: 'fill',
12848 int: true,
12849 k: ['none'],
12850 d: 'none',
12851 syntax: PropertySyntax.PAINT,
12852 },
12853 {
12854 n: 'fillRule',
12855 k: ['nonzero', 'evenodd'],
12856 d: 'nonzero',
12857 },
12858 /**
12859 * default to none
12860 * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke#usage_notes
12861 */
12862 {
12863 n: 'stroke',
12864 int: true,
12865 k: ['none'],
12866 d: 'none',
12867 syntax: PropertySyntax.PAINT,
12868 /**
12869 * Stroke 'none' won't affect geometry but others will.
12870 */
12871 l: true,
12872 },
12873 {
12874 n: 'shadowType',
12875 k: ['inner', 'outer', 'both'],
12876 d: 'outer',
12877 l: true,
12878 },
12879 {
12880 n: 'shadowColor',
12881 int: true,
12882 syntax: PropertySyntax.COLOR,
12883 },
12884 {
12885 n: 'shadowOffsetX',
12886 int: true,
12887 l: true,
12888 d: '0',
12889 syntax: PropertySyntax.LENGTH_PERCENTAGE,
12890 },
12891 {
12892 n: 'shadowOffsetY',
12893 int: true,
12894 l: true,
12895 d: '0',
12896 syntax: PropertySyntax.LENGTH_PERCENTAGE,
12897 },
12898 {
12899 n: 'shadowBlur',
12900 int: true,
12901 l: true,
12902 d: '0',
12903 syntax: PropertySyntax.SHADOW_BLUR,
12904 },
12905 {
12906 /**
12907 * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-width
12908 */
12909 n: 'lineWidth',
12910 int: true,
12911 inh: true,
12912 d: '1',
12913 l: true,
12914 a: ['strokeWidth'],
12915 syntax: PropertySyntax.LENGTH_PERCENTAGE,
12916 },
12917 {
12918 n: 'increasedLineWidthForHitTesting',
12919 inh: true,
12920 d: '0',
12921 l: true,
12922 syntax: PropertySyntax.LENGTH_PERCENTAGE,
12923 },
12924 {
12925 n: 'lineJoin',
12926 inh: true,
12927 l: true,
12928 a: ['strokeLinejoin'],
12929 k: ['miter', 'bevel', 'round'],
12930 d: 'miter',
12931 },
12932 {
12933 n: 'lineCap',
12934 inh: true,
12935 l: true,
12936 a: ['strokeLinecap'],
12937 k: ['butt', 'round', 'square'],
12938 d: 'butt',
12939 },
12940 {
12941 n: 'lineDash',
12942 int: true,
12943 inh: true,
12944 k: ['none'],
12945 a: ['strokeDasharray'],
12946 syntax: PropertySyntax.LENGTH_PERCENTAGE_12,
12947 },
12948 {
12949 n: 'lineDashOffset',
12950 int: true,
12951 inh: true,
12952 d: '0',
12953 a: ['strokeDashoffset'],
12954 syntax: PropertySyntax.LENGTH_PERCENTAGE,
12955 },
12956 {
12957 n: 'offsetPath',
12958 syntax: PropertySyntax.DEFINED_PATH,
12959 },
12960 {
12961 n: 'offsetDistance',
12962 int: true,
12963 syntax: PropertySyntax.OFFSET_DISTANCE,
12964 },
12965 {
12966 n: 'dx',
12967 int: true,
12968 l: true,
12969 d: '0',
12970 syntax: PropertySyntax.LENGTH_PERCENTAGE,
12971 },
12972 {
12973 n: 'dy',
12974 int: true,
12975 l: true,
12976 d: '0',
12977 syntax: PropertySyntax.LENGTH_PERCENTAGE,
12978 },
12979 {
12980 n: 'zIndex',
12981 ind: true,
12982 int: true,
12983 d: '0',
12984 k: ['auto'],
12985 syntax: PropertySyntax.Z_INDEX,
12986 },
12987 {
12988 n: 'visibility',
12989 k: ['visible', 'hidden'],
12990 ind: true,
12991 inh: true,
12992 /**
12993 * support interpolation
12994 * @see https://developer.mozilla.org/en-US/docs/Web/CSS/visibility#interpolation
12995 */
12996 int: true,
12997 d: 'visible',
12998 },
12999 {
13000 n: 'pointerEvents',
13001 inh: true,
13002 k: [
13003 'none',
13004 'auto',
13005 'stroke',
13006 'fill',
13007 'painted',
13008 'visible',
13009 'visiblestroke',
13010 'visiblefill',
13011 'visiblepainted',
13012 // 'bounding-box',
13013 'all',
13014 ],
13015 d: 'auto',
13016 },
13017 {
13018 n: 'filter',
13019 ind: true,
13020 l: true,
13021 k: ['none'],
13022 d: 'none',
13023 syntax: PropertySyntax.FILTER,
13024 },
13025 {
13026 n: 'clipPath',
13027 syntax: PropertySyntax.DEFINED_PATH,
13028 },
13029 {
13030 n: 'textPath',
13031 syntax: PropertySyntax.DEFINED_PATH,
13032 },
13033 {
13034 n: 'textPathSide',
13035 k: ['left', 'right'],
13036 d: 'left',
13037 },
13038 {
13039 n: 'textPathStartOffset',
13040 l: true,
13041 d: '0',
13042 syntax: PropertySyntax.LENGTH_PERCENTAGE,
13043 },
13044 {
13045 n: 'transform',
13046 p: 100,
13047 int: true,
13048 k: ['none'],
13049 d: 'none',
13050 syntax: PropertySyntax.TRANSFORM,
13051 },
13052 {
13053 n: 'transformOrigin',
13054 p: 100,
13055 // int: true,
13056 d: function (nodeName) {
13057 if (nodeName === Shape.CIRCLE || nodeName === Shape.ELLIPSE) {
13058 return 'center';
13059 }
13060 if (nodeName === Shape.TEXT) {
13061 return 'text-anchor';
13062 }
13063 return 'left top';
13064 },
13065 l: true,
13066 syntax: PropertySyntax.TRANSFORM_ORIGIN,
13067 },
13068 {
13069 n: 'anchor',
13070 p: 99,
13071 d: function (nodeName) {
13072 if (nodeName === Shape.CIRCLE || nodeName === Shape.ELLIPSE) {
13073 return '0.5 0.5';
13074 }
13075 return '0 0';
13076 },
13077 l: true,
13078 syntax: PropertySyntax.LENGTH_PERCENTAGE_12,
13079 },
13080 // <circle> & <ellipse>
13081 {
13082 n: 'cx',
13083 int: true,
13084 d: '0',
13085 syntax: PropertySyntax.COORDINATE,
13086 },
13087 {
13088 n: 'cy',
13089 int: true,
13090 d: '0',
13091 syntax: PropertySyntax.COORDINATE,
13092 },
13093 {
13094 n: 'cz',
13095 int: true,
13096 d: '0',
13097 syntax: PropertySyntax.COORDINATE,
13098 },
13099 {
13100 n: 'r',
13101 int: true,
13102 l: true,
13103 d: '0',
13104 syntax: PropertySyntax.LENGTH_PERCENTAGE,
13105 },
13106 {
13107 n: 'rx',
13108 int: true,
13109 l: true,
13110 d: '0',
13111 syntax: PropertySyntax.LENGTH_PERCENTAGE,
13112 },
13113 {
13114 n: 'ry',
13115 int: true,
13116 l: true,
13117 d: '0',
13118 syntax: PropertySyntax.LENGTH_PERCENTAGE,
13119 },
13120 // Rect Image Group
13121 {
13122 // x in local space
13123 n: 'x',
13124 int: true,
13125 d: '0',
13126 syntax: PropertySyntax.COORDINATE,
13127 },
13128 {
13129 // y in local space
13130 n: 'y',
13131 int: true,
13132 d: '0',
13133 syntax: PropertySyntax.COORDINATE,
13134 },
13135 {
13136 // z in local space
13137 n: 'z',
13138 int: true,
13139 d: '0',
13140 syntax: PropertySyntax.COORDINATE,
13141 },
13142 {
13143 n: 'width',
13144 int: true,
13145 l: true,
13146 /**
13147 * @see https://developer.mozilla.org/zh-CN/docs/Web/CSS/width
13148 */
13149 k: ['auto', 'fit-content', 'min-content', 'max-content'],
13150 d: '0',
13151 syntax: PropertySyntax.LENGTH_PERCENTAGE,
13152 },
13153 {
13154 n: 'height',
13155 int: true,
13156 l: true,
13157 /**
13158 * @see https://developer.mozilla.org/zh-CN/docs/Web/CSS/height
13159 */
13160 k: ['auto', 'fit-content', 'min-content', 'max-content'],
13161 d: '0',
13162 syntax: PropertySyntax.LENGTH_PERCENTAGE,
13163 },
13164 {
13165 n: 'radius',
13166 int: true,
13167 l: true,
13168 d: '0',
13169 syntax: PropertySyntax.LENGTH_PERCENTAGE_14,
13170 },
13171 // Line
13172 {
13173 n: 'x1',
13174 int: true,
13175 l: true,
13176 syntax: PropertySyntax.COORDINATE,
13177 },
13178 {
13179 n: 'y1',
13180 int: true,
13181 l: true,
13182 syntax: PropertySyntax.COORDINATE,
13183 },
13184 {
13185 n: 'z1',
13186 int: true,
13187 l: true,
13188 syntax: PropertySyntax.COORDINATE,
13189 },
13190 {
13191 n: 'x2',
13192 int: true,
13193 l: true,
13194 syntax: PropertySyntax.COORDINATE,
13195 },
13196 {
13197 n: 'y2',
13198 int: true,
13199 l: true,
13200 syntax: PropertySyntax.COORDINATE,
13201 },
13202 {
13203 n: 'z2',
13204 int: true,
13205 l: true,
13206 syntax: PropertySyntax.COORDINATE,
13207 },
13208 // Path
13209 {
13210 n: 'path',
13211 int: true,
13212 l: true,
13213 d: '',
13214 a: ['d'],
13215 syntax: PropertySyntax.PATH,
13216 p: 50,
13217 },
13218 // Polyline & Polygon
13219 {
13220 n: 'points',
13221 /**
13222 * support interpolation
13223 */
13224 int: true,
13225 l: true,
13226 syntax: PropertySyntax.LIST_OF_POINTS,
13227 p: 50,
13228 },
13229 // Text
13230 {
13231 n: 'text',
13232 l: true,
13233 d: '',
13234 syntax: PropertySyntax.TEXT,
13235 p: 50,
13236 },
13237 {
13238 n: 'textTransform',
13239 l: true,
13240 inh: true,
13241 k: ['capitalize', 'uppercase', 'lowercase', 'none'],
13242 d: 'none',
13243 syntax: PropertySyntax.TEXT_TRANSFORM,
13244 p: 51, // it must get parsed after text
13245 },
13246 {
13247 n: 'font',
13248 l: true,
13249 },
13250 {
13251 n: 'fontSize',
13252 int: true,
13253 inh: true,
13254 /**
13255 * @see https://www.w3schools.com/css/css_font_size.asp
13256 */
13257 d: '16px',
13258 l: true,
13259 syntax: PropertySyntax.LENGTH_PERCENTAGE,
13260 },
13261 {
13262 n: 'fontFamily',
13263 l: true,
13264 inh: true,
13265 d: 'sans-serif',
13266 },
13267 {
13268 n: 'fontStyle',
13269 l: true,
13270 inh: true,
13271 k: ['normal', 'italic', 'oblique'],
13272 d: 'normal',
13273 },
13274 {
13275 n: 'fontWeight',
13276 l: true,
13277 inh: true,
13278 k: ['normal', 'bold', 'bolder', 'lighter'],
13279 d: 'normal',
13280 },
13281 {
13282 n: 'fontVariant',
13283 l: true,
13284 inh: true,
13285 k: ['normal', 'small-caps'],
13286 d: 'normal',
13287 },
13288 {
13289 n: 'lineHeight',
13290 l: true,
13291 syntax: PropertySyntax.LENGTH,
13292 int: true,
13293 d: '0',
13294 },
13295 {
13296 n: 'letterSpacing',
13297 l: true,
13298 syntax: PropertySyntax.LENGTH,
13299 int: true,
13300 d: '0',
13301 },
13302 {
13303 n: 'miterLimit',
13304 l: true,
13305 syntax: PropertySyntax.NUMBER,
13306 d: function (nodeName) {
13307 if (nodeName === Shape.PATH ||
13308 nodeName === Shape.POLYGON ||
13309 nodeName === Shape.POLYLINE) {
13310 return '4';
13311 }
13312 return '10';
13313 },
13314 },
13315 {
13316 n: 'wordWrap',
13317 l: true,
13318 },
13319 {
13320 n: 'wordWrapWidth',
13321 l: true,
13322 },
13323 {
13324 n: 'maxLines',
13325 l: true,
13326 },
13327 {
13328 n: 'textOverflow',
13329 l: true,
13330 d: 'clip',
13331 },
13332 {
13333 n: 'leading',
13334 l: true,
13335 },
13336 {
13337 n: 'textBaseline',
13338 l: true,
13339 inh: true,
13340 k: ['top', 'hanging', 'middle', 'alphabetic', 'ideographic', 'bottom'],
13341 d: 'alphabetic',
13342 },
13343 {
13344 n: 'textAlign',
13345 l: true,
13346 inh: true,
13347 k: ['start', 'center', 'middle', 'end', 'left', 'right'],
13348 d: 'start',
13349 },
13350 // {
13351 // n: 'whiteSpace',
13352 // l: true,
13353 // },
13354 {
13355 n: 'markerStart',
13356 syntax: PropertySyntax.MARKER,
13357 },
13358 {
13359 n: 'markerEnd',
13360 syntax: PropertySyntax.MARKER,
13361 },
13362 {
13363 n: 'markerMid',
13364 syntax: PropertySyntax.MARKER,
13365 },
13366 {
13367 n: 'markerStartOffset',
13368 syntax: PropertySyntax.LENGTH,
13369 l: true,
13370 int: true,
13371 d: '0',
13372 },
13373 {
13374 n: 'markerEndOffset',
13375 syntax: PropertySyntax.LENGTH,
13376 l: true,
13377 int: true,
13378 d: '0',
13379 },
13380 ];
13381 var GEOMETRY_ATTRIBUTE_NAMES = BUILT_IN_PROPERTIES.filter(function (n) { return !!n.l; }).map(function (n) { return n.n; });
13382 var propertyMetadataCache = {};
13383 var unresolvedProperties = new WeakMap();
13384 // const uniqueAttributeSet = new Set<string>();
13385 // const tmpVec3a = vec3.create();
13386 // const tmpVec3b = vec3.create();
13387 // const tmpVec3c = vec3.create();
13388 var isPropertyResolved = function (object, name) {
13389 var properties = unresolvedProperties.get(object);
13390 if (!properties || properties.length === 0) {
13391 return true;
13392 }
13393 return properties.includes(name);
13394 };
13395 var DefaultStyleValueRegistry = /** @class */ (function () {
13396 /**
13397 * need recalc later
13398 */
13399 // dirty = false;
13400 function DefaultStyleValueRegistry(runtime) {
13401 var _this = this;
13402 this.runtime = runtime;
13403 BUILT_IN_PROPERTIES.forEach(function (property) {
13404 _this.registerMetadata(property);
13405 });
13406 }
13407 DefaultStyleValueRegistry.prototype.registerMetadata = function (metadata) {
13408 __spreadArray([metadata.n], __read((metadata.a || [])), false).forEach(function (name) {
13409 propertyMetadataCache[name] = metadata;
13410 });
13411 };
13412 DefaultStyleValueRegistry.prototype.unregisterMetadata = function (name) {
13413 delete propertyMetadataCache[name];
13414 };
13415 DefaultStyleValueRegistry.prototype.getPropertySyntax = function (syntax) {
13416 return this.runtime.CSSPropertySyntaxFactory[syntax];
13417 };
13418 /**
13419 * * parse value, eg.
13420 * fill: 'red' => CSSRGB
13421 * translateX: '10px' => CSSUnitValue { unit: 'px', value: 10 }
13422 * fontSize: '2em' => { unit: 'px', value: 32 }
13423 *
13424 * * calculate used value
13425 * * post process
13426 */
13427 DefaultStyleValueRegistry.prototype.processProperties = function (object, attributes, options) {
13428 var _this = this;
13429 if (options === void 0) { options = {
13430 skipUpdateAttribute: false,
13431 skipParse: false,
13432 forceUpdateGeometry: false,
13433 usedAttributes: [],
13434 memoize: true,
13435 }; }
13436 if (!this.runtime.enableCSSParsing) {
13437 Object.assign(object.attributes, attributes);
13438 var attributeNames_1 = Object.keys(attributes);
13439 // clipPath
13440 var oldClipPath = object.parsedStyle.clipPath;
13441 var oldOffsetPath = object.parsedStyle.offsetPath;
13442 object.parsedStyle = Object.assign(object.parsedStyle, attributes);
13443 var needUpdateGeometry_1 = !!options.forceUpdateGeometry;
13444 if (!needUpdateGeometry_1) {
13445 for (var i = 0; i < GEOMETRY_ATTRIBUTE_NAMES.length; i++) {
13446 if (GEOMETRY_ATTRIBUTE_NAMES[i] in attributes) {
13447 needUpdateGeometry_1 = true;
13448 break;
13449 }
13450 }
13451 }
13452 if (attributes.fill) {
13453 object.parsedStyle.fill = parseColor(attributes.fill);
13454 }
13455 if (attributes.stroke) {
13456 object.parsedStyle.stroke = parseColor(attributes.stroke);
13457 }
13458 if (attributes.shadowColor) {
13459 object.parsedStyle.shadowColor = parseColor(attributes.shadowColor);
13460 }
13461 if (attributes.filter) {
13462 object.parsedStyle.filter = parseFilter(attributes.filter);
13463 }
13464 // Rect
13465 // @ts-ignore
13466 if (!isNil(attributes.radius)) {
13467 // @ts-ignore
13468 object.parsedStyle.radius = parseDimensionArrayFormat(
13469 // @ts-ignore
13470 attributes.radius, 4);
13471 }
13472 // Polyline
13473 if (!isNil(attributes.lineDash)) {
13474 object.parsedStyle.lineDash = parseDimensionArrayFormat(attributes.lineDash, 2);
13475 }
13476 // @ts-ignore
13477 if (attributes.points) {
13478 // @ts-ignore
13479 object.parsedStyle.points = parsePoints(attributes.points, object);
13480 }
13481 // Path
13482 // @ts-ignore
13483 if (attributes.path === '') {
13484 object.parsedStyle.path = __assign({}, EMPTY_PARSED_PATH);
13485 }
13486 // @ts-ignore
13487 if (attributes.path) {
13488 object.parsedStyle.path = parsePath(
13489 // @ts-ignore
13490 attributes.path);
13491 object.parsedStyle.defX = object.parsedStyle.path.rect.x;
13492 object.parsedStyle.defY = object.parsedStyle.path.rect.y;
13493 }
13494 // Text
13495 if (attributes.textTransform) {
13496 this.runtime.CSSPropertySyntaxFactory['<text-transform>'].calculator(null, null, { value: attributes.textTransform }, object, null);
13497 }
13498 if (attributes.clipPath) {
13499 this.runtime.CSSPropertySyntaxFactory['<defined-path>'].calculator('clipPath', oldClipPath, attributes.clipPath, object, this.runtime);
13500 }
13501 if (attributes.offsetPath) {
13502 this.runtime.CSSPropertySyntaxFactory['<defined-path>'].calculator('offsetPath', oldOffsetPath, attributes.offsetPath, object, this.runtime);
13503 }
13504 if (attributes.anchor) {
13505 object.parsedStyle.anchor = parseDimensionArrayFormat(
13506 // @ts-ignorex
13507 attributes.anchor, 2);
13508 }
13509 if (attributes.transform) {
13510 object.parsedStyle.transform = parseTransform(attributes.transform);
13511 }
13512 if (attributes.transformOrigin) {
13513 object.parsedStyle.transformOrigin = parseTransformOrigin(attributes.transformOrigin);
13514 }
13515 // Marker
13516 // @ts-ignore
13517 if (attributes.markerStart) {
13518 object.parsedStyle.markerStart = this.runtime.CSSPropertySyntaxFactory['<marker>'].calculator(null,
13519 // @ts-ignore
13520 attributes.markerStart,
13521 // @ts-ignore
13522 attributes.markerStart, null, null);
13523 }
13524 // @ts-ignore
13525 if (attributes.markerEnd) {
13526 object.parsedStyle.markerEnd = this.runtime.CSSPropertySyntaxFactory['<marker>'].calculator(null,
13527 // @ts-ignore
13528 attributes.markerEnd,
13529 // @ts-ignore
13530 attributes.markerEnd, null, null);
13531 }
13532 // @ts-ignore
13533 if (attributes.markerMid) {
13534 object.parsedStyle.markerMid = this.runtime.CSSPropertySyntaxFactory['<marker>'].calculator('',
13535 // @ts-ignore
13536 attributes.markerMid,
13537 // @ts-ignore
13538 attributes.markerMid, null, null);
13539 }
13540 if (
13541 // Circle & Ellipse
13542 ((object.nodeName === Shape.CIRCLE ||
13543 object.nodeName === Shape.ELLIPSE) &&
13544 // @ts-ignore
13545 (!isNil(attributes.cx) ||
13546 // @ts-ignore
13547 !isNil(attributes.cy))) ||
13548 ((object.nodeName === Shape.RECT ||
13549 object.nodeName === Shape.IMAGE ||
13550 object.nodeName === Shape.GROUP ||
13551 object.nodeName === Shape.HTML ||
13552 object.nodeName === Shape.TEXT ||
13553 object.nodeName === Shape.MESH) &&
13554 // @ts-ignore
13555 (!isNil(attributes.x) ||
13556 // @ts-ignore
13557 !isNil(attributes.y) ||
13558 // @ts-ignore
13559 !isNil(attributes.z))) ||
13560 // Line
13561 (object.nodeName === Shape.LINE &&
13562 // @ts-ignore
13563 (!isNil(attributes.x1) ||
13564 // @ts-ignore
13565 !isNil(attributes.y1) ||
13566 // @ts-ignore
13567 !isNil(attributes.z1) ||
13568 // @ts-ignore
13569 !isNil(attributes.x2) ||
13570 // @ts-ignore
13571 !isNil(attributes.y2) ||
13572 // @ts-ignore
13573 !isNil(attributes.z2)))) {
13574 this.runtime.CSSPropertySyntaxFactory['<coordinate>'].postProcessor(object, attributeNames_1);
13575 }
13576 if (!isNil(attributes.zIndex)) {
13577 this.runtime.CSSPropertySyntaxFactory['<z-index>'].postProcessor(object, attributeNames_1);
13578 }
13579 // @ts-ignore
13580 if (attributes.path) {
13581 this.runtime.CSSPropertySyntaxFactory['<path>'].postProcessor(object, attributeNames_1);
13582 }
13583 // @ts-ignore
13584 if (attributes.points) {
13585 this.runtime.CSSPropertySyntaxFactory['<list-of-points>'].postProcessor(object, attributeNames_1);
13586 }
13587 if (!isNil(attributes.offsetDistance)) {
13588 this.runtime.CSSPropertySyntaxFactory['<offset-distance>'].postProcessor(object, attributeNames_1);
13589 }
13590 if (attributes.transform) {
13591 this.runtime.CSSPropertySyntaxFactory['<transform>'].postProcessor(object, attributeNames_1);
13592 }
13593 if (needUpdateGeometry_1) {
13594 this.updateGeometry(object);
13595 }
13596 return;
13597 }
13598 var skipUpdateAttribute = options.skipUpdateAttribute, skipParse = options.skipParse, forceUpdateGeometry = options.forceUpdateGeometry, usedAttributes = options.usedAttributes, memoize = options.memoize;
13599 var needUpdateGeometry = forceUpdateGeometry;
13600 var attributeNames = Object.keys(attributes);
13601 attributeNames.forEach(function (attributeName) {
13602 var _a;
13603 if (!skipUpdateAttribute) {
13604 object.attributes[attributeName] = attributes[attributeName];
13605 }
13606 if (!needUpdateGeometry && ((_a = propertyMetadataCache[attributeName]) === null || _a === void 0 ? void 0 : _a.l)) {
13607 needUpdateGeometry = true;
13608 }
13609 });
13610 if (!skipParse) {
13611 attributeNames.forEach(function (name) {
13612 object.computedStyle[name] = _this.parseProperty(name, object.attributes[name], object, memoize);
13613 });
13614 }
13615 // let hasUnresolvedProperties = false;
13616 // parse according to priority
13617 // path 50
13618 // points 50
13619 // text 50
13620 // textTransform 51
13621 // anchor 99
13622 // transform 100
13623 // transformOrigin 100
13624 if (usedAttributes === null || usedAttributes === void 0 ? void 0 : usedAttributes.length) {
13625 // uniqueAttributeSet.clear();
13626 attributeNames = Array.from(new Set(attributeNames.concat(usedAttributes)));
13627 }
13628 // [
13629 // 'path',
13630 // 'points',
13631 // 'text',
13632 // 'textTransform',
13633 // 'anchor',
13634 // 'transform',
13635 // 'transformOrigin',
13636 // ].forEach((name) => {
13637 // const index = attributeNames.indexOf(name);
13638 // if (index > -1) {
13639 // attributeNames.splice(index, 1);
13640 // attributeNames.push(name);
13641 // }
13642 // });
13643 attributeNames.forEach(function (name) {
13644 // some style props maybe deleted after parsing such as `anchor` in Text
13645 if (name in object.computedStyle) {
13646 object.parsedStyle[name] = _this.computeProperty(name, object.computedStyle[name], object, memoize);
13647 }
13648 });
13649 // if (hasUnresolvedProperties) {
13650 // this.dirty = true;
13651 // return;
13652 // }
13653 // update geometry
13654 if (needUpdateGeometry) {
13655 // object.geometry.dirty = true;
13656 // runtime.sceneGraphService.dirtifyToRoot(object);
13657 this.updateGeometry(object);
13658 }
13659 attributeNames.forEach(function (name) {
13660 if (name in object.parsedStyle) {
13661 _this.postProcessProperty(name, object, attributeNames);
13662 }
13663 });
13664 if (this.runtime.enableCSSParsing && object.children.length) {
13665 attributeNames.forEach(function (name) {
13666 if (name in object.parsedStyle && _this.isPropertyInheritable(name)) {
13667 // update children's inheritable
13668 object.children.forEach(function (child) {
13669 child.internalSetAttribute(name, null, {
13670 skipUpdateAttribute: true,
13671 skipParse: true,
13672 });
13673 });
13674 }
13675 });
13676 }
13677 };
13678 /**
13679 * string -> parsed value
13680 */
13681 DefaultStyleValueRegistry.prototype.parseProperty = function (name, value, object, memoized) {
13682 var metadata = propertyMetadataCache[name];
13683 var computed = value;
13684 if (value === '' || isNil(value)) {
13685 value = 'unset';
13686 }
13687 if (value === 'unset' || value === 'initial' || value === 'inherit') {
13688 // computed = new CSSKeywordValue(value);
13689 computed = getOrCreateKeyword(value);
13690 }
13691 else {
13692 if (metadata) {
13693 var keywords = metadata.k, syntax = metadata.syntax;
13694 var handler = syntax && this.getPropertySyntax(syntax);
13695 // use keywords
13696 if (keywords && keywords.indexOf(value) > -1) {
13697 // computed = new CSSKeywordValue(value);
13698 computed = getOrCreateKeyword(value);
13699 }
13700 else if (handler) {
13701 if (!memoized && handler.parserUnmemoize) {
13702 computed = handler.parserUnmemoize(value, object);
13703 }
13704 else if (handler.parser) {
13705 // try to parse it to CSSStyleValue, eg. '10px' -> CSS.px(10)
13706 computed = handler.parser(value, object);
13707 }
13708 }
13709 }
13710 }
13711 return computed;
13712 };
13713 /**
13714 * computed value -> used value
13715 */
13716 DefaultStyleValueRegistry.prototype.computeProperty = function (name, computed, object, memoized) {
13717 var metadata = propertyMetadataCache[name];
13718 var isDocumentElement = object.id === 'g-root';
13719 // let used: CSSStyleValue = computed instanceof CSSStyleValue ? computed.clone() : computed;
13720 var used = computed;
13721 if (metadata) {
13722 var syntax = metadata.syntax, inherited = metadata.inh, defaultValue = metadata.d;
13723 if (computed instanceof CSSKeywordValue) {
13724 var value = computed.value;
13725 /**
13726 * @see https://developer.mozilla.org/zh-CN/docs/Web/CSS/unset
13727 */
13728 if (value === 'unset') {
13729 if (inherited && !isDocumentElement) {
13730 value = 'inherit';
13731 }
13732 else {
13733 value = 'initial';
13734 }
13735 }
13736 if (value === 'initial') {
13737 // @see https://developer.mozilla.org/en-US/docs/Web/CSS/initial
13738 if (!isNil(defaultValue)) {
13739 computed = this.parseProperty(name, isFunction$1(defaultValue)
13740 ? defaultValue(object.nodeName)
13741 : defaultValue, object, memoized);
13742 }
13743 }
13744 else if (value === 'inherit') {
13745 // @see https://developer.mozilla.org/en-US/docs/Web/CSS/inherit
13746 // behave like `inherit`
13747 var resolved = this.tryToResolveProperty(object, name, {
13748 inherited: true,
13749 });
13750 if (!isNil(resolved)) {
13751 // object.parsedStyle[name] = resolved;
13752 // return false;
13753 return resolved;
13754 }
13755 else {
13756 this.addUnresolveProperty(object, name);
13757 return;
13758 }
13759 }
13760 }
13761 var handler = syntax && this.getPropertySyntax(syntax);
13762 if (handler && handler.calculator) {
13763 // convert computed value to used value
13764 var oldParsedValue = object.parsedStyle[name];
13765 used = handler.calculator(name, oldParsedValue, computed, object, this.runtime);
13766 }
13767 else if (computed instanceof CSSKeywordValue) {
13768 used = computed.value;
13769 }
13770 else {
13771 used = computed;
13772 }
13773 }
13774 // object.parsedStyle[name] = used;
13775 // return false;
13776 return used;
13777 };
13778 DefaultStyleValueRegistry.prototype.postProcessProperty = function (name, object, attributes) {
13779 var metadata = propertyMetadataCache[name];
13780 if (metadata && metadata.syntax) {
13781 var handler = metadata.syntax && this.getPropertySyntax(metadata.syntax);
13782 var propertyHandler = handler;
13783 if (propertyHandler && propertyHandler.postProcessor) {
13784 propertyHandler.postProcessor(object, attributes);
13785 }
13786 }
13787 };
13788 /**
13789 * resolve later
13790 */
13791 DefaultStyleValueRegistry.prototype.addUnresolveProperty = function (object, name) {
13792 var properties = unresolvedProperties.get(object);
13793 if (!properties) {
13794 unresolvedProperties.set(object, []);
13795 properties = unresolvedProperties.get(object);
13796 }
13797 if (properties.indexOf(name) === -1) {
13798 properties.push(name);
13799 }
13800 };
13801 DefaultStyleValueRegistry.prototype.tryToResolveProperty = function (object, name, options) {
13802 if (options === void 0) { options = {}; }
13803 var inherited = options.inherited;
13804 if (inherited) {
13805 if (object.parentElement &&
13806 isPropertyResolved(object.parentElement, name)) {
13807 // const computedValue = object.parentElement.computedStyle[name];
13808 var usedValue = object.parentElement.parsedStyle[name];
13809 if (
13810 // usedValue instanceof CSSKeywordValue &&
13811 usedValue === 'unset' ||
13812 usedValue === 'initial' ||
13813 usedValue === 'inherit') {
13814 return;
13815 }
13816 // else if (
13817 // usedValue instanceof CSSUnitValue &&
13818 // CSSUnitValue.isRelativeUnit(usedValue.unit)
13819 // ) {
13820 // return false;
13821 // }
13822 return usedValue;
13823 }
13824 }
13825 return;
13826 };
13827 DefaultStyleValueRegistry.prototype.recalc = function (object) {
13828 var properties = unresolvedProperties.get(object);
13829 if (properties && properties.length) {
13830 var attributes_1 = {};
13831 properties.forEach(function (property) {
13832 attributes_1[property] = object.attributes[property];
13833 });
13834 this.processProperties(object, attributes_1);
13835 unresolvedProperties.delete(object);
13836 }
13837 };
13838 /**
13839 * update geometry when relative props changed,
13840 * eg. r of Circle, width/height of Rect
13841 */
13842 DefaultStyleValueRegistry.prototype.updateGeometry = function (object) {
13843 var nodeName = object.nodeName;
13844 var geometryUpdater = this.runtime.geometryUpdaterFactory[nodeName];
13845 if (geometryUpdater) {
13846 var geometry_1 = object.geometry;
13847 if (!geometry_1.contentBounds) {
13848 geometry_1.contentBounds = new AABB();
13849 }
13850 if (!geometry_1.renderBounds) {
13851 geometry_1.renderBounds = new AABB();
13852 }
13853 var parsedStyle = object.parsedStyle;
13854 var _a = geometryUpdater.update(parsedStyle, object), width = _a.width, height = _a.height, _b = _a.depth, depth = _b === void 0 ? 0 : _b, _c = _a.offsetX, offsetX = _c === void 0 ? 0 : _c, _d = _a.offsetY, offsetY = _d === void 0 ? 0 : _d, _e = _a.offsetZ, offsetZ = _e === void 0 ? 0 : _e;
13855 // init with content box
13856 var halfExtents = [
13857 Math.abs(width) / 2,
13858 Math.abs(height) / 2,
13859 depth / 2,
13860 ];
13861 // const halfExtents = vec3.set(
13862 // tmpVec3a,
13863 // Math.abs(width) / 2,
13864 // Math.abs(height) / 2,
13865 // depth / 2,
13866 // );
13867 // anchor is center by default, don't account for lineWidth here
13868 var _f = parsedStyle, stroke = _f.stroke, lineWidth = _f.lineWidth,
13869 // lineCap,
13870 // lineJoin,
13871 // miterLimit,
13872 increasedLineWidthForHitTesting = _f.increasedLineWidthForHitTesting, shadowType = _f.shadowType, shadowColor = _f.shadowColor, _g = _f.filter, filter = _g === void 0 ? [] : _g, transformOrigin = _f.transformOrigin;
13873 var anchor = parsedStyle.anchor;
13874 // <Text> use textAlign & textBaseline instead of anchor
13875 if (nodeName === Shape.TEXT) {
13876 delete parsedStyle.anchor;
13877 }
13878 else if (nodeName === Shape.MESH) {
13879 parsedStyle.anchor[2] = 0.5;
13880 }
13881 var center = [
13882 ((1 - ((anchor && anchor[0]) || 0) * 2) * width) / 2 + offsetX,
13883 ((1 - ((anchor && anchor[1]) || 0) * 2) * height) / 2 + offsetY,
13884 (1 - ((anchor && anchor[2]) || 0) * 2) * halfExtents[2] + offsetZ,
13885 ];
13886 // const center = vec3.set(
13887 // tmpVec3b,
13888 // ((1 - ((anchor && anchor[0]) || 0) * 2) * width) / 2 + offsetX,
13889 // ((1 - ((anchor && anchor[1]) || 0) * 2) * height) / 2 + offsetY,
13890 // (1 - ((anchor && anchor[2]) || 0) * 2) * halfExtents[2] + offsetZ,
13891 // );
13892 // update geometry's AABB
13893 geometry_1.contentBounds.update(center, halfExtents);
13894 // @see https://github.molgen.mpg.de/git-mirror/cairo/blob/master/src/cairo-stroke-style.c#L97..L128
13895 var expansion = nodeName === Shape.POLYLINE ||
13896 nodeName === Shape.POLYGON ||
13897 nodeName === Shape.PATH
13898 ? Math.SQRT2
13899 : 0.5;
13900 // if (lineCap?.value === 'square') {
13901 // expansion = Math.SQRT1_2;
13902 // }
13903 // if (lineJoin?.value === 'miter' && expansion < Math.SQRT2 * miterLimit) {
13904 // expansion = Math.SQRT1_2 * miterLimit;
13905 // }
13906 // append border only if stroke existed
13907 var hasStroke = stroke && !stroke.isNone;
13908 if (hasStroke) {
13909 var halfLineWidth = ((lineWidth || 0) + (increasedLineWidthForHitTesting || 0)) *
13910 expansion;
13911 // halfExtents[0] += halfLineWidth[0];
13912 // halfExtents[1] += halfLineWidth[1];
13913 halfExtents[0] += halfLineWidth;
13914 halfExtents[1] += halfLineWidth;
13915 // vec3.add(
13916 // halfExtents,
13917 // halfExtents,
13918 // vec3.set(tmpVec3c, halfLineWidth, halfLineWidth, 0),
13919 // );
13920 }
13921 geometry_1.renderBounds.update(center, halfExtents);
13922 // account for shadow, only support constant value now
13923 if (shadowColor && shadowType && shadowType !== 'inner') {
13924 var _h = geometry_1.renderBounds, min = _h.min, max = _h.max;
13925 var _j = parsedStyle, shadowBlur = _j.shadowBlur, shadowOffsetX = _j.shadowOffsetX, shadowOffsetY = _j.shadowOffsetY;
13926 var shadowBlurInPixels = shadowBlur || 0;
13927 var shadowOffsetXInPixels = shadowOffsetX || 0;
13928 var shadowOffsetYInPixels = shadowOffsetY || 0;
13929 var shadowLeft = min[0] - shadowBlurInPixels + shadowOffsetXInPixels;
13930 var shadowRight = max[0] + shadowBlurInPixels + shadowOffsetXInPixels;
13931 var shadowTop = min[1] - shadowBlurInPixels + shadowOffsetYInPixels;
13932 var shadowBottom = max[1] + shadowBlurInPixels + shadowOffsetYInPixels;
13933 min[0] = Math.min(min[0], shadowLeft);
13934 max[0] = Math.max(max[0], shadowRight);
13935 min[1] = Math.min(min[1], shadowTop);
13936 max[1] = Math.max(max[1], shadowBottom);
13937 geometry_1.renderBounds.setMinMax(min, max);
13938 }
13939 // account for filter, eg. blur(5px), drop-shadow()
13940 filter.forEach(function (_a) {
13941 var name = _a.name, params = _a.params;
13942 if (name === 'blur') {
13943 var blurRadius = params[0].value;
13944 geometry_1.renderBounds.update(geometry_1.renderBounds.center, addVec3(geometry_1.renderBounds.halfExtents, geometry_1.renderBounds.halfExtents, [blurRadius, blurRadius, 0]));
13945 }
13946 else if (name === 'drop-shadow') {
13947 var shadowOffsetX = params[0].value;
13948 var shadowOffsetY = params[1].value;
13949 var shadowBlur = params[2].value;
13950 var _b = geometry_1.renderBounds, min = _b.min, max = _b.max;
13951 var shadowLeft = min[0] - shadowBlur + shadowOffsetX;
13952 var shadowRight = max[0] + shadowBlur + shadowOffsetX;
13953 var shadowTop = min[1] - shadowBlur + shadowOffsetY;
13954 var shadowBottom = max[1] + shadowBlur + shadowOffsetY;
13955 min[0] = Math.min(min[0], shadowLeft);
13956 max[0] = Math.max(max[0], shadowRight);
13957 min[1] = Math.min(min[1], shadowTop);
13958 max[1] = Math.max(max[1], shadowBottom);
13959 geometry_1.renderBounds.setMinMax(min, max);
13960 }
13961 });
13962 anchor = parsedStyle.anchor;
13963 // if (nodeName === Shape.RECT) {
13964 // account for negative width / height of Rect
13965 // @see https://github.com/antvis/g/issues/957
13966 var flipY = width < 0;
13967 var flipX = height < 0;
13968 // } else {
13969 // }
13970 // set transform origin
13971 var usedOriginXValue = (flipY ? -1 : 1) *
13972 (transformOrigin
13973 ? convertPercentUnit(transformOrigin[0], 0, object)
13974 : 0);
13975 var usedOriginYValue = (flipX ? -1 : 1) *
13976 (transformOrigin
13977 ? convertPercentUnit(transformOrigin[1], 1, object)
13978 : 0);
13979 usedOriginXValue =
13980 usedOriginXValue -
13981 (flipY ? -1 : 1) *
13982 ((anchor && anchor[0]) || 0) *
13983 geometry_1.contentBounds.halfExtents[0] *
13984 2;
13985 usedOriginYValue =
13986 usedOriginYValue -
13987 (flipX ? -1 : 1) *
13988 ((anchor && anchor[1]) || 0) *
13989 geometry_1.contentBounds.halfExtents[1] *
13990 2;
13991 object.setOrigin(usedOriginXValue, usedOriginYValue);
13992 // FIXME setOrigin may have already dirtified to root.
13993 this.runtime.sceneGraphService.dirtifyToRoot(object);
13994 }
13995 };
13996 DefaultStyleValueRegistry.prototype.updateSizeAttenuation = function (node, zoom) {
13997 if (node.style.isSizeAttenuation) {
13998 if (!node.style.rawLineWidth) {
13999 node.style.rawLineWidth = node.style.lineWidth;
14000 }
14001 node.style.lineWidth = node.style.rawLineWidth / zoom;
14002 if (node.nodeName === Shape.CIRCLE) {
14003 if (!node.style.rawR) {
14004 node.style.rawR = node.style.r;
14005 }
14006 node.style.r = node.style.rawR / zoom;
14007 }
14008 }
14009 else {
14010 if (node.style.rawLineWidth) {
14011 node.style.lineWidth = node.style.rawLineWidth;
14012 delete node.style.rawLineWidth;
14013 }
14014 if (node.nodeName === Shape.CIRCLE) {
14015 if (node.style.rawR) {
14016 node.style.r = node.style.rawR;
14017 delete node.style.rawR;
14018 }
14019 }
14020 }
14021 };
14022 DefaultStyleValueRegistry.prototype.isPropertyInheritable = function (name) {
14023 var metadata = propertyMetadataCache[name];
14024 if (!metadata) {
14025 return false;
14026 }
14027 return metadata.inh;
14028 };
14029 return DefaultStyleValueRegistry;
14030 }());
14031
14032 var CSSPropertyAngle = /** @class */ (function () {
14033 function CSSPropertyAngle() {
14034 this.parser = parseAngle;
14035 this.parserUnmemoize = parseAngleUnmemoize;
14036 this.parserWithCSSDisabled = null;
14037 this.mixer = mergeNumbers;
14038 }
14039 CSSPropertyAngle.prototype.calculator = function (name, oldParsed, parsed, object) {
14040 return convertAngleUnit(parsed);
14041 };
14042 return CSSPropertyAngle;
14043 }());
14044
14045 /**
14046 * clipPath / textPath / offsetPath
14047 */
14048 var CSSPropertyClipPath = /** @class */ (function () {
14049 function CSSPropertyClipPath() {
14050 }
14051 CSSPropertyClipPath.prototype.calculator = function (name, oldPath, newPath, object, runtime) {
14052 // unset
14053 if (newPath instanceof CSSKeywordValue) {
14054 newPath = null;
14055 }
14056 runtime.sceneGraphService.updateDisplayObjectDependency(name, oldPath, newPath, object);
14057 if (name === 'clipPath') {
14058 // should affect children
14059 object.forEach(function (leaf) {
14060 if (leaf.childNodes.length === 0) {
14061 runtime.sceneGraphService.dirtifyToRoot(leaf);
14062 }
14063 });
14064 }
14065 return newPath;
14066 };
14067 return CSSPropertyClipPath;
14068 }());
14069
14070 var CSSPropertyColor = /** @class */ (function () {
14071 function CSSPropertyColor() {
14072 this.parser = parseColor;
14073 this.parserWithCSSDisabled = parseColor;
14074 this.mixer = mergeColors;
14075 }
14076 CSSPropertyColor.prototype.calculator = function (name, oldParsed, parsed, object) {
14077 if (parsed instanceof CSSKeywordValue) {
14078 // 'unset' 'none'
14079 return parsed.value === 'none' ? noneColor : transparentColor;
14080 }
14081 return parsed;
14082 };
14083 return CSSPropertyColor;
14084 }());
14085
14086 var CSSPropertyFilter = /** @class */ (function () {
14087 function CSSPropertyFilter() {
14088 this.parser = parseFilter;
14089 }
14090 CSSPropertyFilter.prototype.calculator = function (name, oldParsed, parsed) {
14091 // unset or none
14092 if (parsed instanceof CSSKeywordValue) {
14093 return [];
14094 }
14095 return parsed;
14096 };
14097 return CSSPropertyFilter;
14098 }());
14099
14100 function getFontSize(object) {
14101 var fontSize = object.parsedStyle.fontSize;
14102 return isNil(fontSize) ? null : fontSize;
14103 }
14104 /**
14105 * <length> & <percentage>
14106 */
14107 var CSSPropertyLengthOrPercentage = /** @class */ (function () {
14108 function CSSPropertyLengthOrPercentage() {
14109 this.parser = parseLengthOrPercentage;
14110 this.parserUnmemoize = parseLengthOrPercentageUnmemoize;
14111 this.parserWithCSSDisabled = null;
14112 this.mixer = mergeNumbers;
14113 }
14114 /**
14115 * according to parent's bounds
14116 *
14117 * @example
14118 * CSS.percent(50) -> CSS.px(0.5 * parent.width)
14119 */
14120 CSSPropertyLengthOrPercentage.prototype.calculator = function (name, oldParsed, computed, object, runtime) {
14121 var _a;
14122 if (isNumber(computed)) {
14123 return computed;
14124 }
14125 if (CSSUnitValue.isRelativeUnit(computed.unit)) {
14126 var registry = runtime.styleValueRegistry;
14127 if (computed.unit === UnitType.kPercentage) {
14128 // TODO: merge dimensions
14129 return 0;
14130 }
14131 else if (computed.unit === UnitType.kEms) {
14132 if (object.parentNode) {
14133 var fontSize = getFontSize(object.parentNode);
14134 if (fontSize) {
14135 fontSize *= computed.value;
14136 return fontSize;
14137 }
14138 else {
14139 registry.addUnresolveProperty(object, name);
14140 }
14141 }
14142 else {
14143 registry.addUnresolveProperty(object, name);
14144 }
14145 return 0;
14146 }
14147 else if (computed.unit === UnitType.kRems) {
14148 if ((_a = object === null || object === void 0 ? void 0 : object.ownerDocument) === null || _a === void 0 ? void 0 : _a.documentElement) {
14149 var fontSize = getFontSize(object.ownerDocument.documentElement);
14150 if (fontSize) {
14151 fontSize *= computed.value;
14152 return fontSize;
14153 }
14154 else {
14155 registry.addUnresolveProperty(object, name);
14156 }
14157 }
14158 else {
14159 registry.addUnresolveProperty(object, name);
14160 }
14161 return 0;
14162 }
14163 }
14164 else {
14165 // remove listener if exists
14166 // registry.unregisterParentGeometryBoundsChangedHandler(object, name);
14167 // return absolute value
14168 return computed.value;
14169 }
14170 };
14171 return CSSPropertyLengthOrPercentage;
14172 }());
14173
14174 /**
14175 * format to Tuple2<CSSUnitValue>
14176 *
14177 * @example
14178 * rect.style.lineDash = 10;
14179 * rect.style.lineDash = [10, 10];
14180 * rect.style.lineDash = '10 10';
14181 */
14182 var CSSPropertyLengthOrPercentage12 = /** @class */ (function () {
14183 function CSSPropertyLengthOrPercentage12() {
14184 this.mixer = mergeNumberLists;
14185 }
14186 CSSPropertyLengthOrPercentage12.prototype.parser = function (radius) {
14187 var parsed = parseDimensionArray(isNumber(radius) ? [radius] : radius);
14188 var formatted;
14189 if (parsed.length === 1) {
14190 formatted = [parsed[0], parsed[0]];
14191 }
14192 else {
14193 formatted = [parsed[0], parsed[1]];
14194 }
14195 return formatted;
14196 };
14197 CSSPropertyLengthOrPercentage12.prototype.calculator = function (name, oldParsed, computed) {
14198 return computed.map(function (c) { return c.value; });
14199 };
14200 return CSSPropertyLengthOrPercentage12;
14201 }());
14202
14203 /**
14204 * used in rounded rect
14205 *
14206 * @example
14207 * rect.style.radius = 10;
14208 * rect.style.radius = '10 10';
14209 * rect.style.radius = '10 10 10 10';
14210 */
14211 var CSSPropertyLengthOrPercentage14 = /** @class */ (function () {
14212 function CSSPropertyLengthOrPercentage14() {
14213 this.mixer = mergeNumberLists;
14214 }
14215 CSSPropertyLengthOrPercentage14.prototype.parser = function (radius) {
14216 var parsed = parseDimensionArray(isNumber(radius) ? [radius] : radius);
14217 var formatted;
14218 // format to Tuple<CSSUnitValue>
14219 if (parsed.length === 1) {
14220 formatted = [parsed[0], parsed[0], parsed[0], parsed[0]];
14221 }
14222 else if (parsed.length === 2) {
14223 formatted = [parsed[0], parsed[1], parsed[0], parsed[1]];
14224 }
14225 else if (parsed.length === 3) {
14226 formatted = [parsed[0], parsed[1], parsed[2], parsed[1]];
14227 }
14228 else {
14229 formatted = [parsed[0], parsed[1], parsed[2], parsed[3]];
14230 }
14231 return formatted;
14232 };
14233 CSSPropertyLengthOrPercentage14.prototype.calculator = function (name, oldParsed, computed) {
14234 return computed.map(function (c) { return c.value; });
14235 };
14236 return CSSPropertyLengthOrPercentage14;
14237 }());
14238
14239 var tmpMat4 = create$1();
14240 function parsedTransformToMat4(transform, object) {
14241 var defX = object.parsedStyle.defX || 0;
14242 var defY = object.parsedStyle.defY || 0;
14243 // reset transform
14244 object.resetLocalTransform();
14245 object.setLocalPosition(defX, defY);
14246 transform.forEach(function (parsed) {
14247 var t = parsed.t, d = parsed.d;
14248 if (t === 'scale') {
14249 // scale(1) scale(1, 1)
14250 var newScale = (d === null || d === void 0 ? void 0 : d.map(function (s) { return s.value; })) || [1, 1];
14251 object.scaleLocal(newScale[0], newScale[1], 1);
14252 }
14253 else if (t === 'scalex') {
14254 var newScale = (d === null || d === void 0 ? void 0 : d.map(function (s) { return s.value; })) || [1];
14255 object.scaleLocal(newScale[0], 1, 1);
14256 }
14257 else if (t === 'scaley') {
14258 var newScale = (d === null || d === void 0 ? void 0 : d.map(function (s) { return s.value; })) || [1];
14259 object.scaleLocal(1, newScale[0], 1);
14260 }
14261 else if (t === 'scalez') {
14262 var newScale = (d === null || d === void 0 ? void 0 : d.map(function (s) { return s.value; })) || [1];
14263 object.scaleLocal(1, 1, newScale[0]);
14264 }
14265 else if (t === 'scale3d') {
14266 var newScale = (d === null || d === void 0 ? void 0 : d.map(function (s) { return s.value; })) || [1, 1, 1];
14267 object.scaleLocal(newScale[0], newScale[1], newScale[2]);
14268 }
14269 else if (t === 'translate') {
14270 var newTranslation = d || [Opx, Opx];
14271 object.translateLocal(newTranslation[0].value, newTranslation[1].value, 0);
14272 }
14273 else if (t === 'translatex') {
14274 var newTranslation = d || [Opx];
14275 object.translateLocal(newTranslation[0].value, 0, 0);
14276 }
14277 else if (t === 'translatey') {
14278 var newTranslation = d || [Opx];
14279 object.translateLocal(0, newTranslation[0].value, 0);
14280 }
14281 else if (t === 'translatez') {
14282 var newTranslation = d || [Opx];
14283 object.translateLocal(0, 0, newTranslation[0].value);
14284 }
14285 else if (t === 'translate3d') {
14286 var newTranslation = d || [Opx, Opx, Opx];
14287 object.translateLocal(newTranslation[0].value, newTranslation[1].value, newTranslation[2].value);
14288 }
14289 else if (t === 'rotate') {
14290 var newAngles = d || [Odeg];
14291 object.rotateLocal(0, 0, convertAngleUnit(newAngles[0]));
14292 }
14293 else if (t === 'rotatex') {
14294 var newAngles = d || [Odeg];
14295 object.rotateLocal(convertAngleUnit(newAngles[0]), 0, 0);
14296 }
14297 else if (t === 'rotatey') {
14298 var newAngles = d || [Odeg];
14299 object.rotateLocal(0, convertAngleUnit(newAngles[0]), 0);
14300 }
14301 else if (t === 'rotatez') {
14302 var newAngles = d || [Odeg];
14303 object.rotateLocal(0, 0, convertAngleUnit(newAngles[0]));
14304 }
14305 else if (t === 'rotate3d') ;
14306 else if (t === 'skew') {
14307 var newSkew = (d === null || d === void 0 ? void 0 : d.map(function (s) { return s.value; })) || [0, 0];
14308 object.setLocalSkew(deg2rad(newSkew[0]), deg2rad(newSkew[1]));
14309 }
14310 else if (t === 'skewx') {
14311 var newSkew = (d === null || d === void 0 ? void 0 : d.map(function (s) { return s.value; })) || [0];
14312 object.setLocalSkew(deg2rad(newSkew[0]), object.getLocalSkew()[1]);
14313 }
14314 else if (t === 'skewy') {
14315 var newSkew = (d === null || d === void 0 ? void 0 : d.map(function (s) { return s.value; })) || [0];
14316 object.setLocalSkew(object.getLocalSkew()[0], deg2rad(newSkew[0]));
14317 }
14318 else if (t === 'matrix') {
14319 var _a = __read(d.map(function (s) { return s.value; }), 6), a = _a[0], b = _a[1], c = _a[2], dd = _a[3], tx = _a[4], ty = _a[5];
14320 object.setLocalTransform(set(tmpMat4, a, b, 0, 0, c, dd, 0, 0, 0, 0, 1, 0, tx + defX, ty + defY, 0, 1));
14321 }
14322 else if (t === 'matrix3d') {
14323 // @ts-ignore
14324 set.apply(mat4, __spreadArray([tmpMat4], __read(d.map(function (s) { return s.value; })), false));
14325 tmpMat4[12] += defX;
14326 tmpMat4[13] += defY;
14327 object.setLocalTransform(tmpMat4);
14328 }
14329 });
14330 return object.getLocalTransform();
14331 }
14332
14333 /**
14334 * local position
14335 */
14336 var CSSPropertyLocalPosition = /** @class */ (function (_super) {
14337 __extends(CSSPropertyLocalPosition, _super);
14338 function CSSPropertyLocalPosition() {
14339 return _super !== null && _super.apply(this, arguments) || this;
14340 }
14341 /**
14342 * update local position
14343 */
14344 CSSPropertyLocalPosition.prototype.postProcessor = function (object, attributes) {
14345 var x;
14346 var y;
14347 var z;
14348 switch (object.nodeName) {
14349 case Shape.CIRCLE:
14350 case Shape.ELLIPSE:
14351 var _a = object.parsedStyle, cx = _a.cx, cy = _a.cy, cz = _a.cz;
14352 if (!isNil(cx)) {
14353 x = cx;
14354 }
14355 if (!isNil(cy)) {
14356 y = cy;
14357 }
14358 if (!isNil(cz)) {
14359 z = cz;
14360 }
14361 break;
14362 case Shape.LINE:
14363 var _b = object.parsedStyle, x1 = _b.x1, x2 = _b.x2, y1 = _b.y1, y2 = _b.y2;
14364 var minX = Math.min(x1, x2);
14365 var minY = Math.min(y1, y2);
14366 x = minX;
14367 y = minY;
14368 z = 0;
14369 break;
14370 case Shape.RECT:
14371 case Shape.IMAGE:
14372 case Shape.GROUP:
14373 case Shape.HTML:
14374 case Shape.TEXT:
14375 case Shape.MESH:
14376 if (!isNil(object.parsedStyle.x)) {
14377 x = object.parsedStyle.x;
14378 }
14379 if (!isNil(object.parsedStyle.y)) {
14380 y = object.parsedStyle.y;
14381 }
14382 if (!isNil(object.parsedStyle.z)) {
14383 z = object.parsedStyle.z;
14384 }
14385 break;
14386 }
14387 if (object.nodeName !== Shape.PATH &&
14388 object.nodeName !== Shape.POLYLINE &&
14389 object.nodeName !== Shape.POLYGON) {
14390 object.parsedStyle.defX = x || 0;
14391 object.parsedStyle.defY = y || 0;
14392 }
14393 var needResetLocalPosition = !isNil(x) || !isNil(y) || !isNil(z);
14394 // only if `transform` won't be processed later
14395 if (needResetLocalPosition && attributes.indexOf('transform') === -1) {
14396 // account for current transform if needed
14397 var transform = object.parsedStyle.transform;
14398 if (transform && transform.length) {
14399 parsedTransformToMat4(transform, object);
14400 }
14401 else {
14402 var _c = __read(object.getLocalPosition(), 3), ox = _c[0], oy = _c[1], oz = _c[2];
14403 object.setLocalPosition(isNil(x) ? ox : x, isNil(y) ? oy : y, isNil(z) ? oz : z);
14404 }
14405 }
14406 };
14407 return CSSPropertyLocalPosition;
14408 }(CSSPropertyLengthOrPercentage));
14409
14410 var CSSPropertyMarker = /** @class */ (function () {
14411 function CSSPropertyMarker() {
14412 }
14413 CSSPropertyMarker.prototype.calculator = function (name, oldMarker, newMarker, object) {
14414 // unset
14415 if (newMarker instanceof CSSKeywordValue) {
14416 newMarker = null;
14417 }
14418 var cloned = newMarker === null || newMarker === void 0 ? void 0 : newMarker.cloneNode(true);
14419 if (cloned) {
14420 // FIXME: SVG should not inherit parent's style, add a flag here
14421 cloned.style.isMarker = true;
14422 }
14423 return cloned;
14424 };
14425 return CSSPropertyMarker;
14426 }());
14427
14428 var CSSPropertyNumber = /** @class */ (function () {
14429 function CSSPropertyNumber() {
14430 this.mixer = mergeNumbers;
14431 this.parser = parseNumber;
14432 this.parserUnmemoize = parseNumberUnmemoize;
14433 this.parserWithCSSDisabled = null;
14434 }
14435 CSSPropertyNumber.prototype.calculator = function (name, oldParsed, computed) {
14436 return computed.value;
14437 };
14438 return CSSPropertyNumber;
14439 }());
14440
14441 var CSSPropertyOffsetDistance = /** @class */ (function () {
14442 function CSSPropertyOffsetDistance() {
14443 this.parser = parseNumber;
14444 this.parserUnmemoize = parseNumberUnmemoize;
14445 this.parserWithCSSDisabled = null;
14446 this.mixer = clampedMergeNumbers(0, 1);
14447 }
14448 CSSPropertyOffsetDistance.prototype.calculator = function (name, oldParsed, computed) {
14449 return computed.value;
14450 };
14451 CSSPropertyOffsetDistance.prototype.postProcessor = function (object) {
14452 var _a = object.parsedStyle, offsetPath = _a.offsetPath, offsetDistance = _a.offsetDistance;
14453 if (!offsetPath) {
14454 return;
14455 }
14456 var nodeName = offsetPath.nodeName;
14457 if (nodeName === Shape.LINE ||
14458 nodeName === Shape.PATH ||
14459 nodeName === Shape.POLYLINE) {
14460 // set position in world space
14461 var point = offsetPath.getPoint(offsetDistance);
14462 if (point) {
14463 object.parsedStyle.defX = point.x;
14464 object.parsedStyle.defY = point.y;
14465 object.setLocalPosition(point.x, point.y);
14466 }
14467 }
14468 };
14469 return CSSPropertyOffsetDistance;
14470 }());
14471
14472 /**
14473 * opacity
14474 */
14475 var CSSPropertyOpacity = /** @class */ (function () {
14476 function CSSPropertyOpacity() {
14477 this.parser = parseNumber;
14478 this.parserUnmemoize = parseNumberUnmemoize;
14479 this.parserWithCSSDisabled = null;
14480 this.mixer = clampedMergeNumbers(0, 1);
14481 }
14482 CSSPropertyOpacity.prototype.calculator = function (name, oldParsed, computed) {
14483 return computed.value;
14484 };
14485 return CSSPropertyOpacity;
14486 }());
14487
14488 var CSSPropertyPath = /** @class */ (function () {
14489 function CSSPropertyPath() {
14490 /**
14491 * path2Curve
14492 */
14493 this.parser = parsePath;
14494 this.parserWithCSSDisabled = parsePath;
14495 this.mixer = mergePaths;
14496 }
14497 CSSPropertyPath.prototype.calculator = function (name, oldParsed, parsed) {
14498 // unset
14499 if (parsed instanceof CSSKeywordValue && parsed.value === 'unset') {
14500 return {
14501 absolutePath: [],
14502 hasArc: false,
14503 segments: [],
14504 polygons: [],
14505 polylines: [],
14506 curve: null,
14507 totalLength: 0,
14508 rect: new Rectangle(0, 0, 0, 0),
14509 };
14510 }
14511 return parsed;
14512 };
14513 /**
14514 * update local position
14515 */
14516 CSSPropertyPath.prototype.postProcessor = function (object, attributes) {
14517 object.parsedStyle.defX = object.parsedStyle.path.rect.x;
14518 object.parsedStyle.defY = object.parsedStyle.path.rect.y;
14519 if (object.nodeName === Shape.PATH &&
14520 attributes.indexOf('transform') === -1) {
14521 var _a = object.parsedStyle, _b = _a.defX, defX = _b === void 0 ? 0 : _b, _c = _a.defY, defY = _c === void 0 ? 0 : _c;
14522 object.setLocalPosition(defX, defY);
14523 }
14524 };
14525 return CSSPropertyPath;
14526 }());
14527
14528 var CSSPropertyPoints = /** @class */ (function () {
14529 function CSSPropertyPoints() {
14530 this.parser = parsePoints;
14531 this.mixer = mergePoints;
14532 }
14533 /**
14534 * update local position
14535 */
14536 CSSPropertyPoints.prototype.postProcessor = function (object, attributes) {
14537 if ((object.nodeName === Shape.POLYGON ||
14538 object.nodeName === Shape.POLYLINE) &&
14539 attributes.indexOf('transform') === -1) {
14540 var _a = object.parsedStyle, defX = _a.defX, defY = _a.defY;
14541 object.setLocalPosition(defX, defY);
14542 }
14543 };
14544 return CSSPropertyPoints;
14545 }());
14546
14547 var CSSPropertyShadowBlur = /** @class */ (function (_super) {
14548 __extends(CSSPropertyShadowBlur, _super);
14549 function CSSPropertyShadowBlur() {
14550 var _this = _super.apply(this, __spreadArray([], __read(arguments), false)) || this;
14551 _this.mixer = clampedMergeNumbers(0, Infinity);
14552 return _this;
14553 }
14554 return CSSPropertyShadowBlur;
14555 }(CSSPropertyLengthOrPercentage));
14556
14557 var CSSPropertyText = /** @class */ (function () {
14558 function CSSPropertyText() {
14559 }
14560 CSSPropertyText.prototype.calculator = function (name, oldParsed, parsed, object) {
14561 if (parsed instanceof CSSKeywordValue) {
14562 if (parsed.value === 'unset') {
14563 return '';
14564 }
14565 else {
14566 return parsed.value;
14567 }
14568 }
14569 // allow number as valid text content
14570 return "".concat(parsed);
14571 };
14572 CSSPropertyText.prototype.postProcessor = function (object) {
14573 object.nodeValue = "".concat(object.parsedStyle.text) || '';
14574 };
14575 return CSSPropertyText;
14576 }());
14577
14578 /**
14579 * it must transform after text get parsed
14580 * @see https://developer.mozilla.org/zh-CN/docs/Web/CSS/text-transform
14581 */
14582 var CSSPropertyTextTransform = /** @class */ (function () {
14583 function CSSPropertyTextTransform() {
14584 }
14585 CSSPropertyTextTransform.prototype.calculator = function (name, oldParsed, parsed, object) {
14586 var rawText = object.getAttribute('text');
14587 if (rawText) {
14588 var transformedText = rawText;
14589 if (parsed.value === 'capitalize') {
14590 transformedText = rawText.charAt(0).toUpperCase() + rawText.slice(1);
14591 }
14592 else if (parsed.value === 'lowercase') {
14593 transformedText = rawText.toLowerCase();
14594 }
14595 else if (parsed.value === 'uppercase') {
14596 transformedText = rawText.toUpperCase();
14597 }
14598 object.parsedStyle.text = transformedText;
14599 }
14600 return parsed.value;
14601 };
14602 return CSSPropertyTextTransform;
14603 }());
14604
14605 var canvasMap = {};
14606 var defaultCanvasIdCounter = 0;
14607 /**
14608 * destroy existed canvas with the same id
14609 */
14610 function cleanExistedCanvas(container, canvas) {
14611 if (container) {
14612 var id = typeof container === 'string'
14613 ? container
14614 : container.id || defaultCanvasIdCounter++;
14615 if (canvasMap[id]) {
14616 canvasMap[id].destroy();
14617 }
14618 canvasMap[id] = canvas;
14619 }
14620 }
14621 var isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
14622
14623 function isElement(target) {
14624 return !!target.getAttribute;
14625 }
14626 function sortedIndex(array, value) {
14627 var low = 0;
14628 var high = array.length;
14629 while (low < high) {
14630 var mid = (low + high) >>> 1;
14631 if (sortByZIndex(array[mid], value) < 0) {
14632 low = mid + 1;
14633 }
14634 else {
14635 high = mid;
14636 }
14637 }
14638 return low;
14639 }
14640 function sortByZIndex(o1, o2) {
14641 var zIndex1 = Number(o1.parsedStyle.zIndex);
14642 var zIndex2 = Number(o2.parsedStyle.zIndex);
14643 if (zIndex1 === zIndex2) {
14644 var parent_1 = o1.parentNode;
14645 if (parent_1) {
14646 var children = parent_1.childNodes || [];
14647 return children.indexOf(o1) - children.indexOf(o2);
14648 }
14649 }
14650 return zIndex1 - zIndex2;
14651 }
14652 function findClosestClipPathTarget(object) {
14653 var _a;
14654 var el = object;
14655 do {
14656 var clipPath = (_a = el.parsedStyle) === null || _a === void 0 ? void 0 : _a.clipPath;
14657 if (clipPath)
14658 return el;
14659 el = el.parentElement;
14660 } while (el !== null);
14661 return null;
14662 }
14663 function getStyle($el, property) {
14664 if (isBrowser) {
14665 return document.defaultView
14666 .getComputedStyle($el, null)
14667 .getPropertyValue(property);
14668 }
14669 }
14670 function getWidth($el) {
14671 var width = getStyle($el, 'width');
14672 if (width === 'auto') {
14673 return $el.offsetWidth;
14674 }
14675 return parseFloat(width);
14676 }
14677 function getHeight($el) {
14678 var height = getStyle($el, 'height');
14679 if (height === 'auto') {
14680 return $el.offsetHeight;
14681 }
14682 return parseFloat(height);
14683 }
14684
14685 // borrow from hammer.js
14686 var MOUSE_POINTER_ID = 1;
14687 var TOUCH_TO_POINTER = {
14688 touchstart: 'pointerdown',
14689 touchend: 'pointerup',
14690 touchendoutside: 'pointerupoutside',
14691 touchmove: 'pointermove',
14692 touchcancel: 'pointercancel',
14693 };
14694 var clock = typeof performance === 'object' && performance.now ? performance : Date;
14695
14696 function isFillOrStrokeAffected(pointerEvents, fill, stroke) {
14697 // account for pointerEvents
14698 // @see https://developer.mozilla.org/en-US/docs/Web/CSS/pointer-events
14699 var hasFill = false;
14700 var hasStroke = false;
14701 var isFillOtherThanNone = !!fill && !fill.isNone;
14702 var isStrokeOtherThanNone = !!stroke && !stroke.isNone;
14703 if (pointerEvents === 'visiblepainted' ||
14704 pointerEvents === 'painted' ||
14705 pointerEvents === 'auto') {
14706 hasFill = isFillOtherThanNone;
14707 hasStroke = isStrokeOtherThanNone;
14708 }
14709 else if (pointerEvents === 'visiblefill' || pointerEvents === 'fill') {
14710 hasFill = true;
14711 }
14712 else if (pointerEvents === 'visiblestroke' || pointerEvents === 'stroke') {
14713 hasStroke = true;
14714 }
14715 else if (pointerEvents === 'visible' || pointerEvents === 'all') {
14716 // The values of the fill and stroke do not affect event processing.
14717 hasFill = true;
14718 hasStroke = true;
14719 }
14720 return [hasFill, hasStroke];
14721 }
14722
14723 /**
14724 * Thanks for following contributor of codes
14725 * https://gist.github.com/1866474
14726 * http://paulirish.com/2011/requestanimationframe-for-smart-animating/
14727 * http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
14728 * https://github.com/Financial-Times/polyfill-library/blob/master/polyfills/requestAnimationFrame/polyfill.js
14729 **/
14730 var uId = 1;
14731 var uniqueId = function () { return uId++; };
14732 // We use `self` instead of `window` for `WebWorker` support.
14733 var root = typeof self === 'object' && self.self == self
14734 ? self
14735 : // @ts-ignore
14736 typeof global === 'object' && global.global == global
14737 ? // @ts-ignore
14738 global
14739 : {};
14740 var nowOffset = Date.now();
14741 // use performance api if exist, otherwise use Date.now.
14742 // Date.now polyfill required.
14743 var pnow = function () {
14744 if (root.performance && typeof root.performance.now === 'function') {
14745 return root.performance.now();
14746 }
14747 // fallback
14748 return Date.now() - nowOffset;
14749 };
14750 var reservedCBs = {};
14751 var lastTime = Date.now();
14752 var polyfillRaf = function (callback) {
14753 if (typeof callback !== 'function') {
14754 throw new TypeError(callback + ' is not a function');
14755 }
14756 var currentTime = Date.now();
14757 var gap = currentTime - lastTime;
14758 var delay = gap > 16 ? 0 : 16 - gap;
14759 var id = uniqueId();
14760 reservedCBs[id] = callback;
14761 // keys(reservedCBs).length > 1 의미는 이미 setTimeout 이 걸려있는 경우.
14762 // 함께 callback 이 실행될 수 있게 reservedCBs 에만 추가해주고 return
14763 if (Object.keys(reservedCBs).length > 1)
14764 return id;
14765 setTimeout(function () {
14766 lastTime = currentTime;
14767 var copied = reservedCBs;
14768 reservedCBs = {};
14769 Object.keys(copied).forEach(function (key) { return copied[key](pnow()); });
14770 }, delay);
14771 return id;
14772 };
14773 var polyfillCaf = function (id) {
14774 delete reservedCBs[id];
14775 };
14776 var vendorPrefixes = ['', 'webkit', 'moz', 'ms', 'o'];
14777 var getRequestAnimationFrame = function (vp) {
14778 if (typeof vp !== 'string')
14779 return polyfillRaf;
14780 if (vp === '')
14781 return root['requestAnimationFrame'];
14782 return root[vp + 'RequestAnimationFrame'];
14783 };
14784 var getCancelAnimationFrame = function (vp) {
14785 if (typeof vp !== 'string')
14786 return polyfillCaf;
14787 if (vp === '')
14788 return root['cancelAnimationFrame'];
14789 return (root[vp + 'CancelAnimationFrame'] ||
14790 root[vp + 'CancelRequestAnimationFrame']);
14791 };
14792 var find$1 = function (arr, predicate) {
14793 var i = 0;
14794 while (arr[i] !== void 0) {
14795 if (predicate(arr[i]))
14796 return arr[i];
14797 i = i + 1;
14798 }
14799 };
14800 var vp = find$1(vendorPrefixes, function (vp) { return !!getRequestAnimationFrame(vp); });
14801 var raf = getRequestAnimationFrame(vp);
14802 var caf = getCancelAnimationFrame(vp);
14803 root.requestAnimationFrame = raf;
14804 root.cancelAnimationFrame = caf;
14805
14806 var AsyncParallelHook = /** @class */ (function () {
14807 function AsyncParallelHook() {
14808 this.callbacks = [];
14809 }
14810 AsyncParallelHook.prototype.getCallbacksNum = function () {
14811 return this.callbacks.length;
14812 };
14813 AsyncParallelHook.prototype.tapPromise = function (options, fn) {
14814 this.callbacks.push(fn);
14815 };
14816 AsyncParallelHook.prototype.promise = function () {
14817 var args = [];
14818 for (var _i = 0; _i < arguments.length; _i++) {
14819 args[_i] = arguments[_i];
14820 }
14821 return Promise.all(this.callbacks.map(function (callback) {
14822 return callback.apply(void 0, __spreadArray([], __read(args), false));
14823 }));
14824 };
14825 return AsyncParallelHook;
14826 }());
14827
14828 var AsyncSeriesWaterfallHook = /** @class */ (function () {
14829 function AsyncSeriesWaterfallHook() {
14830 this.callbacks = [];
14831 }
14832 AsyncSeriesWaterfallHook.prototype.tapPromise = function (options, fn) {
14833 this.callbacks.push(fn);
14834 };
14835 AsyncSeriesWaterfallHook.prototype.promise = function () {
14836 var args = [];
14837 for (var _i = 0; _i < arguments.length; _i++) {
14838 args[_i] = arguments[_i];
14839 }
14840 return __awaiter(this, void 0, void 0, function () {
14841 var result, i, callback;
14842 var _a;
14843 return __generator(this, function (_b) {
14844 switch (_b.label) {
14845 case 0:
14846 if (!this.callbacks.length) return [3 /*break*/, 6];
14847 return [4 /*yield*/, (_a = this.callbacks)[0].apply(_a, __spreadArray([], __read(args), false))];
14848 case 1:
14849 result = _b.sent();
14850 i = 0;
14851 _b.label = 2;
14852 case 2:
14853 if (!(i < this.callbacks.length - 1)) return [3 /*break*/, 5];
14854 callback = this.callbacks[i];
14855 return [4 /*yield*/, callback(result)];
14856 case 3:
14857 // @ts-ignore
14858 result = _b.sent();
14859 _b.label = 4;
14860 case 4:
14861 i++;
14862 return [3 /*break*/, 2];
14863 case 5: return [2 /*return*/, result];
14864 case 6: return [2 /*return*/, null];
14865 }
14866 });
14867 });
14868 };
14869 return AsyncSeriesWaterfallHook;
14870 }());
14871
14872 var SyncHook = /** @class */ (function () {
14873 function SyncHook() {
14874 this.callbacks = [];
14875 }
14876 SyncHook.prototype.tap = function (options, fn) {
14877 this.callbacks.push(fn);
14878 };
14879 SyncHook.prototype.call = function () {
14880 /* eslint-disable-next-line prefer-rest-params */
14881 var argsArr = arguments;
14882 this.callbacks.forEach(function (callback) {
14883 /* eslint-disable-next-line prefer-spread */
14884 callback.apply(void 0, argsArr);
14885 });
14886 };
14887 return SyncHook;
14888 }());
14889
14890 var SyncWaterfallHook = /** @class */ (function () {
14891 function SyncWaterfallHook() {
14892 this.callbacks = [];
14893 }
14894 SyncWaterfallHook.prototype.tap = function (options, fn) {
14895 this.callbacks.push(fn);
14896 };
14897 SyncWaterfallHook.prototype.call = function () {
14898 if (this.callbacks.length) {
14899 /* eslint-disable-next-line prefer-rest-params */
14900 var argsArr = arguments;
14901 /* eslint-disable-next-line prefer-spread */
14902 var result = this.callbacks[0].apply(void 0, argsArr);
14903 for (var i = 0; i < this.callbacks.length - 1; i++) {
14904 var callback = this.callbacks[i];
14905 // @ts-ignore
14906 result = callback(result);
14907 }
14908 return result;
14909 }
14910 return null;
14911 };
14912 return SyncWaterfallHook;
14913 }());
14914
14915 var genericFontFamilies = [
14916 'serif',
14917 'sans-serif',
14918 'monospace',
14919 'cursive',
14920 'fantasy',
14921 'system-ui',
14922 ];
14923 var stringRegExp = /([\"\'])[^\'\"]+\1/;
14924 function toFontString(attributes) {
14925 var fontSize = attributes.fontSize, fontFamily = attributes.fontFamily, fontStyle = attributes.fontStyle, fontVariant = attributes.fontVariant, fontWeight = attributes.fontWeight;
14926 // build canvas api font setting from individual components. Convert a numeric this.fontSize to px
14927 // const fontSizeString: string = isNumber(fontSize) ? `${fontSize}px` : fontSize.toString();
14928 var fontSizeString = (isNumber(fontSize) && "".concat(fontSize, "px")) || '16px';
14929 // Clean-up fontFamily property by quoting each font name
14930 // this will support font names with spaces
14931 var fontFamilies = fontFamily.split(',');
14932 for (var i = fontFamilies.length - 1; i >= 0; i--) {
14933 // Trim any extra white-space
14934 var fontFamily_1 = fontFamilies[i].trim();
14935 // Check if font already contains strings
14936 if (!stringRegExp.test(fontFamily_1) &&
14937 genericFontFamilies.indexOf(fontFamily_1) < 0) {
14938 fontFamily_1 = "\"".concat(fontFamily_1, "\"");
14939 }
14940 fontFamilies[i] = fontFamily_1;
14941 }
14942 return "".concat(fontStyle, " ").concat(fontVariant, " ").concat(fontWeight, " ").concat(fontSizeString, " ").concat(fontFamilies.join(','));
14943 }
14944
14945 /**
14946 * @see /zh/docs/api/animation#支持变换的属性
14947 *
14948 * support the following formats like CSS Transform:
14949 *
14950 * scale
14951 * * scale(x, y)
14952 * * scaleX(x)
14953 * * scaleY(x)
14954 * * scaleZ(z)
14955 * * scale3d(x, y, z)
14956 *
14957 * translate (unit: none, px, %(relative to its bounds))
14958 * * translate(x, y) eg. translate(0, 0) translate(0, 30px) translate(100%, 100%)
14959 * * translateX(0)
14960 * * translateY(0)
14961 * * translateZ(0)
14962 * * translate3d(0, 0, 0)
14963 *
14964 * rotate (unit: deg rad turn)
14965 * * rotate(0.5turn) rotate(30deg) rotate(1rad)
14966 *
14967 * none
14968 *
14969 * unsupported for now:
14970 * * calc() eg. translate(calc(100% + 10px))
14971 * * matrix/matrix3d()
14972 * * skew/skewX/skewY
14973 * * perspective
14974 */
14975 var CSSPropertyTransform = /** @class */ (function () {
14976 function CSSPropertyTransform() {
14977 this.parser = parseTransform;
14978 this.parserUnmemoize = parseTransformUnmemoize;
14979 this.parserWithCSSDisabled = parseTransformUnmemoize;
14980 this.mixer = mergeTransforms;
14981 }
14982 CSSPropertyTransform.prototype.calculator = function (name, oldParsed, parsed, object) {
14983 // 'none'
14984 if (parsed instanceof CSSKeywordValue) {
14985 return [];
14986 }
14987 return parsed;
14988 };
14989 CSSPropertyTransform.prototype.postProcessor = function (object) {
14990 var transform = object.parsedStyle.transform;
14991 parsedTransformToMat4(transform, object);
14992 };
14993 return CSSPropertyTransform;
14994 }());
14995
14996 /**
14997 * @see https://developer.mozilla.org/zh-CN/docs/Web/CSS/transform-origin
14998 * @example
14999 * [10px, 10px] [10%, 10%]
15000 */
15001 var CSSPropertyTransformOrigin = /** @class */ (function () {
15002 function CSSPropertyTransformOrigin() {
15003 this.parser = parseTransformOrigin;
15004 this.parserUnmemoize = parseTransformOriginUnmemoize;
15005 // calculator(
15006 // name: string,
15007 // oldParsed: [CSSUnitValue, CSSUnitValue],
15008 // parsed: [CSSUnitValue, CSSUnitValue],
15009 // object: DisplayObject,
15010 // ): [number, number] {
15011 // console.log(object, parsed);
15012 // return [parsed[0].value, parsed[1].value];
15013 // // return [convertPercentUnit(parsed[0], 0, object), convertPercentUnit(parsed[1], 1, object)];
15014 // }
15015 }
15016 return CSSPropertyTransformOrigin;
15017 }());
15018
15019 var CSSPropertyZIndex = /** @class */ (function () {
15020 function CSSPropertyZIndex() {
15021 this.parser = parseNumber;
15022 this.parserUnmemoize = parseNumberUnmemoize;
15023 }
15024 CSSPropertyZIndex.prototype.calculator = function (name, oldParsed, computed, object) {
15025 return computed.value;
15026 };
15027 CSSPropertyZIndex.prototype.postProcessor = function (object) {
15028 if (object.parentNode) {
15029 var parentEntity = object.parentNode;
15030 var parentRenderable = parentEntity.renderable;
15031 var parentSortable = parentEntity.sortable;
15032 if (parentRenderable) {
15033 parentRenderable.dirty = true;
15034 }
15035 // need re-sort on parent
15036 if (parentSortable) {
15037 parentSortable.dirty = true;
15038 parentSortable.dirtyReason = SortReason.Z_INDEX_CHANGED;
15039 }
15040 }
15041 };
15042 return CSSPropertyZIndex;
15043 }());
15044
15045 var CircleUpdater = /** @class */ (function () {
15046 function CircleUpdater() {
15047 }
15048 CircleUpdater.prototype.update = function (parsedStyle, object) {
15049 var r = parsedStyle.r;
15050 var width = r * 2;
15051 var height = r * 2;
15052 return {
15053 width: width,
15054 height: height,
15055 };
15056 };
15057 return CircleUpdater;
15058 }());
15059
15060 var EllipseUpdater = /** @class */ (function () {
15061 function EllipseUpdater() {
15062 }
15063 EllipseUpdater.prototype.update = function (parsedStyle, object) {
15064 var rx = parsedStyle.rx, ry = parsedStyle.ry;
15065 var width = rx * 2;
15066 var height = ry * 2;
15067 return {
15068 width: width,
15069 height: height,
15070 };
15071 };
15072 return EllipseUpdater;
15073 }());
15074
15075 var LineUpdater = /** @class */ (function () {
15076 function LineUpdater() {
15077 }
15078 LineUpdater.prototype.update = function (parsedStyle) {
15079 var x1 = parsedStyle.x1, y1 = parsedStyle.y1, x2 = parsedStyle.x2, y2 = parsedStyle.y2;
15080 var minX = Math.min(x1, x2);
15081 var maxX = Math.max(x1, x2);
15082 var minY = Math.min(y1, y2);
15083 var maxY = Math.max(y1, y2);
15084 var width = maxX - minX;
15085 var height = maxY - minY;
15086 return {
15087 width: width,
15088 height: height,
15089 };
15090 };
15091 return LineUpdater;
15092 }());
15093
15094 var PathUpdater = /** @class */ (function () {
15095 function PathUpdater() {
15096 }
15097 PathUpdater.prototype.update = function (parsedStyle) {
15098 var path = parsedStyle.path;
15099 var _a = path.rect, width = _a.width, height = _a.height;
15100 return {
15101 width: width,
15102 height: height,
15103 };
15104 };
15105 return PathUpdater;
15106 }());
15107
15108 var PolylineUpdater = /** @class */ (function () {
15109 function PolylineUpdater() {
15110 }
15111 PolylineUpdater.prototype.update = function (parsedStyle) {
15112 if (parsedStyle.points && isArray(parsedStyle.points.points)) {
15113 var points = parsedStyle.points.points;
15114 // FIXME: account for miter lineJoin
15115 var minX = Math.min.apply(Math, __spreadArray([], __read(points.map(function (point) { return point[0]; })), false));
15116 var maxX = Math.max.apply(Math, __spreadArray([], __read(points.map(function (point) { return point[0]; })), false));
15117 var minY = Math.min.apply(Math, __spreadArray([], __read(points.map(function (point) { return point[1]; })), false));
15118 var maxY = Math.max.apply(Math, __spreadArray([], __read(points.map(function (point) { return point[1]; })), false));
15119 var width = maxX - minX;
15120 var height = maxY - minY;
15121 return {
15122 width: width,
15123 height: height,
15124 };
15125 }
15126 return {
15127 width: 0,
15128 height: 0,
15129 };
15130 };
15131 return PolylineUpdater;
15132 }());
15133
15134 var RectUpdater = /** @class */ (function () {
15135 function RectUpdater() {
15136 }
15137 RectUpdater.prototype.update = function (parsedStyle, object) {
15138 var img = parsedStyle.img, _a = parsedStyle.width, width = _a === void 0 ? 0 : _a, _b = parsedStyle.height, height = _b === void 0 ? 0 : _b;
15139 var contentWidth = width;
15140 var contentHeight = height;
15141 // resize with HTMLImageElement's size
15142 if (img && !isString(img)) {
15143 if (!contentWidth) {
15144 contentWidth = img.width;
15145 parsedStyle.width = contentWidth;
15146 }
15147 if (!contentHeight) {
15148 contentHeight = img.height;
15149 parsedStyle.height = contentHeight;
15150 }
15151 }
15152 return {
15153 width: contentWidth,
15154 height: contentHeight,
15155 };
15156 };
15157 return RectUpdater;
15158 }());
15159
15160 var TextUpdater = /** @class */ (function () {
15161 function TextUpdater(globalRuntime) {
15162 this.globalRuntime = globalRuntime;
15163 }
15164 TextUpdater.prototype.isReadyToMeasure = function (parsedStyle, object) {
15165 var text = parsedStyle.text, textAlign = parsedStyle.textAlign, textBaseline = parsedStyle.textBaseline, fontSize = parsedStyle.fontSize, fontStyle = parsedStyle.fontStyle, fontWeight = parsedStyle.fontWeight, fontVariant = parsedStyle.fontVariant, lineWidth = parsedStyle.lineWidth;
15166 return (text &&
15167 fontSize &&
15168 fontStyle &&
15169 fontWeight &&
15170 fontVariant &&
15171 textAlign &&
15172 textBaseline &&
15173 !isNil(lineWidth));
15174 };
15175 TextUpdater.prototype.update = function (parsedStyle, object) {
15176 var _a, _b;
15177 var text = parsedStyle.text, textAlign = parsedStyle.textAlign, lineWidth = parsedStyle.lineWidth, textBaseline = parsedStyle.textBaseline, dx = parsedStyle.dx, dy = parsedStyle.dy;
15178 if (!this.isReadyToMeasure(parsedStyle, object)) {
15179 parsedStyle.metrics = {
15180 font: '',
15181 width: 0,
15182 height: 0,
15183 lines: [],
15184 lineWidths: [],
15185 lineHeight: 0,
15186 maxLineWidth: 0,
15187 fontProperties: {
15188 ascent: 0,
15189 descent: 0,
15190 fontSize: 0,
15191 },
15192 lineMetrics: [],
15193 };
15194 return {
15195 width: 0,
15196 height: 0,
15197 x: 0,
15198 y: 0,
15199 offsetX: 0,
15200 offsetY: 0,
15201 };
15202 }
15203 var offscreenCanvas = (((_b = (_a = object === null || object === void 0 ? void 0 : object.ownerDocument) === null || _a === void 0 ? void 0 : _a.defaultView) === null || _b === void 0 ? void 0 : _b.getConfig()) || {}).offscreenCanvas;
15204 var metrics = this.globalRuntime.textService.measureText(text, parsedStyle, offscreenCanvas);
15205 parsedStyle.metrics = metrics;
15206 var width = metrics.width, height = metrics.height, lineHeight = metrics.lineHeight, fontProperties = metrics.fontProperties;
15207 // anchor is left-top by default
15208 var halfExtents = [width / 2, height / 2, 0];
15209 // default 'left'
15210 var anchor = [0, 1];
15211 var lineXOffset = 0;
15212 if (textAlign === 'center' || textAlign === 'middle') {
15213 lineXOffset = lineWidth / 2;
15214 anchor = [0.5, 1];
15215 }
15216 else if (textAlign === 'right' || textAlign === 'end') {
15217 lineXOffset = lineWidth;
15218 anchor = [1, 1];
15219 }
15220 var lineYOffset = 0;
15221 if (textBaseline === 'middle') {
15222 // eslint-disable-next-line prefer-destructuring
15223 lineYOffset = halfExtents[1];
15224 }
15225 else if (textBaseline === 'top' || textBaseline === 'hanging') {
15226 lineYOffset = halfExtents[1] * 2;
15227 }
15228 else if (textBaseline === 'alphabetic') {
15229 // prevent calling getImageData for ascent metrics
15230 lineYOffset = this.globalRuntime.enableCSSParsing
15231 ? lineHeight - fontProperties.ascent
15232 : 0;
15233 }
15234 else if (textBaseline === 'bottom' || textBaseline === 'ideographic') {
15235 lineYOffset = 0;
15236 }
15237 // TODO: ideographic & bottom
15238 if (dx) {
15239 lineXOffset += dx;
15240 }
15241 if (dy) {
15242 lineYOffset += dy;
15243 }
15244 // update anchor
15245 parsedStyle.anchor = [anchor[0], anchor[1], 0];
15246 return {
15247 width: halfExtents[0] * 2,
15248 height: halfExtents[1] * 2,
15249 offsetX: lineXOffset,
15250 offsetY: lineYOffset,
15251 };
15252 };
15253 return TextUpdater;
15254 }());
15255
15256 function isFederatedEvent(value) {
15257 return !!value.type;
15258 }
15259 /**
15260 * An DOM-compatible synthetic event implementation that is "forwarded" on behalf of an original
15261 * FederatedEvent or native Event.
15262 */
15263 var FederatedEvent = /** @class */ (function () {
15264 /**
15265 * The event boundary which manages this event. Propagation can only occur
15266 * within the boundary's jurisdiction.
15267 */
15268 function FederatedEvent(manager) {
15269 /**
15270 * The propagation phase.
15271 * @see https://developer.mozilla.org/en-US/docs/Web/API/Event/eventPhase
15272 */
15273 this.eventPhase = FederatedEvent.prototype.NONE;
15274 /**
15275 * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Event/bubbles
15276 */
15277 this.bubbles = true;
15278 /**
15279 * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Event/cancelBubble
15280 */
15281 this.cancelBubble = true;
15282 /**
15283 * @see https://developer.mozilla.org/en-US/docs/Web/API/Event/cancelable
15284 */
15285 this.cancelable = false;
15286 /** Flags whether the default response of the user agent was prevent through this event. */
15287 this.defaultPrevented = false;
15288 /** Flags whether propagation was stopped. */
15289 this.propagationStopped = false;
15290 /** Flags whether propagation was immediately stopped. */
15291 this.propagationImmediatelyStopped = false;
15292 /**
15293 * The coordinates of the evnet relative to the nearest DOM layer.
15294 * This is a non-standard property.
15295 */
15296 this.layer = new Point();
15297 /**
15298 * The coordinates of the event relative to the DOM document.
15299 * This is a non-standard property.
15300 * relative to the DOM document.
15301 * @see https://developer.mozilla.org/zh-CN/docs/Web/API/MouseEvent/pageX
15302 */
15303 this.page = new Point();
15304 /**
15305 * relative to Canvas, origin is left-top
15306 */
15307 this.canvas = new Point();
15308 /**
15309 * relative to Viewport, account for Camera
15310 */
15311 this.viewport = new Point();
15312 this.composed = false;
15313 this.NONE = 0;
15314 this.CAPTURING_PHASE = 1;
15315 this.AT_TARGET = 2;
15316 this.BUBBLING_PHASE = 3;
15317 this.manager = manager;
15318 }
15319 Object.defineProperty(FederatedEvent.prototype, "name", {
15320 /**
15321 * @deprecated
15322 */
15323 get: function () {
15324 return this.type;
15325 },
15326 enumerable: false,
15327 configurable: true
15328 });
15329 Object.defineProperty(FederatedEvent.prototype, "layerX", {
15330 get: function () {
15331 return this.layer.x;
15332 },
15333 enumerable: false,
15334 configurable: true
15335 });
15336 Object.defineProperty(FederatedEvent.prototype, "layerY", {
15337 get: function () {
15338 return this.layer.y;
15339 },
15340 enumerable: false,
15341 configurable: true
15342 });
15343 Object.defineProperty(FederatedEvent.prototype, "pageX", {
15344 get: function () {
15345 return this.page.x;
15346 },
15347 enumerable: false,
15348 configurable: true
15349 });
15350 Object.defineProperty(FederatedEvent.prototype, "pageY", {
15351 get: function () {
15352 return this.page.y;
15353 },
15354 enumerable: false,
15355 configurable: true
15356 });
15357 Object.defineProperty(FederatedEvent.prototype, "x", {
15358 get: function () {
15359 return this.canvas.x;
15360 },
15361 enumerable: false,
15362 configurable: true
15363 });
15364 Object.defineProperty(FederatedEvent.prototype, "y", {
15365 get: function () {
15366 return this.canvas.y;
15367 },
15368 enumerable: false,
15369 configurable: true
15370 });
15371 Object.defineProperty(FederatedEvent.prototype, "canvasX", {
15372 get: function () {
15373 return this.canvas.x;
15374 },
15375 enumerable: false,
15376 configurable: true
15377 });
15378 Object.defineProperty(FederatedEvent.prototype, "canvasY", {
15379 get: function () {
15380 return this.canvas.y;
15381 },
15382 enumerable: false,
15383 configurable: true
15384 });
15385 Object.defineProperty(FederatedEvent.prototype, "viewportX", {
15386 get: function () {
15387 return this.viewport.x;
15388 },
15389 enumerable: false,
15390 configurable: true
15391 });
15392 Object.defineProperty(FederatedEvent.prototype, "viewportY", {
15393 get: function () {
15394 return this.viewport.y;
15395 },
15396 enumerable: false,
15397 configurable: true
15398 });
15399 /**
15400 * The propagation path for this event
15401 * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Event/composedPath
15402 *
15403 * So composedPath()[0] represents the original target.
15404 * @see https://polymer-library.polymer-project.org/3.0/docs/devguide/events#retargeting
15405 */
15406 FederatedEvent.prototype.composedPath = function () {
15407 if (this.manager && (!this.path || this.path[0] !== this.target)) {
15408 this.path = this.target ? this.manager.propagationPath(this.target) : [];
15409 }
15410 return this.path;
15411 };
15412 Object.defineProperty(FederatedEvent.prototype, "propagationPath", {
15413 /**
15414 * @deprecated
15415 */
15416 get: function () {
15417 return this.composedPath();
15418 },
15419 enumerable: false,
15420 configurable: true
15421 });
15422 /**
15423 * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Event/preventDefault
15424 */
15425 FederatedEvent.prototype.preventDefault = function () {
15426 if (this.nativeEvent instanceof Event && this.nativeEvent.cancelable) {
15427 this.nativeEvent.preventDefault();
15428 }
15429 this.defaultPrevented = true;
15430 };
15431 /**
15432 * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Event/stopImmediatePropagation
15433 */
15434 FederatedEvent.prototype.stopImmediatePropagation = function () {
15435 this.propagationImmediatelyStopped = true;
15436 };
15437 /**
15438 * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Event/stopPropagation
15439 */
15440 FederatedEvent.prototype.stopPropagation = function () {
15441 this.propagationStopped = true;
15442 };
15443 /**
15444 * added for compatibility with DOM Event,
15445 * deprecated props and methods
15446 */
15447 FederatedEvent.prototype.initEvent = function () { };
15448 FederatedEvent.prototype.initUIEvent = function () { };
15449 FederatedEvent.prototype.clone = function () {
15450 throw new Error(ERROR_MSG_METHOD_NOT_IMPLEMENTED);
15451 };
15452 return FederatedEvent;
15453 }());
15454
15455 var FederatedMouseEvent = /** @class */ (function (_super) {
15456 __extends(FederatedMouseEvent, _super);
15457 function FederatedMouseEvent() {
15458 var _this = _super.apply(this, __spreadArray([], __read(arguments), false)) || this;
15459 /**
15460 * The coordinates of the mouse event relative to the canvas.
15461 */
15462 _this.client = new Point();
15463 /**
15464 * The movement in this pointer relative to the last `mousemove` event.
15465 */
15466 _this.movement = new Point();
15467 /**
15468 * The offset of the pointer coordinates w.r.t. target DisplayObject in world space. This is
15469 * not supported at the moment.
15470 */
15471 _this.offset = new Point();
15472 /**
15473 * The pointer coordinates in world space.
15474 */
15475 _this.global = new Point();
15476 /**
15477 * The pointer coordinates in sceen space.
15478 */
15479 _this.screen = new Point();
15480 return _this;
15481 }
15482 Object.defineProperty(FederatedMouseEvent.prototype, "clientX", {
15483 get: function () {
15484 return this.client.x;
15485 },
15486 enumerable: false,
15487 configurable: true
15488 });
15489 Object.defineProperty(FederatedMouseEvent.prototype, "clientY", {
15490 get: function () {
15491 return this.client.y;
15492 },
15493 enumerable: false,
15494 configurable: true
15495 });
15496 Object.defineProperty(FederatedMouseEvent.prototype, "movementX", {
15497 get: function () {
15498 return this.movement.x;
15499 },
15500 enumerable: false,
15501 configurable: true
15502 });
15503 Object.defineProperty(FederatedMouseEvent.prototype, "movementY", {
15504 get: function () {
15505 return this.movement.y;
15506 },
15507 enumerable: false,
15508 configurable: true
15509 });
15510 Object.defineProperty(FederatedMouseEvent.prototype, "offsetX", {
15511 get: function () {
15512 return this.offset.x;
15513 },
15514 enumerable: false,
15515 configurable: true
15516 });
15517 Object.defineProperty(FederatedMouseEvent.prototype, "offsetY", {
15518 get: function () {
15519 return this.offset.y;
15520 },
15521 enumerable: false,
15522 configurable: true
15523 });
15524 Object.defineProperty(FederatedMouseEvent.prototype, "globalX", {
15525 get: function () {
15526 return this.global.x;
15527 },
15528 enumerable: false,
15529 configurable: true
15530 });
15531 Object.defineProperty(FederatedMouseEvent.prototype, "globalY", {
15532 get: function () {
15533 return this.global.y;
15534 },
15535 enumerable: false,
15536 configurable: true
15537 });
15538 Object.defineProperty(FederatedMouseEvent.prototype, "screenX", {
15539 get: function () {
15540 return this.screen.x;
15541 },
15542 enumerable: false,
15543 configurable: true
15544 });
15545 Object.defineProperty(FederatedMouseEvent.prototype, "screenY", {
15546 get: function () {
15547 return this.screen.y;
15548 },
15549 enumerable: false,
15550 configurable: true
15551 });
15552 FederatedMouseEvent.prototype.getModifierState = function (key) {
15553 return ('getModifierState' in this.nativeEvent &&
15554 this.nativeEvent.getModifierState(key));
15555 };
15556 FederatedMouseEvent.prototype.initMouseEvent = function () {
15557 throw new Error(ERROR_MSG_METHOD_NOT_IMPLEMENTED);
15558 };
15559 return FederatedMouseEvent;
15560 }(FederatedEvent));
15561
15562 // @ts-ignore
15563 var FederatedPointerEvent = /** @class */ (function (_super) {
15564 __extends(FederatedPointerEvent, _super);
15565 function FederatedPointerEvent() {
15566 var _this = _super.apply(this, __spreadArray([], __read(arguments), false)) || this;
15567 /**
15568 * The width of the pointer's contact along the x-axis, measured in CSS pixels.
15569 * radiusX of TouchEvents will be represented by this value.
15570 *
15571 * @see https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent/width
15572 */
15573 _this.width = 0;
15574 /**
15575 * The height of the pointer's contact along the y-axis, measured in CSS pixels.
15576 * radiusY of TouchEvents will be represented by this value.
15577 *
15578 * @see https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent/height
15579 */
15580 _this.height = 0;
15581 /**
15582 * Indicates whether or not the pointer device that created the event is the primary pointer.
15583 *
15584 * @see https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent/isPrimary
15585 */
15586 _this.isPrimary = false;
15587 return _this;
15588 }
15589 /**
15590 * @see https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent/getCoalescedEvents
15591 */
15592 FederatedPointerEvent.prototype.getCoalescedEvents = function () {
15593 if (this.type === 'pointermove' ||
15594 this.type === 'mousemove' ||
15595 this.type === 'touchmove') {
15596 // @ts-ignore
15597 return [this];
15598 }
15599 return [];
15600 };
15601 /**
15602 * @see https://chromestatus.com/feature/5765569655603200
15603 */
15604 FederatedPointerEvent.prototype.getPredictedEvents = function () {
15605 throw new Error('getPredictedEvents is not supported!');
15606 };
15607 /**
15608 * @see https://github.com/antvis/G/issues/1115
15609 * We currently reuses event objects in the event system,
15610 * avoiding the creation of a large number of event objects.
15611 * Reused objects are only used to carry different data,
15612 * such as coordinate information, native event objects,
15613 * and therefore the lifecycle is limited to the event handler,
15614 * which can lead to unintended consequences if an attempt is made to cache the entire event object.
15615 *
15616 * Therefore, while keeping the above performance considerations in mind, it is possible to provide a clone method that creates a new object when the user really wants to cache it, e.g.
15617 */
15618 FederatedPointerEvent.prototype.clone = function () {
15619 return this.manager.clonePointerEvent(this);
15620 };
15621 return FederatedPointerEvent;
15622 }(FederatedMouseEvent));
15623
15624 // @ts-ignore
15625 var FederatedWheelEvent = /** @class */ (function (_super) {
15626 __extends(FederatedWheelEvent, _super);
15627 function FederatedWheelEvent() {
15628 return _super !== null && _super.apply(this, arguments) || this;
15629 }
15630 FederatedWheelEvent.prototype.clone = function () {
15631 return this.manager.cloneWheelEvent(this);
15632 };
15633 return FederatedWheelEvent;
15634 }(FederatedMouseEvent));
15635
15636 /**
15637 * @see https://developer.mozilla.org/en-US/docs/Web/Events/Creating_and_triggering_events
15638 *
15639 * @example
15640 const event = new CustomEvent('build', { detail: { prop1: 'xx' } });
15641 circle.addEventListener('build', (e) => {
15642 e.target; // circle
15643 e.detail; // { prop1: 'xx' }
15644 });
15645
15646 circle.dispatchEvent(event);
15647 */
15648 var CustomEvent = /** @class */ (function (_super) {
15649 __extends(CustomEvent, _super);
15650 // eslint-disable-next-line @typescript-eslint/ban-types
15651 function CustomEvent(eventName, object) {
15652 var _this = _super.call(this, null) || this;
15653 _this.type = eventName;
15654 _this.detail = object;
15655 // compatible with G 3.0
15656 Object.assign(_this, object);
15657 return _this;
15658 }
15659 return CustomEvent;
15660 }(FederatedEvent));
15661
15662 var DELEGATION_SPLITTER = ':';
15663 /**
15664 * Objects that can receive events and may have listeners for them.
15665 * eg. Element, Canvas, DisplayObject
15666 * @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget
15667 */
15668 var EventTarget = /** @class */ (function () {
15669 function EventTarget() {
15670 /**
15671 * event emitter
15672 */
15673 this.emitter = new eventemitter3();
15674 }
15675 /**
15676 * @deprecated
15677 * @alias addEventListener
15678 */
15679 EventTarget.prototype.on = function (type, listener, options) {
15680 this.addEventListener(type, listener, options);
15681 return this;
15682 };
15683 /**
15684 * support `capture` & `once` in options
15685 * @see https://developer.mozilla.org/zh-CN/docs/Web/API/EventTarget/addEventListener
15686 */
15687 EventTarget.prototype.addEventListener = function (type, listener, options) {
15688 var capture = (isBoolean(options) && options) || (isObject(options) && options.capture);
15689 var once = isObject(options) && options.once;
15690 var context = isFunction$1(listener) ? undefined : listener;
15691 // compatible with G 3.0
15692 // support using delegate name in event type, eg. 'node:click'
15693 var useDelegatedName = false;
15694 var delegatedName = '';
15695 if (type.indexOf(DELEGATION_SPLITTER) > -1) {
15696 var _a = __read(type.split(DELEGATION_SPLITTER), 2), name_1 = _a[0], eventType = _a[1];
15697 type = eventType;
15698 delegatedName = name_1;
15699 useDelegatedName = true;
15700 }
15701 type = capture ? "".concat(type, "capture") : type;
15702 listener = isFunction$1(listener) ? listener : listener.handleEvent;
15703 // compatible with G 3.0
15704 if (useDelegatedName) {
15705 var originListener_1 = listener;
15706 listener = function () {
15707 var _a;
15708 var args = [];
15709 for (var _i = 0; _i < arguments.length; _i++) {
15710 args[_i] = arguments[_i];
15711 }
15712 if (((_a = args[0].target) === null || _a === void 0 ? void 0 : _a.name) !== delegatedName) {
15713 return;
15714 }
15715 // @ts-ignore
15716 originListener_1.apply(void 0, __spreadArray([], __read(args), false));
15717 };
15718 }
15719 if (once) {
15720 this.emitter.once(type, listener, context);
15721 }
15722 else {
15723 this.emitter.on(type, listener, context);
15724 }
15725 return this;
15726 };
15727 /**
15728 * @deprecated
15729 * @alias removeEventListener
15730 */
15731 EventTarget.prototype.off = function (type, listener, options) {
15732 if (type) {
15733 this.removeEventListener(type, listener, options);
15734 }
15735 else {
15736 // remove all listeners
15737 this.removeAllEventListeners();
15738 }
15739 return this;
15740 };
15741 EventTarget.prototype.removeAllEventListeners = function () {
15742 this.emitter.removeAllListeners();
15743 };
15744 EventTarget.prototype.removeEventListener = function (type, listener, options) {
15745 var capture = (isBoolean(options) && options) || (isObject(options) && options.capture);
15746 var context = isFunction$1(listener) ? undefined : listener;
15747 type = capture ? "".concat(type, "capture") : type;
15748 listener = isFunction$1(listener) ? listener : listener === null || listener === void 0 ? void 0 : listener.handleEvent;
15749 this.emitter.off(type, listener, context);
15750 return this;
15751 };
15752 /**
15753 * @deprecated
15754 * @alias dispatchEvent
15755 */
15756 // eslint-disable-next-line @typescript-eslint/ban-types
15757 EventTarget.prototype.emit = function (eventName, object) {
15758 this.dispatchEvent(new CustomEvent(eventName, object));
15759 };
15760 /**
15761 * @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/dispatchEvent
15762 */
15763 EventTarget.prototype.dispatchEvent = function (e, skipPropagate) {
15764 var _a, _b;
15765 if (skipPropagate === void 0) { skipPropagate = false; }
15766 if (!isFederatedEvent(e)) {
15767 throw new Error('DisplayObject cannot propagate events outside of the Federated Events API');
15768 }
15769 // should account for Element / Document / Canvas
15770 var canvas;
15771 // @ts-ignore
15772 if (this.document) {
15773 canvas = this;
15774 // @ts-ignore
15775 }
15776 else if (this.defaultView) {
15777 canvas = this.defaultView;
15778 }
15779 else {
15780 canvas = (_a = this.ownerDocument) === null || _a === void 0 ? void 0 : _a.defaultView;
15781 }
15782 // assign event manager
15783 if (canvas) {
15784 e.manager = canvas.getEventService() || null;
15785 if (!e.manager) {
15786 return false;
15787 }
15788 e.defaultPrevented = false;
15789 e.path = [];
15790 if (!skipPropagate) {
15791 e.target = this;
15792 }
15793 (_b = e.manager) === null || _b === void 0 ? void 0 : _b.dispatchEvent(e, e.type, skipPropagate);
15794 }
15795 return !e.defaultPrevented;
15796 };
15797 return EventTarget;
15798 }());
15799
15800 /**
15801 * @see https://developer.mozilla.org/en-US/docs/Web/API/Node
15802 */
15803 var Node = /** @class */ (function (_super) {
15804 __extends(Node, _super);
15805 function Node() {
15806 var _this = _super.apply(this, __spreadArray([], __read(arguments), false)) || this;
15807 _this.shadow = false;
15808 /**
15809 * points to canvas.document
15810 * @see https://developer.mozilla.org/en-US/docs/Web/API/Node/ownerDocument
15811 */
15812 _this.ownerDocument = null;
15813 /**
15814 * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Node/isConnected
15815 * @example
15816 circle.isConnected; // false
15817 canvas.appendChild(circle);
15818 circle.isConnected; // true
15819 */
15820 _this.isConnected = false;
15821 /**
15822 * Returns node's node document's document base URL.
15823 * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Node
15824 */
15825 _this.baseURI = '';
15826 /**
15827 * Returns the children.
15828 * @see https://developer.mozilla.org/en-US/docs/Web/API/Node/childNodes
15829 */
15830 _this.childNodes = [];
15831 /**
15832 * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Node/nodeType
15833 */
15834 _this.nodeType = 0;
15835 /**
15836 * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Node/nodeName
15837 */
15838 _this.nodeName = '';
15839 /**
15840 * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Node/nodeValue
15841 */
15842 _this.nodeValue = null;
15843 /**
15844 * @see https://developer.mozilla.org/en-US/docs/Web/API/ParentNode
15845 */
15846 _this.parentNode = null;
15847 return _this;
15848 }
15849 Node.isNode = function (target) {
15850 return !!target.childNodes;
15851 };
15852 Object.defineProperty(Node.prototype, "textContent", {
15853 /**
15854 * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Node/textContent
15855 */
15856 get: function () {
15857 var e_1, _a;
15858 var out = '';
15859 if (this.nodeName === Shape.TEXT) {
15860 // @ts-ignore
15861 out += this.style.text;
15862 }
15863 try {
15864 for (var _b = __values(this.childNodes), _c = _b.next(); !_c.done; _c = _b.next()) {
15865 var child = _c.value;
15866 if (child.nodeName === Shape.TEXT) {
15867 out += child.nodeValue;
15868 }
15869 else {
15870 out += child.textContent;
15871 }
15872 }
15873 }
15874 catch (e_1_1) { e_1 = { error: e_1_1 }; }
15875 finally {
15876 try {
15877 if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
15878 }
15879 finally { if (e_1) throw e_1.error; }
15880 }
15881 return out;
15882 },
15883 set: function (content) {
15884 var _this = this;
15885 // remove all children
15886 this.childNodes.slice().forEach(function (child) {
15887 _this.removeChild(child);
15888 });
15889 if (this.nodeName === Shape.TEXT) {
15890 // @ts-ignore
15891 this.style.text = "".concat(content);
15892 }
15893 },
15894 enumerable: false,
15895 configurable: true
15896 });
15897 /**
15898 * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Node/getRootNode
15899 */
15900 Node.prototype.getRootNode = function (opts) {
15901 if (opts === void 0) { opts = {}; }
15902 if (this.parentNode) {
15903 return this.parentNode.getRootNode(opts);
15904 }
15905 if (opts.composed && this.host) {
15906 return this.host.getRootNode(opts);
15907 }
15908 return this;
15909 };
15910 Node.prototype.hasChildNodes = function () {
15911 return this.childNodes.length > 0;
15912 };
15913 Node.prototype.isDefaultNamespace = function (namespace) {
15914 throw new Error(ERROR_MSG_METHOD_NOT_IMPLEMENTED);
15915 };
15916 Node.prototype.lookupNamespaceURI = function (prefix) {
15917 throw new Error(ERROR_MSG_METHOD_NOT_IMPLEMENTED);
15918 };
15919 Node.prototype.lookupPrefix = function (namespace) {
15920 throw new Error(ERROR_MSG_METHOD_NOT_IMPLEMENTED);
15921 };
15922 Node.prototype.normalize = function () {
15923 throw new Error(ERROR_MSG_METHOD_NOT_IMPLEMENTED);
15924 };
15925 /**
15926 * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Node/isEqualNode
15927 */
15928 Node.prototype.isEqualNode = function (otherNode) {
15929 // TODO: compare 2 nodes, not sameness
15930 return this === otherNode;
15931 };
15932 Node.prototype.isSameNode = function (otherNode) {
15933 return this.isEqualNode(otherNode);
15934 };
15935 Object.defineProperty(Node.prototype, "parent", {
15936 /**
15937 * @deprecated
15938 * @alias parentNode
15939 */
15940 get: function () {
15941 return this.parentNode;
15942 },
15943 enumerable: false,
15944 configurable: true
15945 });
15946 Object.defineProperty(Node.prototype, "parentElement", {
15947 get: function () {
15948 return null;
15949 },
15950 enumerable: false,
15951 configurable: true
15952 });
15953 Object.defineProperty(Node.prototype, "nextSibling", {
15954 get: function () {
15955 return null;
15956 },
15957 enumerable: false,
15958 configurable: true
15959 });
15960 Object.defineProperty(Node.prototype, "previousSibling", {
15961 get: function () {
15962 return null;
15963 },
15964 enumerable: false,
15965 configurable: true
15966 });
15967 Object.defineProperty(Node.prototype, "firstChild", {
15968 get: function () {
15969 return this.childNodes.length > 0 ? this.childNodes[0] : null;
15970 },
15971 enumerable: false,
15972 configurable: true
15973 });
15974 Object.defineProperty(Node.prototype, "lastChild", {
15975 get: function () {
15976 return this.childNodes.length > 0
15977 ? this.childNodes[this.childNodes.length - 1]
15978 : null;
15979 },
15980 enumerable: false,
15981 configurable: true
15982 });
15983 /**
15984 * @see https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition
15985 * @see https://github.com/b-fuze/deno-dom/blob/master/src/dom/node.ts#L338
15986 */
15987 Node.prototype.compareDocumentPosition = function (other) {
15988 var _a;
15989 if (other === this) {
15990 // same node
15991 return 0;
15992 }
15993 // if (!(other instanceof Node)) {
15994 // throw new TypeError(
15995 // 'Node.compareDocumentPosition: Argument 1 does not implement interface Node.',
15996 // );
15997 // }
15998 var node1Root = other;
15999 // eslint-disable-next-line @typescript-eslint/no-this-alias
16000 var node2Root = this;
16001 var node1Hierarchy = [node1Root];
16002 var node2Hierarchy = [node2Root];
16003 while ((_a = node1Root.parentNode) !== null && _a !== void 0 ? _a : node2Root.parentNode) {
16004 node1Root = node1Root.parentNode
16005 ? (node1Hierarchy.push(node1Root.parentNode), node1Root.parentNode)
16006 : node1Root;
16007 node2Root = node2Root.parentNode
16008 ? (node2Hierarchy.push(node2Root.parentNode), node2Root.parentNode)
16009 : node2Root;
16010 }
16011 // Check if they don't share the same root node
16012 if (node1Root !== node2Root) {
16013 return (Node.DOCUMENT_POSITION_DISCONNECTED |
16014 Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC |
16015 Node.DOCUMENT_POSITION_PRECEDING);
16016 }
16017 var longerHierarchy = node1Hierarchy.length > node2Hierarchy.length
16018 ? node1Hierarchy
16019 : node2Hierarchy;
16020 var shorterHierarchy = longerHierarchy === node1Hierarchy ? node2Hierarchy : node1Hierarchy;
16021 // Check if either is a container of the other
16022 if (longerHierarchy[longerHierarchy.length - shorterHierarchy.length] ===
16023 shorterHierarchy[0]) {
16024 return longerHierarchy === node1Hierarchy
16025 ? // other is a child of this
16026 Node.DOCUMENT_POSITION_CONTAINED_BY | Node.DOCUMENT_POSITION_FOLLOWING
16027 : // this is a child of other
16028 Node.DOCUMENT_POSITION_CONTAINS | Node.DOCUMENT_POSITION_PRECEDING;
16029 }
16030 // Find their first common ancestor and see whether they
16031 // are preceding or following
16032 var longerStart = longerHierarchy.length - shorterHierarchy.length;
16033 for (var i = shorterHierarchy.length - 1; i >= 0; i--) {
16034 var shorterHierarchyNode = shorterHierarchy[i];
16035 var longerHierarchyNode = longerHierarchy[longerStart + i];
16036 // We found the first common ancestor
16037 if (longerHierarchyNode !== shorterHierarchyNode) {
16038 var siblings = shorterHierarchyNode.parentNode.childNodes;
16039 if (siblings.indexOf(shorterHierarchyNode) <
16040 siblings.indexOf(longerHierarchyNode)) {
16041 // Shorter is before longer
16042 if (shorterHierarchy === node1Hierarchy) {
16043 // Other is before this
16044 return Node.DOCUMENT_POSITION_PRECEDING;
16045 }
16046 else {
16047 // This is before other
16048 return Node.DOCUMENT_POSITION_FOLLOWING;
16049 }
16050 }
16051 else {
16052 // Longer is before shorter
16053 if (longerHierarchy === node1Hierarchy) {
16054 // Other is before this
16055 return Node.DOCUMENT_POSITION_PRECEDING;
16056 }
16057 else {
16058 // Other is after this
16059 return Node.DOCUMENT_POSITION_FOLLOWING;
16060 }
16061 }
16062 }
16063 }
16064 return Node.DOCUMENT_POSITION_FOLLOWING;
16065 };
16066 /**
16067 * @deprecated
16068 * @alias contains
16069 */
16070 Node.prototype.contain = function (other) {
16071 return this.contains(other);
16072 };
16073 Node.prototype.contains = function (other) {
16074 // the node itself, one of its direct children
16075 var tmp = other;
16076 // @see https://developer.mozilla.org/en-US/docs/Web/API/Node/contains
16077 while (tmp && this !== tmp) {
16078 tmp = tmp.parentNode;
16079 }
16080 return !!tmp;
16081 };
16082 Node.prototype.getAncestor = function (n) {
16083 // eslint-disable-next-line @typescript-eslint/no-this-alias
16084 var temp = this;
16085 while (n > 0 && temp) {
16086 temp = temp.parentNode;
16087 n--;
16088 }
16089 return temp;
16090 };
16091 Node.prototype.forEach = function (callback, assigned) {
16092 if (assigned === void 0) { assigned = false; }
16093 if (!callback(this)) {
16094 (assigned ? this.childNodes.slice() : this.childNodes).forEach(function (child) {
16095 child.forEach(callback);
16096 });
16097 }
16098 };
16099 /**
16100 * Both nodes are in different documents or different trees in the same document.
16101 */
16102 Node.DOCUMENT_POSITION_DISCONNECTED = 1;
16103 /**
16104 * otherNode precedes the node in either a pre-order depth-first traversal
16105 * of a tree containing both (e.g., as an ancestor or previous sibling or a descendant of a previous sibling or previous sibling of an ancestor) or (if they are disconnected) in an arbitrary but consistent ordering.
16106 */
16107 Node.DOCUMENT_POSITION_PRECEDING = 2;
16108 /**
16109 * otherNode follows the node in either a pre-order depth-first traversal of a tree containing both (e.g., as a descendant or following sibling or a descendant of a following sibling or following sibling of an ancestor) or (if they are disconnected) in an arbitrary but consistent ordering.
16110 */
16111 Node.DOCUMENT_POSITION_FOLLOWING = 4;
16112 /**
16113 * otherNode is an ancestor of the node.
16114 */
16115 Node.DOCUMENT_POSITION_CONTAINS = 8;
16116 /**
16117 * otherNode is a descendant of the node.
16118 */
16119 Node.DOCUMENT_POSITION_CONTAINED_BY = 16;
16120 /**
16121 * The result relies upon arbitrary and/or implementation-specific behavior and is not guaranteed to be portable.
16122 */
16123 Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 32;
16124 return Node;
16125 }(EventTarget));
16126
16127 var PROPAGATION_LIMIT = 2048;
16128 var EventService = /** @class */ (function () {
16129 function EventService(globalRuntime, context) {
16130 var _this = this;
16131 this.globalRuntime = globalRuntime;
16132 this.context = context;
16133 this.emitter = new eventemitter3();
16134 /**
16135 * Store HTML elements in current canvas.
16136 */
16137 this.nativeHTMLMap = new WeakMap();
16138 this.cursor = 'default';
16139 this.mappingTable = {};
16140 this.mappingState = {
16141 trackingData: {},
16142 };
16143 this.eventPool = new Map();
16144 this.tmpMatrix = create$1();
16145 this.tmpVec3 = create$2();
16146 this.onPointerDown = function (from) {
16147 var e = _this.createPointerEvent(from);
16148 _this.dispatchEvent(e, 'pointerdown');
16149 if (e.pointerType === 'touch') {
16150 _this.dispatchEvent(e, 'touchstart');
16151 }
16152 else if (e.pointerType === 'mouse' || e.pointerType === 'pen') {
16153 var isRightButton = e.button === 2;
16154 _this.dispatchEvent(e, isRightButton ? 'rightdown' : 'mousedown');
16155 }
16156 var trackingData = _this.trackingData(from.pointerId);
16157 trackingData.pressTargetsByButton[from.button] = e.composedPath();
16158 _this.freeEvent(e);
16159 };
16160 this.onPointerUp = function (from) {
16161 var _a;
16162 var now = clock.now();
16163 var e = _this.createPointerEvent(from, undefined, undefined, _this.context.config.alwaysTriggerPointerEventOnCanvas
16164 ? _this.rootTarget
16165 : undefined);
16166 _this.dispatchEvent(e, 'pointerup');
16167 if (e.pointerType === 'touch') {
16168 _this.dispatchEvent(e, 'touchend');
16169 }
16170 else if (e.pointerType === 'mouse' || e.pointerType === 'pen') {
16171 var isRightButton = e.button === 2;
16172 _this.dispatchEvent(e, isRightButton ? 'rightup' : 'mouseup');
16173 }
16174 var trackingData = _this.trackingData(from.pointerId);
16175 var pressTarget = _this.findMountedTarget(trackingData.pressTargetsByButton[from.button]);
16176 var clickTarget = pressTarget;
16177 // pointerupoutside only bubbles. It only bubbles upto the parent that doesn't contain
16178 // the pointerup location.
16179 if (pressTarget && !e.composedPath().includes(pressTarget)) {
16180 var currentTarget = pressTarget;
16181 while (currentTarget && !e.composedPath().includes(currentTarget)) {
16182 e.currentTarget = currentTarget;
16183 _this.notifyTarget(e, 'pointerupoutside');
16184 if (e.pointerType === 'touch') {
16185 _this.notifyTarget(e, 'touchendoutside');
16186 }
16187 else if (e.pointerType === 'mouse' || e.pointerType === 'pen') {
16188 var isRightButton = e.button === 2;
16189 _this.notifyTarget(e, isRightButton ? 'rightupoutside' : 'mouseupoutside');
16190 }
16191 if (Node.isNode(currentTarget)) {
16192 currentTarget = currentTarget.parentNode;
16193 }
16194 }
16195 delete trackingData.pressTargetsByButton[from.button];
16196 // currentTarget is the most specific ancestor holding both the pointerdown and pointerup
16197 // targets. That is - it's our click target!
16198 clickTarget = currentTarget;
16199 }
16200 if (clickTarget) {
16201 var clickEvent = _this.clonePointerEvent(e, 'click');
16202 clickEvent.target = clickTarget;
16203 clickEvent.path = [];
16204 if (!trackingData.clicksByButton[from.button]) {
16205 trackingData.clicksByButton[from.button] = {
16206 clickCount: 0,
16207 target: clickEvent.target,
16208 timeStamp: now,
16209 };
16210 }
16211 var clickHistory = trackingData.clicksByButton[from.button];
16212 if (clickHistory.target === clickEvent.target &&
16213 now - clickHistory.timeStamp < 200) {
16214 ++clickHistory.clickCount;
16215 }
16216 else {
16217 clickHistory.clickCount = 1;
16218 }
16219 clickHistory.target = clickEvent.target;
16220 clickHistory.timeStamp = now;
16221 clickEvent.detail = clickHistory.clickCount;
16222 // @see https://github.com/antvis/G/issues/1091
16223 if (!((_a = e.detail) === null || _a === void 0 ? void 0 : _a.preventClick)) {
16224 if (!_this.context.config.useNativeClickEvent &&
16225 (clickEvent.pointerType === 'mouse' ||
16226 clickEvent.pointerType === 'touch')) {
16227 _this.dispatchEvent(clickEvent, 'click');
16228 }
16229 _this.dispatchEvent(clickEvent, 'pointertap');
16230 }
16231 _this.freeEvent(clickEvent);
16232 }
16233 _this.freeEvent(e);
16234 };
16235 this.onPointerMove = function (from) {
16236 var e = _this.createPointerEvent(from, undefined, undefined, _this.context.config.alwaysTriggerPointerEventOnCanvas
16237 ? _this.rootTarget
16238 : undefined);
16239 var isMouse = e.pointerType === 'mouse' || e.pointerType === 'pen';
16240 var trackingData = _this.trackingData(from.pointerId);
16241 var outTarget = _this.findMountedTarget(trackingData.overTargets);
16242 // First pointerout/pointerleave
16243 if (trackingData.overTargets && outTarget !== e.target) {
16244 // pointerout always occurs on the overTarget when the pointer hovers over another element.
16245 var outType = from.type === 'mousemove' ? 'mouseout' : 'pointerout';
16246 var outEvent = _this.createPointerEvent(from, outType, outTarget || undefined);
16247 _this.dispatchEvent(outEvent, 'pointerout');
16248 if (isMouse)
16249 _this.dispatchEvent(outEvent, 'mouseout');
16250 // If the pointer exits overTarget and its descendants, then a pointerleave event is also fired. This event
16251 // is dispatched to all ancestors that no longer capture the pointer.
16252 if (!e.composedPath().includes(outTarget)) {
16253 var leaveEvent = _this.createPointerEvent(from, 'pointerleave', outTarget || undefined);
16254 leaveEvent.eventPhase = leaveEvent.AT_TARGET;
16255 while (leaveEvent.target &&
16256 !e.composedPath().includes(leaveEvent.target)) {
16257 leaveEvent.currentTarget = leaveEvent.target;
16258 _this.notifyTarget(leaveEvent);
16259 if (isMouse) {
16260 _this.notifyTarget(leaveEvent, 'mouseleave');
16261 }
16262 if (Node.isNode(leaveEvent.target)) {
16263 leaveEvent.target = leaveEvent.target.parentNode;
16264 }
16265 }
16266 _this.freeEvent(leaveEvent);
16267 }
16268 _this.freeEvent(outEvent);
16269 }
16270 // Then pointerover
16271 if (outTarget !== e.target) {
16272 // pointerover always occurs on the new overTarget
16273 var overType = from.type === 'mousemove' ? 'mouseover' : 'pointerover';
16274 var overEvent = _this.clonePointerEvent(e, overType); // clone faster
16275 _this.dispatchEvent(overEvent, 'pointerover');
16276 if (isMouse)
16277 _this.dispatchEvent(overEvent, 'mouseover');
16278 // Probe whether the newly hovered Node is an ancestor of the original overTarget.
16279 var overTargetAncestor = outTarget && Node.isNode(outTarget) && outTarget.parentNode;
16280 while (overTargetAncestor &&
16281 overTargetAncestor !==
16282 (Node.isNode(_this.rootTarget) && _this.rootTarget.parentNode)) {
16283 if (overTargetAncestor === e.target)
16284 break;
16285 overTargetAncestor = overTargetAncestor.parentNode;
16286 }
16287 // The pointer has entered a non-ancestor of the original overTarget. This means we need a pointerentered
16288 // event.
16289 var didPointerEnter = !overTargetAncestor ||
16290 overTargetAncestor ===
16291 (Node.isNode(_this.rootTarget) && _this.rootTarget.parentNode);
16292 if (didPointerEnter) {
16293 var enterEvent = _this.clonePointerEvent(e, 'pointerenter');
16294 enterEvent.eventPhase = enterEvent.AT_TARGET;
16295 while (enterEvent.target &&
16296 enterEvent.target !== outTarget &&
16297 enterEvent.target !==
16298 (Node.isNode(_this.rootTarget) && _this.rootTarget.parentNode)) {
16299 enterEvent.currentTarget = enterEvent.target;
16300 _this.notifyTarget(enterEvent);
16301 if (isMouse)
16302 _this.notifyTarget(enterEvent, 'mouseenter');
16303 if (Node.isNode(enterEvent.target)) {
16304 enterEvent.target = enterEvent.target.parentNode;
16305 }
16306 }
16307 _this.freeEvent(enterEvent);
16308 }
16309 _this.freeEvent(overEvent);
16310 }
16311 // Then pointermove
16312 _this.dispatchEvent(e, 'pointermove');
16313 if (e.pointerType === 'touch')
16314 _this.dispatchEvent(e, 'touchmove');
16315 if (isMouse) {
16316 _this.dispatchEvent(e, 'mousemove');
16317 _this.cursor = _this.getCursor(e.target);
16318 }
16319 trackingData.overTargets = e.composedPath();
16320 _this.freeEvent(e);
16321 };
16322 this.onPointerOut = function (from) {
16323 var trackingData = _this.trackingData(from.pointerId);
16324 if (trackingData.overTargets) {
16325 var isMouse = from.pointerType === 'mouse' || from.pointerType === 'pen';
16326 var outTarget = _this.findMountedTarget(trackingData.overTargets);
16327 // pointerout first
16328 var outEvent = _this.createPointerEvent(from, 'pointerout', outTarget || undefined);
16329 _this.dispatchEvent(outEvent);
16330 if (isMouse)
16331 _this.dispatchEvent(outEvent, 'mouseout');
16332 // pointerleave(s) are also dispatched b/c the pointer must've left rootTarget and its descendants to
16333 // get an upstream pointerout event (upstream events do not know rootTarget has descendants).
16334 var leaveEvent = _this.createPointerEvent(from, 'pointerleave', outTarget || undefined);
16335 leaveEvent.eventPhase = leaveEvent.AT_TARGET;
16336 while (leaveEvent.target &&
16337 leaveEvent.target !==
16338 (Node.isNode(_this.rootTarget) && _this.rootTarget.parentNode)) {
16339 leaveEvent.currentTarget = leaveEvent.target;
16340 _this.notifyTarget(leaveEvent);
16341 if (isMouse) {
16342 _this.notifyTarget(leaveEvent, 'mouseleave');
16343 }
16344 if (Node.isNode(leaveEvent.target)) {
16345 leaveEvent.target = leaveEvent.target.parentNode;
16346 }
16347 }
16348 trackingData.overTargets = null;
16349 _this.freeEvent(outEvent);
16350 _this.freeEvent(leaveEvent);
16351 }
16352 _this.cursor = null;
16353 };
16354 this.onPointerOver = function (from) {
16355 var trackingData = _this.trackingData(from.pointerId);
16356 var e = _this.createPointerEvent(from);
16357 var isMouse = e.pointerType === 'mouse' || e.pointerType === 'pen';
16358 _this.dispatchEvent(e, 'pointerover');
16359 if (isMouse)
16360 _this.dispatchEvent(e, 'mouseover');
16361 if (e.pointerType === 'mouse')
16362 _this.cursor = _this.getCursor(e.target);
16363 // pointerenter events must be fired since the pointer entered from upstream.
16364 var enterEvent = _this.clonePointerEvent(e, 'pointerenter');
16365 enterEvent.eventPhase = enterEvent.AT_TARGET;
16366 while (enterEvent.target &&
16367 enterEvent.target !==
16368 (Node.isNode(_this.rootTarget) && _this.rootTarget.parentNode)) {
16369 enterEvent.currentTarget = enterEvent.target;
16370 _this.notifyTarget(enterEvent);
16371 if (isMouse) {
16372 // mouseenter should not bubble
16373 // @see https://developer.mozilla.org/en-US/docs/Web/API/Element/mouseenter_event#usage_notes
16374 _this.notifyTarget(enterEvent, 'mouseenter');
16375 }
16376 if (Node.isNode(enterEvent.target)) {
16377 enterEvent.target = enterEvent.target.parentNode;
16378 }
16379 }
16380 trackingData.overTargets = e.composedPath();
16381 _this.freeEvent(e);
16382 _this.freeEvent(enterEvent);
16383 };
16384 this.onPointerUpOutside = function (from) {
16385 var trackingData = _this.trackingData(from.pointerId);
16386 var pressTarget = _this.findMountedTarget(trackingData.pressTargetsByButton[from.button]);
16387 var e = _this.createPointerEvent(from);
16388 if (pressTarget) {
16389 var currentTarget = pressTarget;
16390 while (currentTarget) {
16391 e.currentTarget = currentTarget;
16392 _this.notifyTarget(e, 'pointerupoutside');
16393 if (e.pointerType === 'touch') ;
16394 else if (e.pointerType === 'mouse' || e.pointerType === 'pen') {
16395 _this.notifyTarget(e, e.button === 2 ? 'rightupoutside' : 'mouseupoutside');
16396 }
16397 if (Node.isNode(currentTarget)) {
16398 currentTarget = currentTarget.parentNode;
16399 }
16400 }
16401 delete trackingData.pressTargetsByButton[from.button];
16402 }
16403 _this.freeEvent(e);
16404 };
16405 this.onWheel = function (from) {
16406 var wheelEvent = _this.createWheelEvent(from);
16407 _this.dispatchEvent(wheelEvent);
16408 _this.freeEvent(wheelEvent);
16409 };
16410 this.onClick = function (from) {
16411 if (_this.context.config.useNativeClickEvent) {
16412 var e = _this.createPointerEvent(from);
16413 _this.dispatchEvent(e);
16414 _this.freeEvent(e);
16415 }
16416 };
16417 this.onPointerCancel = function (from) {
16418 var e = _this.createPointerEvent(from, undefined, undefined, _this.context.config.alwaysTriggerPointerEventOnCanvas
16419 ? _this.rootTarget
16420 : undefined);
16421 _this.dispatchEvent(e);
16422 _this.freeEvent(e);
16423 };
16424 }
16425 EventService.prototype.init = function () {
16426 this.rootTarget = this.context.renderingContext.root.parentNode; // document
16427 this.addEventMapping('pointerdown', this.onPointerDown);
16428 this.addEventMapping('pointerup', this.onPointerUp);
16429 this.addEventMapping('pointermove', this.onPointerMove);
16430 this.addEventMapping('pointerout', this.onPointerOut);
16431 this.addEventMapping('pointerleave', this.onPointerOut);
16432 this.addEventMapping('pointercancel', this.onPointerCancel);
16433 this.addEventMapping('pointerover', this.onPointerOver);
16434 this.addEventMapping('pointerupoutside', this.onPointerUpOutside);
16435 this.addEventMapping('wheel', this.onWheel);
16436 this.addEventMapping('click', this.onClick);
16437 };
16438 EventService.prototype.destroy = function () {
16439 this.emitter.removeAllListeners();
16440 this.mappingTable = {};
16441 this.mappingState = {};
16442 this.eventPool.clear();
16443 };
16444 EventService.prototype.client2Viewport = function (client) {
16445 var bbox = this.context.contextService.getBoundingClientRect();
16446 return new Point(client.x - ((bbox === null || bbox === void 0 ? void 0 : bbox.left) || 0), client.y - ((bbox === null || bbox === void 0 ? void 0 : bbox.top) || 0));
16447 };
16448 EventService.prototype.viewport2Client = function (canvas) {
16449 var bbox = this.context.contextService.getBoundingClientRect();
16450 return new Point(canvas.x + ((bbox === null || bbox === void 0 ? void 0 : bbox.left) || 0), canvas.y + ((bbox === null || bbox === void 0 ? void 0 : bbox.top) || 0));
16451 };
16452 EventService.prototype.viewport2Canvas = function (_a) {
16453 var x = _a.x, y = _a.y;
16454 var canvas = this.rootTarget.defaultView;
16455 var camera = canvas.getCamera();
16456 var _b = this.context.config, width = _b.width, height = _b.height;
16457 var projectionMatrixInverse = camera.getPerspectiveInverse();
16458 var worldMatrix = camera.getWorldTransform();
16459 var vpMatrix = multiply(this.tmpMatrix, worldMatrix, projectionMatrixInverse);
16460 var viewport = set$1(this.tmpVec3, (x / width) * 2 - 1, (1 - y / height) * 2 - 1, 0);
16461 transformMat4(viewport, viewport, vpMatrix);
16462 return new Point(viewport[0], viewport[1]);
16463 };
16464 EventService.prototype.canvas2Viewport = function (canvasP) {
16465 var canvas = this.rootTarget.defaultView;
16466 var camera = canvas.getCamera();
16467 // World -> Clip
16468 var projectionMatrix = camera.getPerspective();
16469 var viewMatrix = camera.getViewTransform();
16470 var vpMatrix = multiply(this.tmpMatrix, projectionMatrix, viewMatrix);
16471 var clip = set$1(this.tmpVec3, canvasP.x, canvasP.y, 0);
16472 transformMat4(this.tmpVec3, this.tmpVec3, vpMatrix);
16473 // Clip -> NDC -> Viewport, flip Y
16474 var _a = this.context.config, width = _a.width, height = _a.height;
16475 return new Point(((clip[0] + 1) / 2) * width, (1 - (clip[1] + 1) / 2) * height);
16476 };
16477 EventService.prototype.setPickHandler = function (pickHandler) {
16478 this.pickHandler = pickHandler;
16479 };
16480 EventService.prototype.addEventMapping = function (type, fn) {
16481 if (!this.mappingTable[type]) {
16482 this.mappingTable[type] = [];
16483 }
16484 this.mappingTable[type].push({
16485 fn: fn,
16486 priority: 0,
16487 });
16488 this.mappingTable[type].sort(function (a, b) { return a.priority - b.priority; });
16489 };
16490 EventService.prototype.mapEvent = function (e) {
16491 if (!this.rootTarget) {
16492 return;
16493 }
16494 var mappers = this.mappingTable[e.type];
16495 if (mappers) {
16496 for (var i = 0, j = mappers.length; i < j; i++) {
16497 mappers[i].fn(e);
16498 }
16499 }
16500 else {
16501 console.warn("[EventService]: Event mapping not defined for ".concat(e.type));
16502 }
16503 };
16504 EventService.prototype.dispatchEvent = function (e, type, skipPropagate) {
16505 // Canvas should skip
16506 if (!skipPropagate) {
16507 e.propagationStopped = false;
16508 e.propagationImmediatelyStopped = false;
16509 this.propagate(e, type);
16510 }
16511 else {
16512 // target phase
16513 e.eventPhase = e.AT_TARGET;
16514 var canvas = this.rootTarget.defaultView || null;
16515 e.currentTarget = canvas;
16516 this.notifyListeners(e, type);
16517 }
16518 this.emitter.emit(type || e.type, e);
16519 };
16520 EventService.prototype.propagate = function (e, type) {
16521 if (!e.target) {
16522 return;
16523 }
16524 // [target, parent, root, Canvas]
16525 var composedPath = e.composedPath();
16526 // event flow: capture -> target -> bubbling
16527 // capture phase
16528 e.eventPhase = e.CAPTURING_PHASE;
16529 for (var i = composedPath.length - 1; i >= 1; i--) {
16530 e.currentTarget = composedPath[i];
16531 this.notifyTarget(e, type);
16532 if (e.propagationStopped || e.propagationImmediatelyStopped)
16533 return;
16534 }
16535 // target phase
16536 e.eventPhase = e.AT_TARGET;
16537 e.currentTarget = e.target;
16538 this.notifyTarget(e, type);
16539 if (e.propagationStopped || e.propagationImmediatelyStopped)
16540 return;
16541 // find current target in composed path
16542 var index = composedPath.indexOf(e.currentTarget);
16543 // bubbling phase
16544 e.eventPhase = e.BUBBLING_PHASE;
16545 for (var i = index + 1; i < composedPath.length; i++) {
16546 e.currentTarget = composedPath[i];
16547 this.notifyTarget(e, type);
16548 if (e.propagationStopped || e.propagationImmediatelyStopped)
16549 return;
16550 }
16551 };
16552 EventService.prototype.propagationPath = function (target) {
16553 var propagationPath = [target];
16554 var canvas = this.rootTarget.defaultView || null;
16555 if (canvas && canvas === target) {
16556 propagationPath.unshift(canvas.document);
16557 return propagationPath;
16558 }
16559 for (var i = 0; i < PROPAGATION_LIMIT && target !== this.rootTarget; i++) {
16560 // if (Node.isNode(target) && !target.parentNode) {
16561 // throw new Error('Cannot find propagation path to disconnected target');
16562 // }
16563 if (Node.isNode(target) && target.parentNode) {
16564 // [target, parent, parent, root]
16565 propagationPath.push(target.parentNode);
16566 target = target.parentNode;
16567 }
16568 }
16569 if (canvas) {
16570 // @ts-ignore
16571 propagationPath.push(canvas);
16572 }
16573 return propagationPath;
16574 };
16575 EventService.prototype.hitTest = function (position) {
16576 var viewportX = position.viewportX, viewportY = position.viewportY;
16577 var _a = this.context.config, width = _a.width, height = _a.height, disableHitTesting = _a.disableHitTesting;
16578 // outside canvas
16579 if (viewportX < 0 ||
16580 viewportY < 0 ||
16581 viewportX > width ||
16582 viewportY > height) {
16583 return null;
16584 }
16585 return ((!disableHitTesting && this.pickHandler(position)) ||
16586 this.rootTarget || // return Document
16587 null);
16588 };
16589 /**
16590 * whether the native event trigger came from Canvas,
16591 * should account for HTML shape
16592 */
16593 EventService.prototype.isNativeEventFromCanvas = function ($el, nativeEvent) {
16594 var target = nativeEvent === null || nativeEvent === void 0 ? void 0 : nativeEvent.target;
16595 // Get event target inside a web component.
16596 // @see https://stackoverflow.com/questions/57963312/get-event-target-inside-a-web-component
16597 if (target === null || target === void 0 ? void 0 : target.shadowRoot) {
16598 target = nativeEvent.composedPath()[0];
16599 }
16600 if (target) {
16601 // from <canvas>
16602 if (target === $el) {
16603 return true;
16604 }
16605 // from <svg>
16606 if ($el && $el.contains) {
16607 return $el.contains(target);
16608 }
16609 }
16610 if (nativeEvent === null || nativeEvent === void 0 ? void 0 : nativeEvent.composedPath) {
16611 return nativeEvent.composedPath().indexOf($el) > -1;
16612 }
16613 // account for Touch
16614 return false;
16615 };
16616 /**
16617 * Find HTML from composed path in native UI event.
16618 */
16619 EventService.prototype.getExistedHTML = function (event) {
16620 var e_1, _a;
16621 if (event.nativeEvent.composedPath) {
16622 try {
16623 for (var _b = __values(event.nativeEvent.composedPath()), _c = _b.next(); !_c.done; _c = _b.next()) {
16624 var eventTarget = _c.value;
16625 var existed = this.nativeHTMLMap.get(eventTarget);
16626 if (existed) {
16627 return existed;
16628 }
16629 }
16630 }
16631 catch (e_1_1) { e_1 = { error: e_1_1 }; }
16632 finally {
16633 try {
16634 if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
16635 }
16636 finally { if (e_1) throw e_1.error; }
16637 }
16638 }
16639 return null;
16640 };
16641 EventService.prototype.pickTarget = function (event) {
16642 return this.hitTest({
16643 clientX: event.clientX,
16644 clientY: event.clientY,
16645 viewportX: event.viewportX,
16646 viewportY: event.viewportY,
16647 x: event.canvasX,
16648 y: event.canvasY,
16649 });
16650 };
16651 EventService.prototype.createPointerEvent = function (from, type, target, fallbackTarget) {
16652 var event = this.allocateEvent(FederatedPointerEvent);
16653 this.copyPointerData(from, event);
16654 this.copyMouseData(from, event);
16655 this.copyData(from, event);
16656 event.nativeEvent = from.nativeEvent;
16657 event.originalEvent = from;
16658 var existedHTML = this.getExistedHTML(event);
16659 var $el = this.context.contextService.getDomElement();
16660 event.target =
16661 target !== null && target !== void 0 ? target : (existedHTML ||
16662 (this.isNativeEventFromCanvas($el, event.nativeEvent) &&
16663 this.pickTarget(event)) ||
16664 fallbackTarget);
16665 if (typeof type === 'string') {
16666 event.type = type;
16667 }
16668 return event;
16669 };
16670 EventService.prototype.createWheelEvent = function (from) {
16671 var event = this.allocateEvent(FederatedWheelEvent);
16672 this.copyWheelData(from, event);
16673 this.copyMouseData(from, event);
16674 this.copyData(from, event);
16675 event.nativeEvent = from.nativeEvent;
16676 event.originalEvent = from;
16677 var existedHTML = this.getExistedHTML(event);
16678 var $el = this.context.contextService.getDomElement();
16679 event.target =
16680 existedHTML ||
16681 (this.isNativeEventFromCanvas($el, event.nativeEvent) &&
16682 this.pickTarget(event));
16683 return event;
16684 };
16685 EventService.prototype.trackingData = function (id) {
16686 if (!this.mappingState.trackingData[id]) {
16687 this.mappingState.trackingData[id] = {
16688 pressTargetsByButton: {},
16689 clicksByButton: {},
16690 overTarget: null,
16691 };
16692 }
16693 return this.mappingState.trackingData[id];
16694 };
16695 EventService.prototype.cloneWheelEvent = function (from) {
16696 var event = this.allocateEvent(FederatedWheelEvent);
16697 event.nativeEvent = from.nativeEvent;
16698 event.originalEvent = from.originalEvent;
16699 this.copyWheelData(from, event);
16700 this.copyMouseData(from, event);
16701 this.copyData(from, event);
16702 event.target = from.target;
16703 event.path = from.composedPath().slice();
16704 event.type = from.type;
16705 return event;
16706 };
16707 EventService.prototype.clonePointerEvent = function (from, type) {
16708 var event = this.allocateEvent(FederatedPointerEvent);
16709 event.nativeEvent = from.nativeEvent;
16710 event.originalEvent = from.originalEvent;
16711 this.copyPointerData(from, event);
16712 this.copyMouseData(from, event);
16713 this.copyData(from, event);
16714 event.target = from.target;
16715 event.path = from.composedPath().slice();
16716 event.type = type !== null && type !== void 0 ? type : event.type;
16717 return event;
16718 };
16719 EventService.prototype.copyPointerData = function (from, to) {
16720 // if (
16721 // !(
16722 // from instanceof FederatedPointerEvent &&
16723 // to instanceof FederatedPointerEvent
16724 // )
16725 // )
16726 // return;
16727 to.pointerId = from.pointerId;
16728 to.width = from.width;
16729 to.height = from.height;
16730 to.isPrimary = from.isPrimary;
16731 to.pointerType = from.pointerType;
16732 to.pressure = from.pressure;
16733 to.tangentialPressure = from.tangentialPressure;
16734 to.tiltX = from.tiltX;
16735 to.tiltY = from.tiltY;
16736 to.twist = from.twist;
16737 };
16738 EventService.prototype.copyMouseData = function (from, to) {
16739 // if (
16740 // !(
16741 // from instanceof FederatedMouseEvent && to instanceof FederatedMouseEvent
16742 // )
16743 // )
16744 // return;
16745 to.altKey = from.altKey;
16746 to.button = from.button;
16747 to.buttons = from.buttons;
16748 to.ctrlKey = from.ctrlKey;
16749 to.metaKey = from.metaKey;
16750 to.shiftKey = from.shiftKey;
16751 to.client.copyFrom(from.client);
16752 to.movement.copyFrom(from.movement);
16753 to.canvas.copyFrom(from.canvas);
16754 to.screen.copyFrom(from.screen);
16755 to.global.copyFrom(from.global);
16756 to.offset.copyFrom(from.offset);
16757 };
16758 EventService.prototype.copyWheelData = function (from, to) {
16759 to.deltaMode = from.deltaMode;
16760 to.deltaX = from.deltaX;
16761 to.deltaY = from.deltaY;
16762 to.deltaZ = from.deltaZ;
16763 };
16764 EventService.prototype.copyData = function (from, to) {
16765 to.isTrusted = from.isTrusted;
16766 to.timeStamp = clock.now();
16767 to.type = from.type;
16768 to.detail = from.detail;
16769 to.view = from.view;
16770 to.page.copyFrom(from.page);
16771 to.viewport.copyFrom(from.viewport);
16772 };
16773 EventService.prototype.allocateEvent = function (constructor) {
16774 if (!this.eventPool.has(constructor)) {
16775 this.eventPool.set(constructor, []);
16776 }
16777 // @ts-ignore
16778 var event = this.eventPool.get(constructor).pop() ||
16779 new constructor(this);
16780 event.eventPhase = event.NONE;
16781 event.currentTarget = null;
16782 event.path = [];
16783 event.target = null;
16784 return event;
16785 };
16786 EventService.prototype.freeEvent = function (event) {
16787 if (event.manager !== this)
16788 throw new Error('It is illegal to free an event not managed by this EventBoundary!');
16789 var constructor = event.constructor;
16790 if (!this.eventPool.has(constructor)) {
16791 this.eventPool.set(constructor, []);
16792 }
16793 // @ts-ignore
16794 this.eventPool.get(constructor).push(event);
16795 };
16796 EventService.prototype.notifyTarget = function (e, type) {
16797 type = type !== null && type !== void 0 ? type : e.type;
16798 var key = e.eventPhase === e.CAPTURING_PHASE || e.eventPhase === e.AT_TARGET
16799 ? "".concat(type, "capture")
16800 : type;
16801 this.notifyListeners(e, key);
16802 if (e.eventPhase === e.AT_TARGET) {
16803 this.notifyListeners(e, type);
16804 }
16805 };
16806 EventService.prototype.notifyListeners = function (e, type) {
16807 // hack EventEmitter, stops if the `propagationImmediatelyStopped` flag is set
16808 // @ts-ignore
16809 var emitter = e.currentTarget.emitter;
16810 // @ts-ignore
16811 var listeners = emitter._events[type];
16812 if (!listeners)
16813 return;
16814 if ('fn' in listeners) {
16815 if (listeners.once) {
16816 emitter.removeListener(type, listeners.fn, undefined, true);
16817 }
16818 listeners.fn.call(e.currentTarget || listeners.context, e);
16819 // listeners.fn.call(listeners.context, e);
16820 }
16821 else {
16822 for (var i = 0; i < listeners.length && !e.propagationImmediatelyStopped; i++) {
16823 if (listeners[i].once) {
16824 emitter.removeListener(type, listeners[i].fn, undefined, true);
16825 }
16826 listeners[i].fn.call(e.currentTarget || listeners[i].context, e);
16827 // listeners[i].fn.call(listeners[i].context, e);
16828 }
16829 }
16830 };
16831 /**
16832 * some detached nodes may exist in propagation path, need to skip them
16833 */
16834 EventService.prototype.findMountedTarget = function (propagationPath) {
16835 if (!propagationPath) {
16836 return null;
16837 }
16838 var currentTarget = propagationPath[propagationPath.length - 1];
16839 for (var i = propagationPath.length - 2; i >= 0; i--) {
16840 var target = propagationPath[i];
16841 if (target === this.rootTarget ||
16842 (Node.isNode(target) && target.parentNode === currentTarget)) {
16843 currentTarget = propagationPath[i];
16844 }
16845 else {
16846 break;
16847 }
16848 }
16849 return currentTarget;
16850 };
16851 EventService.prototype.getCursor = function (target) {
16852 var tmp = target;
16853 while (tmp) {
16854 var cursor = isElement(tmp) && tmp.getAttribute('cursor');
16855 if (cursor) {
16856 return cursor;
16857 }
16858 tmp = Node.isNode(tmp) && tmp.parentNode;
16859 }
16860 };
16861 return EventService;
16862 }());
16863
16864 /**
16865 * used in following scenes:
16866 * - g `ctx.measureText`
16867 * - g-plugin-canvas-picker `ctx.isPointInPath`
16868 * - g-plugin-device-renderer `ctx.createLinearGradient` and generate texture
16869 *
16870 * @see https://blog.scottlogic.com/2020/03/19/offscreen-canvas.html
16871 */
16872 var OffscreenCanvasCreator = /** @class */ (function () {
16873 function OffscreenCanvasCreator() {
16874 }
16875 OffscreenCanvasCreator.prototype.getOrCreateCanvas = function (offscreenCanvas, contextAttributes) {
16876 if (this.canvas) {
16877 return this.canvas;
16878 }
16879 // user-defined offscreen canvas
16880 if (offscreenCanvas || runtime.offscreenCanvas) {
16881 this.canvas = offscreenCanvas || runtime.offscreenCanvas;
16882 this.context = this.canvas.getContext('2d', __assign({ willReadFrequently: true }, contextAttributes));
16883 }
16884 else {
16885 try {
16886 // OffscreenCanvas2D measureText can be up to 40% faster.
16887 this.canvas = new window.OffscreenCanvas(0, 0);
16888 this.context = this.canvas.getContext('2d', __assign({ willReadFrequently: true }, contextAttributes));
16889 if (!this.context || !this.context.measureText) {
16890 this.canvas = document.createElement('canvas');
16891 this.context = this.canvas.getContext('2d');
16892 }
16893 }
16894 catch (ex) {
16895 this.canvas = document.createElement('canvas');
16896 this.context = this.canvas.getContext('2d', __assign({ willReadFrequently: true }, contextAttributes));
16897 }
16898 }
16899 this.canvas.width = 10;
16900 this.canvas.height = 10;
16901 return this.canvas;
16902 };
16903 OffscreenCanvasCreator.prototype.getOrCreateContext = function (offscreenCanvas, contextAttributes) {
16904 if (this.context) {
16905 return this.context;
16906 }
16907 this.getOrCreateCanvas(offscreenCanvas, contextAttributes);
16908 return this.context;
16909 };
16910 return OffscreenCanvasCreator;
16911 }());
16912
16913 /**
16914 * why we need re-render
16915 */
16916 var RenderReason;
16917 (function (RenderReason) {
16918 RenderReason[RenderReason["CAMERA_CHANGED"] = 0] = "CAMERA_CHANGED";
16919 RenderReason[RenderReason["DISPLAY_OBJECT_CHANGED"] = 1] = "DISPLAY_OBJECT_CHANGED";
16920 RenderReason[RenderReason["NONE"] = 2] = "NONE";
16921 })(RenderReason || (RenderReason = {}));
16922
16923 /**
16924 * Use frame renderer implemented by `g-canvas/svg/webgl`, in every frame we do followings:
16925 * * update & merge dirty rectangles
16926 * * begin frame
16927 * * filter by visible
16928 * * sort by z-index in scene graph
16929 * * culling with strategies registered in `g-canvas/webgl`
16930 * * end frame
16931 */
16932 var RenderingService = /** @class */ (function () {
16933 function RenderingService(globalRuntime, context) {
16934 this.globalRuntime = globalRuntime;
16935 this.context = context;
16936 this.inited = false;
16937 this.stats = {
16938 /**
16939 * total display objects in scenegraph
16940 */
16941 total: 0,
16942 /**
16943 * number of display objects need to render in current frame
16944 */
16945 rendered: 0,
16946 };
16947 this.zIndexCounter = 0;
16948 this.hooks = {
16949 /**
16950 * called before any frame rendered
16951 */
16952 init: new SyncHook(),
16953 initAsync: new AsyncParallelHook(),
16954 /**
16955 * only dirty object which has sth changed will be rendered
16956 */
16957 dirtycheck: new SyncWaterfallHook(),
16958 /**
16959 * do culling
16960 */
16961 cull: new SyncWaterfallHook(),
16962 /**
16963 * called at beginning of each frame, won't get called if nothing to re-render
16964 */
16965 beginFrame: new SyncHook(),
16966 /**
16967 * called before every dirty object get rendered
16968 */
16969 beforeRender: new SyncHook(),
16970 /**
16971 * called when every dirty object rendering even it's culled
16972 */
16973 render: new SyncHook(),
16974 /**
16975 * called after every dirty object get rendered
16976 */
16977 afterRender: new SyncHook(),
16978 endFrame: new SyncHook(),
16979 destroy: new SyncHook(),
16980 /**
16981 * use async but faster method such as GPU-based picking in `g-plugin-device-renderer`
16982 */
16983 pick: new AsyncSeriesWaterfallHook(),
16984 /**
16985 * Unsafe but sync version of pick.
16986 */
16987 pickSync: new SyncWaterfallHook(),
16988 /**
16989 * used in event system
16990 */
16991 pointerDown: new SyncHook(),
16992 pointerUp: new SyncHook(),
16993 pointerMove: new SyncHook(),
16994 pointerOut: new SyncHook(),
16995 pointerOver: new SyncHook(),
16996 pointerWheel: new SyncHook(),
16997 pointerCancel: new SyncHook(),
16998 click: new SyncHook(),
16999 };
17000 }
17001 RenderingService.prototype.init = function (callback) {
17002 var _this = this;
17003 var context = __assign(__assign({}, this.globalRuntime), this.context);
17004 // register rendering plugins
17005 this.context.renderingPlugins.forEach(function (plugin) {
17006 plugin.apply(context, _this.globalRuntime);
17007 });
17008 this.hooks.init.call();
17009 if (this.hooks.initAsync.getCallbacksNum() === 0) {
17010 this.inited = true;
17011 callback();
17012 }
17013 else {
17014 this.hooks.initAsync.promise().then(function () {
17015 _this.inited = true;
17016 callback();
17017 });
17018 }
17019 };
17020 RenderingService.prototype.getStats = function () {
17021 return this.stats;
17022 };
17023 /**
17024 * Meet the following conditions:
17025 * * disable DirtyRectangleRendering
17026 * * camera changed
17027 */
17028 RenderingService.prototype.disableDirtyRectangleRendering = function () {
17029 var renderer = this.context.config.renderer;
17030 var enableDirtyRectangleRendering = renderer.getConfig().enableDirtyRectangleRendering;
17031 return (!enableDirtyRectangleRendering ||
17032 this.context.renderingContext.renderReasons.has(RenderReason.CAMERA_CHANGED));
17033 };
17034 RenderingService.prototype.render = function (canvasConfig, rerenderCallback) {
17035 var _this = this;
17036 this.stats.total = 0;
17037 this.stats.rendered = 0;
17038 this.zIndexCounter = 0;
17039 var renderingContext = this.context.renderingContext;
17040 this.globalRuntime.sceneGraphService.syncHierarchy(renderingContext.root);
17041 this.globalRuntime.sceneGraphService.triggerPendingEvents();
17042 if (renderingContext.renderReasons.size && this.inited) {
17043 // @ts-ignore
17044 renderingContext.dirtyRectangleRenderingDisabled =
17045 this.disableDirtyRectangleRendering();
17046 var onlyCameraChanged = renderingContext.renderReasons.size === 1 &&
17047 renderingContext.renderReasons.has(RenderReason.CAMERA_CHANGED);
17048 var shouldTriggerRenderHooks = !canvasConfig.disableRenderHooks ||
17049 !(canvasConfig.disableRenderHooks && onlyCameraChanged);
17050 if (shouldTriggerRenderHooks) {
17051 this.renderDisplayObject(renderingContext.root, canvasConfig, renderingContext);
17052 }
17053 this.hooks.beginFrame.call();
17054 if (shouldTriggerRenderHooks) {
17055 renderingContext.renderListCurrentFrame.forEach(function (object) {
17056 _this.hooks.beforeRender.call(object);
17057 _this.hooks.render.call(object);
17058 _this.hooks.afterRender.call(object);
17059 });
17060 }
17061 this.hooks.endFrame.call();
17062 renderingContext.renderListCurrentFrame = [];
17063 renderingContext.renderReasons.clear();
17064 rerenderCallback();
17065 }
17066 // console.log('stats', this.stats);
17067 };
17068 RenderingService.prototype.renderDisplayObject = function (displayObject, canvasConfig, renderingContext) {
17069 var _this = this;
17070 var _a = canvasConfig.renderer.getConfig(), enableDirtyCheck = _a.enableDirtyCheck, enableCulling = _a.enableCulling;
17071 // recalc style values
17072 if (this.globalRuntime.enableCSSParsing) {
17073 this.globalRuntime.styleValueRegistry.recalc(displayObject);
17074 }
17075 // TODO: relayout
17076 // dirtycheck first
17077 var renderable = displayObject.renderable;
17078 var objectChanged = enableDirtyCheck
17079 ? // @ts-ignore
17080 renderable.dirty || renderingContext.dirtyRectangleRenderingDisabled
17081 ? displayObject
17082 : null
17083 : displayObject;
17084 if (objectChanged) {
17085 var objectToRender = enableCulling
17086 ? this.hooks.cull.call(objectChanged, this.context.camera)
17087 : objectChanged;
17088 if (objectToRender) {
17089 this.stats.rendered++;
17090 renderingContext.renderListCurrentFrame.push(objectToRender);
17091 }
17092 }
17093 displayObject.renderable.dirty = false;
17094 displayObject.sortable.renderOrder = this.zIndexCounter++;
17095 this.stats.total++;
17096 // sort is very expensive, use cached result if possible
17097 var sortable = displayObject.sortable;
17098 if (sortable.dirty) {
17099 this.sort(displayObject, sortable);
17100 sortable.dirty = false;
17101 sortable.dirtyChildren = [];
17102 sortable.dirtyReason = undefined;
17103 }
17104 // recursive rendering its children
17105 (sortable.sorted || displayObject.childNodes).forEach(function (child) {
17106 _this.renderDisplayObject(child, canvasConfig, renderingContext);
17107 });
17108 };
17109 RenderingService.prototype.sort = function (displayObject, sortable) {
17110 if (sortable.sorted &&
17111 sortable.dirtyReason !== SortReason.Z_INDEX_CHANGED) {
17112 // avoid re-sorting the whole children list
17113 sortable.dirtyChildren.forEach(function (child) {
17114 var index = displayObject.childNodes.indexOf(child);
17115 if (index === -1) {
17116 // remove from sorted list
17117 var index_1 = sortable.sorted.indexOf(child);
17118 if (index_1 >= 0) {
17119 sortable.sorted.splice(index_1, 1);
17120 }
17121 }
17122 else {
17123 if (sortable.sorted.length === 0) {
17124 sortable.sorted.push(child);
17125 }
17126 else {
17127 var index_2 = sortedIndex(sortable.sorted, child);
17128 sortable.sorted.splice(index_2, 0, child);
17129 }
17130 }
17131 });
17132 }
17133 else {
17134 sortable.sorted = displayObject.childNodes.slice().sort(sortByZIndex);
17135 }
17136 };
17137 RenderingService.prototype.destroy = function () {
17138 this.inited = false;
17139 this.hooks.destroy.call();
17140 this.globalRuntime.sceneGraphService.clearPendingEvents();
17141 };
17142 RenderingService.prototype.dirtify = function () {
17143 // need re-render
17144 this.context.renderingContext.renderReasons.add(RenderReason.DISPLAY_OBJECT_CHANGED);
17145 };
17146 return RenderingService;
17147 }());
17148
17149 var ATTRIBUTE_REGEXP = /\[\s*(.*)=(.*)\s*\]/;
17150 /**
17151 * support the following DOM API:
17152 * * getElementById
17153 * * getElementsByClassName
17154 * * getElementsByName
17155 * * getElementsByTag
17156 * * querySelector
17157 * * querySelectorAll
17158 */
17159 var DefaultSceneGraphSelector = /** @class */ (function () {
17160 function DefaultSceneGraphSelector() {
17161 }
17162 DefaultSceneGraphSelector.prototype.selectOne = function (query, root) {
17163 var _this = this;
17164 if (query.startsWith('.')) {
17165 return root.find(function (node) {
17166 // return !node.shadow && node.id === query.substring(1);
17167 return (((node === null || node === void 0 ? void 0 : node.classList) || []).indexOf(_this.getIdOrClassname(query)) > -1);
17168 });
17169 }
17170 else if (query.startsWith('#')) {
17171 // getElementById('id')
17172 return root.find(function (node) {
17173 // return !node.shadow && node.id === query.substring(1);
17174 return node.id === _this.getIdOrClassname(query);
17175 });
17176 }
17177 else if (query.startsWith('[')) {
17178 var _a = this.getAttribute(query), name_1 = _a.name, value_1 = _a.value;
17179 if (name_1) {
17180 // getElementByName();
17181 return root.find(function (node) {
17182 return root !== node &&
17183 (name_1 === 'name'
17184 ? node.name === value_1
17185 : _this.attributeToString(node, name_1) === value_1);
17186 });
17187 }
17188 else {
17189 return null;
17190 }
17191 }
17192 else {
17193 // getElementsByTag('circle');
17194 return root.find(function (node) { return root !== node && node.nodeName === query; });
17195 }
17196 };
17197 DefaultSceneGraphSelector.prototype.selectAll = function (query, root) {
17198 var _this = this;
17199 // only support `[name="${name}"]` `.className` `#id`
17200 if (query.startsWith('.')) {
17201 // getElementsByClassName('className');
17202 // should not include itself
17203 return root.findAll(function (node) {
17204 return root !== node &&
17205 ((node === null || node === void 0 ? void 0 : node.classList) || []).indexOf(_this.getIdOrClassname(query)) > -1;
17206 });
17207 }
17208 else if (query.startsWith('#')) {
17209 return root.findAll(function (node) {
17210 return root !== node &&
17211 node.id === _this.getIdOrClassname(query);
17212 });
17213 }
17214 else if (query.startsWith('[')) {
17215 var _a = this.getAttribute(query), name_2 = _a.name, value_2 = _a.value;
17216 if (name_2) {
17217 // getElementsByName();
17218 return root.findAll(function (node) {
17219 return root !== node &&
17220 (name_2 === 'name'
17221 ? node.name === value_2
17222 : _this.attributeToString(node, name_2) === value_2);
17223 });
17224 }
17225 else {
17226 return [];
17227 }
17228 }
17229 else {
17230 // getElementsByTag('circle');
17231 return root.findAll(function (node) { return root !== node && node.nodeName === query; });
17232 }
17233 };
17234 DefaultSceneGraphSelector.prototype.is = function (query, node) {
17235 // a simple `matches` implementation
17236 if (query.startsWith('.')) {
17237 return node.className === this.getIdOrClassname(query);
17238 }
17239 else if (query.startsWith('#')) {
17240 return node.id === this.getIdOrClassname(query);
17241 }
17242 else if (query.startsWith('[')) {
17243 var _a = this.getAttribute(query), name_3 = _a.name, value = _a.value;
17244 return name_3 === 'name'
17245 ? node.name === value
17246 : this.attributeToString(node, name_3) === value;
17247 }
17248 else {
17249 return node.nodeName === query;
17250 }
17251 };
17252 DefaultSceneGraphSelector.prototype.getIdOrClassname = function (query) {
17253 return query.substring(1);
17254 };
17255 DefaultSceneGraphSelector.prototype.getAttribute = function (query) {
17256 var matches = query.match(ATTRIBUTE_REGEXP);
17257 var name = '';
17258 var value = '';
17259 if (matches && matches.length > 2) {
17260 name = matches[1].replace(/"/g, '');
17261 value = matches[2].replace(/"/g, '');
17262 }
17263 return { name: name, value: value };
17264 };
17265 DefaultSceneGraphSelector.prototype.attributeToString = function (node, name) {
17266 if (!node.getAttribute) {
17267 return '';
17268 }
17269 var value = node.getAttribute(name);
17270 if (isNil(value)) {
17271 return '';
17272 }
17273 if (value.toString) {
17274 return value.toString();
17275 }
17276 return '';
17277 };
17278 return DefaultSceneGraphSelector;
17279 }());
17280
17281 var MutationEvent = /** @class */ (function (_super) {
17282 __extends(MutationEvent, _super);
17283 function MutationEvent(typeArg, relatedNode, prevValue, newValue, attrName, attrChange, prevParsedValue, newParsedValue) {
17284 var _this = _super.call(this, null) || this;
17285 _this.relatedNode = relatedNode;
17286 _this.prevValue = prevValue;
17287 _this.newValue = newValue;
17288 _this.attrName = attrName;
17289 _this.attrChange = attrChange;
17290 _this.prevParsedValue = prevParsedValue;
17291 _this.newParsedValue = newParsedValue;
17292 _this.type = typeArg;
17293 return _this;
17294 }
17295 MutationEvent.ADDITION = 2;
17296 MutationEvent.MODIFICATION = 1;
17297 MutationEvent.REMOVAL = 3;
17298 return MutationEvent;
17299 }(FederatedEvent));
17300
17301 /**
17302 * built-in events for element
17303 * @see https://developer.mozilla.org/en-US/docs/Web/API/MutationEvent
17304 *
17305 * TODO: use MutationObserver instead
17306 * @see https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
17307 */
17308 var ElementEvent;
17309 (function (ElementEvent) {
17310 ElementEvent["REPARENT"] = "reparent";
17311 ElementEvent["DESTROY"] = "destroy";
17312 /**
17313 * @see https://www.w3.org/TR/DOM-Level-3-Events/#event-type-DOMAttrModified
17314 */
17315 ElementEvent["ATTR_MODIFIED"] = "DOMAttrModified";
17316 /**
17317 * it has been inserted
17318 * @see https://www.w3.org/TR/DOM-Level-3-Events/#event-type-DOMNodeInserted
17319 */
17320 ElementEvent["INSERTED"] = "DOMNodeInserted";
17321 /**
17322 * it is being removed
17323 * @see https://www.w3.org/TR/DOM-Level-3-Events/#event-type-DOMNodeRemoved
17324 */
17325 ElementEvent["REMOVED"] = "removed";
17326 /**
17327 * @see https://www.w3.org/TR/DOM-Level-3-Events/#domnodeinsertedintodocument
17328 */
17329 ElementEvent["MOUNTED"] = "DOMNodeInsertedIntoDocument";
17330 /**
17331 * @see https://www.w3.org/TR/DOM-Level-3-Events/#domnoderemovedfromdocument
17332 */
17333 ElementEvent["UNMOUNTED"] = "DOMNodeRemovedFromDocument";
17334 ElementEvent["BOUNDS_CHANGED"] = "bounds-changed";
17335 ElementEvent["CULLED"] = "culled";
17336 })(ElementEvent || (ElementEvent = {}));
17337
17338 function markRenderableDirty(e) {
17339 var renderable = e.renderable;
17340 if (renderable) {
17341 renderable.renderBoundsDirty = true;
17342 renderable.boundsDirty = true;
17343 }
17344 }
17345 var reparentEvent = new MutationEvent(ElementEvent.REPARENT, null, '', '', '', 0, '', '');
17346 /**
17347 * update transform in scene graph
17348 *
17349 * @see https://community.khronos.org/t/scene-graphs/50542/7
17350 */
17351 var DefaultSceneGraphService = /** @class */ (function () {
17352 function DefaultSceneGraphService(runtime) {
17353 var _this = this;
17354 this.runtime = runtime;
17355 this.pendingEvents = [];
17356 this.boundsChangedEvent = new CustomEvent(ElementEvent.BOUNDS_CHANGED);
17357 /**
17358 * rotate in world space
17359 */
17360 this.rotate = (function () {
17361 var parentInvertRotation = create$4();
17362 return function (element, degrees, y, z) {
17363 if (y === void 0) { y = 0; }
17364 if (z === void 0) { z = 0; }
17365 if (typeof degrees === 'number') {
17366 degrees = fromValues$2(degrees, y, z);
17367 }
17368 var transform = element.transformable;
17369 if (element.parentNode === null ||
17370 !element.parentNode.transformable) {
17371 _this.rotateLocal(element, degrees);
17372 }
17373 else {
17374 var rotation = create$4();
17375 fromEuler(rotation, degrees[0], degrees[1], degrees[2]);
17376 var rot = _this.getRotation(element);
17377 var parentRot = _this.getRotation(element.parentNode);
17378 copy$3(parentInvertRotation, parentRot);
17379 invert$1(parentInvertRotation, parentInvertRotation);
17380 multiply$2(rotation, parentInvertRotation, rotation);
17381 multiply$2(transform.localRotation, rotation, rot);
17382 normalize$2(transform.localRotation, transform.localRotation);
17383 _this.dirtifyLocal(element, transform);
17384 }
17385 };
17386 })();
17387 /**
17388 * rotate in local space
17389 * @see @see https://docs.microsoft.com/en-us/windows/win32/api/directxmath/nf-directxmath-xmquaternionrotationrollpitchyaw
17390 */
17391 this.rotateLocal = (function () {
17392 var rotation = create$4();
17393 return function (element, degrees, y, z) {
17394 if (y === void 0) { y = 0; }
17395 if (z === void 0) { z = 0; }
17396 if (typeof degrees === 'number') {
17397 degrees = fromValues$2(degrees, y, z);
17398 }
17399 var transform = element.transformable;
17400 fromEuler(rotation, degrees[0], degrees[1], degrees[2]);
17401 mul$1(transform.localRotation, transform.localRotation, rotation);
17402 _this.dirtifyLocal(element, transform);
17403 };
17404 })();
17405 /**
17406 * set euler angles(degrees) in world space
17407 */
17408 this.setEulerAngles = (function () {
17409 var invParentRot = create$4();
17410 return function (element, degrees, y, z) {
17411 if (y === void 0) { y = 0; }
17412 if (z === void 0) { z = 0; }
17413 if (typeof degrees === 'number') {
17414 degrees = fromValues$2(degrees, y, z);
17415 }
17416 var transform = element.transformable;
17417 if (element.parentNode === null ||
17418 !element.parentNode.transformable) {
17419 _this.setLocalEulerAngles(element, degrees);
17420 }
17421 else {
17422 fromEuler(transform.localRotation, degrees[0], degrees[1], degrees[2]);
17423 var parentRotation = _this.getRotation(element.parentNode);
17424 copy$3(invParentRot, invert$1(create$4(), parentRotation));
17425 mul$1(transform.localRotation, transform.localRotation, invParentRot);
17426 _this.dirtifyLocal(element, transform);
17427 }
17428 };
17429 })();
17430 /**
17431 * translate in local space
17432 *
17433 * @example
17434 * ```
17435 * translateLocal(x, y, z)
17436 * translateLocal(vec3(x, y, z))
17437 * ```
17438 */
17439 this.translateLocal = (function () {
17440 return function (element, translation, y, z) {
17441 if (y === void 0) { y = 0; }
17442 if (z === void 0) { z = 0; }
17443 if (typeof translation === 'number') {
17444 translation = fromValues$2(translation, y, z);
17445 }
17446 var transform = element.transformable;
17447 if (equals$1(translation, create$2())) {
17448 return;
17449 }
17450 transformQuat(translation, translation, transform.localRotation);
17451 add$1(transform.localPosition, transform.localPosition, translation);
17452 _this.dirtifyLocal(element, transform);
17453 };
17454 })();
17455 /**
17456 * move to position in world space
17457 *
17458 * 对应 g 原版的 move/moveTo
17459 * @see https://github.com/antvis/g/blob/master/packages/g-base/src/abstract/element.ts#L684-L689
17460 */
17461 this.setPosition = (function () {
17462 var parentInvertMatrix = create$1();
17463 var tmpPosition = create$2();
17464 return function (element, position) {
17465 var transform = element.transformable;
17466 tmpPosition[0] = position[0];
17467 tmpPosition[1] = position[1];
17468 tmpPosition[2] = position[2] || 0;
17469 if (equals$1(_this.getPosition(element), tmpPosition)) {
17470 return;
17471 }
17472 copy$1(transform.position, tmpPosition);
17473 if (element.parentNode === null ||
17474 !element.parentNode.transformable) {
17475 copy$1(transform.localPosition, tmpPosition);
17476 }
17477 else {
17478 var parentTransform = element.parentNode.transformable;
17479 copy(parentInvertMatrix, parentTransform.worldTransform);
17480 invert(parentInvertMatrix, parentInvertMatrix);
17481 transformMat4(transform.localPosition, tmpPosition, parentInvertMatrix);
17482 }
17483 _this.dirtifyLocal(element, transform);
17484 };
17485 })();
17486 /**
17487 * move to position in local space
17488 */
17489 this.setLocalPosition = (function () {
17490 var tmpPosition = create$2();
17491 return function (element, position) {
17492 var transform = element.transformable;
17493 tmpPosition[0] = position[0];
17494 tmpPosition[1] = position[1];
17495 tmpPosition[2] = position[2] || 0;
17496 if (equals$1(transform.localPosition, tmpPosition)) {
17497 return;
17498 }
17499 copy$1(transform.localPosition, tmpPosition);
17500 _this.dirtifyLocal(element, transform);
17501 };
17502 })();
17503 /**
17504 * translate in world space
17505 *
17506 * @example
17507 * ```
17508 * translate(x, y, z)
17509 * translate(vec3(x, y, z))
17510 * ```
17511 *
17512 * 对应 g 原版的 translate 2D
17513 * @see https://github.com/antvis/g/blob/master/packages/g-base/src/abstract/element.ts#L665-L676
17514 */
17515 this.translate = (function () {
17516 var zeroVec3 = create$2();
17517 var tmpVec3 = create$2();
17518 var tr = create$2();
17519 return function (element, translation, y, z) {
17520 if (y === void 0) { y = 0; }
17521 if (z === void 0) { z = 0; }
17522 if (typeof translation === 'number') {
17523 translation = set$1(tmpVec3, translation, y, z);
17524 }
17525 if (equals$1(translation, zeroVec3)) {
17526 return;
17527 }
17528 add$1(tr, _this.getPosition(element), translation);
17529 _this.setPosition(element, tr);
17530 };
17531 })();
17532 this.setRotation = function () {
17533 var parentInvertRotation = create$4();
17534 return function (element, rotation, y, z, w) {
17535 var transform = element.transformable;
17536 if (typeof rotation === 'number') {
17537 rotation = fromValues$4(rotation, y, z, w);
17538 }
17539 if (element.parentNode === null ||
17540 !element.parentNode.transformable) {
17541 _this.setLocalRotation(element, rotation);
17542 }
17543 else {
17544 var parentRot = _this.getRotation(element.parentNode);
17545 copy$3(parentInvertRotation, parentRot);
17546 invert$1(parentInvertRotation, parentInvertRotation);
17547 multiply$2(transform.localRotation, parentInvertRotation, rotation);
17548 normalize$2(transform.localRotation, transform.localRotation);
17549 _this.dirtifyLocal(element, transform);
17550 }
17551 };
17552 };
17553 this.displayObjectDependencyMap = new WeakMap();
17554 this.calcLocalTransform = (function () {
17555 var tmpMat = create$1();
17556 var tmpPosition = create$2();
17557 var tmpQuat = fromValues$4(0, 0, 0, 1);
17558 return function (transform) {
17559 var hasSkew = transform.localSkew[0] !== 0 || transform.localSkew[1] !== 0;
17560 if (hasSkew) {
17561 fromRotationTranslationScaleOrigin(transform.localTransform, transform.localRotation, transform.localPosition, fromValues$2(1, 1, 1), transform.origin);
17562 // apply skew2D
17563 if (transform.localSkew[0] !== 0 || transform.localSkew[1] !== 0) {
17564 var tmpMat4 = identity$1(tmpMat);
17565 tmpMat4[4] = Math.tan(transform.localSkew[0]);
17566 tmpMat4[1] = Math.tan(transform.localSkew[1]);
17567 multiply(transform.localTransform, transform.localTransform, tmpMat4);
17568 }
17569 var scaling = fromRotationTranslationScaleOrigin(tmpMat, tmpQuat, tmpPosition, transform.localScale, transform.origin);
17570 multiply(transform.localTransform, transform.localTransform, scaling);
17571 }
17572 else {
17573 // @see https://github.com/mattdesl/css-mat4/blob/master/index.js
17574 fromRotationTranslationScaleOrigin(transform.localTransform, transform.localRotation, transform.localPosition, transform.localScale, transform.origin);
17575 }
17576 };
17577 })();
17578 }
17579 DefaultSceneGraphService.prototype.matches = function (query, root) {
17580 return this.runtime.sceneGraphSelector.is(query, root);
17581 };
17582 DefaultSceneGraphService.prototype.querySelector = function (query, root) {
17583 return this.runtime.sceneGraphSelector.selectOne(query, root);
17584 };
17585 DefaultSceneGraphService.prototype.querySelectorAll = function (query, root) {
17586 return this.runtime.sceneGraphSelector.selectAll(query, root);
17587 // .filter((node) => !node.shadow);
17588 };
17589 DefaultSceneGraphService.prototype.attach = function (child, parent, index) {
17590 var _a, _b;
17591 var detached = false;
17592 if (child.parentNode) {
17593 detached = child.parentNode !== parent;
17594 this.detach(child);
17595 }
17596 child.parentNode = parent;
17597 if (!isNil(index)) {
17598 child.parentNode.childNodes.splice(index, 0, child);
17599 }
17600 else {
17601 child.parentNode.childNodes.push(child);
17602 }
17603 // parent needs re-sort
17604 var sortable = parent.sortable;
17605 if (((_a = sortable === null || sortable === void 0 ? void 0 : sortable.sorted) === null || _a === void 0 ? void 0 : _a.length) ||
17606 ((_b = child.style) === null || _b === void 0 ? void 0 : _b.zIndex)) {
17607 if (sortable.dirtyChildren.indexOf(child) === -1) {
17608 sortable.dirtyChildren.push(child);
17609 }
17610 // if (sortable) {
17611 // only child has z-Index
17612 sortable.dirty = true;
17613 sortable.dirtyReason = SortReason.ADDED;
17614 }
17615 // this.updateGraphDepth(child);
17616 var transform = child.transformable;
17617 if (transform) {
17618 this.dirtifyWorld(child, transform);
17619 }
17620 if (transform.frozen) {
17621 this.unfreezeParentToRoot(child);
17622 }
17623 if (detached) {
17624 child.dispatchEvent(reparentEvent);
17625 }
17626 };
17627 DefaultSceneGraphService.prototype.detach = function (child) {
17628 var _a, _b;
17629 if (child.parentNode) {
17630 var transform = child.transformable;
17631 // if (transform) {
17632 // const worldTransform = this.getWorldTransform(child, transform);
17633 // mat4.getScaling(transform.localScale, worldTransform);
17634 // mat4.getTranslation(transform.localPosition, worldTransform);
17635 // mat4.getRotation(transform.localRotation, worldTransform);
17636 // transform.localDirtyFlag = true;
17637 // }
17638 // parent needs re-sort
17639 var sortable = child.parentNode.sortable;
17640 // if (sortable) {
17641 if (((_a = sortable === null || sortable === void 0 ? void 0 : sortable.sorted) === null || _a === void 0 ? void 0 : _a.length) ||
17642 ((_b = child.style) === null || _b === void 0 ? void 0 : _b.zIndex)) {
17643 if (sortable.dirtyChildren.indexOf(child) === -1) {
17644 sortable.dirtyChildren.push(child);
17645 }
17646 sortable.dirty = true;
17647 sortable.dirtyReason = SortReason.REMOVED;
17648 }
17649 var index = child.parentNode.childNodes.indexOf(child);
17650 if (index > -1) {
17651 child.parentNode.childNodes.splice(index, 1);
17652 }
17653 if (transform) {
17654 this.dirtifyWorld(child, transform);
17655 }
17656 child.parentNode = null;
17657 }
17658 };
17659 DefaultSceneGraphService.prototype.getOrigin = function (element) {
17660 return element.transformable.origin;
17661 };
17662 /**
17663 * same as pivot in Pixi.js
17664 *
17665 * @see https://stackoverflow.com/questions/40748452/how-to-change-css-transform-origin-but-preserve-transformation
17666 */
17667 DefaultSceneGraphService.prototype.setOrigin = function (element, origin, y, z) {
17668 if (y === void 0) { y = 0; }
17669 if (z === void 0) { z = 0; }
17670 if (typeof origin === 'number') {
17671 origin = [origin, y, z];
17672 }
17673 var transform = element.transformable;
17674 if (origin[0] === transform.origin[0] &&
17675 origin[1] === transform.origin[1] &&
17676 origin[2] === transform.origin[2]) {
17677 return;
17678 }
17679 var originVec = transform.origin;
17680 // const delta = vec3.subtract(vec3.create(), origin, originVec);
17681 // vec3.add(transform.localPosition, transform.localPosition, delta);
17682 // update origin
17683 originVec[0] = origin[0];
17684 originVec[1] = origin[1];
17685 originVec[2] = origin[2] || 0;
17686 this.dirtifyLocal(element, transform);
17687 };
17688 /**
17689 * set euler angles(degrees) in local space
17690 */
17691 DefaultSceneGraphService.prototype.setLocalEulerAngles = function (element, degrees, y, z) {
17692 if (y === void 0) { y = 0; }
17693 if (z === void 0) { z = 0; }
17694 if (typeof degrees === 'number') {
17695 degrees = fromValues$2(degrees, y, z);
17696 }
17697 var transform = element.transformable;
17698 fromEuler(transform.localRotation, degrees[0], degrees[1], degrees[2]);
17699 this.dirtifyLocal(element, transform);
17700 };
17701 /**
17702 * scale in local space
17703 */
17704 DefaultSceneGraphService.prototype.scaleLocal = function (element, scaling) {
17705 var transform = element.transformable;
17706 multiply$1(transform.localScale, transform.localScale, fromValues$2(scaling[0], scaling[1], scaling[2] || 1));
17707 this.dirtifyLocal(element, transform);
17708 };
17709 DefaultSceneGraphService.prototype.setLocalScale = function (element, scaling) {
17710 var transform = element.transformable;
17711 var updatedScaling = fromValues$2(scaling[0], scaling[1], scaling[2] || transform.localScale[2]);
17712 if (equals$1(updatedScaling, transform.localScale)) {
17713 return;
17714 }
17715 copy$1(transform.localScale, updatedScaling);
17716 this.dirtifyLocal(element, transform);
17717 };
17718 DefaultSceneGraphService.prototype.setLocalRotation = function (element, rotation, y, z, w) {
17719 if (typeof rotation === 'number') {
17720 rotation = fromValues$4(rotation, y, z, w);
17721 }
17722 var transform = element.transformable;
17723 copy$3(transform.localRotation, rotation);
17724 this.dirtifyLocal(element, transform);
17725 };
17726 DefaultSceneGraphService.prototype.setLocalSkew = function (element, skew, y) {
17727 if (typeof skew === 'number') {
17728 skew = fromValues$5(skew, y);
17729 }
17730 var transform = element.transformable;
17731 copy$4(transform.localSkew, skew);
17732 this.dirtifyLocal(element, transform);
17733 };
17734 DefaultSceneGraphService.prototype.dirtifyLocal = function (element, transform) {
17735 if (!transform.localDirtyFlag) {
17736 transform.localDirtyFlag = true;
17737 if (!transform.dirtyFlag) {
17738 this.dirtifyWorld(element, transform);
17739 }
17740 }
17741 };
17742 DefaultSceneGraphService.prototype.dirtifyWorld = function (element, transform) {
17743 if (!transform.dirtyFlag) {
17744 this.unfreezeParentToRoot(element);
17745 }
17746 this.dirtifyWorldInternal(element, transform);
17747 this.dirtifyToRoot(element, true);
17748 };
17749 DefaultSceneGraphService.prototype.triggerPendingEvents = function () {
17750 var _this = this;
17751 var set = new Set();
17752 var trigger = function (element, detail) {
17753 if (element.isConnected && !set.has(element.entity)) {
17754 _this.boundsChangedEvent.detail = detail;
17755 _this.boundsChangedEvent.target = element;
17756 if (element.isMutationObserved) {
17757 element.dispatchEvent(_this.boundsChangedEvent);
17758 }
17759 else {
17760 element.ownerDocument.defaultView.dispatchEvent(_this.boundsChangedEvent, true);
17761 }
17762 set.add(element.entity);
17763 }
17764 };
17765 this.pendingEvents.forEach(function (_a) {
17766 var _b = __read(_a, 2), element = _b[0], detail = _b[1];
17767 if (detail.affectChildren) {
17768 element.forEach(function (e) {
17769 trigger(e, detail);
17770 });
17771 }
17772 else {
17773 trigger(element, detail);
17774 }
17775 });
17776 this.clearPendingEvents();
17777 set.clear();
17778 };
17779 DefaultSceneGraphService.prototype.clearPendingEvents = function () {
17780 this.pendingEvents = [];
17781 };
17782 DefaultSceneGraphService.prototype.dirtifyToRoot = function (element, affectChildren) {
17783 if (affectChildren === void 0) { affectChildren = false; }
17784 var p = element;
17785 // only need to re-render itself
17786 if (p.renderable) {
17787 p.renderable.dirty = true;
17788 }
17789 while (p) {
17790 markRenderableDirty(p);
17791 p = p.parentNode;
17792 }
17793 if (affectChildren) {
17794 element.forEach(function (e) {
17795 markRenderableDirty(e);
17796 });
17797 }
17798 // inform dependencies
17799 this.informDependentDisplayObjects(element);
17800 // reuse the same custom event
17801 this.pendingEvents.push([element, { affectChildren: affectChildren }]);
17802 };
17803 DefaultSceneGraphService.prototype.updateDisplayObjectDependency = function (name, oldPath, newPath, object) {
17804 // clear ref to old clip path
17805 if (oldPath && oldPath !== newPath) {
17806 var oldDependencyMap = this.displayObjectDependencyMap.get(oldPath);
17807 if (oldDependencyMap && oldDependencyMap[name]) {
17808 var index = oldDependencyMap[name].indexOf(object);
17809 oldDependencyMap[name].splice(index, 1);
17810 }
17811 }
17812 if (newPath) {
17813 var newDependencyMap = this.displayObjectDependencyMap.get(newPath);
17814 if (!newDependencyMap) {
17815 this.displayObjectDependencyMap.set(newPath, {});
17816 newDependencyMap = this.displayObjectDependencyMap.get(newPath);
17817 }
17818 if (!newDependencyMap[name]) {
17819 newDependencyMap[name] = [];
17820 }
17821 newDependencyMap[name].push(object);
17822 }
17823 };
17824 DefaultSceneGraphService.prototype.informDependentDisplayObjects = function (object) {
17825 var _this = this;
17826 var dependencyMap = this.displayObjectDependencyMap.get(object);
17827 if (dependencyMap) {
17828 Object.keys(dependencyMap).forEach(function (name) {
17829 dependencyMap[name].forEach(function (target) {
17830 _this.dirtifyToRoot(target, true);
17831 target.dispatchEvent(new MutationEvent(ElementEvent.ATTR_MODIFIED, target, _this, _this, name, MutationEvent.MODIFICATION, _this, _this));
17832 if (target.isCustomElement && target.isConnected) {
17833 if (target.attributeChangedCallback) {
17834 target.attributeChangedCallback(name, _this, _this);
17835 }
17836 }
17837 });
17838 });
17839 }
17840 };
17841 DefaultSceneGraphService.prototype.getPosition = function (element) {
17842 var transform = element.transformable;
17843 return getTranslation(transform.position, this.getWorldTransform(element, transform));
17844 };
17845 DefaultSceneGraphService.prototype.getRotation = function (element) {
17846 var transform = element.transformable;
17847 return getRotation(transform.rotation, this.getWorldTransform(element, transform));
17848 };
17849 DefaultSceneGraphService.prototype.getScale = function (element) {
17850 var transform = element.transformable;
17851 return getScaling(transform.scaling, this.getWorldTransform(element, transform));
17852 };
17853 DefaultSceneGraphService.prototype.getWorldTransform = function (element, transform) {
17854 if (transform === void 0) { transform = element.transformable; }
17855 if (!transform.localDirtyFlag && !transform.dirtyFlag) {
17856 return transform.worldTransform;
17857 }
17858 if (element.parentNode && element.parentNode.transformable) {
17859 this.getWorldTransform(element.parentNode);
17860 }
17861 this.sync(element, transform);
17862 return transform.worldTransform;
17863 };
17864 DefaultSceneGraphService.prototype.getLocalPosition = function (element) {
17865 return element.transformable.localPosition;
17866 };
17867 DefaultSceneGraphService.prototype.getLocalRotation = function (element) {
17868 return element.transformable.localRotation;
17869 };
17870 DefaultSceneGraphService.prototype.getLocalScale = function (element) {
17871 return element.transformable.localScale;
17872 };
17873 DefaultSceneGraphService.prototype.getLocalSkew = function (element) {
17874 return element.transformable.localSkew;
17875 };
17876 DefaultSceneGraphService.prototype.getLocalTransform = function (element) {
17877 var transform = element.transformable;
17878 if (transform.localDirtyFlag) {
17879 this.calcLocalTransform(transform);
17880 transform.localDirtyFlag = false;
17881 }
17882 return transform.localTransform;
17883 };
17884 DefaultSceneGraphService.prototype.setLocalTransform = function (element, transform) {
17885 var t = getTranslation(create$2(), transform);
17886 var r = getRotation(create$4(), transform);
17887 var s = getScaling(create$2(), transform);
17888 this.setLocalScale(element, s);
17889 this.setLocalPosition(element, t);
17890 this.setLocalRotation(element, r);
17891 };
17892 DefaultSceneGraphService.prototype.resetLocalTransform = function (element) {
17893 this.setLocalScale(element, [1, 1, 1]);
17894 this.setLocalPosition(element, [0, 0, 0]);
17895 this.setLocalEulerAngles(element, [0, 0, 0]);
17896 this.setLocalSkew(element, [0, 0]);
17897 };
17898 DefaultSceneGraphService.prototype.getTransformedGeometryBounds = function (element, render, existedAABB) {
17899 if (render === void 0) { render = false; }
17900 var bounds = this.getGeometryBounds(element, render);
17901 if (!AABB.isEmpty(bounds)) {
17902 var aabb = existedAABB || new AABB();
17903 aabb.setFromTransformedAABB(bounds, this.getWorldTransform(element));
17904 return aabb;
17905 }
17906 else {
17907 return null;
17908 }
17909 };
17910 /**
17911 * won't account for children
17912 */
17913 DefaultSceneGraphService.prototype.getGeometryBounds = function (element, render) {
17914 if (render === void 0) { render = false; }
17915 var geometry = element.geometry;
17916 var bounds = render
17917 ? geometry.renderBounds
17918 : geometry.contentBounds || null;
17919 // return (bounds && new AABB(bounds.center, bounds.halfExtents)) || new AABB();
17920 return bounds || new AABB();
17921 };
17922 /**
17923 * account for children in world space
17924 */
17925 DefaultSceneGraphService.prototype.getBounds = function (element, render) {
17926 var _this = this;
17927 if (render === void 0) { render = false; }
17928 var renderable = element.renderable;
17929 if (!renderable.boundsDirty && !render && renderable.bounds) {
17930 return renderable.bounds;
17931 }
17932 if (!renderable.renderBoundsDirty && render && renderable.renderBounds) {
17933 return renderable.renderBounds;
17934 }
17935 // reuse existed if possible
17936 var existedAABB = render ? renderable.renderBounds : renderable.bounds;
17937 // reset with geometry's aabb
17938 var aabb = this.getTransformedGeometryBounds(element, render, existedAABB);
17939 // merge children's aabbs
17940 var children = element.childNodes;
17941 children.forEach(function (child) {
17942 var childBounds = _this.getBounds(child, render);
17943 if (childBounds) {
17944 if (!aabb) {
17945 aabb = existedAABB || new AABB();
17946 aabb.update(childBounds.center, childBounds.halfExtents);
17947 }
17948 else {
17949 aabb.add(childBounds);
17950 }
17951 }
17952 });
17953 if (!aabb) {
17954 aabb = new AABB();
17955 }
17956 if (render) {
17957 // FIXME: account for clip path
17958 var clipped = findClosestClipPathTarget(element);
17959 if (clipped) {
17960 // use bounds under world space
17961 var clipPathBounds = clipped.parsedStyle.clipPath.getBounds(render);
17962 if (!aabb) {
17963 aabb.update(clipPathBounds.center, clipPathBounds.halfExtents);
17964 }
17965 else if (clipPathBounds) {
17966 aabb = clipPathBounds.intersection(aabb);
17967 }
17968 }
17969 }
17970 if (render) {
17971 renderable.renderBounds = aabb;
17972 renderable.renderBoundsDirty = false;
17973 }
17974 else {
17975 renderable.bounds = aabb;
17976 renderable.boundsDirty = false;
17977 }
17978 return aabb;
17979 };
17980 /**
17981 * account for children in local space
17982 */
17983 DefaultSceneGraphService.prototype.getLocalBounds = function (element) {
17984 if (element.parentNode) {
17985 var parentInvert = create$1();
17986 if (element.parentNode.transformable) {
17987 parentInvert = invert(create$1(), this.getWorldTransform(element.parentNode));
17988 }
17989 var bounds = this.getBounds(element);
17990 if (!AABB.isEmpty(bounds)) {
17991 var localBounds = new AABB();
17992 localBounds.setFromTransformedAABB(bounds, parentInvert);
17993 return localBounds;
17994 }
17995 }
17996 return this.getBounds(element);
17997 };
17998 DefaultSceneGraphService.prototype.getBoundingClientRect = function (element) {
17999 var _a, _b;
18000 var aabb;
18001 var bounds = this.getGeometryBounds(element);
18002 if (!AABB.isEmpty(bounds)) {
18003 aabb = new AABB();
18004 // apply transformation to aabb
18005 aabb.setFromTransformedAABB(bounds, this.getWorldTransform(element));
18006 }
18007 // calc context's offset
18008 var bbox = (_b = (_a = element.ownerDocument) === null || _a === void 0 ? void 0 : _a.defaultView) === null || _b === void 0 ? void 0 : _b.getContextService().getBoundingClientRect();
18009 if (aabb) {
18010 var _c = __read(aabb.getMin(), 2), left = _c[0], top_1 = _c[1];
18011 var _d = __read(aabb.getMax(), 2), right = _d[0], bottom = _d[1];
18012 return new Rectangle(left + ((bbox === null || bbox === void 0 ? void 0 : bbox.left) || 0), top_1 + ((bbox === null || bbox === void 0 ? void 0 : bbox.top) || 0), right - left, bottom - top_1);
18013 }
18014 return new Rectangle((bbox === null || bbox === void 0 ? void 0 : bbox.left) || 0, (bbox === null || bbox === void 0 ? void 0 : bbox.top) || 0, 0, 0);
18015 };
18016 DefaultSceneGraphService.prototype.dirtifyWorldInternal = function (element, transform) {
18017 var _this = this;
18018 if (!transform.dirtyFlag) {
18019 transform.dirtyFlag = true;
18020 transform.frozen = false;
18021 element.childNodes.forEach(function (child) {
18022 var childTransform = child.transformable;
18023 if (!childTransform.dirtyFlag) {
18024 _this.dirtifyWorldInternal(child, childTransform);
18025 }
18026 });
18027 var renderable = element.renderable;
18028 if (renderable) {
18029 renderable.renderBoundsDirty = true;
18030 renderable.boundsDirty = true;
18031 renderable.dirty = true;
18032 }
18033 }
18034 };
18035 DefaultSceneGraphService.prototype.syncHierarchy = function (element) {
18036 var transform = element.transformable;
18037 if (transform.frozen) {
18038 return;
18039 }
18040 transform.frozen = true;
18041 if (transform.localDirtyFlag || transform.dirtyFlag) {
18042 this.sync(element, transform);
18043 }
18044 var children = element.childNodes;
18045 for (var i = 0; i < children.length; i++) {
18046 this.syncHierarchy(children[i]);
18047 }
18048 };
18049 DefaultSceneGraphService.prototype.sync = function (element, transform) {
18050 if (transform.localDirtyFlag) {
18051 this.calcLocalTransform(transform);
18052 transform.localDirtyFlag = false;
18053 }
18054 if (transform.dirtyFlag) {
18055 var parent_1 = element.parentNode;
18056 var parentTransform = parent_1 && parent_1.transformable;
18057 if (parent_1 === null || !parentTransform) {
18058 copy(transform.worldTransform, transform.localTransform);
18059 }
18060 else {
18061 // TODO: should we support scale compensation?
18062 // @see https://github.com/playcanvas/engine/issues/1077#issuecomment-359765557
18063 multiply(transform.worldTransform, parentTransform.worldTransform, transform.localTransform);
18064 }
18065 transform.dirtyFlag = false;
18066 }
18067 };
18068 DefaultSceneGraphService.prototype.unfreezeParentToRoot = function (child) {
18069 var p = child.parentNode;
18070 while (p) {
18071 var transform = p.transformable;
18072 if (transform) {
18073 transform.frozen = false;
18074 }
18075 p = p.parentNode;
18076 }
18077 };
18078 return DefaultSceneGraphService;
18079 }());
18080
18081 var TEXT_METRICS = {
18082 MetricsString: '|ÉqÅ',
18083 BaselineSymbol: 'M',
18084 BaselineMultiplier: 1.4,
18085 HeightMultiplier: 2,
18086 Newlines: [
18087 0x000a, // line feed
18088 0x000d, // carriage return
18089 ],
18090 BreakingSpaces: [
18091 0x0009, // character tabulation
18092 0x0020, // space
18093 0x2000, // en quad
18094 0x2001, // em quad
18095 0x2002, // en space
18096 0x2003, // em space
18097 0x2004, // three-per-em space
18098 0x2005, // four-per-em space
18099 0x2006, // six-per-em space
18100 0x2008, // punctuation space
18101 0x2009, // thin space
18102 0x200a, // hair space
18103 0x205f, // medium mathematical space
18104 0x3000, // ideographic space
18105 ],
18106 };
18107 var LATIN_REGEX = /[a-zA-Z0-9\u00C0-\u00D6\u00D8-\u00f6\u00f8-\u00ff!"#$%&'()*+,-./:;]/;
18108 // Line breaking rules in CJK (Kinsoku Shori)
18109 // Refer from https://en.wikipedia.org/wiki/Line_breaking_rules_in_East_Asian_languages
18110 var regexCannotStartZhCn = /[!%),.:;?\]}¢°·'""†‡›℃∶、。〃〆〕〗〞﹚﹜!"%'),.:;?!]}~]/;
18111 var regexCannotEndZhCn = /[$(£¥·'"〈《「『【〔〖〝﹙﹛$(.[{£¥]/;
18112 var regexCannotStartZhTw = /[!),.:;?\]}¢·–—'"•"、。〆〞〕〉》」︰︱︲︳﹐﹑﹒﹓﹔﹕﹖﹘﹚﹜!),.:;?︶︸︺︼︾﹀﹂﹗]|}、]/;
18113 var regexCannotEndZhTw = /[([{£¥'"‵〈《「『〔〝︴﹙﹛({︵︷︹︻︽︿﹁﹃﹏]/;
18114 var regexCannotStartJaJp = /[)\]}〕〉》」』】〙〗〟'"⦆»ヽヾーァィゥェォッャュョヮヵヶぁぃぅぇぉっゃゅょゎゕゖㇰㇱㇲㇳㇴㇵㇶㇷㇸㇹㇺㇻㇼㇽㇾㇿ々〻‐゠–〜?!‼⁇⁈⁉・、:;,。.]/;
18115 var regexCannotEndJaJp = /[([{〔〈《「『【〘〖〝'"⦅«—...‥〳〴〵]/;
18116 var regexCannotStartKoKr = /[!%),.:;?\]}¢°'"†‡℃〆〈《「『〕!%),.:;?]}]/;
18117 var regexCannotEndKoKr = /[$([{£¥'"々〇〉》」〔$([{⦆¥₩#]/;
18118 var regexCannotStart = new RegExp("".concat(regexCannotStartZhCn.source, "|").concat(regexCannotStartZhTw.source, "|").concat(regexCannotStartJaJp.source, "|").concat(regexCannotStartKoKr.source));
18119 var regexCannotEnd = new RegExp("".concat(regexCannotEndZhCn.source, "|").concat(regexCannotEndZhTw.source, "|").concat(regexCannotEndJaJp.source, "|").concat(regexCannotEndKoKr.source));
18120 /**
18121 * Borrow from pixi/packages/text/src/TextMetrics.ts
18122 */
18123 var TextService = /** @class */ (function () {
18124 function TextService(runtime) {
18125 var _this = this;
18126 this.runtime = runtime;
18127 /**
18128 * font metrics cache
18129 */
18130 this.fontMetricsCache = {};
18131 this.shouldBreakByKinsokuShorui = function (char, nextChar) {
18132 if (_this.isBreakingSpace(nextChar))
18133 return false;
18134 if (char) {
18135 // Line breaking rules in CJK (Kinsoku Shori)
18136 if (regexCannotEnd.exec(nextChar) || regexCannotStart.exec(char)) {
18137 return true;
18138 }
18139 }
18140 return false;
18141 };
18142 this.trimByKinsokuShorui = function (prev) {
18143 var next = __spreadArray([], __read(prev), false);
18144 var prevLine = next[next.length - 2];
18145 if (!prevLine) {
18146 return prev;
18147 }
18148 var lastChar = prevLine[prevLine.length - 1];
18149 next[next.length - 2] = prevLine.slice(0, -1);
18150 next[next.length - 1] = lastChar + next[next.length - 1];
18151 return next;
18152 };
18153 }
18154 /**
18155 * Calculates the ascent, descent and fontSize of a given font-style.
18156 */
18157 TextService.prototype.measureFont = function (font, offscreenCanvas) {
18158 // as this method is used for preparing assets, don't recalculate things if we don't need to
18159 if (this.fontMetricsCache[font]) {
18160 return this.fontMetricsCache[font];
18161 }
18162 var properties = {
18163 ascent: 0,
18164 descent: 0,
18165 fontSize: 0,
18166 };
18167 var canvas = this.runtime.offscreenCanvasCreator.getOrCreateCanvas(offscreenCanvas);
18168 var context = this.runtime.offscreenCanvasCreator.getOrCreateContext(offscreenCanvas, {
18169 willReadFrequently: true,
18170 });
18171 context.font = font;
18172 var metricsString = TEXT_METRICS.MetricsString + TEXT_METRICS.BaselineSymbol;
18173 var width = Math.ceil(context.measureText(metricsString).width);
18174 var baseline = Math.ceil(context.measureText(TEXT_METRICS.BaselineSymbol).width);
18175 var height = TEXT_METRICS.HeightMultiplier * baseline;
18176 baseline = (baseline * TEXT_METRICS.BaselineMultiplier) | 0;
18177 // @ts-ignore
18178 canvas.width = width;
18179 // @ts-ignore
18180 canvas.height = height;
18181 context.fillStyle = '#f00';
18182 context.fillRect(0, 0, width, height);
18183 context.font = font;
18184 context.textBaseline = 'alphabetic';
18185 context.fillStyle = '#000';
18186 context.fillText(metricsString, 0, baseline);
18187 var imagedata = context.getImageData(0, 0, width || 1, height || 1).data;
18188 var pixels = imagedata.length;
18189 var line = width * 4;
18190 var i = 0;
18191 var idx = 0;
18192 var stop = false;
18193 // ascent. scan from top to bottom until we find a non red pixel
18194 for (i = 0; i < baseline; ++i) {
18195 for (var j = 0; j < line; j += 4) {
18196 if (imagedata[idx + j] !== 255) {
18197 stop = true;
18198 break;
18199 }
18200 }
18201 if (!stop) {
18202 idx += line;
18203 }
18204 else {
18205 break;
18206 }
18207 }
18208 properties.ascent = baseline - i;
18209 idx = pixels - line;
18210 stop = false;
18211 // descent. scan from bottom to top until we find a non red pixel
18212 for (i = height; i > baseline; --i) {
18213 for (var j = 0; j < line; j += 4) {
18214 if (imagedata[idx + j] !== 255) {
18215 stop = true;
18216 break;
18217 }
18218 }
18219 if (!stop) {
18220 idx -= line;
18221 }
18222 else {
18223 break;
18224 }
18225 }
18226 properties.descent = i - baseline;
18227 properties.fontSize = properties.ascent + properties.descent;
18228 this.fontMetricsCache[font] = properties;
18229 return properties;
18230 };
18231 TextService.prototype.measureText = function (text, parsedStyle, offscreenCanvas) {
18232 var fontSize = parsedStyle.fontSize, wordWrap = parsedStyle.wordWrap, strokeHeight = parsedStyle.lineHeight, lineWidth = parsedStyle.lineWidth, textBaseline = parsedStyle.textBaseline, textAlign = parsedStyle.textAlign, letterSpacing = parsedStyle.letterSpacing, textPath = parsedStyle.textPath; parsedStyle.textPathSide; parsedStyle.textPathStartOffset;
18233 var // dropShadow = 0,
18234 // dropShadowDistance = 0,
18235 _a = parsedStyle.leading,
18236 // dropShadow = 0,
18237 // dropShadowDistance = 0,
18238 leading = _a === void 0 ? 0 : _a;
18239 var font = toFontString(parsedStyle);
18240 // if (runtime.enableCSSParsing) {
18241 var fontProperties = this.measureFont(font, offscreenCanvas);
18242 // fallback in case UA disallow canvas data extraction
18243 // (toDataURI, getImageData functions)
18244 if (fontProperties.fontSize === 0) {
18245 fontProperties.fontSize = fontSize;
18246 fontProperties.ascent = fontSize;
18247 }
18248 // } else {
18249 // fontProperties = {
18250 // fontSize,
18251 // };
18252 // }
18253 var context = this.runtime.offscreenCanvasCreator.getOrCreateContext(offscreenCanvas);
18254 context.font = font;
18255 // no overflowing by default
18256 parsedStyle.isOverflowing = false;
18257 var outputText = wordWrap
18258 ? this.wordWrap(text, parsedStyle, offscreenCanvas)
18259 : text;
18260 var lines = outputText.split(/(?:\r\n|\r|\n)/);
18261 var lineWidths = new Array(lines.length);
18262 var maxLineWidth = 0;
18263 // account for textPath
18264 if (textPath) {
18265 textPath.getTotalLength();
18266 // const startingPoint = textPath.getPoint(0);
18267 for (var i = 0; i < lines.length; i++) {
18268 var width = context.measureText(lines[i]).width +
18269 (lines[i].length - 1) * letterSpacing;
18270 // for (
18271 // let i = reverse ? lines[0].length - 1 : 0;
18272 // reverse ? i >= 0 : i < lines[0].length;
18273 // reverse ? i-- : i++
18274 // ) {
18275 // graphemeInfo = lineBounds[i];
18276 // if (positionInPath > totalPathLength) {
18277 // positionInPath %= totalPathLength;
18278 // } else if (positionInPath < 0) {
18279 // positionInPath += totalPathLength;
18280 // }
18281 // // it would probably much faster to send all the grapheme position for a line
18282 // // and calculate path position/angle at once.
18283 // this.setGraphemeOnPath(
18284 // positionInPath,
18285 // graphemeInfo,
18286 // startingPoint
18287 // );
18288 // positionInPath += graphemeInfo.kernedWidth;
18289 // }
18290 }
18291 }
18292 else {
18293 for (var i = 0; i < lines.length; i++) {
18294 // char width + letterSpacing
18295 var lineWidth_1 = context.measureText(lines[i]).width +
18296 (lines[i].length - 1) * letterSpacing;
18297 lineWidths[i] = lineWidth_1;
18298 maxLineWidth = Math.max(maxLineWidth, lineWidth_1);
18299 }
18300 var width = maxLineWidth + lineWidth;
18301 // if (dropShadow) {
18302 // width += dropShadowDistance;
18303 // }
18304 var lineHeight_1 = strokeHeight || fontProperties.fontSize + lineWidth;
18305 var height = Math.max(lineHeight_1, fontProperties.fontSize + lineWidth) +
18306 (lines.length - 1) * (lineHeight_1 + leading);
18307 // if (dropShadow) {
18308 // height += dropShadowDistance;
18309 // }
18310 lineHeight_1 += leading;
18311 // handle vertical text baseline
18312 var offsetY_1 = 0;
18313 if (textBaseline === 'middle') {
18314 offsetY_1 = -height / 2;
18315 }
18316 else if (textBaseline === 'bottom' ||
18317 textBaseline === 'alphabetic' ||
18318 textBaseline === 'ideographic') {
18319 offsetY_1 = -height;
18320 }
18321 else if (textBaseline === 'top' || textBaseline === 'hanging') {
18322 offsetY_1 = 0;
18323 }
18324 return {
18325 font: font,
18326 width: width,
18327 height: height,
18328 lines: lines,
18329 lineWidths: lineWidths,
18330 lineHeight: lineHeight_1,
18331 maxLineWidth: maxLineWidth,
18332 fontProperties: fontProperties,
18333 lineMetrics: lineWidths.map(function (width, i) {
18334 var offsetX = 0;
18335 // handle horizontal text align
18336 if (textAlign === 'center' || textAlign === 'middle') {
18337 offsetX -= width / 2;
18338 }
18339 else if (textAlign === 'right' || textAlign === 'end') {
18340 offsetX -= width;
18341 }
18342 return new Rectangle(offsetX - lineWidth / 2, offsetY_1 + i * lineHeight_1, width + lineWidth, lineHeight_1);
18343 }),
18344 };
18345 }
18346 };
18347 TextService.prototype.setGraphemeOnPath = function () { };
18348 TextService.prototype.wordWrap = function (text, parsedStyle, offscreenCanvas) {
18349 var _this = this;
18350 var _a = parsedStyle.wordWrapWidth, wordWrapWidth = _a === void 0 ? 0 : _a, letterSpacing = parsedStyle.letterSpacing, _b = parsedStyle.maxLines, maxLines = _b === void 0 ? Infinity : _b, textOverflow = parsedStyle.textOverflow;
18351 var context = this.runtime.offscreenCanvasCreator.getOrCreateContext(offscreenCanvas);
18352 var maxWidth = wordWrapWidth + letterSpacing;
18353 var ellipsis = '';
18354 if (textOverflow === 'ellipsis') {
18355 ellipsis = '...';
18356 }
18357 else if (textOverflow && textOverflow !== 'clip') {
18358 ellipsis = textOverflow;
18359 }
18360 var lines = [];
18361 var currentIndex = 0;
18362 var currentWidth = 0;
18363 var cache = {};
18364 var calcWidth = function (char) {
18365 return _this.getFromCache(char, letterSpacing, cache, context);
18366 };
18367 var ellipsisWidth = Array.from(ellipsis).reduce(function (prev, cur) {
18368 return prev + calcWidth(cur);
18369 }, 0);
18370 var chars = Array.from(text);
18371 for (var i = 0; i < chars.length; i++) {
18372 var char = chars[i];
18373 var prevChar = text[i - 1];
18374 var nextChar = text[i + 1];
18375 var charWidth = calcWidth(char);
18376 if (this.isNewline(char)) {
18377 currentIndex++;
18378 // exceed maxLines, break immediately
18379 if (currentIndex >= maxLines) {
18380 parsedStyle.isOverflowing = true;
18381 break;
18382 }
18383 currentWidth = 0;
18384 lines[currentIndex] = '';
18385 continue;
18386 }
18387 if (currentWidth > 0 && currentWidth + charWidth > maxWidth) {
18388 if (currentIndex + 1 >= maxLines) {
18389 parsedStyle.isOverflowing = true;
18390 // If there is not enough space to display the string itself, it is clipped.
18391 // @see https://developer.mozilla.org/en-US/docs/Web/CSS/text-overflow#values
18392 if (ellipsisWidth > 0 && ellipsisWidth <= maxWidth) {
18393 // Backspace from line's end.
18394 var currentLineLength = lines[currentIndex].length;
18395 var lastLineWidth = 0;
18396 var lastLineIndex = currentLineLength;
18397 for (var i_1 = 0; i_1 < currentLineLength; i_1++) {
18398 var width = calcWidth(lines[currentIndex][i_1]);
18399 if (lastLineWidth + width + ellipsisWidth > maxWidth) {
18400 lastLineIndex = i_1;
18401 break;
18402 }
18403 lastLineWidth += width;
18404 }
18405 lines[currentIndex] =
18406 (lines[currentIndex] || '').slice(0, lastLineIndex) + ellipsis;
18407 }
18408 break;
18409 }
18410 currentIndex++;
18411 currentWidth = 0;
18412 lines[currentIndex] = '';
18413 if (this.isBreakingSpace(char)) {
18414 continue;
18415 }
18416 if (!this.canBreakInLastChar(char)) {
18417 lines = this.trimToBreakable(lines);
18418 currentWidth = this.sumTextWidthByCache(lines[currentIndex] || '', cache);
18419 }
18420 if (this.shouldBreakByKinsokuShorui(char, nextChar)) {
18421 lines = this.trimByKinsokuShorui(lines);
18422 currentWidth += calcWidth(prevChar || '');
18423 }
18424 }
18425 currentWidth += charWidth;
18426 lines[currentIndex] = (lines[currentIndex] || '') + char;
18427 }
18428 return lines.join('\n');
18429 };
18430 TextService.prototype.isBreakingSpace = function (char) {
18431 if (typeof char !== 'string') {
18432 return false;
18433 }
18434 return TEXT_METRICS.BreakingSpaces.indexOf(char.charCodeAt(0)) >= 0;
18435 };
18436 TextService.prototype.isNewline = function (char) {
18437 if (typeof char !== 'string') {
18438 return false;
18439 }
18440 return TEXT_METRICS.Newlines.indexOf(char.charCodeAt(0)) >= 0;
18441 };
18442 TextService.prototype.trimToBreakable = function (prev) {
18443 var next = __spreadArray([], __read(prev), false);
18444 var prevLine = next[next.length - 2];
18445 var index = this.findBreakableIndex(prevLine);
18446 if (index === -1 || !prevLine)
18447 return next;
18448 var trimmedChar = prevLine.slice(index, index + 1);
18449 var isTrimmedWithSpace = this.isBreakingSpace(trimmedChar);
18450 var trimFrom = index + 1;
18451 var trimTo = index + (isTrimmedWithSpace ? 0 : 1);
18452 next[next.length - 1] += prevLine.slice(trimFrom, prevLine.length);
18453 next[next.length - 2] = prevLine.slice(0, trimTo);
18454 return next;
18455 };
18456 TextService.prototype.canBreakInLastChar = function (char) {
18457 if (char && LATIN_REGEX.test(char))
18458 return false;
18459 return true;
18460 };
18461 TextService.prototype.sumTextWidthByCache = function (text, cache) {
18462 return text.split('').reduce(function (sum, c) {
18463 if (!cache[c])
18464 throw Error('cannot count the word without cache');
18465 return sum + cache[c];
18466 }, 0);
18467 };
18468 TextService.prototype.findBreakableIndex = function (line) {
18469 for (var i = line.length - 1; i >= 0; i--) {
18470 if (!LATIN_REGEX.test(line[i]))
18471 return i;
18472 }
18473 return -1;
18474 };
18475 TextService.prototype.getFromCache = function (key, letterSpacing, cache, context) {
18476 var width = cache[key];
18477 if (typeof width !== 'number') {
18478 var spacing = key.length * letterSpacing;
18479 width = context.measureText(key).width + spacing;
18480 cache[key] = width;
18481 }
18482 return width;
18483 };
18484 return TextService;
18485 }());
18486
18487 var runtime = {};
18488 /**
18489 * Replace with IoC container
18490 */
18491 var geometryUpdaterFactory = (function () {
18492 var _a;
18493 var rectUpdater = new RectUpdater();
18494 var polylineUpdater = new PolylineUpdater();
18495 return _a = {},
18496 _a[Shape.CIRCLE] = new CircleUpdater(),
18497 _a[Shape.ELLIPSE] = new EllipseUpdater(),
18498 _a[Shape.RECT] = rectUpdater,
18499 _a[Shape.IMAGE] = rectUpdater,
18500 _a[Shape.GROUP] = rectUpdater,
18501 _a[Shape.LINE] = new LineUpdater(),
18502 _a[Shape.TEXT] = new TextUpdater(runtime),
18503 _a[Shape.POLYLINE] = polylineUpdater,
18504 _a[Shape.POLYGON] = polylineUpdater,
18505 _a[Shape.PATH] = new PathUpdater(),
18506 _a[Shape.HTML] = null,
18507 _a[Shape.MESH] = null,
18508 _a;
18509 })();
18510 var CSSPropertySyntaxFactory = (function () {
18511 var _a;
18512 var color = new CSSPropertyColor();
18513 var length = new CSSPropertyLengthOrPercentage();
18514 return _a = {},
18515 _a[PropertySyntax.PERCENTAGE] = null,
18516 _a[PropertySyntax.NUMBER] = new CSSPropertyNumber(),
18517 _a[PropertySyntax.ANGLE] = new CSSPropertyAngle(),
18518 _a[PropertySyntax.DEFINED_PATH] = new CSSPropertyClipPath(),
18519 _a[PropertySyntax.PAINT] = color,
18520 _a[PropertySyntax.COLOR] = color,
18521 _a[PropertySyntax.FILTER] = new CSSPropertyFilter(),
18522 _a[PropertySyntax.LENGTH] = length,
18523 _a[PropertySyntax.LENGTH_PERCENTAGE] = length,
18524 _a[PropertySyntax.LENGTH_PERCENTAGE_12] = new CSSPropertyLengthOrPercentage12(),
18525 _a[PropertySyntax.LENGTH_PERCENTAGE_14] = new CSSPropertyLengthOrPercentage14(),
18526 _a[PropertySyntax.COORDINATE] = new CSSPropertyLocalPosition(),
18527 _a[PropertySyntax.OFFSET_DISTANCE] = new CSSPropertyOffsetDistance(),
18528 _a[PropertySyntax.OPACITY_VALUE] = new CSSPropertyOpacity(),
18529 _a[PropertySyntax.PATH] = new CSSPropertyPath(),
18530 _a[PropertySyntax.LIST_OF_POINTS] = new CSSPropertyPoints(),
18531 _a[PropertySyntax.SHADOW_BLUR] = new CSSPropertyShadowBlur(),
18532 _a[PropertySyntax.TEXT] = new CSSPropertyText(),
18533 _a[PropertySyntax.TEXT_TRANSFORM] = new CSSPropertyTextTransform(),
18534 _a[PropertySyntax.TRANSFORM] = new CSSPropertyTransform(),
18535 _a[PropertySyntax.TRANSFORM_ORIGIN] = new CSSPropertyTransformOrigin(),
18536 _a[PropertySyntax.Z_INDEX] = new CSSPropertyZIndex(),
18537 _a[PropertySyntax.MARKER] = new CSSPropertyMarker(),
18538 _a;
18539 })();
18540 var getGlobalThis = function () {
18541 if (typeof globalThis !== 'undefined')
18542 return globalThis;
18543 if (typeof self !== 'undefined')
18544 return self;
18545 if (typeof window !== 'undefined')
18546 return window;
18547 // @ts-ignore
18548 if (typeof global !== 'undefined')
18549 return global;
18550 return {};
18551 // [!] Error: The 'this' keyword is equivalent to 'undefined' at the top level of an ES module, and has been rewritten
18552 // @see https://rollupjs.org/troubleshooting/#error-this-is-undefined
18553 // if (typeof this !== 'undefined') return this;
18554 };
18555 /**
18556 * Camera
18557 * `g-camera-api` will provide an advanced implementation
18558 */
18559 runtime.CameraContribution = Camera;
18560 /**
18561 * `g-web-animations-api` will provide an AnimationTimeline
18562 */
18563 runtime.AnimationTimeline = null;
18564 runtime.EasingFunction = null;
18565 runtime.offscreenCanvasCreator = new OffscreenCanvasCreator();
18566 runtime.sceneGraphSelector = new DefaultSceneGraphSelector();
18567 runtime.sceneGraphService = new DefaultSceneGraphService(runtime);
18568 runtime.textService = new TextService(runtime);
18569 runtime.geometryUpdaterFactory = geometryUpdaterFactory;
18570 runtime.CSSPropertySyntaxFactory = CSSPropertySyntaxFactory;
18571 runtime.styleValueRegistry = new DefaultStyleValueRegistry(runtime);
18572 runtime.layoutRegistry = null;
18573 runtime.globalThis = getGlobalThis();
18574 runtime.enableCSSParsing = true;
18575 runtime.enableDataset = false;
18576 runtime.enableStyleSyntax = true;
18577 runtime.enableSizeAttenuation = false;
18578
18579 var entityCounter = 0;
18580 var insertedEvent = new MutationEvent(ElementEvent.INSERTED, null, '', '', '', 0, '', '');
18581 var removedEvent = new MutationEvent(ElementEvent.REMOVED, null, '', '', '', 0, '', '');
18582 var destroyEvent = new CustomEvent(ElementEvent.DESTROY);
18583 /**
18584 * Has following capabilities:
18585 * * Node insert/remove, eg. appendChild, removeChild, remove...
18586 * * Query eg. querySelector getElementById...
18587 * * Animation
18588 */
18589 var Element = /** @class */ (function (_super) {
18590 __extends(Element, _super);
18591 function Element() {
18592 var _this = _super.apply(this, __spreadArray([], __read(arguments), false)) || this;
18593 /**
18594 * Unique id.
18595 */
18596 _this.entity = entityCounter++;
18597 _this.renderable = {
18598 bounds: undefined,
18599 boundsDirty: true,
18600 renderBounds: undefined,
18601 renderBoundsDirty: true,
18602 dirtyRenderBounds: undefined,
18603 dirty: false,
18604 };
18605 _this.cullable = {
18606 strategy: Strategy.Standard,
18607 visibilityPlaneMask: -1,
18608 visible: true,
18609 enable: true,
18610 };
18611 _this.transformable = {
18612 dirtyFlag: false,
18613 localDirtyFlag: false,
18614 frozen: false,
18615 localPosition: [0, 0, 0],
18616 localRotation: [0, 0, 0, 1],
18617 localScale: [1, 1, 1],
18618 localTransform: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
18619 localSkew: [0, 0],
18620 position: [0, 0, 0],
18621 rotation: [0, 0, 0, 1],
18622 scaling: [1, 1, 1],
18623 worldTransform: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
18624 origin: [0, 0, 0],
18625 };
18626 _this.sortable = {
18627 dirty: false,
18628 sorted: undefined,
18629 renderOrder: 0,
18630 dirtyChildren: [],
18631 dirtyReason: undefined,
18632 };
18633 _this.geometry = {
18634 contentBounds: undefined,
18635 renderBounds: undefined,
18636 };
18637 _this.rBushNode = {
18638 aabb: undefined,
18639 };
18640 /**
18641 * https://developer.mozilla.org/zh-CN/docs/Web/API/Element/namespaceURI
18642 */
18643 _this.namespaceURI = 'g';
18644 _this.scrollLeft = 0;
18645 _this.scrollTop = 0;
18646 /**
18647 * We don't support border now
18648 * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/clientTop
18649 */
18650 _this.clientTop = 0;
18651 _this.clientLeft = 0;
18652 /**
18653 * is destroyed or not
18654 */
18655 _this.destroyed = false;
18656 /**
18657 * compatible with `style`
18658 * @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style
18659 */
18660 _this.style = {};
18661 _this.computedStyle = runtime.enableCSSParsing
18662 ? {
18663 anchor: unsetKeywordValue,
18664 opacity: unsetKeywordValue,
18665 fillOpacity: unsetKeywordValue,
18666 strokeOpacity: unsetKeywordValue,
18667 fill: unsetKeywordValue,
18668 stroke: unsetKeywordValue,
18669 transform: unsetKeywordValue,
18670 transformOrigin: unsetKeywordValue,
18671 visibility: unsetKeywordValue,
18672 pointerEvents: unsetKeywordValue,
18673 lineWidth: unsetKeywordValue,
18674 lineCap: unsetKeywordValue,
18675 lineJoin: unsetKeywordValue,
18676 increasedLineWidthForHitTesting: unsetKeywordValue,
18677 fontSize: unsetKeywordValue,
18678 fontFamily: unsetKeywordValue,
18679 fontStyle: unsetKeywordValue,
18680 fontWeight: unsetKeywordValue,
18681 fontVariant: unsetKeywordValue,
18682 textAlign: unsetKeywordValue,
18683 textBaseline: unsetKeywordValue,
18684 textTransform: unsetKeywordValue,
18685 zIndex: unsetKeywordValue,
18686 filter: unsetKeywordValue,
18687 shadowType: unsetKeywordValue,
18688 }
18689 : null;
18690 /**
18691 * Renderers will use these used values.
18692 */
18693 _this.parsedStyle = {
18694 // opacity: '',
18695 // fillOpacity: '',
18696 // strokeOpacity: '',
18697 // transformOrigin: '',
18698 // visibility: '',
18699 // pointerEvents: '',
18700 // lineWidth: '',
18701 // lineCap: '',
18702 // lineJoin: '',
18703 // increasedLineWidthForHitTesting: '',
18704 // fontSize: '',
18705 // fontFamily: '',
18706 // fontStyle: '',
18707 // fontWeight: '',
18708 // fontVariant: '',
18709 // textAlign: '',
18710 // textBaseline: '',
18711 // textTransform: '',
18712 };
18713 /**
18714 * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/attributes
18715 */
18716 _this.attributes = {};
18717 return _this;
18718 }
18719 Object.defineProperty(Element.prototype, "className", {
18720 /**
18721 * used in `getElementsByClassName`
18722 * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName
18723 */
18724 get: function () {
18725 // @ts-ignore
18726 return this.getAttribute('class') || '';
18727 },
18728 set: function (className) {
18729 this.setAttribute('class', className);
18730 },
18731 enumerable: false,
18732 configurable: true
18733 });
18734 Object.defineProperty(Element.prototype, "classList", {
18735 /**
18736 * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/classList
18737 */
18738 get: function () {
18739 return this.className.split(' ').filter(function (c) { return c !== ''; });
18740 },
18741 enumerable: false,
18742 configurable: true
18743 });
18744 Object.defineProperty(Element.prototype, "tagName", {
18745 get: function () {
18746 return this.nodeName;
18747 },
18748 enumerable: false,
18749 configurable: true
18750 });
18751 Object.defineProperty(Element.prototype, "children", {
18752 get: function () {
18753 return this.childNodes;
18754 },
18755 enumerable: false,
18756 configurable: true
18757 });
18758 Object.defineProperty(Element.prototype, "childElementCount", {
18759 get: function () {
18760 return this.childNodes.length;
18761 },
18762 enumerable: false,
18763 configurable: true
18764 });
18765 Object.defineProperty(Element.prototype, "firstElementChild", {
18766 get: function () {
18767 return this.firstChild;
18768 },
18769 enumerable: false,
18770 configurable: true
18771 });
18772 Object.defineProperty(Element.prototype, "lastElementChild", {
18773 get: function () {
18774 return this.lastChild;
18775 },
18776 enumerable: false,
18777 configurable: true
18778 });
18779 Object.defineProperty(Element.prototype, "parentElement", {
18780 get: function () {
18781 return this.parentNode;
18782 },
18783 enumerable: false,
18784 configurable: true
18785 });
18786 Object.defineProperty(Element.prototype, "nextSibling", {
18787 get: function () {
18788 if (this.parentNode) {
18789 var index = this.parentNode.childNodes.indexOf(this);
18790 return this.parentNode.childNodes[index + 1] || null;
18791 }
18792 return null;
18793 },
18794 enumerable: false,
18795 configurable: true
18796 });
18797 Object.defineProperty(Element.prototype, "previousSibling", {
18798 get: function () {
18799 if (this.parentNode) {
18800 var index = this.parentNode.childNodes.indexOf(this);
18801 return this.parentNode.childNodes[index - 1] || null;
18802 }
18803 return null;
18804 },
18805 enumerable: false,
18806 configurable: true
18807 });
18808 Element.prototype.cloneNode = function (deep) {
18809 throw new Error(ERROR_MSG_METHOD_NOT_IMPLEMENTED);
18810 };
18811 Element.prototype.appendChild = function (child, index) {
18812 var _a;
18813 if (child.destroyed) {
18814 throw new Error(ERROR_MSG_APPEND_DESTROYED_ELEMENT);
18815 }
18816 runtime.sceneGraphService.attach(child, this, index);
18817 if ((_a = this.ownerDocument) === null || _a === void 0 ? void 0 : _a.defaultView) {
18818 this.ownerDocument.defaultView.mountChildren(child);
18819 }
18820 insertedEvent.relatedNode = this;
18821 child.dispatchEvent(insertedEvent);
18822 return child;
18823 };
18824 Element.prototype.insertBefore = function (newChild, refChild) {
18825 if (!refChild) {
18826 this.appendChild(newChild);
18827 }
18828 else {
18829 if (newChild.parentElement) {
18830 newChild.parentElement.removeChild(newChild);
18831 }
18832 var index = this.childNodes.indexOf(refChild);
18833 if (index === -1) {
18834 this.appendChild(newChild);
18835 }
18836 else {
18837 this.appendChild(newChild, index);
18838 }
18839 }
18840 return newChild;
18841 };
18842 Element.prototype.replaceChild = function (newChild, oldChild) {
18843 var index = this.childNodes.indexOf(oldChild);
18844 this.removeChild(oldChild);
18845 this.appendChild(newChild, index);
18846 return oldChild;
18847 };
18848 Element.prototype.removeChild = function (child) {
18849 var _a;
18850 // should emit on itself before detach
18851 removedEvent.relatedNode = this;
18852 child.dispatchEvent(removedEvent);
18853 if ((_a = child.ownerDocument) === null || _a === void 0 ? void 0 : _a.defaultView) {
18854 child.ownerDocument.defaultView.unmountChildren(child);
18855 }
18856 // remove from scene graph
18857 runtime.sceneGraphService.detach(child);
18858 return child;
18859 };
18860 /**
18861 * Remove all children which can be appended to its original parent later again.
18862 */
18863 Element.prototype.removeChildren = function () {
18864 for (var i = this.childNodes.length - 1; i >= 0; i--) {
18865 var child = this.childNodes[i];
18866 this.removeChild(child);
18867 }
18868 };
18869 /**
18870 * Recursively destroy all children which can not be appended to its original parent later again.
18871 */
18872 Element.prototype.destroyChildren = function () {
18873 for (var i = this.childNodes.length - 1; i >= 0; i--) {
18874 var child = this.childNodes[i];
18875 if (child.childNodes.length) {
18876 child.destroyChildren();
18877 }
18878 child.destroy();
18879 }
18880 };
18881 /**
18882 * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/matches
18883 */
18884 Element.prototype.matches = function (selector) {
18885 return runtime.sceneGraphService.matches(selector, this);
18886 };
18887 Element.prototype.getElementById = function (id) {
18888 return runtime.sceneGraphService.querySelector("#".concat(id), this);
18889 };
18890 Element.prototype.getElementsByName = function (name) {
18891 return runtime.sceneGraphService.querySelectorAll("[name=\"".concat(name, "\"]"), this);
18892 };
18893 Element.prototype.getElementsByClassName = function (className) {
18894 return runtime.sceneGraphService.querySelectorAll(".".concat(className), this);
18895 };
18896 Element.prototype.getElementsByTagName = function (tagName) {
18897 return runtime.sceneGraphService.querySelectorAll(tagName, this);
18898 };
18899 Element.prototype.querySelector = function (selectors) {
18900 return runtime.sceneGraphService.querySelector(selectors, this);
18901 };
18902 Element.prototype.querySelectorAll = function (selectors) {
18903 return runtime.sceneGraphService.querySelectorAll(selectors, this);
18904 };
18905 /**
18906 * should traverses the element and its parents (heading toward the document root)
18907 * until it finds a node that matches the specified CSS selector.
18908 * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Element/closest
18909 * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/closest#polyfill
18910 */
18911 Element.prototype.closest = function (selectors) {
18912 var el = this;
18913 do {
18914 if (runtime.sceneGraphService.matches(selectors, el))
18915 return el;
18916 el = el.parentElement;
18917 } while (el !== null);
18918 return null;
18919 };
18920 /**
18921 * search in scene group, but should not include itself
18922 */
18923 Element.prototype.find = function (filter) {
18924 var _this = this;
18925 var target = null;
18926 this.forEach(function (object) {
18927 if (object !== _this && filter(object)) {
18928 target = object;
18929 return true;
18930 }
18931 return false;
18932 });
18933 return target;
18934 };
18935 Element.prototype.findAll = function (filter) {
18936 var _this = this;
18937 var objects = [];
18938 this.forEach(function (object) {
18939 if (object !== _this && filter(object)) {
18940 objects.push(object);
18941 }
18942 });
18943 return objects;
18944 };
18945 /**
18946 * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Element/after
18947 */
18948 Element.prototype.after = function () {
18949 var _this = this;
18950 var nodes = [];
18951 for (var _i = 0; _i < arguments.length; _i++) {
18952 nodes[_i] = arguments[_i];
18953 }
18954 if (this.parentNode) {
18955 var index_1 = this.parentNode.childNodes.indexOf(this);
18956 nodes.forEach(function (node, i) { var _a; return (_a = _this.parentNode) === null || _a === void 0 ? void 0 : _a.appendChild(node, index_1 + i + 1); });
18957 }
18958 };
18959 /**
18960 * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Element/before
18961 */
18962 Element.prototype.before = function () {
18963 var _a;
18964 var nodes = [];
18965 for (var _i = 0; _i < arguments.length; _i++) {
18966 nodes[_i] = arguments[_i];
18967 }
18968 if (this.parentNode) {
18969 var index = this.parentNode.childNodes.indexOf(this);
18970 var _b = __read(nodes), first = _b[0], rest = _b.slice(1);
18971 this.parentNode.appendChild(first, index);
18972 (_a = first).after.apply(_a, __spreadArray([], __read(rest), false));
18973 }
18974 };
18975 /**
18976 * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Element/replaceWith
18977 */
18978 Element.prototype.replaceWith = function () {
18979 var nodes = [];
18980 for (var _i = 0; _i < arguments.length; _i++) {
18981 nodes[_i] = arguments[_i];
18982 }
18983 this.after.apply(this, __spreadArray([], __read(nodes), false));
18984 this.remove();
18985 };
18986 /**
18987 * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Element/append
18988 */
18989 Element.prototype.append = function () {
18990 var _this = this;
18991 var nodes = [];
18992 for (var _i = 0; _i < arguments.length; _i++) {
18993 nodes[_i] = arguments[_i];
18994 }
18995 nodes.forEach(function (node) { return _this.appendChild(node); });
18996 };
18997 /**
18998 * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Element/prepend
18999 */
19000 Element.prototype.prepend = function () {
19001 var _this = this;
19002 var nodes = [];
19003 for (var _i = 0; _i < arguments.length; _i++) {
19004 nodes[_i] = arguments[_i];
19005 }
19006 nodes.forEach(function (node, i) { return _this.appendChild(node, i); });
19007 };
19008 /**
19009 * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Element/replaceChildren
19010 */
19011 Element.prototype.replaceChildren = function () {
19012 var nodes = [];
19013 for (var _i = 0; _i < arguments.length; _i++) {
19014 nodes[_i] = arguments[_i];
19015 }
19016 while (this.childNodes.length && this.firstChild) {
19017 this.removeChild(this.firstChild);
19018 }
19019 this.append.apply(this, __spreadArray([], __read(nodes), false));
19020 };
19021 /**
19022 * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Element/remove
19023 */
19024 Element.prototype.remove = function () {
19025 if (this.parentNode) {
19026 return this.parentNode.removeChild(this);
19027 }
19028 return this;
19029 };
19030 Element.prototype.destroy = function () {
19031 // destroy itself before remove
19032 this.dispatchEvent(destroyEvent);
19033 // remove from scenegraph first
19034 this.remove();
19035 // remove event listeners
19036 this.emitter.removeAllListeners();
19037 this.destroyed = true;
19038 };
19039 Element.prototype.getGeometryBounds = function () {
19040 return runtime.sceneGraphService.getGeometryBounds(this);
19041 };
19042 Element.prototype.getRenderBounds = function () {
19043 return runtime.sceneGraphService.getBounds(this, true);
19044 };
19045 /**
19046 * get bounds in world space, account for children
19047 */
19048 Element.prototype.getBounds = function () {
19049 return runtime.sceneGraphService.getBounds(this);
19050 };
19051 /**
19052 * get bounds in local space, account for children
19053 */
19054 Element.prototype.getLocalBounds = function () {
19055 return runtime.sceneGraphService.getLocalBounds(this);
19056 };
19057 /**
19058 * account for context's bounds in client space,
19059 * but not accounting for children
19060 * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect
19061 */
19062 Element.prototype.getBoundingClientRect = function () {
19063 return runtime.sceneGraphService.getBoundingClientRect(this);
19064 };
19065 /**
19066 * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Element/getClientRects
19067 */
19068 Element.prototype.getClientRects = function () {
19069 return [this.getBoundingClientRect()];
19070 };
19071 /**
19072 * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/computedStyleMap
19073 * eg. circle.computedStyleMap().get('fill');
19074 */
19075 Element.prototype.computedStyleMap = function () {
19076 return new Map(Object.entries(this.computedStyle));
19077 };
19078 /**
19079 * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttributeNames
19080 */
19081 Element.prototype.getAttributeNames = function () {
19082 return Object.keys(this.attributes);
19083 };
19084 /**
19085 * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttribute
19086 */
19087 Element.prototype.getAttribute = function (name) {
19088 // @see https://github.com/antvis/G/issues/1267
19089 if (isSymbol(name)) {
19090 return runtime.enableCSSParsing ? null : undefined;
19091 }
19092 var value = this.attributes[name];
19093 if (value === undefined) {
19094 var attributeName = formatAttributeName(name);
19095 value = this.attributes[attributeName];
19096 // if the given attribute does not exist, the value returned will either be null or ""
19097 return runtime.enableCSSParsing ? (isNil(value) ? null : value) : value;
19098 }
19099 else {
19100 return value;
19101 }
19102 };
19103 /**
19104 * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/hasAttribute
19105 */
19106 Element.prototype.hasAttribute = function (qualifiedName) {
19107 return this.getAttributeNames().includes(qualifiedName);
19108 };
19109 /**
19110 * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/hasAttributes
19111 */
19112 Element.prototype.hasAttributes = function () {
19113 return !!this.getAttributeNames().length;
19114 };
19115 /**
19116 * should use removeAttribute() instead of setting the attribute value to null either directly or using setAttribute(). Many attributes will not behave as expected if you set them to null.
19117 * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/removeAttribute
19118 */
19119 Element.prototype.removeAttribute = function (attributeName) {
19120 this.setAttribute(attributeName, null);
19121 delete this.attributes[attributeName];
19122 };
19123 /**
19124 * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute
19125 */
19126 Element.prototype.setAttribute = function (attributeName, value, force) {
19127 this.attributes[attributeName] = value;
19128 };
19129 Element.prototype.getAttributeNS = function (namespace, localName) {
19130 throw new Error(ERROR_MSG_METHOD_NOT_IMPLEMENTED);
19131 };
19132 Element.prototype.getAttributeNode = function (qualifiedName) {
19133 throw new Error(ERROR_MSG_METHOD_NOT_IMPLEMENTED);
19134 };
19135 Element.prototype.getAttributeNodeNS = function (namespace, localName) {
19136 throw new Error(ERROR_MSG_METHOD_NOT_IMPLEMENTED);
19137 };
19138 Element.prototype.hasAttributeNS = function (namespace, localName) {
19139 throw new Error(ERROR_MSG_METHOD_NOT_IMPLEMENTED);
19140 };
19141 Element.prototype.removeAttributeNS = function (namespace, localName) {
19142 throw new Error(ERROR_MSG_METHOD_NOT_IMPLEMENTED);
19143 };
19144 Element.prototype.removeAttributeNode = function (attr) {
19145 throw new Error(ERROR_MSG_METHOD_NOT_IMPLEMENTED);
19146 };
19147 Element.prototype.setAttributeNS = function (namespace, qualifiedName, value) {
19148 throw new Error(ERROR_MSG_METHOD_NOT_IMPLEMENTED);
19149 };
19150 Element.prototype.setAttributeNode = function (attr) {
19151 throw new Error(ERROR_MSG_METHOD_NOT_IMPLEMENTED);
19152 };
19153 Element.prototype.setAttributeNodeNS = function (attr) {
19154 throw new Error(ERROR_MSG_METHOD_NOT_IMPLEMENTED);
19155 };
19156 Element.prototype.toggleAttribute = function (qualifiedName, force) {
19157 throw new Error(ERROR_MSG_METHOD_NOT_IMPLEMENTED);
19158 };
19159 return Element;
19160 }(Node));
19161
19162 function isDisplayObject(value) {
19163 return !!(value === null || value === void 0 ? void 0 : value.nodeName);
19164 }
19165 var mutationEvent = new MutationEvent(ElementEvent.ATTR_MODIFIED, null, null, null, null, MutationEvent.MODIFICATION, null, null);
19166 var DEFAULT_STYLE_PROPS = {
19167 anchor: '',
19168 opacity: '',
19169 fillOpacity: '',
19170 strokeOpacity: '',
19171 fill: '',
19172 stroke: '',
19173 transform: '',
19174 transformOrigin: '',
19175 visibility: '',
19176 pointerEvents: '',
19177 lineWidth: '',
19178 lineCap: '',
19179 lineJoin: '',
19180 increasedLineWidthForHitTesting: '',
19181 fontSize: '',
19182 fontFamily: '',
19183 fontStyle: '',
19184 fontWeight: '',
19185 fontVariant: '',
19186 textAlign: '',
19187 textBaseline: '',
19188 textTransform: '',
19189 zIndex: '',
19190 filter: '',
19191 shadowType: '',
19192 };
19193 var DEFAULT_PARSED_STYLE_PROPS = {
19194 anchor: [0, 0],
19195 fill: noneColor,
19196 stroke: noneColor,
19197 transform: [],
19198 zIndex: 0,
19199 filter: [],
19200 shadowType: 'outer',
19201 miterLimit: 10,
19202 };
19203 var DEFAULT_PARSED_STYLE_PROPS_CSS_DISABLED = __assign(__assign({}, DEFAULT_PARSED_STYLE_PROPS), { opacity: 1, fillOpacity: 1, strokeOpacity: 1, visibility: 'visible', pointerEvents: 'auto', lineWidth: 1, lineCap: 'butt', lineJoin: 'miter', increasedLineWidthForHitTesting: 0, fillRule: 'nonzero' });
19204 var INHERITABLE_BASE_STYLE_PROPS = [
19205 'opacity',
19206 'fillOpacity',
19207 'strokeOpacity',
19208 'transformOrigin',
19209 'visibility',
19210 'pointerEvents',
19211 'lineWidth',
19212 'lineCap',
19213 'lineJoin',
19214 'increasedLineWidthForHitTesting',
19215 ];
19216 var INHERITABLE_STYLE_PROPS = __spreadArray(__spreadArray([], __read(INHERITABLE_BASE_STYLE_PROPS), false), [
19217 'fontSize',
19218 'fontFamily',
19219 'fontStyle',
19220 'fontWeight',
19221 'fontVariant',
19222 'textAlign',
19223 'textBaseline',
19224 'textTransform',
19225 ], false);
19226 var DATASET_PREFIX = 'data-';
19227 /**
19228 * prototype chains: DisplayObject -> Element -> Node -> EventTarget
19229 *
19230 * mixins: Animatable, Transformable, Visible
19231 * @see https://github.com/tannerntannern/ts-mixer/blob/master/README.md#mixing-generic-classes
19232 *
19233 * Provide abilities in scene graph, such as:
19234 * * transform `translate/rotate/scale`
19235 * * add/remove child
19236 * * visibility and z-index
19237 *
19238 * Those abilities are implemented with those components: `Transform/Sortable/Visible`.
19239 *
19240 * Emit following events:
19241 * * init
19242 * * destroy
19243 * * attributeChanged
19244 */
19245 var DisplayObject = /** @class */ (function (_super) {
19246 __extends(DisplayObject, _super);
19247 function DisplayObject(config) {
19248 var _a;
19249 var _this = _super.call(this) || this;
19250 _this.isCustomElement = false;
19251 _this.isMutationObserved = false;
19252 /**
19253 * push to active animations after calling `animate()`
19254 */
19255 _this.activeAnimations = [];
19256 /**
19257 * Use `this.style.clipPath` instead.
19258 * @deprecated
19259 */
19260 _this.getClip = function () {
19261 return this.style.clipPath || null;
19262 };
19263 // assign name, id to config
19264 // eg. group.get('name')
19265 _this.config = config;
19266 // compatible with G 3.0
19267 _this.config.interactive = (_a = _this.config.capture) !== null && _a !== void 0 ? _a : _this.config.interactive;
19268 // init scene graph node
19269 _this.id = _this.config.id || '';
19270 _this.name = _this.config.name || '';
19271 if (_this.config.className || _this.config.class) {
19272 _this.className = _this.config.className || _this.config.class;
19273 }
19274 _this.nodeName = _this.config.type || Shape.GROUP;
19275 // compatible with G 3.0
19276 _this.config.style =
19277 _this.config.style || _this.config.attrs || {};
19278 Object.assign(_this.config.style, _this.config.attrs);
19279 // this.config.style = {
19280 // // ...DEFAULT_STYLE_PROPS,
19281 // ...this.config.style,
19282 // ...this.config.attrs,
19283 // };
19284 if (_this.config.visible != null) {
19285 _this.config.style.visibility =
19286 _this.config.visible === false ? 'hidden' : 'visible';
19287 }
19288 if (_this.config.interactive != null) {
19289 _this.config.style.pointerEvents =
19290 _this.config.interactive === false ? 'none' : 'auto';
19291 }
19292 // merge parsed value
19293 Object.assign(_this.parsedStyle, runtime.enableCSSParsing
19294 ? DEFAULT_PARSED_STYLE_PROPS
19295 : DEFAULT_PARSED_STYLE_PROPS_CSS_DISABLED, _this.config.initialParsedStyle);
19296 if (runtime.enableCSSParsing) {
19297 Object.assign(_this.attributes, DEFAULT_STYLE_PROPS);
19298 }
19299 // start to process attributes
19300 _this.initAttributes(_this.config.style);
19301 var Proxy = runtime.globalThis.Proxy
19302 ? runtime.globalThis.Proxy
19303 : function () { };
19304 if (runtime.enableDataset) {
19305 _this.dataset = new Proxy({}, {
19306 get: function (target, name) {
19307 var formattedName = "".concat(DATASET_PREFIX).concat(kebabize(name));
19308 if (target[formattedName] !== undefined) {
19309 return target[formattedName];
19310 }
19311 return _this.getAttribute(formattedName);
19312 },
19313 set: function (_, prop, value) {
19314 _this.setAttribute("".concat(DATASET_PREFIX).concat(kebabize(prop)), value);
19315 return true;
19316 },
19317 });
19318 }
19319 if (runtime.enableStyleSyntax) {
19320 _this.style = new Proxy(
19321 // @ts-ignore
19322 {
19323 // ...this.attributes,
19324 setProperty: function (propertyName, value) {
19325 _this.setAttribute(propertyName, value);
19326 },
19327 getPropertyValue: function (propertyName) {
19328 return _this.getAttribute(propertyName);
19329 },
19330 removeProperty: function (propertyName) {
19331 _this.removeAttribute(propertyName);
19332 },
19333 item: function () {
19334 return '';
19335 },
19336 }, {
19337 get: function (target, name) {
19338 if (target[name] !== undefined) {
19339 // if (name in target) {
19340 return target[name];
19341 }
19342 return _this.getAttribute(name);
19343 },
19344 set: function (_, prop, value) {
19345 _this.setAttribute(prop, value);
19346 return true;
19347 },
19348 });
19349 }
19350 return _this;
19351 }
19352 DisplayObject.prototype.destroy = function () {
19353 _super.prototype.destroy.call(this);
19354 // stop all active animations
19355 this.getAnimations().forEach(function (animation) {
19356 animation.cancel();
19357 });
19358 // FIXME
19359 // this.renderable = null;
19360 // this.cullable = null;
19361 // this.transformable = null;
19362 // this.rBushNode = null;
19363 // this.geometry = null;
19364 // this.sortable = null;
19365 };
19366 DisplayObject.prototype.cloneNode = function (deep, customCloneFunc) {
19367 var clonedStyle = __assign({}, this.attributes);
19368 for (var attributeName in clonedStyle) {
19369 var attribute = clonedStyle[attributeName];
19370 // @see https://github.com/antvis/G/issues/1095
19371 if (isDisplayObject(attribute) &&
19372 // share the same clipPath if possible
19373 attributeName !== 'clipPath' &&
19374 attributeName !== 'offsetPath' &&
19375 attributeName !== 'textPath') {
19376 clonedStyle[attributeName] = attribute.cloneNode(deep);
19377 }
19378 // TODO: clone other type
19379 if (customCloneFunc) {
19380 clonedStyle[attributeName] = customCloneFunc(attributeName, attribute);
19381 }
19382 }
19383 var cloned = new this.constructor({
19384 // copy id & name
19385 // @see https://developer.mozilla.org/en-US/docs/Web/API/Node/cloneNode#notes
19386 id: this.id,
19387 name: this.name,
19388 className: this.name,
19389 interactive: this.interactive,
19390 style: clonedStyle,
19391 });
19392 // apply transform
19393 cloned.setLocalTransform(this.getLocalTransform());
19394 if (deep) {
19395 this.children.forEach(function (child) {
19396 // skip marker
19397 if (!child.style.isMarker) {
19398 var clonedChild = child.cloneNode(deep);
19399 cloned.appendChild(clonedChild);
19400 }
19401 });
19402 }
19403 return cloned;
19404 };
19405 DisplayObject.prototype.initAttributes = function (attributes) {
19406 if (attributes === void 0) { attributes = {}; }
19407 var renderable = this.renderable;
19408 var options = {
19409 forceUpdateGeometry: true,
19410 // usedAttributes:
19411 // // only Group / Text should account for text relative props
19412 // this.tagName === Shape.GROUP || this.tagName === Shape.TEXT
19413 // ? INHERITABLE_STYLE_PROPS
19414 // : INHERITABLE_BASE_STYLE_PROPS,
19415 };
19416 if (runtime.enableCSSParsing) {
19417 // @ts-ignore
19418 options.usedAttributes = INHERITABLE_STYLE_PROPS;
19419 }
19420 // account for FCP, process properties as less as possible
19421 var formattedAttributes = {};
19422 for (var name_1 in attributes) {
19423 var attributeName = formatAttributeName(name_1);
19424 formattedAttributes[attributeName] = attributes[name_1];
19425 }
19426 runtime.styleValueRegistry.processProperties(this, formattedAttributes, options);
19427 // redraw at next frame
19428 renderable.dirty = true;
19429 };
19430 DisplayObject.prototype.setAttribute = function (name, value, force, memoize) {
19431 if (force === void 0) { force = false; }
19432 if (memoize === void 0) { memoize = true; }
19433 var attributeName = formatAttributeName(name);
19434 // ignore undefined value
19435 if (isUndefined(value)) {
19436 return;
19437 }
19438 if (force || value !== this.attributes[attributeName]) {
19439 this.internalSetAttribute(attributeName, value, { memoize: memoize });
19440 _super.prototype.setAttribute.call(this, attributeName, value);
19441 }
19442 };
19443 /**
19444 * called when attributes get changed or initialized
19445 */
19446 DisplayObject.prototype.internalSetAttribute = function (name, value, parseOptions) {
19447 var _a;
19448 if (parseOptions === void 0) { parseOptions = {}; }
19449 var renderable = this.renderable;
19450 var oldValue = this.attributes[name];
19451 var oldParsedValue = this.parsedStyle[name];
19452 runtime.styleValueRegistry.processProperties(this, (_a = {},
19453 _a[name] = value,
19454 _a), parseOptions);
19455 // redraw at next frame
19456 renderable.dirty = true;
19457 var newParsedValue = this.parsedStyle[name];
19458 if (this.isConnected) {
19459 mutationEvent.relatedNode = this;
19460 mutationEvent.prevValue = oldValue;
19461 mutationEvent.newValue = value;
19462 mutationEvent.attrName = name;
19463 mutationEvent.prevParsedValue = oldParsedValue;
19464 mutationEvent.newParsedValue = newParsedValue;
19465 if (this.isMutationObserved) {
19466 this.dispatchEvent(mutationEvent);
19467 }
19468 else {
19469 mutationEvent.target = this;
19470 this.ownerDocument.defaultView.dispatchEvent(mutationEvent, true);
19471 }
19472 }
19473 if (((this.isCustomElement && this.isConnected) || !this.isCustomElement) &&
19474 this.attributeChangedCallback) {
19475 this.attributeChangedCallback(name, oldValue, value, oldParsedValue, newParsedValue);
19476 }
19477 };
19478 // #region transformable
19479 /**
19480 * returns different values than getBoundingClientRect(), as the latter returns value relative to the viewport
19481 * @see https://developer.mozilla.org/en-US/docs/Web/API/SVGGraphicsElement/getBBox
19482 *
19483 * FIXME: It is worth noting that getBBox responds to original untransformed values of a drawn object.
19484 * @see https://www.w3.org/Graphics/SVG/IG/resources/svgprimer.html#getBBox
19485 */
19486 DisplayObject.prototype.getBBox = function () {
19487 var aabb = this.getBounds();
19488 var _a = __read(aabb.getMin(), 2), left = _a[0], top = _a[1];
19489 var _b = __read(aabb.getMax(), 2), right = _b[0], bottom = _b[1];
19490 return new Rectangle(left, top, right - left, bottom - top);
19491 };
19492 DisplayObject.prototype.setOrigin = function (position, y, z) {
19493 if (y === void 0) { y = 0; }
19494 if (z === void 0) { z = 0; }
19495 runtime.sceneGraphService.setOrigin(this, createVec3(position, y, z));
19496 return this;
19497 };
19498 DisplayObject.prototype.getOrigin = function () {
19499 return runtime.sceneGraphService.getOrigin(this);
19500 };
19501 /**
19502 * set position in world space
19503 */
19504 DisplayObject.prototype.setPosition = function (position, y, z) {
19505 if (y === void 0) { y = 0; }
19506 if (z === void 0) { z = 0; }
19507 runtime.sceneGraphService.setPosition(this, createVec3(position, y, z));
19508 return this;
19509 };
19510 /**
19511 * set position in local space
19512 */
19513 DisplayObject.prototype.setLocalPosition = function (position, y, z) {
19514 if (y === void 0) { y = 0; }
19515 if (z === void 0) { z = 0; }
19516 runtime.sceneGraphService.setLocalPosition(this, createVec3(position, y, z));
19517 return this;
19518 };
19519 /**
19520 * translate in world space
19521 */
19522 DisplayObject.prototype.translate = function (position, y, z) {
19523 if (y === void 0) { y = 0; }
19524 if (z === void 0) { z = 0; }
19525 runtime.sceneGraphService.translate(this, createVec3(position, y, z));
19526 return this;
19527 };
19528 /**
19529 * translate in local space
19530 */
19531 DisplayObject.prototype.translateLocal = function (position, y, z) {
19532 if (y === void 0) { y = 0; }
19533 if (z === void 0) { z = 0; }
19534 runtime.sceneGraphService.translateLocal(this, createVec3(position, y, z));
19535 return this;
19536 };
19537 DisplayObject.prototype.getPosition = function () {
19538 return runtime.sceneGraphService.getPosition(this);
19539 };
19540 DisplayObject.prototype.getLocalPosition = function () {
19541 return runtime.sceneGraphService.getLocalPosition(this);
19542 };
19543 /**
19544 * compatible with G 3.0
19545 *
19546 * scaling in local space
19547 * scale(10) = scale(10, 10, 10)
19548 *
19549 * we can't set scale in world space
19550 */
19551 DisplayObject.prototype.scale = function (scaling, y, z) {
19552 return this.scaleLocal(scaling, y, z);
19553 };
19554 DisplayObject.prototype.scaleLocal = function (scaling, y, z) {
19555 if (typeof scaling === 'number') {
19556 y = y || scaling;
19557 z = z || scaling;
19558 scaling = createVec3(scaling, y, z);
19559 }
19560 runtime.sceneGraphService.scaleLocal(this, scaling);
19561 return this;
19562 };
19563 /**
19564 * set scaling in local space
19565 */
19566 DisplayObject.prototype.setLocalScale = function (scaling, y, z) {
19567 if (typeof scaling === 'number') {
19568 y = y || scaling;
19569 z = z || scaling;
19570 scaling = createVec3(scaling, y, z);
19571 }
19572 runtime.sceneGraphService.setLocalScale(this, scaling);
19573 return this;
19574 };
19575 /**
19576 * get scaling in local space
19577 */
19578 DisplayObject.prototype.getLocalScale = function () {
19579 return runtime.sceneGraphService.getLocalScale(this);
19580 };
19581 /**
19582 * get scaling in world space
19583 */
19584 DisplayObject.prototype.getScale = function () {
19585 return runtime.sceneGraphService.getScale(this);
19586 };
19587 /**
19588 * only return degrees of Z axis in world space
19589 */
19590 DisplayObject.prototype.getEulerAngles = function () {
19591 var _a = __read(getEuler(create$2(), runtime.sceneGraphService.getWorldTransform(this)), 3), ez = _a[2];
19592 return rad2deg(ez);
19593 };
19594 /**
19595 * only return degrees of Z axis in local space
19596 */
19597 DisplayObject.prototype.getLocalEulerAngles = function () {
19598 var _a = __read(getEuler(create$2(), runtime.sceneGraphService.getLocalRotation(this)), 3), ez = _a[2];
19599 return rad2deg(ez);
19600 };
19601 /**
19602 * set euler angles(degrees) in world space
19603 */
19604 DisplayObject.prototype.setEulerAngles = function (z) {
19605 runtime.sceneGraphService.setEulerAngles(this, 0, 0, z);
19606 return this;
19607 };
19608 /**
19609 * set euler angles(degrees) in local space
19610 */
19611 DisplayObject.prototype.setLocalEulerAngles = function (z) {
19612 runtime.sceneGraphService.setLocalEulerAngles(this, 0, 0, z);
19613 return this;
19614 };
19615 DisplayObject.prototype.rotateLocal = function (x, y, z) {
19616 if (isNil(y) && isNil(z)) {
19617 runtime.sceneGraphService.rotateLocal(this, 0, 0, x);
19618 }
19619 else {
19620 runtime.sceneGraphService.rotateLocal(this, x, y, z);
19621 }
19622 return this;
19623 };
19624 DisplayObject.prototype.rotate = function (x, y, z) {
19625 if (isNil(y) && isNil(z)) {
19626 runtime.sceneGraphService.rotate(this, 0, 0, x);
19627 }
19628 else {
19629 runtime.sceneGraphService.rotate(this, x, y, z);
19630 }
19631 return this;
19632 };
19633 DisplayObject.prototype.setRotation = function (rotation, y, z, w) {
19634 runtime.sceneGraphService.setRotation(this, rotation, y, z, w);
19635 return this;
19636 };
19637 DisplayObject.prototype.setLocalRotation = function (rotation, y, z, w) {
19638 runtime.sceneGraphService.setLocalRotation(this, rotation, y, z, w);
19639 return this;
19640 };
19641 DisplayObject.prototype.setLocalSkew = function (skew, y) {
19642 runtime.sceneGraphService.setLocalSkew(this, skew, y);
19643 return this;
19644 };
19645 DisplayObject.prototype.getRotation = function () {
19646 return runtime.sceneGraphService.getRotation(this);
19647 };
19648 DisplayObject.prototype.getLocalRotation = function () {
19649 return runtime.sceneGraphService.getLocalRotation(this);
19650 };
19651 DisplayObject.prototype.getLocalSkew = function () {
19652 return runtime.sceneGraphService.getLocalSkew(this);
19653 };
19654 DisplayObject.prototype.getLocalTransform = function () {
19655 return runtime.sceneGraphService.getLocalTransform(this);
19656 };
19657 DisplayObject.prototype.getWorldTransform = function () {
19658 return runtime.sceneGraphService.getWorldTransform(this);
19659 };
19660 DisplayObject.prototype.setLocalTransform = function (transform) {
19661 runtime.sceneGraphService.setLocalTransform(this, transform);
19662 return this;
19663 };
19664 DisplayObject.prototype.resetLocalTransform = function () {
19665 runtime.sceneGraphService.resetLocalTransform(this);
19666 };
19667 // #endregion transformable
19668 // #region animatable
19669 /**
19670 * returns an array of all Animation objects affecting this element
19671 * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/getAnimations
19672 */
19673 DisplayObject.prototype.getAnimations = function () {
19674 return this.activeAnimations;
19675 };
19676 /**
19677 * create an animation with WAAPI
19678 * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Element/animate
19679 */
19680 DisplayObject.prototype.animate = function (keyframes, options) {
19681 var _a;
19682 var timeline = (_a = this.ownerDocument) === null || _a === void 0 ? void 0 : _a.timeline;
19683 if (timeline) {
19684 return timeline.play(this, keyframes, options);
19685 }
19686 return null;
19687 };
19688 // #endregion animatable
19689 // #region visible
19690 /**
19691 * shortcut for Used value of `visibility`
19692 */
19693 DisplayObject.prototype.isVisible = function () {
19694 var _a;
19695 return ((_a = this.parsedStyle) === null || _a === void 0 ? void 0 : _a.visibility) === 'visible';
19696 };
19697 Object.defineProperty(DisplayObject.prototype, "interactive", {
19698 get: function () {
19699 return this.isInteractive();
19700 },
19701 set: function (b) {
19702 this.style.pointerEvents = b ? 'auto' : 'none';
19703 },
19704 enumerable: false,
19705 configurable: true
19706 });
19707 DisplayObject.prototype.isInteractive = function () {
19708 var _a;
19709 return ((_a = this.parsedStyle) === null || _a === void 0 ? void 0 : _a.pointerEvents) !== 'none';
19710 };
19711 DisplayObject.prototype.isCulled = function () {
19712 return !!(this.cullable && this.cullable.enable && !this.cullable.visible);
19713 };
19714 /**
19715 * bring to front in current group
19716 */
19717 DisplayObject.prototype.toFront = function () {
19718 if (this.parentNode) {
19719 this.style.zIndex =
19720 Math.max.apply(Math, __spreadArray([], __read(this.parentNode.children.map(function (child) {
19721 return Number(child.style.zIndex);
19722 })), false)) + 1;
19723 }
19724 return this;
19725 };
19726 /**
19727 * send to back in current group
19728 */
19729 DisplayObject.prototype.toBack = function () {
19730 if (this.parentNode) {
19731 this.style.zIndex =
19732 Math.min.apply(Math, __spreadArray([], __read(this.parentNode.children.map(function (child) {
19733 return Number(child.style.zIndex);
19734 })), false)) - 1;
19735 }
19736 return this;
19737 };
19738 // #endregion visible
19739 // #region deprecated
19740 /**
19741 * compatible with G 3.0
19742 * @alias object.config
19743 * @deprecated
19744 */
19745 DisplayObject.prototype.getConfig = function () {
19746 return this.config;
19747 };
19748 DisplayObject.prototype.attr = function () {
19749 var _this = this;
19750 var args = [];
19751 for (var _i = 0; _i < arguments.length; _i++) {
19752 args[_i] = arguments[_i];
19753 }
19754 var _a = __read(args, 2), name = _a[0], value = _a[1];
19755 if (!name) {
19756 return this.attributes;
19757 }
19758 if (isObject(name)) {
19759 Object.keys(name).forEach(function (key) {
19760 _this.setAttribute(key, name[key]);
19761 });
19762 return this;
19763 }
19764 if (args.length === 2) {
19765 this.setAttribute(name, value);
19766 return this;
19767 }
19768 return this.attributes[name];
19769 };
19770 /**
19771 * return 3x3 matrix in world space
19772 * @deprecated
19773 */
19774 DisplayObject.prototype.getMatrix = function (transformMat4) {
19775 var transform = transformMat4 || this.getWorldTransform();
19776 var _a = __read(getTranslation(create$2(), transform), 2), tx = _a[0], ty = _a[1];
19777 var _b = __read(getScaling(create$2(), transform), 2), sx = _b[0], sy = _b[1];
19778 var rotation = getRotation(create$4(), transform);
19779 var _c = __read(getEuler(create$2(), rotation), 3), eux = _c[0], euz = _c[2];
19780 // gimbal lock at 90 degrees
19781 return fromRotationTranslationScale$1(eux || euz, tx, ty, sx, sy);
19782 };
19783 /**
19784 * return 3x3 matrix in local space
19785 * @deprecated
19786 */
19787 DisplayObject.prototype.getLocalMatrix = function () {
19788 return this.getMatrix(this.getLocalTransform());
19789 };
19790 /**
19791 * set 3x3 matrix in world space
19792 * @deprecated
19793 */
19794 DisplayObject.prototype.setMatrix = function (mat) {
19795 var _a = __read(decompose(mat), 5), tx = _a[0], ty = _a[1], scalingX = _a[2], scalingY = _a[3], angle = _a[4];
19796 this.setEulerAngles(angle)
19797 .setPosition(tx, ty)
19798 .setLocalScale(scalingX, scalingY);
19799 };
19800 /**
19801 * set 3x3 matrix in local space
19802 * @deprecated
19803 */
19804 DisplayObject.prototype.setLocalMatrix = function (mat) {
19805 var _a = __read(decompose(mat), 5), tx = _a[0], ty = _a[1], scalingX = _a[2], scalingY = _a[3], angle = _a[4];
19806 this.setLocalEulerAngles(angle)
19807 .setLocalPosition(tx, ty)
19808 .setLocalScale(scalingX, scalingY);
19809 };
19810 /**
19811 * Use `visibility: visible` instead.
19812 * @deprecated
19813 */
19814 DisplayObject.prototype.show = function () {
19815 if (runtime.enableCSSParsing) {
19816 this.style.visibility = 'visible';
19817 }
19818 else {
19819 this.forEach(function (object) {
19820 object.style.visibility = 'visible';
19821 });
19822 }
19823 };
19824 /**
19825 * Use `visibility: hidden` instead.
19826 * @deprecated
19827 */
19828 DisplayObject.prototype.hide = function () {
19829 if (runtime.enableCSSParsing) {
19830 this.style.visibility = 'hidden';
19831 }
19832 else {
19833 this.forEach(function (object) {
19834 object.style.visibility = 'hidden';
19835 });
19836 }
19837 };
19838 /**
19839 * Use `childElementCount` instead.
19840 * @deprecated
19841 */
19842 DisplayObject.prototype.getCount = function () {
19843 return this.childElementCount;
19844 };
19845 /**
19846 * Use `parentElement` instead.
19847 * @deprecated
19848 */
19849 DisplayObject.prototype.getParent = function () {
19850 return this.parentElement;
19851 };
19852 /**
19853 * Use `children` instead.
19854 * @deprecated
19855 */
19856 DisplayObject.prototype.getChildren = function () {
19857 return this.children;
19858 };
19859 /**
19860 * Use `firstElementChild` instead.
19861 * @deprecated
19862 */
19863 DisplayObject.prototype.getFirst = function () {
19864 return this.firstElementChild;
19865 };
19866 /**
19867 * Use `lastElementChild` instead.
19868 * @deprecated
19869 */
19870 DisplayObject.prototype.getLast = function () {
19871 return this.lastElementChild;
19872 };
19873 /**
19874 * Use `this.children[index]` instead.
19875 * @deprecated
19876 */
19877 DisplayObject.prototype.getChildByIndex = function (index) {
19878 return this.children[index] || null;
19879 };
19880 /**
19881 * Use `appendChild` instead.
19882 * @deprecated
19883 */
19884 DisplayObject.prototype.add = function (child, index) {
19885 return this.appendChild(child, index);
19886 };
19887 /**
19888 * Use `this.style.clipPath` instead.
19889 * @deprecated
19890 */
19891 DisplayObject.prototype.setClip = function (clipPath) {
19892 this.style.clipPath = clipPath;
19893 };
19894 /**
19895 * @deprecated
19896 */
19897 DisplayObject.prototype.set = function (name, value) {
19898 // @ts-ignore
19899 this.config[name] = value;
19900 };
19901 /**
19902 * @deprecated
19903 */
19904 DisplayObject.prototype.get = function (name) {
19905 return this.config[name];
19906 };
19907 /**
19908 * Use `setPosition` instead.
19909 * @deprecated
19910 */
19911 DisplayObject.prototype.moveTo = function (position, y, z) {
19912 if (y === void 0) { y = 0; }
19913 if (z === void 0) { z = 0; }
19914 this.setPosition(position, y, z);
19915 return this;
19916 };
19917 /**
19918 * Use `setPosition` instead.
19919 * @deprecated
19920 */
19921 DisplayObject.prototype.move = function (position, y, z) {
19922 if (y === void 0) { y = 0; }
19923 if (z === void 0) { z = 0; }
19924 this.setPosition(position, y, z);
19925 return this;
19926 };
19927 /**
19928 * Use `this.style.zIndex` instead.
19929 * @deprecated
19930 */
19931 DisplayObject.prototype.setZIndex = function (zIndex) {
19932 this.style.zIndex = zIndex;
19933 return this;
19934 };
19935 return DisplayObject;
19936 }(Element));
19937
19938 /**
19939 * holds useful CSS-related methods.
19940 * @see https://developer.mozilla.org/en-US/docs/Web/API/CSS
19941 *
19942 * * CSS Typed OM @see https://developer.mozilla.org/en-US/docs/Web/API/CSS/factory_functions
19943 * * register property @see https://developer.mozilla.org/en-US/docs/Web/API/CSS/RegisterProperty
19944 * * CSS Layout API
19945 */
19946 var CSS = {
19947 /**
19948 * <number>
19949 * @see https://drafts.csswg.org/css-values-4/#number-value
19950 */
19951 number: function (n) {
19952 return new CSSUnitValue(n);
19953 },
19954 /**
19955 * <percentage>
19956 * @see https://drafts.csswg.org/css-values-4/#percentage-value
19957 */
19958 percent: function (n) {
19959 return new CSSUnitValue(n, '%');
19960 },
19961 /**
19962 * <length>
19963 */
19964 px: function (n) {
19965 return new CSSUnitValue(n, 'px');
19966 },
19967 /**
19968 * <length>
19969 */
19970 em: function (n) {
19971 return new CSSUnitValue(n, 'em');
19972 },
19973 rem: function (n) {
19974 return new CSSUnitValue(n, 'rem');
19975 },
19976 /**
19977 * <angle>
19978 */
19979 deg: function (n) {
19980 return new CSSUnitValue(n, 'deg');
19981 },
19982 /**
19983 * <angle>
19984 */
19985 grad: function (n) {
19986 return new CSSUnitValue(n, 'grad');
19987 },
19988 /**
19989 * <angle>
19990 */
19991 rad: function (n) {
19992 return new CSSUnitValue(n, 'rad');
19993 },
19994 /**
19995 * <angle>
19996 */
19997 turn: function (n) {
19998 return new CSSUnitValue(n, 'turn');
19999 },
20000 /**
20001 * <time>
20002 */
20003 s: function (n) {
20004 return new CSSUnitValue(n, 's');
20005 },
20006 /**
20007 * <time>
20008 */
20009 ms: function (n) {
20010 return new CSSUnitValue(n, 'ms');
20011 },
20012 /**
20013 * CSS Properties & Values API
20014 *
20015 * @see https://developer.mozilla.org/en-US/docs/Web/API/CSS_Properties_and_Values_API
20016 * @see https://drafts.css-houdini.org/css-properties-values-api/#registering-custom-properties
20017 * @see https://developer.mozilla.org/en-US/docs/Web/API/CSS/RegisterProperty
20018 */
20019 registerProperty: function (definition) {
20020 var name = definition.name, inherits = definition.inherits, interpolable = definition.interpolable, initialValue = definition.initialValue, syntax = definition.syntax;
20021 runtime.styleValueRegistry.registerMetadata({
20022 n: name,
20023 inh: inherits,
20024 int: interpolable,
20025 d: initialValue,
20026 syntax: syntax,
20027 });
20028 },
20029 /**
20030 * CSS Layout API
20031 * register layout
20032 *
20033 * @see https://github.com/w3c/css-houdini-drafts/blob/main/css-layout-api/EXPLAINER.md
20034 * @see https://developer.mozilla.org/en-US/docs/Web/Guide/Houdini#css_layout_api
20035 */
20036 registerLayout: function (name, clazz) {
20037 runtime.layoutRegistry.registerLayout(name, clazz);
20038 },
20039 };
20040
20041 var Circle = /** @class */ (function (_super) {
20042 __extends(Circle, _super);
20043 function Circle(_a) {
20044 if (_a === void 0) { _a = {}; }
20045 var style = _a.style, rest = __rest(_a, ["style"]);
20046 return _super.call(this, __assign({ type: Shape.CIRCLE, style: runtime.enableCSSParsing
20047 ? __assign({ cx: '', cy: '', r: '' }, style) : __assign({}, style), initialParsedStyle: {
20048 anchor: [0.5, 0.5],
20049 transformOrigin: runtime.enableCSSParsing
20050 ? null
20051 : [PECENTAGE_50, PECENTAGE_50],
20052 } }, rest)) || this;
20053 }
20054 return Circle;
20055 }(DisplayObject));
20056
20057 /**
20058 * shadow root
20059 * @see https://yuque.antfin-inc.com/antv/czqvg5/pgqipg
20060 */
20061 var CustomElement = /** @class */ (function (_super) {
20062 __extends(CustomElement, _super);
20063 // private shadowNodes: DisplayObject[] = [];
20064 function CustomElement(_a) {
20065 if (_a === void 0) { _a = {}; }
20066 var _this = this;
20067 var style = _a.style, rest = __rest(_a, ["style"]);
20068 _this = _super.call(this, __assign({ style: runtime.enableCSSParsing
20069 ? __assign({ x: '', y: '' }, style) : __assign({}, style) }, rest)) || this;
20070 // static get observedAttributes(): string[] {
20071 // return [];
20072 // }
20073 _this.isCustomElement = true;
20074 return _this;
20075 }
20076 return CustomElement;
20077 }(DisplayObject));
20078
20079 var Ellipse = /** @class */ (function (_super) {
20080 __extends(Ellipse, _super);
20081 function Ellipse(_a) {
20082 if (_a === void 0) { _a = {}; }
20083 var style = _a.style, rest = __rest(_a, ["style"]);
20084 return _super.call(this, __assign({ type: Shape.ELLIPSE, style: runtime.enableCSSParsing
20085 ? __assign({ cx: '', cy: '', rx: '', ry: '' }, style) : __assign({}, style), initialParsedStyle: {
20086 anchor: [0.5, 0.5],
20087 transformOrigin: runtime.enableCSSParsing
20088 ? null
20089 : [PECENTAGE_50, PECENTAGE_50],
20090 } }, rest)) || this;
20091 }
20092 return Ellipse;
20093 }(DisplayObject));
20094
20095 /**
20096 * its attributes are inherited by its children.
20097 * @see https://developer.mozilla.org/zh-CN/docs/Web/SVG/Element/g
20098 *
20099 * @example
20100 * <g fill="white" stroke="green" stroke-width="5">
20101 <circle cx="40" cy="40" r="25" />
20102 <circle cx="60" cy="60" r="25" />
20103 </g>
20104 */
20105 var Group = /** @class */ (function (_super) {
20106 __extends(Group, _super);
20107 function Group(_a) {
20108 if (_a === void 0) { _a = {}; }
20109 var style = _a.style, rest = __rest(_a, ["style"]);
20110 return _super.call(this, __assign({ type: Shape.GROUP, style: runtime.enableCSSParsing
20111 ? __assign({ x: '', y: '', width: '', height: '' }, style) : __assign({}, style) }, rest)) || this;
20112 }
20113 return Group;
20114 }(DisplayObject));
20115
20116 /**
20117 * HTML container
20118 * @see https://github.com/pmndrs/drei#html
20119 */
20120 var HTML = /** @class */ (function (_super) {
20121 __extends(HTML, _super);
20122 function HTML(_a) {
20123 if (_a === void 0) { _a = {}; }
20124 var _this = this;
20125 var style = _a.style, rest = __rest(_a, ["style"]);
20126 _this = _super.call(this, __assign({ type: Shape.HTML, style: runtime.enableCSSParsing
20127 ? __assign({ x: '', y: '', width: 'auto', height: 'auto', innerHTML: '' }, style) : __assign({}, style) }, rest)) || this;
20128 _this.cullable.enable = false;
20129 return _this;
20130 }
20131 /**
20132 * return wrapper HTMLElement
20133 * * <div> in g-webgl/canvas
20134 * * <foreignObject> in g-svg
20135 */
20136 HTML.prototype.getDomElement = function () {
20137 return this.parsedStyle.$el;
20138 };
20139 /**
20140 * override with $el.getBoundingClientRect
20141 * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Element/getBoundingClientRect
20142 */
20143 HTML.prototype.getBoundingClientRect = function () {
20144 if (this.parsedStyle.$el) {
20145 return this.parsedStyle.$el.getBoundingClientRect();
20146 }
20147 else {
20148 var _a = this.parsedStyle, x = _a.x, y = _a.y, width = _a.width, height = _a.height;
20149 return new Rectangle(x, y, width, height);
20150 }
20151 };
20152 HTML.prototype.getClientRects = function () {
20153 return [this.getBoundingClientRect()];
20154 };
20155 HTML.prototype.getBounds = function () {
20156 var _a, _b;
20157 var clientRect = this.getBoundingClientRect();
20158 // calc context's offset
20159 // @ts-ignore
20160 var canvasRect = (_b = (_a = this.ownerDocument) === null || _a === void 0 ? void 0 : _a.defaultView) === null || _b === void 0 ? void 0 : _b.getContextService().getBoundingClientRect();
20161 var aabb = new AABB();
20162 var minX = clientRect.left - ((canvasRect === null || canvasRect === void 0 ? void 0 : canvasRect.left) || 0);
20163 var minY = clientRect.top - ((canvasRect === null || canvasRect === void 0 ? void 0 : canvasRect.top) || 0);
20164 aabb.setMinMax([minX, minY, 0], [minX + clientRect.width, minY + clientRect.height, 0]);
20165 return aabb;
20166 };
20167 HTML.prototype.getLocalBounds = function () {
20168 if (this.parentNode) {
20169 var parentInvert = invert(create$1(), this.parentNode.getWorldTransform());
20170 var bounds = this.getBounds();
20171 if (!AABB.isEmpty(bounds)) {
20172 var localBounds = new AABB();
20173 localBounds.setFromTransformedAABB(bounds, parentInvert);
20174 return localBounds;
20175 }
20176 }
20177 return this.getBounds();
20178 };
20179 return HTML;
20180 }(DisplayObject));
20181
20182 var Image = /** @class */ (function (_super) {
20183 __extends(Image, _super);
20184 function Image(_a) {
20185 if (_a === void 0) { _a = {}; }
20186 var style = _a.style, rest = __rest(_a, ["style"]);
20187 return _super.call(this, __assign({ type: Shape.IMAGE, style: runtime.enableCSSParsing
20188 ? __assign({ x: '', y: '', img: '', width: '', height: '' }, style) : __assign({}, style) }, rest)) || this;
20189 }
20190 return Image;
20191 }(DisplayObject));
20192
20193 /**
20194 * Create a line connecting two points.
20195 * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Element/line
20196 *
20197 * Also support for using marker.
20198 */
20199 var Line = /** @class */ (function (_super) {
20200 __extends(Line, _super);
20201 function Line(_a) {
20202 if (_a === void 0) { _a = {}; }
20203 var _this = this;
20204 var style = _a.style, rest = __rest(_a, ["style"]);
20205 _this = _super.call(this, __assign({ type: Shape.LINE, style: __assign({ x1: 0, y1: 0, x2: 0, y2: 0, z1: 0, z2: 0 }, style) }, rest)) || this;
20206 _this.markerStartAngle = 0;
20207 _this.markerEndAngle = 0;
20208 var _b = _this.parsedStyle, markerStart = _b.markerStart, markerEnd = _b.markerEnd;
20209 if (markerStart && isDisplayObject(markerStart)) {
20210 _this.markerStartAngle = markerStart.getLocalEulerAngles();
20211 _this.appendChild(markerStart);
20212 }
20213 if (markerEnd && isDisplayObject(markerEnd)) {
20214 _this.markerEndAngle = markerEnd.getLocalEulerAngles();
20215 _this.appendChild(markerEnd);
20216 }
20217 _this.transformMarker(true);
20218 _this.transformMarker(false);
20219 return _this;
20220 }
20221 Line.prototype.attributeChangedCallback = function (attrName, oldValue, newValue, prevParsedValue, newParsedValue) {
20222 if (attrName === 'x1' ||
20223 attrName === 'y1' ||
20224 attrName === 'x2' ||
20225 attrName === 'y2' ||
20226 attrName === 'markerStartOffset' ||
20227 attrName === 'markerEndOffset') {
20228 this.transformMarker(true);
20229 this.transformMarker(false);
20230 }
20231 else if (attrName === 'markerStart') {
20232 if (prevParsedValue && isDisplayObject(prevParsedValue)) {
20233 this.markerStartAngle = 0;
20234 prevParsedValue.remove();
20235 }
20236 // CSSKeyword 'unset'
20237 if (newParsedValue && isDisplayObject(newParsedValue)) {
20238 this.markerStartAngle = newParsedValue.getLocalEulerAngles();
20239 this.appendChild(newParsedValue);
20240 this.transformMarker(true);
20241 }
20242 }
20243 else if (attrName === 'markerEnd') {
20244 if (prevParsedValue && isDisplayObject(prevParsedValue)) {
20245 this.markerEndAngle = 0;
20246 prevParsedValue.remove();
20247 }
20248 if (newParsedValue && isDisplayObject(newParsedValue)) {
20249 this.markerEndAngle = newParsedValue.getLocalEulerAngles();
20250 this.appendChild(newParsedValue);
20251 this.transformMarker(false);
20252 }
20253 }
20254 };
20255 Line.prototype.transformMarker = function (isStart) {
20256 var _a = this.parsedStyle, markerStart = _a.markerStart, markerEnd = _a.markerEnd, markerStartOffset = _a.markerStartOffset, markerEndOffset = _a.markerEndOffset, x1 = _a.x1, x2 = _a.x2, y1 = _a.y1, y2 = _a.y2, defX = _a.defX, defY = _a.defY;
20257 var marker = isStart ? markerStart : markerEnd;
20258 if (!marker || !isDisplayObject(marker)) {
20259 return;
20260 }
20261 var rad = 0;
20262 var x;
20263 var y;
20264 var ox;
20265 var oy;
20266 var offset;
20267 var originalAngle;
20268 if (isStart) {
20269 ox = x1 - defX;
20270 oy = y1 - defY;
20271 x = x2 - x1;
20272 y = y2 - y1;
20273 offset = markerStartOffset || 0;
20274 originalAngle = this.markerStartAngle;
20275 }
20276 else {
20277 ox = x2 - defX;
20278 oy = y2 - defY;
20279 x = x1 - x2;
20280 y = y1 - y2;
20281 offset = markerEndOffset || 0;
20282 originalAngle = this.markerEndAngle;
20283 }
20284 rad = Math.atan2(y, x);
20285 // account for markerOffset
20286 marker.setLocalEulerAngles((rad * 180) / Math.PI + originalAngle);
20287 marker.setLocalPosition(ox + Math.cos(rad) * offset, oy + Math.sin(rad) * offset);
20288 };
20289 Line.prototype.getPoint = function (ratio, inWorldSpace) {
20290 if (inWorldSpace === void 0) { inWorldSpace = false; }
20291 // TODO: account for z1/z2 in 3D line
20292 var _a = this.parsedStyle, x1 = _a.x1, y1 = _a.y1, x2 = _a.x2, y2 = _a.y2, defX = _a.defX, defY = _a.defY;
20293 var _b = pointAt$3(x1, y1, x2, y2, ratio), x = _b.x, y = _b.y;
20294 var transformed = transformMat4(create$2(), fromValues$2(x - defX, y - defY, 0), inWorldSpace ? this.getWorldTransform() : this.getLocalTransform());
20295 // apply local transformation
20296 return new Point(transformed[0], transformed[1]);
20297 };
20298 Line.prototype.getPointAtLength = function (distance, inWorldSpace) {
20299 if (inWorldSpace === void 0) { inWorldSpace = false; }
20300 return this.getPoint(distance / this.getTotalLength(), inWorldSpace);
20301 };
20302 Line.prototype.getTotalLength = function () {
20303 // TODO: account for z1/z2 in 3D line
20304 var _a = this.parsedStyle, x1 = _a.x1, y1 = _a.y1, x2 = _a.x2, y2 = _a.y2;
20305 return length$4(x1, y1, x2, y2);
20306 };
20307 return Line;
20308 }(DisplayObject));
20309
20310 var Path = /** @class */ (function (_super) {
20311 __extends(Path, _super);
20312 function Path(_a) {
20313 if (_a === void 0) { _a = {}; }
20314 var _this = this;
20315 var style = _a.style, rest = __rest(_a, ["style"]);
20316 _this = _super.call(this, __assign({ type: Shape.PATH, style: runtime.enableCSSParsing
20317 ? __assign({ path: '', miterLimit: '' }, style) : __assign({}, style), initialParsedStyle: runtime.enableCSSParsing
20318 ? null
20319 : {
20320 miterLimit: 4,
20321 path: __assign({}, EMPTY_PARSED_PATH),
20322 } }, rest)) || this;
20323 _this.markerStartAngle = 0;
20324 _this.markerEndAngle = 0;
20325 /**
20326 * markers placed at the mid
20327 */
20328 _this.markerMidList = [];
20329 var _b = _this.parsedStyle, markerStart = _b.markerStart, markerEnd = _b.markerEnd, markerMid = _b.markerMid;
20330 if (markerStart && isDisplayObject(markerStart)) {
20331 _this.markerStartAngle = markerStart.getLocalEulerAngles();
20332 _this.appendChild(markerStart);
20333 }
20334 if (markerMid && isDisplayObject(markerMid)) {
20335 _this.placeMarkerMid(markerMid);
20336 }
20337 if (markerEnd && isDisplayObject(markerEnd)) {
20338 _this.markerEndAngle = markerEnd.getLocalEulerAngles();
20339 _this.appendChild(markerEnd);
20340 }
20341 _this.transformMarker(true);
20342 _this.transformMarker(false);
20343 return _this;
20344 }
20345 Path.prototype.attributeChangedCallback = function (attrName, oldValue, newValue, prevParsedValue, newParsedValue) {
20346 if (attrName === 'path') {
20347 // recalc markers
20348 this.transformMarker(true);
20349 this.transformMarker(false);
20350 this.placeMarkerMid(this.parsedStyle.markerMid);
20351 }
20352 else if (attrName === 'markerStartOffset' ||
20353 attrName === 'markerEndOffset') {
20354 this.transformMarker(true);
20355 this.transformMarker(false);
20356 }
20357 else if (attrName === 'markerStart') {
20358 if (prevParsedValue && isDisplayObject(prevParsedValue)) {
20359 this.markerStartAngle = 0;
20360 prevParsedValue.remove();
20361 }
20362 // CSSKeyword 'unset'
20363 if (newParsedValue && isDisplayObject(newParsedValue)) {
20364 this.markerStartAngle = newParsedValue.getLocalEulerAngles();
20365 this.appendChild(newParsedValue);
20366 this.transformMarker(true);
20367 }
20368 }
20369 else if (attrName === 'markerEnd') {
20370 if (prevParsedValue && isDisplayObject(prevParsedValue)) {
20371 this.markerEndAngle = 0;
20372 prevParsedValue.remove();
20373 }
20374 if (newParsedValue && isDisplayObject(newParsedValue)) {
20375 this.markerEndAngle = newParsedValue.getLocalEulerAngles();
20376 this.appendChild(newParsedValue);
20377 this.transformMarker(false);
20378 }
20379 }
20380 else if (attrName === 'markerMid') {
20381 this.placeMarkerMid(newParsedValue);
20382 }
20383 };
20384 Path.prototype.transformMarker = function (isStart) {
20385 var _a = this.parsedStyle, markerStart = _a.markerStart, markerEnd = _a.markerEnd, markerStartOffset = _a.markerStartOffset, markerEndOffset = _a.markerEndOffset, defX = _a.defX, defY = _a.defY;
20386 var marker = isStart ? markerStart : markerEnd;
20387 if (!marker || !isDisplayObject(marker)) {
20388 return;
20389 }
20390 var rad = 0;
20391 var x;
20392 var y;
20393 var ox;
20394 var oy;
20395 var offset;
20396 var originalAngle;
20397 if (isStart) {
20398 var _b = __read(this.getStartTangent(), 2), p1 = _b[0], p2 = _b[1];
20399 ox = p2[0] - defX;
20400 oy = p2[1] - defY;
20401 x = p1[0] - p2[0];
20402 y = p1[1] - p2[1];
20403 offset = markerStartOffset || 0;
20404 originalAngle = this.markerStartAngle;
20405 }
20406 else {
20407 var _c = __read(this.getEndTangent(), 2), p1 = _c[0], p2 = _c[1];
20408 ox = p2[0] - defX;
20409 oy = p2[1] - defY;
20410 x = p1[0] - p2[0];
20411 y = p1[1] - p2[1];
20412 offset = markerEndOffset || 0;
20413 originalAngle = this.markerEndAngle;
20414 }
20415 rad = Math.atan2(y, x);
20416 // account for markerOffset
20417 marker.setLocalEulerAngles((rad * 180) / Math.PI + originalAngle);
20418 marker.setLocalPosition(ox + Math.cos(rad) * offset, oy + Math.sin(rad) * offset);
20419 };
20420 Path.prototype.placeMarkerMid = function (marker) {
20421 var _a = this.parsedStyle, segments = _a.path.segments, defX = _a.defX, defY = _a.defY;
20422 // clear all existed markers
20423 this.markerMidList.forEach(function (marker) {
20424 marker.remove();
20425 });
20426 if (marker && isDisplayObject(marker)) {
20427 for (var i = 1; i < segments.length - 1; i++) {
20428 var _b = __read(segments[i].currentPoint, 2), ox = _b[0], oy = _b[1];
20429 var cloned = i === 1 ? marker : marker.cloneNode(true);
20430 this.markerMidList.push(cloned);
20431 this.appendChild(cloned);
20432 cloned.setLocalPosition(ox - defX, oy - defY);
20433 // TODO: orient of marker
20434 }
20435 }
20436 };
20437 /**
20438 * Returns the total length of the path.
20439 * @see https://developer.mozilla.org/en-US/docs/Web/API/SVGGeometryElement/getTotalLength
20440 */
20441 Path.prototype.getTotalLength = function () {
20442 return getOrCalculatePathTotalLength(this);
20443 };
20444 /**
20445 * Returns the point at a given distance along the path.
20446 * @see https://developer.mozilla.org/en-US/docs/Web/API/SVGGeometryElement/getPointAtLength
20447 */
20448 Path.prototype.getPointAtLength = function (distance, inWorldSpace) {
20449 if (inWorldSpace === void 0) { inWorldSpace = false; }
20450 var _a = this.parsedStyle, defX = _a.defX, defY = _a.defY, absolutePath = _a.path.absolutePath;
20451 var _b = getPointAtLength(absolutePath, distance), x = _b.x, y = _b.y;
20452 var transformed = transformMat4(create$2(), fromValues$2(x - defX, y - defY, 0), inWorldSpace ? this.getWorldTransform() : this.getLocalTransform());
20453 // apply local transformation
20454 return new Point(transformed[0], transformed[1]);
20455 };
20456 /**
20457 * Returns the point at a given ratio of the total length in path.
20458 */
20459 Path.prototype.getPoint = function (ratio, inWorldSpace) {
20460 if (inWorldSpace === void 0) { inWorldSpace = false; }
20461 return this.getPointAtLength(ratio * getOrCalculatePathTotalLength(this), inWorldSpace);
20462 };
20463 /**
20464 * Get start tangent vector
20465 */
20466 Path.prototype.getStartTangent = function () {
20467 var segments = this.parsedStyle.path.segments;
20468 var result = [];
20469 if (segments.length > 1) {
20470 var startPoint = segments[0].currentPoint;
20471 var endPoint = segments[1].currentPoint;
20472 var tangent = segments[1].startTangent;
20473 result = [];
20474 if (tangent) {
20475 result.push([startPoint[0] - tangent[0], startPoint[1] - tangent[1]]);
20476 result.push([startPoint[0], startPoint[1]]);
20477 }
20478 else {
20479 result.push([endPoint[0], endPoint[1]]);
20480 result.push([startPoint[0], startPoint[1]]);
20481 }
20482 }
20483 return result;
20484 };
20485 /**
20486 * Get end tangent vector
20487 */
20488 Path.prototype.getEndTangent = function () {
20489 var segments = this.parsedStyle.path.segments;
20490 var length = segments.length;
20491 var result = [];
20492 if (length > 1) {
20493 var startPoint = segments[length - 2].currentPoint;
20494 var endPoint = segments[length - 1].currentPoint;
20495 var tangent = segments[length - 1].endTangent;
20496 result = [];
20497 if (tangent) {
20498 result.push([endPoint[0] - tangent[0], endPoint[1] - tangent[1]]);
20499 result.push([endPoint[0], endPoint[1]]);
20500 }
20501 else {
20502 result.push([startPoint[0], startPoint[1]]);
20503 result.push([endPoint[0], endPoint[1]]);
20504 }
20505 }
20506 return result;
20507 };
20508 return Path;
20509 }(DisplayObject));
20510
20511 var Polygon = /** @class */ (function (_super) {
20512 __extends(Polygon, _super);
20513 function Polygon(_a) {
20514 if (_a === void 0) { _a = {}; }
20515 var _this = this;
20516 var style = _a.style, rest = __rest(_a, ["style"]);
20517 _this = _super.call(this, __assign({ type: Shape.POLYGON, style: runtime.enableCSSParsing
20518 ? __assign({ points: '', miterLimit: '', isClosed: true }, style) : __assign({}, style), initialParsedStyle: runtime.enableCSSParsing
20519 ? null
20520 : {
20521 points: {
20522 points: [],
20523 totalLength: 0,
20524 segments: [],
20525 },
20526 miterLimit: 4,
20527 isClosed: true,
20528 } }, rest)) || this;
20529 _this.markerStartAngle = 0;
20530 _this.markerEndAngle = 0;
20531 /**
20532 * markers placed at the mid
20533 */
20534 _this.markerMidList = [];
20535 var _b = _this.parsedStyle, markerStart = _b.markerStart, markerEnd = _b.markerEnd, markerMid = _b.markerMid;
20536 if (markerStart && isDisplayObject(markerStart)) {
20537 _this.markerStartAngle = markerStart.getLocalEulerAngles();
20538 _this.appendChild(markerStart);
20539 }
20540 if (markerMid && isDisplayObject(markerMid)) {
20541 _this.placeMarkerMid(markerMid);
20542 }
20543 if (markerEnd && isDisplayObject(markerEnd)) {
20544 _this.markerEndAngle = markerEnd.getLocalEulerAngles();
20545 _this.appendChild(markerEnd);
20546 }
20547 _this.transformMarker(true);
20548 _this.transformMarker(false);
20549 return _this;
20550 }
20551 Polygon.prototype.attributeChangedCallback = function (attrName, oldValue, newValue, prevParsedValue, newParsedValue) {
20552 if (attrName === 'points') {
20553 // recalc markers
20554 this.transformMarker(true);
20555 this.transformMarker(false);
20556 this.placeMarkerMid(this.parsedStyle.markerMid);
20557 }
20558 else if (attrName === 'markerStartOffset' ||
20559 attrName === 'markerEndOffset') {
20560 this.transformMarker(true);
20561 this.transformMarker(false);
20562 }
20563 else if (attrName === 'markerStart') {
20564 if (prevParsedValue && isDisplayObject(prevParsedValue)) {
20565 this.markerStartAngle = 0;
20566 prevParsedValue.remove();
20567 }
20568 // CSSKeyword 'unset'
20569 if (newParsedValue && isDisplayObject(newParsedValue)) {
20570 this.markerStartAngle = newParsedValue.getLocalEulerAngles();
20571 this.appendChild(newParsedValue);
20572 this.transformMarker(true);
20573 }
20574 }
20575 else if (attrName === 'markerEnd') {
20576 if (prevParsedValue && isDisplayObject(prevParsedValue)) {
20577 this.markerEndAngle = 0;
20578 prevParsedValue.remove();
20579 }
20580 if (newParsedValue && isDisplayObject(newParsedValue)) {
20581 this.markerEndAngle = newParsedValue.getLocalEulerAngles();
20582 this.appendChild(newParsedValue);
20583 this.transformMarker(false);
20584 }
20585 }
20586 else if (attrName === 'markerMid') {
20587 this.placeMarkerMid(newParsedValue);
20588 }
20589 };
20590 Polygon.prototype.transformMarker = function (isStart) {
20591 var _a = this.parsedStyle, markerStart = _a.markerStart, markerEnd = _a.markerEnd, markerStartOffset = _a.markerStartOffset, markerEndOffset = _a.markerEndOffset, P = _a.points, defX = _a.defX, defY = _a.defY;
20592 var points = (P || {}).points;
20593 var marker = isStart ? markerStart : markerEnd;
20594 if (!marker || !isDisplayObject(marker) || !points) {
20595 return;
20596 }
20597 var rad = 0;
20598 var x;
20599 var y;
20600 var ox;
20601 var oy;
20602 var offset;
20603 var originalAngle;
20604 ox = points[0][0] - defX;
20605 oy = points[0][1] - defY;
20606 if (isStart) {
20607 x = points[1][0] - points[0][0];
20608 y = points[1][1] - points[0][1];
20609 offset = markerStartOffset || 0;
20610 originalAngle = this.markerStartAngle;
20611 }
20612 else {
20613 var length_1 = points.length;
20614 if (!this.parsedStyle.isClosed) {
20615 ox = points[length_1 - 1][0] - defX;
20616 oy = points[length_1 - 1][1] - defY;
20617 x = points[length_1 - 2][0] - points[length_1 - 1][0];
20618 y = points[length_1 - 2][1] - points[length_1 - 1][1];
20619 }
20620 else {
20621 x = points[length_1 - 1][0] - points[0][0];
20622 y = points[length_1 - 1][1] - points[0][1];
20623 }
20624 offset = markerEndOffset || 0;
20625 originalAngle = this.markerEndAngle;
20626 }
20627 rad = Math.atan2(y, x);
20628 // account for markerOffset
20629 marker.setLocalEulerAngles((rad * 180) / Math.PI + originalAngle);
20630 marker.setLocalPosition(ox + Math.cos(rad) * offset, oy + Math.sin(rad) * offset);
20631 };
20632 Polygon.prototype.placeMarkerMid = function (marker) {
20633 var _a = this.parsedStyle, P = _a.points, defX = _a.defX, defY = _a.defY;
20634 var points = (P || {}).points;
20635 // clear all existed markers
20636 this.markerMidList.forEach(function (marker) {
20637 marker.remove();
20638 });
20639 this.markerMidList = [];
20640 if (marker && isDisplayObject(marker) && points) {
20641 for (var i = 1; i < (this.parsedStyle.isClosed ? points.length : points.length - 1); i++) {
20642 var ox = points[i][0] - defX;
20643 var oy = points[i][1] - defY;
20644 var cloned = i === 1 ? marker : marker.cloneNode(true);
20645 this.markerMidList.push(cloned);
20646 this.appendChild(cloned);
20647 cloned.setLocalPosition(ox, oy);
20648 // TODO: orient of marker
20649 }
20650 }
20651 };
20652 return Polygon;
20653 }(DisplayObject));
20654
20655 /**
20656 * Polyline inherits the marker-related capabilities of Polygon.
20657 */
20658 var Polyline = /** @class */ (function (_super) {
20659 __extends(Polyline, _super);
20660 function Polyline(_a) {
20661 if (_a === void 0) { _a = {}; }
20662 var style = _a.style, rest = __rest(_a, ["style"]);
20663 return _super.call(this, __assign({ type: Shape.POLYLINE, style: runtime.enableCSSParsing
20664 ? __assign({ points: '', miterLimit: '', isClosed: false }, style) : __assign({}, style), initialParsedStyle: runtime.enableCSSParsing
20665 ? null
20666 : {
20667 points: {
20668 points: [],
20669 totalLength: 0,
20670 segments: [],
20671 },
20672 miterLimit: 4,
20673 isClosed: false,
20674 } }, rest)) || this;
20675 }
20676 Polyline.prototype.getTotalLength = function () {
20677 return this.parsedStyle.points.totalLength;
20678 };
20679 Polyline.prototype.getPointAtLength = function (distance, inWorldSpace) {
20680 if (inWorldSpace === void 0) { inWorldSpace = false; }
20681 return this.getPoint(distance / this.getTotalLength(), inWorldSpace);
20682 };
20683 Polyline.prototype.getPoint = function (ratio, inWorldSpace) {
20684 if (inWorldSpace === void 0) { inWorldSpace = false; }
20685 var _a = this.parsedStyle, defX = _a.defX, defY = _a.defY, _b = _a.points, points = _b.points, segments = _b.segments;
20686 var subt = 0;
20687 var index = 0;
20688 segments.forEach(function (v, i) {
20689 if (ratio >= v[0] && ratio <= v[1]) {
20690 subt = (ratio - v[0]) / (v[1] - v[0]);
20691 index = i;
20692 }
20693 });
20694 var _c = pointAt$3(points[index][0], points[index][1], points[index + 1][0], points[index + 1][1], subt), x = _c.x, y = _c.y;
20695 var transformed = transformMat4(create$2(), fromValues$2(x - defX, y - defY, 0), inWorldSpace ? this.getWorldTransform() : this.getLocalTransform());
20696 // apply local transformation
20697 return new Point(transformed[0], transformed[1]);
20698 };
20699 Polyline.prototype.getStartTangent = function () {
20700 var points = this.parsedStyle.points.points;
20701 var result = [];
20702 result.push([points[1][0], points[1][1]]);
20703 result.push([points[0][0], points[0][1]]);
20704 return result;
20705 };
20706 Polyline.prototype.getEndTangent = function () {
20707 var points = this.parsedStyle.points.points;
20708 var l = points.length - 1;
20709 var result = [];
20710 result.push([points[l - 1][0], points[l - 1][1]]);
20711 result.push([points[l][0], points[l][1]]);
20712 return result;
20713 };
20714 return Polyline;
20715 }(Polygon));
20716
20717 var Rect = /** @class */ (function (_super) {
20718 __extends(Rect, _super);
20719 function Rect(_a) {
20720 if (_a === void 0) { _a = {}; }
20721 var style = _a.style, rest = __rest(_a, ["style"]);
20722 return _super.call(this, __assign({ type: Shape.RECT, style: runtime.enableCSSParsing
20723 ? __assign({ x: '', y: '', width: '', height: '', radius: '' }, style) : __assign({}, style) }, rest)) || this;
20724 }
20725 return Rect;
20726 }(DisplayObject));
20727
20728 /**
20729 * <text> @see https://developer.mozilla.org/en-US/docs/Web/API/SVGTextElement
20730 */
20731 var Text = /** @class */ (function (_super) {
20732 __extends(Text, _super);
20733 /**
20734 * @see https://developer.mozilla.org/en-US/docs/Web/API/SVGTextContentElement#constants
20735 */
20736 // LENGTHADJUST_SPACING: number = 1;
20737 // LENGTHADJUST_SPACINGANDGLYPHS: number = 2;
20738 // LENGTHADJUST_UNKNOWN: number = 0;
20739 function Text(_a) {
20740 if (_a === void 0) { _a = {}; }
20741 var style = _a.style, rest = __rest(_a, ["style"]);
20742 return _super.call(this, __assign({ type: Shape.TEXT, style: runtime.enableCSSParsing
20743 ? __assign({ x: '', y: '', text: '', fontSize: '', fontFamily: '', fontStyle: '', fontWeight: '', fontVariant: '', textAlign: '', textBaseline: '', textTransform: '', fill: 'black', letterSpacing: '', lineHeight: '', miterLimit: '',
20744 // whiteSpace: 'pre',
20745 wordWrap: false, wordWrapWidth: 0, leading: 0, dx: '', dy: '' }, style) : __assign({ fill: 'black' }, style), initialParsedStyle: runtime.enableCSSParsing
20746 ? {}
20747 : {
20748 x: 0,
20749 y: 0,
20750 fontSize: 16,
20751 fontFamily: 'sans-serif',
20752 fontStyle: 'normal',
20753 fontWeight: 'normal',
20754 fontVariant: 'normal',
20755 lineHeight: 0,
20756 letterSpacing: 0,
20757 textBaseline: 'alphabetic',
20758 textAlign: 'start',
20759 wordWrap: false,
20760 wordWrapWidth: 0,
20761 leading: 0,
20762 dx: 0,
20763 dy: 0,
20764 } }, rest)) || this;
20765 }
20766 // lengthAdjust: SVGAnimatedEnumeration;
20767 // textLength: SVGAnimatedLength;
20768 // getCharNumAtPosition(point?: DOMPointInit): number {
20769 // throw new Error('Method not implemented.');
20770 // }
20771 /**
20772 * @see https://developer.mozilla.org/en-US/docs/Web/API/SVGTextContentElement
20773 */
20774 Text.prototype.getComputedTextLength = function () {
20775 var _a;
20776 return ((_a = this.parsedStyle.metrics) === null || _a === void 0 ? void 0 : _a.maxLineWidth) || 0;
20777 };
20778 // getEndPositionOfChar(charnum: number): DOMPoint {
20779 // throw new Error('Method not implemented.');
20780 // }
20781 // getExtentOfChar(charnum: number): DOMRect {
20782 // throw new Error('Method not implemented.');
20783 // }
20784 // getNumberOfChars(): number {
20785 // throw new Error('Method not implemented.');
20786 // }
20787 // getRotationOfChar(charnum: number): number {
20788 // throw new Error('Method not implemented.');
20789 // }
20790 // getStartPositionOfChar(charnum: number): DOMPoint {
20791 // throw new Error('Method not implemented.');
20792 // }
20793 // getSubStringLength(charnum: number, nchars: number): number {
20794 // throw new Error('Method not implemented.');
20795 // }
20796 // selectSubString(charnum: number, nchars: number): void {
20797 // throw new Error('Method not implemented.');
20798 // }
20799 Text.prototype.getLineBoundingRects = function () {
20800 var _a;
20801 return ((_a = this.parsedStyle.metrics) === null || _a === void 0 ? void 0 : _a.lineMetrics) || [];
20802 };
20803 Text.prototype.isOverflowing = function () {
20804 return !!this.parsedStyle.isOverflowing;
20805 };
20806 return Text;
20807 }(DisplayObject));
20808
20809 /**
20810 * canvas.customElements
20811 *
20812 * @see https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry
20813 */
20814 var CustomElementRegistry = /** @class */ (function () {
20815 function CustomElementRegistry() {
20816 this.registry = {};
20817 this.define(Shape.CIRCLE, Circle);
20818 this.define(Shape.ELLIPSE, Ellipse);
20819 this.define(Shape.RECT, Rect);
20820 this.define(Shape.IMAGE, Image);
20821 this.define(Shape.LINE, Line);
20822 this.define(Shape.GROUP, Group);
20823 this.define(Shape.PATH, Path);
20824 this.define(Shape.POLYGON, Polygon);
20825 this.define(Shape.POLYLINE, Polyline);
20826 this.define(Shape.TEXT, Text);
20827 this.define(Shape.HTML, HTML);
20828 }
20829 CustomElementRegistry.prototype.define = function (name, constructor) {
20830 this.registry[name] = constructor;
20831 };
20832 /**
20833 * @see https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/get
20834 */
20835 CustomElementRegistry.prototype.get = function (name) {
20836 return this.registry[name];
20837 };
20838 return CustomElementRegistry;
20839 }());
20840
20841 /**
20842 * the entry of DOM tree
20843 * Document -> Node -> EventTarget
20844 * @see https://developer.mozilla.org/en-US/docs/Web/API/Document
20845 */
20846 var Document = /** @class */ (function (_super) {
20847 __extends(Document, _super);
20848 function Document() {
20849 var _this = _super.call(this) || this;
20850 /**
20851 * only document has defaultView, points to canvas,
20852 * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/defaultView
20853 */
20854 _this.defaultView = null;
20855 _this.ownerDocument = null;
20856 _this.nodeName = 'document';
20857 // create timeline
20858 try {
20859 _this.timeline = new runtime.AnimationTimeline(_this);
20860 }
20861 catch (e) { }
20862 /**
20863 * for inherited properties, the initial value is used on the root element only,
20864 * as long as no specified value is supplied.
20865 * @see https://developer.mozilla.org/en-US/docs/Web/CSS/initial_value
20866 */
20867 var initialStyle = {};
20868 BUILT_IN_PROPERTIES.forEach(function (_a) {
20869 var n = _a.n, inh = _a.inh, d = _a.d;
20870 if (inh && d) {
20871 initialStyle[n] = isFunction$1(d) ? d(Shape.GROUP) : d;
20872 }
20873 });
20874 // like <html> in DOM tree
20875 _this.documentElement = new Group({
20876 id: 'g-root',
20877 style: initialStyle,
20878 });
20879 _this.documentElement.ownerDocument = _this;
20880 _this.documentElement.parentNode = _this;
20881 _this.childNodes = [_this.documentElement];
20882 return _this;
20883 }
20884 Object.defineProperty(Document.prototype, "children", {
20885 get: function () {
20886 return this.childNodes;
20887 },
20888 enumerable: false,
20889 configurable: true
20890 });
20891 Object.defineProperty(Document.prototype, "childElementCount", {
20892 get: function () {
20893 return this.childNodes.length;
20894 },
20895 enumerable: false,
20896 configurable: true
20897 });
20898 Object.defineProperty(Document.prototype, "firstElementChild", {
20899 get: function () {
20900 return this.firstChild;
20901 },
20902 enumerable: false,
20903 configurable: true
20904 });
20905 Object.defineProperty(Document.prototype, "lastElementChild", {
20906 get: function () {
20907 return this.lastChild;
20908 },
20909 enumerable: false,
20910 configurable: true
20911 });
20912 /**
20913 * @example const circle = document.createElement('circle', { style: { r: 10 } });
20914 */
20915 Document.prototype.createElement = function (tagName, options) {
20916 // @observablehq/plot will create <svg>
20917 if (tagName === 'svg') {
20918 return this.documentElement;
20919 }
20920 // d3 will use <tspan>
20921 var clazz = this.defaultView.customElements.get(tagName);
20922 if (!clazz) {
20923 console.warn('Unsupported tagName: ', tagName);
20924 clazz = tagName === 'tspan' ? Text : Group;
20925 }
20926 var shape = new clazz(options);
20927 shape.ownerDocument = this;
20928 return shape;
20929 };
20930 Document.prototype.createElementNS = function (namespaceURI, tagName, options) {
20931 return this.createElement(tagName, options);
20932 };
20933 Document.prototype.cloneNode = function (deep) {
20934 throw new Error(ERROR_MSG_METHOD_NOT_IMPLEMENTED);
20935 };
20936 Document.prototype.destroy = function () {
20937 try {
20938 this.documentElement.destroyChildren();
20939 this.timeline.destroy();
20940 }
20941 catch (e) { }
20942 };
20943 /**
20944 * Picking 2D graphics with RBush based on BBox, fast but inaccurate.
20945 */
20946 Document.prototype.elementsFromBBox = function (minX, minY, maxX, maxY) {
20947 var rBush = this.defaultView.context.rBushRoot;
20948 var rBushNodes = rBush.search({ minX: minX, minY: minY, maxX: maxX, maxY: maxY });
20949 var hitTestList = [];
20950 rBushNodes.forEach(function (_a) {
20951 var displayObject = _a.displayObject;
20952 var pointerEvents = displayObject.parsedStyle.pointerEvents;
20953 // account for `visibility`
20954 // @see https://developer.mozilla.org/en-US/docs/Web/CSS/pointer-events
20955 var isVisibilityAffected = [
20956 'auto',
20957 'visiblepainted',
20958 'visiblefill',
20959 'visiblestroke',
20960 'visible',
20961 ].includes(pointerEvents);
20962 if ((!isVisibilityAffected ||
20963 (isVisibilityAffected && displayObject.isVisible())) &&
20964 !displayObject.isCulled() &&
20965 displayObject.isInteractive()) {
20966 hitTestList.push(displayObject);
20967 }
20968 });
20969 // find group with max z-index
20970 hitTestList.sort(function (a, b) { return b.sortable.renderOrder - a.sortable.renderOrder; });
20971 return hitTestList;
20972 };
20973 Document.prototype.elementFromPointSync = function (x, y) {
20974 var _a = this.defaultView.canvas2Viewport({
20975 x: x,
20976 y: y,
20977 }), viewportX = _a.x, viewportY = _a.y;
20978 var _b = this.defaultView.getConfig(), width = _b.width, height = _b.height;
20979 // outside canvas' viewport
20980 if (viewportX < 0 ||
20981 viewportY < 0 ||
20982 viewportX > width ||
20983 viewportY > height) {
20984 return null;
20985 }
20986 var _c = this.defaultView.viewport2Client({
20987 x: viewportX,
20988 y: viewportY,
20989 }), clientX = _c.x, clientY = _c.y;
20990 var picked = this.defaultView
20991 .getRenderingService()
20992 .hooks.pickSync.call({
20993 topmost: true,
20994 position: {
20995 x: x,
20996 y: y,
20997 viewportX: viewportX,
20998 viewportY: viewportY,
20999 clientX: clientX,
21000 clientY: clientY,
21001 },
21002 picked: [],
21003 }).picked;
21004 return (picked && picked[0]) || this.documentElement;
21005 };
21006 /**
21007 * Do picking with API instead of triggering interactive events.
21008 *
21009 * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Document/elementFromPoint
21010 */
21011 Document.prototype.elementFromPoint = function (x, y) {
21012 return __awaiter(this, void 0, void 0, function () {
21013 var _a, viewportX, viewportY, _b, width, height, _c, clientX, clientY, picked;
21014 return __generator(this, function (_d) {
21015 switch (_d.label) {
21016 case 0:
21017 _a = this.defaultView.canvas2Viewport({
21018 x: x,
21019 y: y,
21020 }), viewportX = _a.x, viewportY = _a.y;
21021 _b = this.defaultView.getConfig(), width = _b.width, height = _b.height;
21022 // outside canvas' viewport
21023 if (viewportX < 0 ||
21024 viewportY < 0 ||
21025 viewportX > width ||
21026 viewportY > height) {
21027 return [2 /*return*/, null];
21028 }
21029 _c = this.defaultView.viewport2Client({
21030 x: viewportX,
21031 y: viewportY,
21032 }), clientX = _c.x, clientY = _c.y;
21033 return [4 /*yield*/, this.defaultView
21034 .getRenderingService()
21035 .hooks.pick.promise({
21036 topmost: true,
21037 position: {
21038 x: x,
21039 y: y,
21040 viewportX: viewportX,
21041 viewportY: viewportY,
21042 clientX: clientX,
21043 clientY: clientY,
21044 },
21045 picked: [],
21046 })];
21047 case 1:
21048 picked = (_d.sent()).picked;
21049 return [2 /*return*/, (picked && picked[0]) || this.documentElement];
21050 }
21051 });
21052 });
21053 };
21054 Document.prototype.elementsFromPointSync = function (x, y) {
21055 var _a = this.defaultView.canvas2Viewport({
21056 x: x,
21057 y: y,
21058 }), viewportX = _a.x, viewportY = _a.y;
21059 var _b = this.defaultView.getConfig(), width = _b.width, height = _b.height;
21060 // outside canvas' viewport
21061 if (viewportX < 0 ||
21062 viewportY < 0 ||
21063 viewportX > width ||
21064 viewportY > height) {
21065 return [];
21066 }
21067 var _c = this.defaultView.viewport2Client({
21068 x: viewportX,
21069 y: viewportY,
21070 }), clientX = _c.x, clientY = _c.y;
21071 var picked = this.defaultView
21072 .getRenderingService()
21073 .hooks.pickSync.call({
21074 topmost: false,
21075 position: {
21076 x: x,
21077 y: y,
21078 viewportX: viewportX,
21079 viewportY: viewportY,
21080 clientX: clientX,
21081 clientY: clientY,
21082 },
21083 picked: [],
21084 }).picked;
21085 if (picked[picked.length - 1] !== this.documentElement) {
21086 picked.push(this.documentElement);
21087 }
21088 return picked;
21089 };
21090 /**
21091 * Do picking with API instead of triggering interactive events.
21092 *
21093 * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Document/elementsFromPoint
21094 */
21095 Document.prototype.elementsFromPoint = function (x, y) {
21096 return __awaiter(this, void 0, void 0, function () {
21097 var _a, viewportX, viewportY, _b, width, height, _c, clientX, clientY, picked;
21098 return __generator(this, function (_d) {
21099 switch (_d.label) {
21100 case 0:
21101 _a = this.defaultView.canvas2Viewport({
21102 x: x,
21103 y: y,
21104 }), viewportX = _a.x, viewportY = _a.y;
21105 _b = this.defaultView.getConfig(), width = _b.width, height = _b.height;
21106 // outside canvas' viewport
21107 if (viewportX < 0 ||
21108 viewportY < 0 ||
21109 viewportX > width ||
21110 viewportY > height) {
21111 return [2 /*return*/, []];
21112 }
21113 _c = this.defaultView.viewport2Client({
21114 x: viewportX,
21115 y: viewportY,
21116 }), clientX = _c.x, clientY = _c.y;
21117 return [4 /*yield*/, this.defaultView
21118 .getRenderingService()
21119 .hooks.pick.promise({
21120 topmost: false,
21121 position: {
21122 x: x,
21123 y: y,
21124 viewportX: viewportX,
21125 viewportY: viewportY,
21126 clientX: clientX,
21127 clientY: clientY,
21128 },
21129 picked: [],
21130 })];
21131 case 1:
21132 picked = (_d.sent()).picked;
21133 if (picked[picked.length - 1] !== this.documentElement) {
21134 picked.push(this.documentElement);
21135 }
21136 return [2 /*return*/, picked];
21137 }
21138 });
21139 });
21140 };
21141 /**
21142 * eg. Uncaught DOMException: Failed to execute 'appendChild' on 'Node': Only one element on document allowed.
21143 */
21144 Document.prototype.appendChild = function (newChild, index) {
21145 throw new Error(ERROR_MSG_USE_DOCUMENT_ELEMENT);
21146 };
21147 Document.prototype.insertBefore = function (newChild, refChild) {
21148 throw new Error(ERROR_MSG_USE_DOCUMENT_ELEMENT);
21149 };
21150 Document.prototype.removeChild = function (oldChild, destroy) {
21151 throw new Error(ERROR_MSG_USE_DOCUMENT_ELEMENT);
21152 };
21153 Document.prototype.replaceChild = function (newChild, oldChild, destroy) {
21154 throw new Error(ERROR_MSG_USE_DOCUMENT_ELEMENT);
21155 };
21156 Document.prototype.append = function () {
21157 throw new Error(ERROR_MSG_USE_DOCUMENT_ELEMENT);
21158 };
21159 Document.prototype.prepend = function () {
21160 throw new Error(ERROR_MSG_USE_DOCUMENT_ELEMENT);
21161 };
21162 /**
21163 * Execute query on documentElement.
21164 */
21165 Document.prototype.getElementById = function (id) {
21166 return this.documentElement.getElementById(id);
21167 };
21168 Document.prototype.getElementsByName = function (name) {
21169 return this.documentElement.getElementsByName(name);
21170 };
21171 Document.prototype.getElementsByTagName = function (tagName) {
21172 return this.documentElement.getElementsByTagName(tagName);
21173 };
21174 Document.prototype.getElementsByClassName = function (className) {
21175 return this.documentElement.getElementsByClassName(className);
21176 };
21177 Document.prototype.querySelector = function (selectors) {
21178 return this.documentElement.querySelector(selectors);
21179 };
21180 Document.prototype.querySelectorAll = function (selectors) {
21181 return this.documentElement.querySelectorAll(selectors);
21182 };
21183 Document.prototype.find = function (filter) {
21184 return this.documentElement.find(filter);
21185 };
21186 Document.prototype.findAll = function (filter) {
21187 return this.documentElement.findAll(filter);
21188 };
21189 return Document;
21190 }(Node));
21191
21192 /**
21193 * apply following rules:
21194 * 1. `visibility` in scenegraph node
21195 * 2. other custom culling strategies, eg. frustum culling
21196 */
21197 var CullingPlugin = /** @class */ (function () {
21198 function CullingPlugin(strategies) {
21199 this.strategies = strategies;
21200 }
21201 CullingPlugin.prototype.apply = function (context) {
21202 var camera = context.camera, renderingService = context.renderingService, renderingContext = context.renderingContext;
21203 var strategies = this.strategies;
21204 renderingService.hooks.cull.tap(CullingPlugin.tag, function (object) {
21205 if (object) {
21206 var cullable = object.cullable;
21207 // cullable.visible = true;
21208 // const renderBounds = object.getRenderBounds();
21209 // if (AABB.isEmpty(renderBounds)) {
21210 // cullable.visible = false;
21211 // } else {
21212 // const isShape2D = shape2D.indexOf(object.nodeName as Shape) > -1;
21213 // const [p0, p1, p2, p3] = camera.getFrustum().planes;
21214 // tmpAABB.setMinMax([-p1.distance, -p3.distance, 0], [p0.distance, p2.distance, 0]);
21215 // cullable.visible = isShape2D ? renderBounds.intersects(tmpAABB) : true;
21216 // }
21217 if (strategies.length === 0) {
21218 cullable.visible = renderingContext.unculledEntities.indexOf(object.entity) > -1;
21219 }
21220 else {
21221 // eg. implemented by g-webgl(frustum culling)
21222 cullable.visible = strategies.every(function (strategy) { return strategy.isVisible(camera, object); });
21223 }
21224 if (!object.isCulled() && object.isVisible()) {
21225 return object;
21226 }
21227 else {
21228 // if (this.renderingContext.renderListLastFrame.indexOf(object) > -1) {
21229 object.dispatchEvent(new CustomEvent(ElementEvent.CULLED));
21230 // }
21231 }
21232 return null;
21233 }
21234 return object;
21235 });
21236 renderingService.hooks.afterRender.tap(CullingPlugin.tag, function (object) {
21237 object.cullable.visibilityPlaneMask = -1;
21238 });
21239 };
21240 CullingPlugin.tag = 'Culling';
21241 return CullingPlugin;
21242 }());
21243
21244 /**
21245 * support mouse & touch events
21246 * @see https://github.com/pixijs/pixi.js/blob/dev/packages/interaction/README.md
21247 *
21248 * also provide some extra events such as `drag`
21249 */
21250 var EventPlugin = /** @class */ (function () {
21251 function EventPlugin() {
21252 var _this = this;
21253 this.autoPreventDefault = false;
21254 this.rootPointerEvent = new FederatedPointerEvent(null);
21255 this.rootWheelEvent = new FederatedWheelEvent(null);
21256 this.onPointerMove = function (nativeEvent) {
21257 var e_1, _a;
21258 var _b, _c;
21259 var canvas = (_c = (_b = _this.context.renderingContext.root) === null || _b === void 0 ? void 0 : _b.ownerDocument) === null || _c === void 0 ? void 0 : _c.defaultView;
21260 if (canvas.supportsTouchEvents &&
21261 nativeEvent.pointerType === 'touch')
21262 return;
21263 var normalizedEvents = _this.normalizeToPointerEvent(nativeEvent, canvas);
21264 try {
21265 for (var normalizedEvents_1 = __values(normalizedEvents), normalizedEvents_1_1 = normalizedEvents_1.next(); !normalizedEvents_1_1.done; normalizedEvents_1_1 = normalizedEvents_1.next()) {
21266 var normalizedEvent = normalizedEvents_1_1.value;
21267 var event_1 = _this.bootstrapEvent(_this.rootPointerEvent, normalizedEvent, canvas, nativeEvent);
21268 _this.context.eventService.mapEvent(event_1);
21269 }
21270 }
21271 catch (e_1_1) { e_1 = { error: e_1_1 }; }
21272 finally {
21273 try {
21274 if (normalizedEvents_1_1 && !normalizedEvents_1_1.done && (_a = normalizedEvents_1.return)) _a.call(normalizedEvents_1);
21275 }
21276 finally { if (e_1) throw e_1.error; }
21277 }
21278 _this.setCursor(_this.context.eventService.cursor);
21279 };
21280 this.onClick = function (nativeEvent) {
21281 var e_2, _a;
21282 var _b, _c;
21283 var canvas = (_c = (_b = _this.context.renderingContext.root) === null || _b === void 0 ? void 0 : _b.ownerDocument) === null || _c === void 0 ? void 0 : _c.defaultView;
21284 var normalizedEvents = _this.normalizeToPointerEvent(nativeEvent, canvas);
21285 try {
21286 for (var normalizedEvents_2 = __values(normalizedEvents), normalizedEvents_2_1 = normalizedEvents_2.next(); !normalizedEvents_2_1.done; normalizedEvents_2_1 = normalizedEvents_2.next()) {
21287 var normalizedEvent = normalizedEvents_2_1.value;
21288 var event_2 = _this.bootstrapEvent(_this.rootPointerEvent, normalizedEvent, canvas, nativeEvent);
21289 _this.context.eventService.mapEvent(event_2);
21290 }
21291 }
21292 catch (e_2_1) { e_2 = { error: e_2_1 }; }
21293 finally {
21294 try {
21295 if (normalizedEvents_2_1 && !normalizedEvents_2_1.done && (_a = normalizedEvents_2.return)) _a.call(normalizedEvents_2);
21296 }
21297 finally { if (e_2) throw e_2.error; }
21298 }
21299 _this.setCursor(_this.context.eventService.cursor);
21300 };
21301 }
21302 EventPlugin.prototype.apply = function (context) {
21303 var _this = this;
21304 this.context = context;
21305 var renderingService = context.renderingService;
21306 var canvas = this.context.renderingContext.root.ownerDocument.defaultView;
21307 this.context.eventService.setPickHandler(function (position) {
21308 var picked = _this.context.renderingService.hooks.pickSync.call({
21309 position: position,
21310 picked: [],
21311 topmost: true, // we only concern the topmost element
21312 }).picked;
21313 return picked[0] || null;
21314 });
21315 renderingService.hooks.pointerWheel.tap(EventPlugin.tag, function (nativeEvent) {
21316 var wheelEvent = _this.normalizeWheelEvent(nativeEvent);
21317 _this.context.eventService.mapEvent(wheelEvent);
21318 });
21319 renderingService.hooks.pointerDown.tap(EventPlugin.tag, function (nativeEvent) {
21320 var e_3, _a;
21321 if (canvas.supportsTouchEvents &&
21322 nativeEvent.pointerType === 'touch')
21323 return;
21324 var events = _this.normalizeToPointerEvent(nativeEvent, canvas);
21325 if (_this.autoPreventDefault && events[0].isNormalized) {
21326 var cancelable = nativeEvent.cancelable || !('cancelable' in nativeEvent);
21327 if (cancelable) {
21328 nativeEvent.preventDefault();
21329 }
21330 }
21331 try {
21332 for (var events_1 = __values(events), events_1_1 = events_1.next(); !events_1_1.done; events_1_1 = events_1.next()) {
21333 var event_3 = events_1_1.value;
21334 var federatedEvent = _this.bootstrapEvent(_this.rootPointerEvent, event_3, canvas, nativeEvent);
21335 _this.context.eventService.mapEvent(federatedEvent);
21336 }
21337 }
21338 catch (e_3_1) { e_3 = { error: e_3_1 }; }
21339 finally {
21340 try {
21341 if (events_1_1 && !events_1_1.done && (_a = events_1.return)) _a.call(events_1);
21342 }
21343 finally { if (e_3) throw e_3.error; }
21344 }
21345 _this.setCursor(_this.context.eventService.cursor);
21346 });
21347 renderingService.hooks.pointerUp.tap(EventPlugin.tag, function (nativeEvent) {
21348 var e_4, _a;
21349 if (canvas.supportsTouchEvents &&
21350 nativeEvent.pointerType === 'touch')
21351 return;
21352 // account for element in SVG
21353 var $element = _this.context.contextService.getDomElement();
21354 var isNativeEventFromCanvas = _this.context.eventService.isNativeEventFromCanvas($element, nativeEvent);
21355 var outside = !isNativeEventFromCanvas ? 'outside' : '';
21356 var normalizedEvents = _this.normalizeToPointerEvent(nativeEvent, canvas);
21357 try {
21358 for (var normalizedEvents_3 = __values(normalizedEvents), normalizedEvents_3_1 = normalizedEvents_3.next(); !normalizedEvents_3_1.done; normalizedEvents_3_1 = normalizedEvents_3.next()) {
21359 var normalizedEvent = normalizedEvents_3_1.value;
21360 var event_4 = _this.bootstrapEvent(_this.rootPointerEvent, normalizedEvent, canvas, nativeEvent);
21361 event_4.type += outside;
21362 _this.context.eventService.mapEvent(event_4);
21363 }
21364 }
21365 catch (e_4_1) { e_4 = { error: e_4_1 }; }
21366 finally {
21367 try {
21368 if (normalizedEvents_3_1 && !normalizedEvents_3_1.done && (_a = normalizedEvents_3.return)) _a.call(normalizedEvents_3);
21369 }
21370 finally { if (e_4) throw e_4.error; }
21371 }
21372 _this.setCursor(_this.context.eventService.cursor);
21373 });
21374 renderingService.hooks.pointerMove.tap(EventPlugin.tag, this.onPointerMove);
21375 renderingService.hooks.pointerOver.tap(EventPlugin.tag, this.onPointerMove);
21376 renderingService.hooks.pointerOut.tap(EventPlugin.tag, this.onPointerMove);
21377 renderingService.hooks.click.tap(EventPlugin.tag, this.onClick);
21378 renderingService.hooks.pointerCancel.tap(EventPlugin.tag, function (nativeEvent) {
21379 var e_5, _a;
21380 var normalizedEvents = _this.normalizeToPointerEvent(nativeEvent, canvas);
21381 try {
21382 for (var normalizedEvents_4 = __values(normalizedEvents), normalizedEvents_4_1 = normalizedEvents_4.next(); !normalizedEvents_4_1.done; normalizedEvents_4_1 = normalizedEvents_4.next()) {
21383 var normalizedEvent = normalizedEvents_4_1.value;
21384 var event_5 = _this.bootstrapEvent(_this.rootPointerEvent, normalizedEvent, canvas, nativeEvent);
21385 _this.context.eventService.mapEvent(event_5);
21386 }
21387 }
21388 catch (e_5_1) { e_5 = { error: e_5_1 }; }
21389 finally {
21390 try {
21391 if (normalizedEvents_4_1 && !normalizedEvents_4_1.done && (_a = normalizedEvents_4.return)) _a.call(normalizedEvents_4);
21392 }
21393 finally { if (e_5) throw e_5.error; }
21394 }
21395 _this.setCursor(_this.context.eventService.cursor);
21396 });
21397 };
21398 EventPlugin.prototype.getViewportXY = function (nativeEvent) {
21399 var x;
21400 var y;
21401 /**
21402 * Should account for CSS Transform applied on container.
21403 * @see https://github.com/antvis/G/issues/1161
21404 * @see https://developer.mozilla.org/zh-CN/docs/Web/API/MouseEvent/offsetX
21405 */
21406 var offsetX = nativeEvent.offsetX, offsetY = nativeEvent.offsetY, clientX = nativeEvent.clientX, clientY = nativeEvent.clientY;
21407 if (this.context.config.supportsCSSTransform &&
21408 !isNil(offsetX) &&
21409 !isNil(offsetY)) {
21410 x = offsetX;
21411 y = offsetY;
21412 }
21413 else {
21414 var point = this.context.eventService.client2Viewport(new Point(clientX, clientY));
21415 x = point.x;
21416 y = point.y;
21417 }
21418 return { x: x, y: y };
21419 };
21420 EventPlugin.prototype.bootstrapEvent = function (event, normalizedEvent, view, nativeEvent) {
21421 event.view = view;
21422 event.originalEvent = null;
21423 event.nativeEvent = nativeEvent;
21424 event.pointerId = normalizedEvent.pointerId;
21425 event.width = normalizedEvent.width;
21426 event.height = normalizedEvent.height;
21427 event.isPrimary = normalizedEvent.isPrimary;
21428 event.pointerType = normalizedEvent.pointerType;
21429 event.pressure = normalizedEvent.pressure;
21430 event.tangentialPressure = normalizedEvent.tangentialPressure;
21431 event.tiltX = normalizedEvent.tiltX;
21432 event.tiltY = normalizedEvent.tiltY;
21433 event.twist = normalizedEvent.twist;
21434 this.transferMouseData(event, normalizedEvent);
21435 var _a = this.getViewportXY(normalizedEvent), x = _a.x, y = _a.y;
21436 event.viewport.x = x;
21437 event.viewport.y = y;
21438 var _b = this.context.eventService.viewport2Canvas(event.viewport), canvasX = _b.x, canvasY = _b.y;
21439 event.canvas.x = canvasX;
21440 event.canvas.y = canvasY;
21441 event.global.copyFrom(event.canvas);
21442 event.offset.copyFrom(event.canvas);
21443 event.isTrusted = nativeEvent.isTrusted;
21444 if (event.type === 'pointerleave') {
21445 event.type = 'pointerout';
21446 }
21447 if (event.type.startsWith('mouse')) {
21448 event.type = event.type.replace('mouse', 'pointer');
21449 }
21450 if (event.type.startsWith('touch')) {
21451 event.type = TOUCH_TO_POINTER[event.type] || event.type;
21452 }
21453 return event;
21454 };
21455 EventPlugin.prototype.normalizeWheelEvent = function (nativeEvent) {
21456 var event = this.rootWheelEvent;
21457 this.transferMouseData(event, nativeEvent);
21458 event.deltaMode = nativeEvent.deltaMode;
21459 event.deltaX = nativeEvent.deltaX;
21460 event.deltaY = nativeEvent.deltaY;
21461 event.deltaZ = nativeEvent.deltaZ;
21462 var _a = this.getViewportXY(nativeEvent), x = _a.x, y = _a.y;
21463 event.viewport.x = x;
21464 event.viewport.y = y;
21465 var _b = this.context.eventService.viewport2Canvas(event.viewport), canvasX = _b.x, canvasY = _b.y;
21466 event.canvas.x = canvasX;
21467 event.canvas.y = canvasY;
21468 event.global.copyFrom(event.canvas);
21469 event.offset.copyFrom(event.canvas);
21470 event.nativeEvent = nativeEvent;
21471 event.type = nativeEvent.type;
21472 return event;
21473 };
21474 /**
21475 * Transfers base & mouse event data from the nativeEvent to the federated event.
21476 */
21477 EventPlugin.prototype.transferMouseData = function (event, nativeEvent) {
21478 event.isTrusted = nativeEvent.isTrusted;
21479 event.srcElement = nativeEvent.srcElement;
21480 event.timeStamp = clock.now();
21481 event.type = nativeEvent.type;
21482 event.altKey = nativeEvent.altKey;
21483 event.metaKey = nativeEvent.metaKey;
21484 event.shiftKey = nativeEvent.shiftKey;
21485 event.ctrlKey = nativeEvent.ctrlKey;
21486 event.button = nativeEvent.button;
21487 event.buttons = nativeEvent.buttons;
21488 event.client.x = nativeEvent.clientX;
21489 event.client.y = nativeEvent.clientY;
21490 event.movement.x = nativeEvent.movementX;
21491 event.movement.y = nativeEvent.movementY;
21492 event.page.x = nativeEvent.pageX;
21493 event.page.y = nativeEvent.pageY;
21494 event.screen.x = nativeEvent.screenX;
21495 event.screen.y = nativeEvent.screenY;
21496 event.relatedTarget = null;
21497 };
21498 EventPlugin.prototype.setCursor = function (cursor) {
21499 this.context.contextService.applyCursorStyle(cursor || this.context.config.cursor || 'default');
21500 };
21501 EventPlugin.prototype.normalizeToPointerEvent = function (event, canvas) {
21502 var normalizedEvents = [];
21503 if (canvas.isTouchEvent(event)) {
21504 for (var i = 0; i < event.changedTouches.length; i++) {
21505 var touch = event.changedTouches[i];
21506 // use changedTouches instead of touches since touchend has no touches
21507 // @see https://stackoverflow.com/a/10079076
21508 if (isUndefined(touch.button))
21509 touch.button = 0;
21510 if (isUndefined(touch.buttons))
21511 touch.buttons = 1;
21512 if (isUndefined(touch.isPrimary)) {
21513 touch.isPrimary =
21514 event.touches.length === 1 && event.type === 'touchstart';
21515 }
21516 if (isUndefined(touch.width))
21517 touch.width = touch.radiusX || 1;
21518 if (isUndefined(touch.height))
21519 touch.height = touch.radiusY || 1;
21520 if (isUndefined(touch.tiltX))
21521 touch.tiltX = 0;
21522 if (isUndefined(touch.tiltY))
21523 touch.tiltY = 0;
21524 if (isUndefined(touch.pointerType))
21525 touch.pointerType = 'touch';
21526 // @see https://developer.mozilla.org/zh-CN/docs/Web/API/Touch/identifier
21527 if (isUndefined(touch.pointerId))
21528 touch.pointerId = touch.identifier || 0;
21529 if (isUndefined(touch.pressure))
21530 touch.pressure = touch.force || 0.5;
21531 if (isUndefined(touch.twist))
21532 touch.twist = 0;
21533 if (isUndefined(touch.tangentialPressure))
21534 touch.tangentialPressure = 0;
21535 touch.isNormalized = true;
21536 touch.type = event.type;
21537 normalizedEvents.push(touch);
21538 }
21539 }
21540 else if (canvas.isMouseEvent(event)) {
21541 var tempEvent = event;
21542 if (isUndefined(tempEvent.isPrimary))
21543 tempEvent.isPrimary = true;
21544 if (isUndefined(tempEvent.width))
21545 tempEvent.width = 1;
21546 if (isUndefined(tempEvent.height))
21547 tempEvent.height = 1;
21548 if (isUndefined(tempEvent.tiltX))
21549 tempEvent.tiltX = 0;
21550 if (isUndefined(tempEvent.tiltY))
21551 tempEvent.tiltY = 0;
21552 if (isUndefined(tempEvent.pointerType))
21553 tempEvent.pointerType = 'mouse';
21554 if (isUndefined(tempEvent.pointerId))
21555 tempEvent.pointerId = MOUSE_POINTER_ID;
21556 if (isUndefined(tempEvent.pressure))
21557 tempEvent.pressure = 0.5;
21558 if (isUndefined(tempEvent.twist))
21559 tempEvent.twist = 0;
21560 if (isUndefined(tempEvent.tangentialPressure))
21561 tempEvent.tangentialPressure = 0;
21562 tempEvent.isNormalized = true;
21563 normalizedEvents.push(tempEvent);
21564 }
21565 else {
21566 normalizedEvents.push(event);
21567 }
21568 return normalizedEvents;
21569 };
21570 EventPlugin.tag = 'Event';
21571 return EventPlugin;
21572 }());
21573
21574 // group is not a 2d shape
21575 var shape2D = [
21576 Shape.CIRCLE,
21577 Shape.ELLIPSE,
21578 Shape.IMAGE,
21579 Shape.RECT,
21580 Shape.LINE,
21581 Shape.POLYLINE,
21582 Shape.POLYGON,
21583 Shape.TEXT,
21584 Shape.PATH,
21585 Shape.HTML,
21586 ];
21587 var FrustumCullingStrategy = /** @class */ (function () {
21588 function FrustumCullingStrategy() {
21589 }
21590 FrustumCullingStrategy.prototype.isVisible = function (camera, object) {
21591 // return true;
21592 var _a, _b;
21593 var cullable = object.cullable;
21594 if (!cullable.enable) {
21595 return true;
21596 }
21597 var renderBounds = object.getRenderBounds();
21598 if (AABB.isEmpty(renderBounds)) {
21599 return false;
21600 }
21601 // get VP matrix from camera
21602 var frustum = camera.getFrustum();
21603 var parentVisibilityPlaneMask = (_b = (_a = object.parentNode) === null || _a === void 0 ? void 0 : _a.cullable) === null || _b === void 0 ? void 0 : _b.visibilityPlaneMask;
21604 cullable.visibilityPlaneMask = this.computeVisibilityWithPlaneMask(object, renderBounds, parentVisibilityPlaneMask || Mask.INDETERMINATE, frustum.planes);
21605 cullable.visible = cullable.visibilityPlaneMask !== Mask.OUTSIDE;
21606 return cullable.visible;
21607 };
21608 /**
21609 *
21610 * @see「Optimized View Frustum Culling Algorithms for Bounding Boxes」
21611 * @see https://github.com/antvis/GWebGPUEngine/issues/3
21612 *
21613 * * 基础相交测试 the basic intersection test
21614 * * 标记 masking @see https://cesium.com/blog/2015/08/04/fast-hierarchical-culling/
21615 * * TODO: 平面一致性测试 the plane-coherency test
21616 * * TODO: 支持 mesh 指定自身的剔除策略,参考 Babylon.js @see https://doc.babylonjs.com/how_to/optimizing_your_scene#changing-mesh-culling-strategy
21617 *
21618 * @param aabb aabb
21619 * @param parentPlaneMask mask of parent
21620 * @param planes planes of frustum
21621 */
21622 FrustumCullingStrategy.prototype.computeVisibilityWithPlaneMask = function (object, aabb, parentPlaneMask, planes) {
21623 if (parentPlaneMask === Mask.OUTSIDE || parentPlaneMask === Mask.INSIDE) {
21624 // 父节点完全位于视锥内或者外部,直接返回
21625 return parentPlaneMask;
21626 }
21627 // Start with MASK_INSIDE (all zeros) so that after the loop, the return value can be compared with MASK_INSIDE.
21628 // (Because if there are fewer than 31 planes, the upper bits wont be changed.)
21629 var mask = Mask.INSIDE;
21630 var isShape2D = shape2D.indexOf(object.nodeName) > -1;
21631 // Use viewport culling for 2D shapes
21632 // @see https://github.com/antvis/g/issues/914
21633 for (var k = 0, len = planes.length; k < len; ++k) {
21634 // For k greater than 31 (since 31 is the maximum number of INSIDE/INTERSECTING bits we can store), skip the optimization.
21635 var flag = 1 << k;
21636 if ((parentPlaneMask & flag) === 0) {
21637 // 父节点处于当前面内部,可以跳过
21638 continue;
21639 }
21640 // skip near & far planes when testing 2D shapes
21641 if (isShape2D && (k === 4 || k === 5)) {
21642 continue;
21643 }
21644 // p-vertex n-vertex <-|plane p-vertex n-vertex
21645 // 使用 p-vertex 和 n-vertex 加速,避免进行平面和 aabb 全部顶点的相交检测
21646 var _a = planes[k], normal = _a.normal, distance = _a.distance;
21647 if (dot(normal, aabb.getPositiveFarPoint(planes[k])) + distance <
21648 0) {
21649 return Mask.OUTSIDE;
21650 }
21651 if (dot(normal, aabb.getNegativeFarPoint(planes[k])) + distance <
21652 0) {
21653 // 和当前面相交,对应位置为1,继续检测下一个面
21654 mask |= flag;
21655 }
21656 }
21657 return mask;
21658 };
21659 return FrustumCullingStrategy;
21660 }());
21661
21662 var PrepareRendererPlugin = /** @class */ (function () {
21663 function PrepareRendererPlugin() {
21664 /**
21665 * sync to RBush later
21666 */
21667 this.toSync = new Set();
21668 }
21669 // private isFirstTimeRendering = true;
21670 // private syncing = false;
21671 PrepareRendererPlugin.prototype.apply = function (context) {
21672 var _this = this;
21673 var renderingService = context.renderingService, renderingContext = context.renderingContext, rBushRoot = context.rBushRoot;
21674 var canvas = renderingContext.root.ownerDocument.defaultView;
21675 this.rBush = rBushRoot;
21676 var handleAttributeChanged = function (e) {
21677 var object = e.target;
21678 object.renderable.dirty = true;
21679 renderingService.dirtify();
21680 };
21681 var handleBoundsChanged = function (e) {
21682 var affectChildren = e.detail.affectChildren;
21683 var object = e.target;
21684 if (affectChildren) {
21685 object.forEach(function (node) {
21686 _this.toSync.add(node);
21687 });
21688 }
21689 var p = object;
21690 while (p) {
21691 if (p.renderable) {
21692 _this.toSync.add(p);
21693 }
21694 p = p.parentElement;
21695 }
21696 // this.pushToSync(e.composedPath().slice(0, -2) as DisplayObject[]);
21697 renderingService.dirtify();
21698 };
21699 var handleMounted = function (e) {
21700 var object = e.target;
21701 if (runtime.enableSizeAttenuation) {
21702 runtime.styleValueRegistry.updateSizeAttenuation(object, canvas.getCamera().getZoom());
21703 }
21704 if (runtime.enableCSSParsing) {
21705 // recalc style values
21706 runtime.styleValueRegistry.recalc(object);
21707 }
21708 runtime.sceneGraphService.dirtifyToRoot(object);
21709 renderingService.dirtify();
21710 };
21711 var handleUnmounted = function (e) {
21712 var object = e.target;
21713 var rBushNode = object.rBushNode;
21714 if (rBushNode.aabb) {
21715 _this.rBush.remove(rBushNode.aabb);
21716 }
21717 _this.toSync.delete(object);
21718 runtime.sceneGraphService.dirtifyToRoot(object);
21719 renderingService.dirtify();
21720 };
21721 renderingService.hooks.init.tap(PrepareRendererPlugin.tag, function () {
21722 canvas.addEventListener(ElementEvent.MOUNTED, handleMounted);
21723 canvas.addEventListener(ElementEvent.UNMOUNTED, handleUnmounted);
21724 canvas.addEventListener(ElementEvent.ATTR_MODIFIED, handleAttributeChanged);
21725 canvas.addEventListener(ElementEvent.BOUNDS_CHANGED, handleBoundsChanged);
21726 });
21727 renderingService.hooks.destroy.tap(PrepareRendererPlugin.tag, function () {
21728 canvas.removeEventListener(ElementEvent.MOUNTED, handleMounted);
21729 canvas.removeEventListener(ElementEvent.UNMOUNTED, handleUnmounted);
21730 canvas.removeEventListener(ElementEvent.ATTR_MODIFIED, handleAttributeChanged);
21731 canvas.removeEventListener(ElementEvent.BOUNDS_CHANGED, handleBoundsChanged);
21732 _this.toSync.clear();
21733 });
21734 renderingService.hooks.endFrame.tap(PrepareRendererPlugin.tag, function () {
21735 // if (this.isFirstTimeRendering) {
21736 // this.isFirstTimeRendering = false;
21737 // this.syncing = true;
21738 // // @see https://github.com/antvis/G/issues/1117
21739 // setTimeout(() => {
21740 // this.syncRTree();
21741 // console.log('fcp...');
21742 // });
21743 // } else {
21744 // console.log('next...');
21745 _this.syncRTree();
21746 // }
21747 });
21748 };
21749 PrepareRendererPlugin.prototype.syncRTree = function () {
21750 // if (this.syncing) {
21751 // return;
21752 // }
21753 var _this = this;
21754 // bounds changed, need re-inserting its children
21755 var bulk = [];
21756 Array.from(this.toSync)
21757 // some objects may be removed since last frame
21758 .filter(function (object) { return object.isConnected; })
21759 .forEach(function (node) {
21760 var rBushNode = node.rBushNode;
21761 // clear dirty node
21762 if (rBushNode && rBushNode.aabb) {
21763 _this.rBush.remove(rBushNode.aabb);
21764 }
21765 var renderBounds = node.getRenderBounds();
21766 if (renderBounds) {
21767 var _a = __read(renderBounds.getMin(), 2), minX = _a[0], minY = _a[1];
21768 var _b = __read(renderBounds.getMax(), 2), maxX = _b[0], maxY = _b[1];
21769 if (!rBushNode.aabb) {
21770 rBushNode.aabb = {};
21771 }
21772 rBushNode.aabb.displayObject = node;
21773 rBushNode.aabb.minX = minX;
21774 rBushNode.aabb.minY = minY;
21775 rBushNode.aabb.maxX = maxX;
21776 rBushNode.aabb.maxY = maxY;
21777 }
21778 if (rBushNode.aabb) {
21779 // TODO: NaN occurs when width/height of Rect is 0
21780 if (!isNaN(rBushNode.aabb.maxX) &&
21781 !isNaN(rBushNode.aabb.maxX) &&
21782 !isNaN(rBushNode.aabb.minX) &&
21783 !isNaN(rBushNode.aabb.minY)) {
21784 bulk.push(rBushNode.aabb);
21785 }
21786 }
21787 });
21788 // use bulk inserting, which is ~2-3 times faster
21789 // @see https://github.com/mourner/rbush#bulk-inserting-data
21790 this.rBush.load(bulk);
21791 bulk.length = 0;
21792 this.toSync.clear();
21793 // this.syncing = false;
21794 };
21795 PrepareRendererPlugin.tag = 'Prepare';
21796 return PrepareRendererPlugin;
21797 }());
21798
21799 function isCanvas(value) {
21800 return !!value.document;
21801 }
21802 var CanvasEvent;
21803 (function (CanvasEvent) {
21804 CanvasEvent["READY"] = "ready";
21805 CanvasEvent["BEFORE_RENDER"] = "beforerender";
21806 CanvasEvent["RERENDER"] = "rerender";
21807 CanvasEvent["AFTER_RENDER"] = "afterrender";
21808 CanvasEvent["BEFORE_DESTROY"] = "beforedestroy";
21809 CanvasEvent["AFTER_DESTROY"] = "afterdestroy";
21810 CanvasEvent["RESIZE"] = "resize";
21811 CanvasEvent["DIRTY_RECTANGLE"] = "dirtyrectangle";
21812 CanvasEvent["RENDERER_CHANGED"] = "rendererchanged";
21813 })(CanvasEvent || (CanvasEvent = {}));
21814 var DEFAULT_CAMERA_Z = 500;
21815 var DEFAULT_CAMERA_NEAR = 0.1;
21816 var DEFAULT_CAMERA_FAR = 1000;
21817 /**
21818 * reuse custom event preventing from re-create them in every frame
21819 */
21820 var mountedEvent = new CustomEvent(ElementEvent.MOUNTED);
21821 var unmountedEvent = new CustomEvent(ElementEvent.UNMOUNTED);
21822 var beforeRenderEvent = new CustomEvent(CanvasEvent.BEFORE_RENDER);
21823 var rerenderEvent = new CustomEvent(CanvasEvent.RERENDER);
21824 var afterRenderEvent = new CustomEvent(CanvasEvent.AFTER_RENDER);
21825 /**
21826 * can be treated like Window in DOM
21827 * provide some extra methods like `window`, such as:
21828 * * `window.requestAnimationFrame`
21829 * * `window.devicePixelRatio`
21830 *
21831 * prototype chains: Canvas(Window) -> EventTarget
21832 */
21833 var Canvas = /** @class */ (function (_super) {
21834 __extends(Canvas, _super);
21835 function Canvas(config) {
21836 var _this = _super.call(this) || this;
21837 /**
21838 * @see https://developer.mozilla.org/en-US/docs/Web/API/Element
21839 */
21840 _this.Element = DisplayObject;
21841 _this.inited = false;
21842 _this.context = {};
21843 // create document
21844 _this.document = new Document();
21845 _this.document.defaultView = _this;
21846 // create registry of custom elements
21847 _this.customElements = new CustomElementRegistry();
21848 var container = config.container, canvas = config.canvas, offscreenCanvas = config.offscreenCanvas, width = config.width, height = config.height, devicePixelRatio = config.devicePixelRatio, renderer = config.renderer, background = config.background, cursor = config.cursor, document = config.document, requestAnimationFrame = config.requestAnimationFrame, cancelAnimationFrame = config.cancelAnimationFrame, createImage = config.createImage, supportsPointerEvents = config.supportsPointerEvents, supportsTouchEvents = config.supportsTouchEvents, supportsCSSTransform = config.supportsCSSTransform, supportsMutipleCanvasesInOneContainer = config.supportsMutipleCanvasesInOneContainer, useNativeClickEvent = config.useNativeClickEvent, alwaysTriggerPointerEventOnCanvas = config.alwaysTriggerPointerEventOnCanvas, isTouchEvent = config.isTouchEvent, isMouseEvent = config.isMouseEvent;
21849 if (!supportsMutipleCanvasesInOneContainer) {
21850 cleanExistedCanvas(container, _this);
21851 }
21852 var canvasWidth = width;
21853 var canvasHeight = height;
21854 var dpr = devicePixelRatio;
21855 // use user-defined <canvas> or OffscreenCanvas
21856 if (canvas) {
21857 // infer width & height with dpr
21858 dpr = devicePixelRatio || (isBrowser && window.devicePixelRatio) || 1;
21859 dpr = dpr >= 1 ? Math.ceil(dpr) : 1;
21860 canvasWidth = width || getWidth(canvas) || canvas.width / dpr;
21861 canvasHeight = height || getHeight(canvas) || canvas.height / dpr;
21862 }
21863 // override it in runtime
21864 if (offscreenCanvas) {
21865 runtime.offscreenCanvas = offscreenCanvas;
21866 }
21867 /**
21868 * implements `Window` interface
21869 */
21870 _this.devicePixelRatio = dpr;
21871 _this.requestAnimationFrame =
21872 requestAnimationFrame !== null && requestAnimationFrame !== void 0 ? requestAnimationFrame : raf.bind(runtime.globalThis);
21873 _this.cancelAnimationFrame =
21874 cancelAnimationFrame !== null && cancelAnimationFrame !== void 0 ? cancelAnimationFrame : caf.bind(runtime.globalThis);
21875 /**
21876 * limits query
21877 */
21878 // the following feature-detect from hammer.js
21879 // @see https://github.com/hammerjs/hammer.js/blob/master/src/inputjs/input-consts.js#L5
21880 _this.supportsTouchEvents =
21881 supportsTouchEvents !== null && supportsTouchEvents !== void 0 ? supportsTouchEvents : 'ontouchstart' in runtime.globalThis;
21882 _this.supportsPointerEvents =
21883 supportsPointerEvents !== null && supportsPointerEvents !== void 0 ? supportsPointerEvents : !!runtime.globalThis.PointerEvent;
21884 _this.isTouchEvent =
21885 isTouchEvent !== null && isTouchEvent !== void 0 ? isTouchEvent : (function (event) {
21886 return _this.supportsTouchEvents &&
21887 event instanceof runtime.globalThis.TouchEvent;
21888 });
21889 _this.isMouseEvent =
21890 isMouseEvent !== null && isMouseEvent !== void 0 ? isMouseEvent : (function (event) {
21891 return !runtime.globalThis.MouseEvent ||
21892 (event instanceof runtime.globalThis.MouseEvent &&
21893 (!_this.supportsPointerEvents ||
21894 !(event instanceof runtime.globalThis.PointerEvent)));
21895 });
21896 _this.initRenderingContext({
21897 container: container,
21898 canvas: canvas,
21899 width: canvasWidth,
21900 height: canvasHeight,
21901 renderer: renderer,
21902 offscreenCanvas: offscreenCanvas,
21903 devicePixelRatio: dpr,
21904 cursor: cursor || 'default',
21905 background: background || 'transparent',
21906 createImage: createImage,
21907 document: document,
21908 supportsCSSTransform: supportsCSSTransform,
21909 useNativeClickEvent: useNativeClickEvent,
21910 alwaysTriggerPointerEventOnCanvas: alwaysTriggerPointerEventOnCanvas,
21911 });
21912 _this.initDefaultCamera(canvasWidth, canvasHeight, renderer.clipSpaceNearZ);
21913 _this.initRenderer(renderer, true);
21914 return _this;
21915 }
21916 Canvas.prototype.initRenderingContext = function (mergedConfig) {
21917 this.context.config = mergedConfig;
21918 // bind rendering context, shared by all renderers
21919 this.context.renderingContext = {
21920 /**
21921 * the root node in scene graph
21922 */
21923 root: this.document.documentElement,
21924 renderListCurrentFrame: [],
21925 unculledEntities: [],
21926 renderReasons: new Set(),
21927 force: false,
21928 dirty: false,
21929 };
21930 };
21931 Canvas.prototype.initDefaultCamera = function (width, height, clipSpaceNearZ) {
21932 var _this = this;
21933 // set a default ortho camera
21934 var camera = new runtime.CameraContribution();
21935 camera.clipSpaceNearZ = clipSpaceNearZ;
21936 camera
21937 .setType(CameraType.EXPLORING, CameraTrackingMode.DEFAULT)
21938 .setPosition(width / 2, height / 2, DEFAULT_CAMERA_Z)
21939 .setFocalPoint(width / 2, height / 2, 0)
21940 .setOrthographic(width / -2, width / 2, height / 2, height / -2, DEFAULT_CAMERA_NEAR, DEFAULT_CAMERA_FAR);
21941 // keep ref since it will use raf in camera animation
21942 camera.canvas = this;
21943 // redraw when camera changed
21944 camera.eventEmitter.on(CameraEvent.UPDATED, function () {
21945 _this.context.renderingContext.renderReasons.add(RenderReason.CAMERA_CHANGED);
21946 if (runtime.enableSizeAttenuation &&
21947 _this.getConfig().renderer.getConfig().enableSizeAttenuation) {
21948 _this.updateSizeAttenuation();
21949 }
21950 });
21951 // bind camera
21952 this.context.camera = camera;
21953 };
21954 Canvas.prototype.updateSizeAttenuation = function () {
21955 var zoom = this.getCamera().getZoom();
21956 this.document.documentElement.forEach(function (node) {
21957 runtime.styleValueRegistry.updateSizeAttenuation(node, zoom);
21958 });
21959 };
21960 Canvas.prototype.getConfig = function () {
21961 return this.context.config;
21962 };
21963 /**
21964 * get the root displayObject in scenegraph
21965 * @alias this.document.documentElement
21966 */
21967 Canvas.prototype.getRoot = function () {
21968 return this.document.documentElement;
21969 };
21970 /**
21971 * get the camera of canvas
21972 */
21973 Canvas.prototype.getCamera = function () {
21974 return this.context.camera;
21975 };
21976 Canvas.prototype.getContextService = function () {
21977 return this.context.contextService;
21978 };
21979 Canvas.prototype.getEventService = function () {
21980 return this.context.eventService;
21981 };
21982 Canvas.prototype.getRenderingService = function () {
21983 return this.context.renderingService;
21984 };
21985 Canvas.prototype.getRenderingContext = function () {
21986 return this.context.renderingContext;
21987 };
21988 Canvas.prototype.getStats = function () {
21989 return this.getRenderingService().getStats();
21990 };
21991 Object.defineProperty(Canvas.prototype, "ready", {
21992 // /**
21993 // * @see https://developer.mozilla.org/zh-CN/docs/Web/API/Window/getComputedStyle
21994 // */
21995 // getComputedStyle(node: DisplayObject) {
21996 // return node.computedStyle;
21997 // }
21998 get: function () {
21999 var _this = this;
22000 if (!this.readyPromise) {
22001 this.readyPromise = new Promise(function (resolve) {
22002 _this.resolveReadyPromise = function () {
22003 resolve(_this);
22004 };
22005 });
22006 if (this.inited) {
22007 this.resolveReadyPromise();
22008 }
22009 }
22010 return this.readyPromise;
22011 },
22012 enumerable: false,
22013 configurable: true
22014 });
22015 /**
22016 * `cleanUp` means clean all the internal services of Canvas which happens when calling `canvas.destroy()`.
22017 */
22018 Canvas.prototype.destroy = function (cleanUp, skipTriggerEvent) {
22019 if (cleanUp === void 0) { cleanUp = true; }
22020 if (skipTriggerEvent === void 0) { skipTriggerEvent = false; }
22021 if (!skipTriggerEvent) {
22022 this.dispatchEvent(new CustomEvent(CanvasEvent.BEFORE_DESTROY));
22023 }
22024 if (this.frameId) {
22025 var cancelRAF = this.getConfig().cancelAnimationFrame || cancelAnimationFrame;
22026 cancelRAF(this.frameId);
22027 }
22028 // unmount all children
22029 var root = this.getRoot();
22030 this.unmountChildren(root);
22031 if (cleanUp) {
22032 // destroy Document
22033 this.document.destroy();
22034 this.getEventService().destroy();
22035 }
22036 // destroy services
22037 this.getRenderingService().destroy();
22038 this.getContextService().destroy();
22039 // clear root after renderservice destroyed
22040 if (cleanUp && this.context.rBushRoot) {
22041 // clear rbush
22042 this.context.rBushRoot.clear();
22043 this.context.rBushRoot = null;
22044 this.context.renderingContext.root = null;
22045 }
22046 if (!skipTriggerEvent) {
22047 this.dispatchEvent(new CustomEvent(CanvasEvent.AFTER_DESTROY));
22048 }
22049 };
22050 /**
22051 * compatible with G 3.0
22052 * @deprecated
22053 * @alias resize
22054 */
22055 Canvas.prototype.changeSize = function (width, height) {
22056 this.resize(width, height);
22057 };
22058 Canvas.prototype.resize = function (width, height) {
22059 // update canvas' config
22060 var canvasConfig = this.context.config;
22061 canvasConfig.width = width;
22062 canvasConfig.height = height;
22063 // resize context
22064 this.getContextService().resize(width, height);
22065 // resize camera
22066 var camera = this.context.camera;
22067 var projectionMode = camera.getProjectionMode();
22068 camera
22069 .setPosition(width / 2, height / 2, DEFAULT_CAMERA_Z)
22070 .setFocalPoint(width / 2, height / 2, 0);
22071 if (projectionMode === CameraProjectionMode.ORTHOGRAPHIC) {
22072 camera.setOrthographic(width / -2, width / 2, height / 2, height / -2, camera.getNear(), camera.getFar());
22073 }
22074 else {
22075 camera.setAspect(width / height);
22076 }
22077 this.dispatchEvent(new CustomEvent(CanvasEvent.RESIZE, { width: width, height: height }));
22078 };
22079 // proxy to document.documentElement
22080 Canvas.prototype.appendChild = function (child, index) {
22081 return this.document.documentElement.appendChild(child, index);
22082 };
22083 Canvas.prototype.insertBefore = function (newChild, refChild) {
22084 return this.document.documentElement.insertBefore(newChild, refChild);
22085 };
22086 Canvas.prototype.removeChild = function (child) {
22087 return this.document.documentElement.removeChild(child);
22088 };
22089 /**
22090 * Remove all children which can be appended to its original parent later again.
22091 */
22092 Canvas.prototype.removeChildren = function () {
22093 this.document.documentElement.removeChildren();
22094 };
22095 /**
22096 * Recursively destroy all children which can not be appended to its original parent later again.
22097 * But the canvas remains running which means display objects can be appended later.
22098 */
22099 Canvas.prototype.destroyChildren = function () {
22100 this.document.documentElement.destroyChildren();
22101 };
22102 Canvas.prototype.render = function () {
22103 var _this = this;
22104 this.dispatchEvent(beforeRenderEvent);
22105 var renderingService = this.getRenderingService();
22106 renderingService.render(this.getConfig(), function () {
22107 // trigger actual rerender event
22108 // @see https://github.com/antvis/G/issues/1268
22109 _this.dispatchEvent(rerenderEvent);
22110 });
22111 this.dispatchEvent(afterRenderEvent);
22112 };
22113 Canvas.prototype.run = function () {
22114 var _this = this;
22115 var tick = function () {
22116 _this.render();
22117 _this.frameId = _this.requestAnimationFrame(tick);
22118 };
22119 tick();
22120 };
22121 Canvas.prototype.initRenderer = function (renderer, firstContentfullPaint) {
22122 var _this = this;
22123 if (firstContentfullPaint === void 0) { firstContentfullPaint = false; }
22124 if (!renderer) {
22125 throw new Error('Renderer is required.');
22126 }
22127 // reset
22128 this.inited = false;
22129 this.readyPromise = undefined;
22130 // FIXME: should re-create here?
22131 this.context.rBushRoot = new RBush();
22132 // reset rendering plugins
22133 this.context.renderingPlugins = [];
22134 this.context.renderingPlugins.push(new EventPlugin(), new PrepareRendererPlugin(),
22135 // new DirtyCheckPlugin(),
22136 new CullingPlugin([new FrustumCullingStrategy()]));
22137 //
22138 this.loadRendererContainerModule(renderer);
22139 // init context service
22140 this.context.contextService = new this.context.ContextService(__assign(__assign({}, runtime), this.context));
22141 // init rendering service
22142 this.context.renderingService = new RenderingService(runtime, this.context);
22143 // init event service
22144 this.context.eventService = new EventService(runtime, this.context);
22145 this.context.eventService.init();
22146 if (this.context.contextService.init) {
22147 this.context.contextService.init();
22148 this.initRenderingService(renderer, firstContentfullPaint, true);
22149 }
22150 else {
22151 this.context.contextService.initAsync().then(function () {
22152 _this.initRenderingService(renderer, firstContentfullPaint);
22153 });
22154 }
22155 };
22156 Canvas.prototype.initRenderingService = function (renderer, firstContentfullPaint, async) {
22157 var _this = this;
22158 if (firstContentfullPaint === void 0) { firstContentfullPaint = false; }
22159 if (async === void 0) { async = false; }
22160 this.context.renderingService.init(function () {
22161 _this.inited = true;
22162 if (firstContentfullPaint) {
22163 if (async) {
22164 _this.requestAnimationFrame(function () {
22165 _this.dispatchEvent(new CustomEvent(CanvasEvent.READY));
22166 });
22167 }
22168 else {
22169 _this.dispatchEvent(new CustomEvent(CanvasEvent.READY));
22170 }
22171 if (_this.readyPromise) {
22172 _this.resolveReadyPromise();
22173 }
22174 }
22175 else {
22176 _this.dispatchEvent(new CustomEvent(CanvasEvent.RENDERER_CHANGED));
22177 }
22178 if (!firstContentfullPaint) {
22179 _this.getRoot().forEach(function (node) {
22180 var renderable = node.renderable;
22181 if (renderable) {
22182 renderable.renderBoundsDirty = true;
22183 renderable.boundsDirty = true;
22184 renderable.dirty = true;
22185 }
22186 });
22187 }
22188 // keep current scenegraph unchanged, just trigger mounted event
22189 _this.mountChildren(_this.getRoot());
22190 if (renderer.getConfig().enableAutoRendering) {
22191 _this.run();
22192 }
22193 });
22194 };
22195 Canvas.prototype.loadRendererContainerModule = function (renderer) {
22196 var _this = this;
22197 // load other container modules provided by g-canvas/g-svg/g-webgl
22198 var plugins = renderer.getPlugins();
22199 plugins.forEach(function (plugin) {
22200 plugin.context = _this.context;
22201 plugin.init(runtime);
22202 });
22203 };
22204 Canvas.prototype.setRenderer = function (renderer) {
22205 // update canvas' config
22206 var canvasConfig = this.getConfig();
22207 if (canvasConfig.renderer === renderer) {
22208 return;
22209 }
22210 var oldRenderer = canvasConfig.renderer;
22211 canvasConfig.renderer = renderer;
22212 // keep all children undestroyed
22213 this.destroy(false, true);
22214 // destroy all plugins, reverse will mutate origin array
22215 __spreadArray([], __read(oldRenderer === null || oldRenderer === void 0 ? void 0 : oldRenderer.getPlugins()), false).reverse().forEach(function (plugin) {
22216 plugin.destroy(runtime);
22217 });
22218 this.initRenderer(renderer);
22219 };
22220 Canvas.prototype.setCursor = function (cursor) {
22221 var canvasConfig = this.getConfig();
22222 canvasConfig.cursor = cursor;
22223 this.getContextService().applyCursorStyle(cursor);
22224 };
22225 Canvas.prototype.unmountChildren = function (parent) {
22226 var _this = this;
22227 // unmountChildren recursively
22228 parent.childNodes.forEach(function (child) {
22229 _this.unmountChildren(child);
22230 });
22231 if (this.inited) {
22232 if (parent.isMutationObserved) {
22233 parent.dispatchEvent(unmountedEvent);
22234 }
22235 else {
22236 unmountedEvent.target = parent;
22237 this.dispatchEvent(unmountedEvent, true);
22238 }
22239 // skip document.documentElement
22240 if (parent !== this.document.documentElement) {
22241 parent.ownerDocument = null;
22242 }
22243 parent.isConnected = false;
22244 }
22245 // trigger after unmounted
22246 if (parent.isCustomElement) {
22247 if (parent.disconnectedCallback) {
22248 parent.disconnectedCallback();
22249 }
22250 }
22251 };
22252 Canvas.prototype.mountChildren = function (parent) {
22253 var _this = this;
22254 if (this.inited) {
22255 if (!parent.isConnected) {
22256 parent.ownerDocument = this.document;
22257 parent.isConnected = true;
22258 if (parent.isMutationObserved) {
22259 parent.dispatchEvent(mountedEvent);
22260 }
22261 else {
22262 mountedEvent.target = parent;
22263 this.dispatchEvent(mountedEvent, true);
22264 }
22265 }
22266 }
22267 else {
22268 console.warn("[g]: You are trying to call `canvas.appendChild` before canvas' initialization finished. You can either await `canvas.ready` or listen to `CanvasEvent.READY` manually.", 'appended child: ', parent.nodeName);
22269 }
22270 // recursively mount children
22271 parent.childNodes.forEach(function (child) {
22272 _this.mountChildren(child);
22273 });
22274 // trigger after mounted
22275 if (parent.isCustomElement) {
22276 if (parent.connectedCallback) {
22277 parent.connectedCallback();
22278 }
22279 }
22280 };
22281 Canvas.prototype.client2Viewport = function (client) {
22282 return this.getEventService().client2Viewport(client);
22283 };
22284 Canvas.prototype.viewport2Client = function (canvas) {
22285 return this.getEventService().viewport2Client(canvas);
22286 };
22287 Canvas.prototype.viewport2Canvas = function (viewport) {
22288 return this.getEventService().viewport2Canvas(viewport);
22289 };
22290 Canvas.prototype.canvas2Viewport = function (canvas) {
22291 return this.getEventService().canvas2Viewport(canvas);
22292 };
22293 /**
22294 * @deprecated
22295 * @alias client2Viewport
22296 */
22297 Canvas.prototype.getPointByClient = function (clientX, clientY) {
22298 return this.client2Viewport({ x: clientX, y: clientY });
22299 };
22300 /**
22301 * @deprecated
22302 * @alias viewport2Client
22303 */
22304 Canvas.prototype.getClientByPoint = function (x, y) {
22305 return this.viewport2Client({ x: x, y: y });
22306 };
22307 return Canvas;
22308 }(EventTarget));
22309
22310 var polarToCartesian = function polarToCartesian(centerX, centerY, radius, angleInRadian) {
22311 return {
22312 x: centerX + radius * Math.cos(angleInRadian),
22313 y: centerY + radius * Math.sin(angleInRadian)
22314 };
22315 };
22316
22317 function computeArcSweep(startAngle, endAngle, anticlockwise) {
22318 // 顺时针方向
22319 if (!anticlockwise) {
22320 if (endAngle >= startAngle) {
22321 return endAngle - startAngle <= Math.PI ? 0 : 1;
22322 }
22323 return endAngle - startAngle <= -Math.PI ? 0 : 1;
22324 }
22325 // 逆时针方向
22326 if (endAngle >= startAngle) {
22327 return endAngle - startAngle <= Math.PI ? 1 : 0;
22328 }
22329 return endAngle - startAngle <= -Math.PI ? 1 : 0;
22330 }
22331 var Arc = /** @class */function (_super) {
22332 __extends(Arc, _super);
22333 function Arc(config) {
22334 var _this = _super.call(this, config) || this;
22335 _this.updatePath();
22336 return _this;
22337 }
22338 Arc.prototype.setAttribute = function (name, value, force) {
22339 _super.prototype.setAttribute.call(this, name, value, force);
22340 if (['cx', 'cy', 'startAngle', 'endAngle', 'r', 'anticlockwise'].indexOf(name) > -1) {
22341 this.updatePath();
22342 }
22343 };
22344 Arc.prototype.updatePath = function () {
22345 var _a = this.parsedStyle,
22346 _b = _a.cx,
22347 cx = _b === void 0 ? 0 : _b,
22348 _c = _a.cy,
22349 cy = _c === void 0 ? 0 : _c,
22350 startAngle = _a.startAngle,
22351 endAngle = _a.endAngle,
22352 r = _a.r,
22353 anticlockwise = _a.anticlockwise;
22354 if (isNil(startAngle) || isNil(endAngle) || startAngle === endAngle || isNil(r) || r <= 0) {
22355 _super.prototype.setAttribute.call(this, 'path', '');
22356 return;
22357 }
22358 var path = this.createPath(cx, cy, deg2rad(startAngle), deg2rad(endAngle), r, anticlockwise);
22359 _super.prototype.setAttribute.call(this, 'path', path);
22360 };
22361 Arc.prototype.createPath = function (x, y, startAngle, endAngle, r, anticlockwise) {
22362 var start = polarToCartesian(x, y, r, startAngle);
22363 var end = polarToCartesian(x, y, r, endAngle);
22364 var angle = Math.abs(endAngle - startAngle);
22365 if (angle >= Math.PI * 2 || isNumberEqual(angle, Math.PI * 2)) {
22366 var middlePoint = polarToCartesian(x, y, r, startAngle + Math.PI);
22367 return [['M', start.x, start.y], ['A', r, r, 0, 1, anticlockwise ? 0 : 1, middlePoint.x, middlePoint.y], ['A', r, r, 0, 1, anticlockwise ? 0 : 1, start.x, start.y], ['Z']];
22368 }
22369 var arcSweep = computeArcSweep(startAngle, endAngle, anticlockwise);
22370 return [['M', start.x, start.y], ['A', r, r, 0, arcSweep, anticlockwise ? 0 : 1, end.x, end.y]];
22371 };
22372 return Arc;
22373 }(Path);
22374
22375 var SYMBOLS = {
22376 circle: function circle(x, y, r) {
22377 return [['M', x - r, y], ['A', r, r, 0, 1, 0, x + r, y], ['A', r, r, 0, 1, 0, x - r, y]];
22378 },
22379 square: function square(x, y, r) {
22380 return [['M', x - r, y - r], ['L', x + r, y - r], ['L', x + r, y + r], ['L', x - r, y + r], ['Z']];
22381 },
22382 arrow: function arrow(x, y, r) {
22383 return [['M', x - r, y + 2 * r / Math.sqrt(3)], ['L', x + r, y + 2 * r / Math.sqrt(3)], ['L', x, y - 2 * r / Math.sqrt(3)], ['Z']];
22384 }
22385 };
22386 var Marker = /** @class */function (_super) {
22387 __extends(Marker, _super);
22388 function Marker(config) {
22389 var _this = _super.call(this, config) || this;
22390 _this.updatePath();
22391 return _this;
22392 }
22393 Marker.prototype.setAttribute = function (name, value, force) {
22394 _super.prototype.setAttribute.call(this, name, value, force);
22395 if (['x', 'y', 'symbol', 'radius'].indexOf(name) > -1) {
22396 this.updatePath();
22397 }
22398 };
22399 Marker.prototype.updatePath = function () {
22400 var _a = this.parsedStyle,
22401 _b = _a.x,
22402 x = _b === void 0 ? 0 : _b,
22403 _c = _a.y,
22404 y = _c === void 0 ? 0 : _c;
22405 var _d = this.attributes,
22406 radius = _d.radius,
22407 symbol = _d.symbol;
22408 if (!symbol) return;
22409 var method = SYMBOLS[symbol];
22410 if (!method) return;
22411 var path = method(x, y, radius);
22412 _super.prototype.setAttribute.call(this, 'path', path);
22413 };
22414 return Marker;
22415 }(Path);
22416
22417 var PI = Math.PI;
22418 var PI2 = PI * 2;
22419 var mathSin = Math.sin;
22420 var mathCos = Math.cos;
22421 var mathACos = Math.acos;
22422 var mathATan2 = Math.atan2;
22423 // const mathAbs = Math.abs;
22424 var mathSqrt = Math.sqrt;
22425 var mathMax = Math.max;
22426 var mathMin = Math.min;
22427 var e = 1e-4;
22428 function intersect(x0, y0, x1, y1, x2, y2, x3, y3) {
22429 var dx10 = x1 - x0;
22430 var dy10 = y1 - y0;
22431 var dx32 = x3 - x2;
22432 var dy32 = y3 - y2;
22433 var t = dy32 * dx10 - dx32 * dy10;
22434 if (t * t < e) {
22435 return;
22436 }
22437 t = (dx32 * (y0 - y2) - dy32 * (x0 - x2)) / t;
22438 return [x0 + t * dx10, y0 + t * dy10];
22439 }
22440 // Compute perpendicular offset line of length rc.
22441 function computeCornerTangents(x0, y0, x1, y1, radius, cr, clockwise) {
22442 var x01 = x0 - x1;
22443 var y01 = y0 - y1;
22444 var lo = (clockwise ? cr : -cr) / mathSqrt(x01 * x01 + y01 * y01);
22445 var ox = lo * y01;
22446 var oy = -lo * x01;
22447 var x11 = x0 + ox;
22448 var y11 = y0 + oy;
22449 var x10 = x1 + ox;
22450 var y10 = y1 + oy;
22451 var x00 = (x11 + x10) / 2;
22452 var y00 = (y11 + y10) / 2;
22453 var dx = x10 - x11;
22454 var dy = y10 - y11;
22455 var d2 = dx * dx + dy * dy;
22456 var r = radius - cr;
22457 var s = x11 * y10 - x10 * y11;
22458 var d = (dy < 0 ? -1 : 1) * mathSqrt(mathMax(0, r * r * d2 - s * s));
22459 var cx0 = (s * dy - dx * d) / d2;
22460 var cy0 = (-s * dx - dy * d) / d2;
22461 var cx1 = (s * dy + dx * d) / d2;
22462 var cy1 = (-s * dx + dy * d) / d2;
22463 var dx0 = cx0 - x00;
22464 var dy0 = cy0 - y00;
22465 var dx1 = cx1 - x00;
22466 var dy1 = cy1 - y00;
22467 // Pick the closer of the two intersection points
22468 // TODO: Is there a faster way to determine which intersection to use?
22469 if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) {
22470 cx0 = cx1;
22471 cy0 = cy1;
22472 }
22473 return {
22474 cx: cx0,
22475 cy: cy0,
22476 x0: -ox,
22477 y0: -oy,
22478 x1: cx0 * (radius / r - 1),
22479 y1: cy0 * (radius / r - 1)
22480 };
22481 }
22482 function computeArcSweep$1(startAngle, endAngle, clockwise) {
22483 if (clockwise === void 0) {
22484 clockwise = true;
22485 }
22486 if (!clockwise) {
22487 var replaceAngle = endAngle;
22488 endAngle = startAngle;
22489 startAngle = replaceAngle;
22490 }
22491 endAngle = endAngle - startAngle < 0 ? endAngle + PI2 : endAngle;
22492 return Math.abs(endAngle - startAngle) % PI2 <= PI ? 0 : 1;
22493 }
22494 var Sector = /** @class */function (_super) {
22495 __extends(Sector, _super);
22496 function Sector(config) {
22497 var _this = _super.call(this, config) || this;
22498 _this.updatePath();
22499 return _this;
22500 }
22501 Sector.prototype.setAttribute = function (name, value, force) {
22502 _super.prototype.setAttribute.call(this, name, value, force);
22503 if (['startAngle', 'endAngle', 'r', 'r0', 'radius', 'cx', 'cy'].indexOf(name) > -1) {
22504 this.updatePath();
22505 }
22506 };
22507 Sector.prototype.updatePath = function () {
22508 var _a = this.parsedStyle,
22509 cx = _a.cx,
22510 cy = _a.cy,
22511 startAngle = _a.startAngle,
22512 endAngle = _a.endAngle,
22513 r = _a.r,
22514 r0 = _a.r0,
22515 radius = _a.radius,
22516 _b = _a.anticlockwise,
22517 anticlockwise = _b === void 0 ? false : _b;
22518 if (isNil(startAngle) || isNil(endAngle) || startAngle === endAngle || isNil(r) || r <= 0) {
22519 _super.prototype.setAttribute.call(this, 'path', '');
22520 return;
22521 }
22522 var path = this.createPath(cx, cy, deg2rad(startAngle), deg2rad(endAngle), r, r0 ? r0 : 0, radius ? radius : [0, 0, 0, 0], anticlockwise);
22523 _super.prototype.setAttribute.call(this, 'path', path);
22524 };
22525 Sector.prototype.createPath = function (x, y, startAngle, endAngle, r, r0, borderRadius, anticlockwise) {
22526 var start = polarToCartesian(x, y, r, startAngle);
22527 var end = polarToCartesian(x, y, r, endAngle);
22528 var innerStart = polarToCartesian(x, y, r0, startAngle);
22529 var innerEnd = polarToCartesian(x, y, r0, endAngle);
22530 var clockwise = !anticlockwise;
22531 var angle = clockwise ? endAngle - startAngle : startAngle - endAngle;
22532 // 整圆
22533 if (Math.abs(angle) >= PI2 || isNumberEqual(Math.abs(angle), PI2)) {
22534 // 整个圆是分割成两个圆
22535 var middlePoint = polarToCartesian(x, y, r, startAngle + Math.PI);
22536 var innerMiddlePoint = polarToCartesian(x, y, r0, startAngle + Math.PI);
22537 var circlePathCommands = [['M', start.x, start.y], ['A', r, r, 0, 1, clockwise ? 1 : 0, middlePoint.x, middlePoint.y], ['A', r, r, 0, 1, clockwise ? 1 : 0, end.x, end.y]];
22538 if (r0 > 0) {
22539 circlePathCommands.push(['M', innerStart.x, innerStart.y]);
22540 circlePathCommands.push(['A', r0, r0, 0, 1, clockwise ? 0 : 1, innerMiddlePoint.x, innerMiddlePoint.y]);
22541 circlePathCommands.push(['A', r0, r0, 0, 1, clockwise ? 0 : 1, innerEnd.x, innerEnd.y]);
22542 }
22543 circlePathCommands.push(['M', start.x, start.y]);
22544 circlePathCommands.push(['Z']);
22545 return circlePathCommands;
22546 }
22547 var xrs = r * mathCos(startAngle);
22548 var yrs = r * mathSin(startAngle);
22549 var xire = r0 * mathCos(endAngle);
22550 var yire = r0 * mathSin(endAngle);
22551 var xre = r * mathCos(endAngle);
22552 var yre = r * mathSin(endAngle);
22553 var xirs = r0 * mathCos(startAngle);
22554 var yirs = r0 * mathSin(startAngle);
22555 // 顺时针反向,同 radius
22556 var outStartRadius = borderRadius[0],
22557 outEndRadius = borderRadius[1],
22558 innerEndRadius = borderRadius[2],
22559 innerStartRadius = borderRadius[3];
22560 var halfRadius = (r - r0) / 2;
22561 var outStartBorderRadius = mathMin(halfRadius, outStartRadius);
22562 var outEndBorderRadius = mathMin(halfRadius, outEndRadius);
22563 var innerEndBorderRadius = mathMin(halfRadius, innerEndRadius);
22564 var innerStartBorderRadius = mathMin(halfRadius, innerStartRadius);
22565 var outBorderRadiusMax = mathMax(outStartBorderRadius, outEndBorderRadius);
22566 var innerBorderRadiusMax = mathMax(innerEndBorderRadius, innerStartBorderRadius);
22567 var limitedOutBorderRadiusMax = outBorderRadiusMax;
22568 var limitedInnerBorderRadiusMax = innerBorderRadiusMax;
22569 // draw corner radius
22570 if (outBorderRadiusMax > e || innerBorderRadiusMax > e) {
22571 // restrict the max value of corner radius
22572 if (angle < PI) {
22573 var it_1 = intersect(xrs, yrs, xirs, yirs, xre, yre, xire, yire);
22574 if (it_1) {
22575 var x0 = xrs - it_1[0];
22576 var y0 = yrs - it_1[1];
22577 var x1 = xre - it_1[0];
22578 var y1 = yre - it_1[1];
22579 var a = 1 / mathSin(mathACos((x0 * x1 + y0 * y1) / (mathSqrt(x0 * x0 + y0 * y0) * mathSqrt(x1 * x1 + y1 * y1))) / 2);
22580 var b = mathSqrt(it_1[0] * it_1[0] + it_1[1] * it_1[1]);
22581 limitedOutBorderRadiusMax = mathMin(outBorderRadiusMax, (r - b) / (a + 1));
22582 limitedInnerBorderRadiusMax = mathMin(innerBorderRadiusMax, (r0 - b) / (a - 1));
22583 }
22584 }
22585 }
22586 var arcSweep = computeArcSweep$1(startAngle, endAngle, clockwise);
22587 var sectorPathCommands = [];
22588 if (limitedOutBorderRadiusMax > e) {
22589 var crStart = mathMin(outStartRadius, limitedOutBorderRadiusMax);
22590 var crEnd = mathMin(outEndRadius, limitedOutBorderRadiusMax);
22591 var ct0 = computeCornerTangents(xirs, yirs, xrs, yrs, r, crStart, clockwise);
22592 var ct1 = computeCornerTangents(xre, yre, xire, yire, r, crEnd, clockwise);
22593 sectorPathCommands.push(['M', x + ct0.cx + ct0.x0, y + ct0.cy + ct0.y0]);
22594 // Have the corners merged?
22595 if (limitedOutBorderRadiusMax < outBorderRadiusMax && crStart === crEnd) {
22596 var outStartBorderRadiusStartAngle = mathATan2(ct0.cy + ct0.y0, ct0.cx + ct0.x0);
22597 var outStartBorderRadiusEndAngle = mathATan2(ct1.cy + ct1.y0, ct1.cx + ct1.x0);
22598 sectorPathCommands.push(['A', limitedOutBorderRadiusMax, limitedOutBorderRadiusMax, 0, computeArcSweep$1(outStartBorderRadiusStartAngle, outStartBorderRadiusEndAngle, !clockwise), clockwise ? 1 : 0, x + ct1.cx + ct1.x0, y + ct1.cy + ct1.y0]);
22599 } else {
22600 // draw the two corners and the ring
22601 if (crStart > 0) {
22602 var outStartBorderRadiusStartAngle = mathATan2(ct0.y0, ct0.x0);
22603 var outStartBorderRadiusEndAngle = mathATan2(ct0.y1, ct0.x1);
22604 var outStartBorderRadiusEndPoint = polarToCartesian(x, y, r, outStartBorderRadiusEndAngle);
22605 sectorPathCommands.push(['A', crStart, crStart, 0, computeArcSweep$1(outStartBorderRadiusStartAngle, outStartBorderRadiusEndAngle, clockwise), clockwise ? 1 : 0, outStartBorderRadiusEndPoint.x, outStartBorderRadiusEndPoint.y]);
22606 }
22607 var outRadiusStartAngle = mathATan2(ct0.cy + ct0.y1, ct0.cx + ct0.x1);
22608 var outRadiusEndAngle = mathATan2(ct1.cy + ct1.y1, ct1.cx + ct1.x1);
22609 var outRadiusEndPoint = polarToCartesian(x, y, r, outRadiusEndAngle);
22610 sectorPathCommands.push(['A', r, r, 1, computeArcSweep$1(outRadiusStartAngle, outRadiusEndAngle, clockwise), clockwise ? 1 : 0, outRadiusEndPoint.x, outRadiusEndPoint.y]);
22611 if (crEnd > 0) {
22612 var outEndBorderRadiusStartAngle = mathATan2(ct1.y1, ct1.x1);
22613 var outEndBorderRadiusEndAngle = mathATan2(ct1.y0, ct1.x0);
22614 sectorPathCommands.push(['A', crEnd, crEnd, 0, computeArcSweep$1(outEndBorderRadiusStartAngle, outEndBorderRadiusEndAngle, clockwise), clockwise ? 1 : 0, x + ct1.cx + ct1.x0, y + ct1.cy + ct1.y0]);
22615 }
22616 }
22617 } else {
22618 sectorPathCommands.push(['M', start.x, start.y]);
22619 sectorPathCommands.push(['A', r, r, 0, arcSweep, clockwise ? 1 : 0, end.x, end.y]);
22620 }
22621 // no inner ring, is a circular sector
22622 if (r0 < e) {
22623 sectorPathCommands.push(['L', innerEnd.x, innerEnd.y]);
22624 } else if (limitedInnerBorderRadiusMax > e) {
22625 var crStart = mathMin(innerStartRadius, limitedInnerBorderRadiusMax);
22626 var crEnd = mathMin(innerEndRadius, limitedInnerBorderRadiusMax);
22627 var ct0 = computeCornerTangents(0, 0, xire, yire, r0, -crEnd, clockwise);
22628 var ct1 = computeCornerTangents(xirs, yirs, 0, 0, r0, -crStart, clockwise);
22629 sectorPathCommands.push(['L', x + ct0.cx + ct0.x0, y + ct0.cy + ct0.y0]);
22630 // Have the corners merged?
22631 if (limitedInnerBorderRadiusMax < innerBorderRadiusMax && crStart === crEnd) {
22632 var innerStartBorderRadiusStartAngle = mathATan2(ct0.y0, ct0.x0);
22633 var innerStartBorderRadiusEndAngle = mathATan2(ct1.y0, ct1.x0);
22634 sectorPathCommands.push(['A', limitedInnerBorderRadiusMax, limitedInnerBorderRadiusMax, 0, computeArcSweep$1(innerStartBorderRadiusStartAngle, innerStartBorderRadiusEndAngle), 1, x + ct1.cx + ct1.x0, y + ct1.cy + ct1.y0]);
22635 } else {
22636 // draw the two corners and the ring
22637 if (crEnd > 0) {
22638 var innerStartBorderRadiusStartAngle = mathATan2(ct0.y0, ct0.x0);
22639 var innerStartBorderRadiusEndAngle = mathATan2(ct0.y1, ct0.x1);
22640 sectorPathCommands.push(['A', crEnd, crEnd, 0, computeArcSweep$1(innerStartBorderRadiusStartAngle, innerStartBorderRadiusEndAngle, clockwise), clockwise ? 1 : 0, x + ct0.cx + ct0.x1, y + ct0.cy + ct0.y1]);
22641 }
22642 var innerRadiusStartAngle = mathATan2(ct0.cy + ct0.y1, ct0.cx + ct0.x1);
22643 var innerRadiusEndAngle = mathATan2(ct1.cy + ct1.y1, ct1.cx + ct1.x1);
22644 var innerRadiusEndPoint = polarToCartesian(x, y, r0, innerRadiusEndAngle);
22645 sectorPathCommands.push(['A', r0, r0, 0, computeArcSweep$1(innerRadiusEndAngle, innerRadiusStartAngle, clockwise), clockwise ? 0 : 1, innerRadiusEndPoint.x, innerRadiusEndPoint.y]);
22646 if (crStart > 0) {
22647 var innerEndBorderRadiusStartAngle = mathATan2(ct1.y1, ct1.x1);
22648 var innerEndBorderRadiusEndAngle = mathATan2(ct1.y0, ct1.x0);
22649 sectorPathCommands.push(['A', crStart, crStart, 0, computeArcSweep$1(innerEndBorderRadiusStartAngle, innerEndBorderRadiusEndAngle, clockwise), clockwise ? 1 : 0, x + ct1.cx + ct1.x0, y + ct1.cy + ct1.y0]);
22650 }
22651 }
22652 }
22653 // the inner ring is just a circular arc
22654 else {
22655 sectorPathCommands.push(['L', innerEnd.x, innerEnd.y]);
22656 sectorPathCommands.push(['A', r0, r0, 0, arcSweep, clockwise ? 0 : 1, innerStart.x, innerStart.y]);
22657 }
22658 sectorPathCommands.push(['Z']);
22659 return sectorPathCommands;
22660 };
22661 return Sector;
22662 }(Path);
22663
22664 /**
22665 * @fileOverview convert the line to curve
22666 * @author dxq613@gmail.com
22667 */
22668 function getPoint(v) {
22669 return [v.x, v.y];
22670 }
22671 function smoothBezier(points, smooth, isLoop, constraint) {
22672 var cps = [];
22673 var prevPoint;
22674 var nextPoint;
22675 var hasConstraint = !!constraint;
22676 var min;
22677 var max;
22678 var point;
22679 var len;
22680 var l;
22681 var i;
22682 if (hasConstraint) {
22683 min = [Infinity, Infinity];
22684 max = [-Infinity, -Infinity];
22685 for (i = 0, l = points.length; i < l; i++) {
22686 point = getPoint(points[i]);
22687 min$1(min, min, point);
22688 max$1(max, max, point);
22689 }
22690 min$1(min, min, constraint[0]);
22691 max$1(max, max, constraint[1]);
22692 }
22693 for (i = 0, len = points.length; i < len; i++) {
22694 point = getPoint(points[i]);
22695 if (isLoop) {
22696 prevPoint = getPoint(points[i ? i - 1 : len - 1]);
22697 nextPoint = getPoint(points[(i + 1) % len]);
22698 } else {
22699 if (i === 0 || i === len - 1) {
22700 cps.push([point[0], point[1]]);
22701 continue;
22702 } else {
22703 prevPoint = getPoint(points[i - 1]);
22704 nextPoint = getPoint(points[i + 1]);
22705 }
22706 }
22707 var v = sub$1([], nextPoint, prevPoint);
22708 scale$2(v, v, smooth);
22709 var d0 = distance(point, prevPoint);
22710 var d1 = distance(point, nextPoint);
22711 var sum = d0 + d1;
22712 if (sum !== 0) {
22713 d0 /= sum;
22714 d1 /= sum;
22715 }
22716 var v1 = scale$2([], v, -d0);
22717 var v2 = scale$2([], v, d1);
22718 var cp0 = add$2([], point, v1);
22719 var cp1 = add$2([], point, v2);
22720 if (hasConstraint) {
22721 max$1(cp0, cp0, min);
22722 min$1(cp0, cp0, max);
22723 max$1(cp1, cp1, min);
22724 min$1(cp1, cp1, max);
22725 }
22726 cps.push([cp0[0], cp0[1]]);
22727 cps.push([cp1[0], cp1[1]]);
22728 }
22729 if (isLoop) {
22730 cps.push(cps.shift());
22731 }
22732 return cps;
22733 }
22734 function catmullRom2bezier(pointList, z, constraint) {
22735 var isLoop = !!z;
22736 var controlPointList = smoothBezier(pointList, 0.4, isLoop, constraint);
22737 var len = pointList.length;
22738 var d1 = [];
22739 var cp1;
22740 var cp2;
22741 var p;
22742 for (var i = 0; i < len - 1; i++) {
22743 cp1 = controlPointList[i * 2];
22744 cp2 = controlPointList[i * 2 + 1];
22745 p = pointList[i + 1];
22746 d1.push(['C', cp1[0], cp1[1], cp2[0], cp2[1], p.x, p.y]);
22747 }
22748 if (isLoop) {
22749 cp1 = controlPointList[len];
22750 cp2 = controlPointList[len + 1];
22751 p = pointList[0];
22752 d1.push(['C', cp1[0], cp1[1], cp2[0], cp2[1], p.x, p.y]);
22753 }
22754 return d1;
22755 }
22756
22757 var smooth = /*#__PURE__*/Object.freeze({
22758 __proto__: null,
22759 smooth: catmullRom2bezier
22760 });
22761
22762 var SmoothPolyline = /** @class */function (_super) {
22763 __extends(SmoothPolyline, _super);
22764 function SmoothPolyline(config) {
22765 var _this = _super.call(this, config) || this;
22766 _this.updatePath();
22767 return _this;
22768 }
22769 SmoothPolyline.prototype.setAttribute = function (name, value, force) {
22770 _super.prototype.setAttribute.call(this, name, value, force);
22771 if (['smooth', 'points', 'step'].indexOf(name) > -1) {
22772 this.updatePath();
22773 }
22774 };
22775 SmoothPolyline.prototype.updatePath = function () {
22776 var _a = this.parsedStyle,
22777 smooth$1 = _a.smooth,
22778 points = _a.points,
22779 step = _a.step;
22780 var pos = points.points;
22781 var d = [['M', pos[0][0], pos[0][1]]];
22782 if (smooth$1) {
22783 var constaint = [[0, 0], [1, 1]];
22784 var sps = catmullRom2bezier(pos.map(function (d) {
22785 return {
22786 x: d[0],
22787 y: d[1]
22788 };
22789 }), false, constaint);
22790 for (var i = 0, n = sps.length; i < n; i++) {
22791 var sp = sps[i];
22792 d.push(['C', sp[1], sp[2], sp[3], sp[4], sp[5], sp[6]]);
22793 }
22794 } else if (step) {
22795 var i = void 0;
22796 var l = void 0;
22797 switch (step) {
22798 case "start":
22799 for (i = 1, l = pos.length; i < l; i++) {
22800 var x = pos[i - 1][0];
22801 d.push(['L', x, pos[i - 1][1]]);
22802 d.push(['L', x, pos[i][1]]);
22803 d.push(['L', pos[i][0], pos[i][1]]);
22804 }
22805 break;
22806 case "middle":
22807 for (i = 1, l = pos.length; i < l; i++) {
22808 var x = (pos[i][0] + pos[i - 1][0]) / 2;
22809 d.push(['L', x, pos[i - 1][1]]);
22810 d.push(['L', x, pos[i][1]]);
22811 d.push(['L', pos[i][0], pos[i][1]]);
22812 }
22813 break;
22814 case "end":
22815 for (i = 1, l = pos.length; i < l; i++) {
22816 var x = pos[i][0];
22817 d.push(['L', x, pos[i - 1][1]]);
22818 d.push(['L', x, pos[i][1]]);
22819 d.push(['L', pos[i][0], pos[i][1]]);
22820 }
22821 break;
22822 }
22823 } else {
22824 var i = void 0;
22825 var l = void 0;
22826 for (i = 1, l = pos.length - 1; i < l; i++) {
22827 d.push(['L', pos[i][0], pos[i][1]]);
22828 }
22829 d.push(['L', pos[l][0], pos[l][1]]);
22830 }
22831 _super.prototype.setAttribute.call(this, 'path', d);
22832 };
22833 SmoothPolyline.tag = 'smooth-polyline';
22834 return SmoothPolyline;
22835 }(Path);
22836
22837 var Gesture = /** @class */function () {
22838 function Gesture(element) {
22839 this.el = element;
22840 }
22841 Gesture.prototype.on = function (eventName, listener) {
22842 if (!eventName) return;
22843 var el = this.el;
22844 el.addEventListener(eventName, listener);
22845 };
22846 Gesture.prototype.off = function (eventName, listener) {
22847 if (!eventName) return;
22848 var el = this.el;
22849 el.removeEventListener(eventName, listener);
22850 };
22851 return Gesture;
22852 }();
22853
22854 var SHAPE_TAG = {};
22855 /**
22856 * 注册新的标签
22857 */
22858 var registerTag = function registerTag(name, ShapeConstructor) {
22859 SHAPE_TAG[name] = ShapeConstructor;
22860 };
22861 var getTag = function getTag(type) {
22862 return SHAPE_TAG[type];
22863 };
22864
22865 var EVENT_LIST = [['click', 'onClick'], ['touchstart', 'onTouchStart'], ['touchmove', 'onTouchMove'], ['touchend', 'onTouchEnd'], ['touchendoutside', 'onTouchEndOutside'],
22866 // drage 相关
22867 ['dragenter', 'onDragEnter'], ['dragleave', 'onDragLeave'], ['dragover', 'onDragOver'], ['drop', 'onDrop'], ['dragstart', 'onDragStart'], ['drag', 'onDrag'], ['dragend', 'onDragEnd'],
22868 // pan
22869 ['panstart', 'onPanStart'], ['pan', 'onPan'], ['panend', 'onPanEnd'],
22870 // press
22871 ['pressstart', 'onPressStart'], ['press', 'onPress'], ['pressend', 'onPressEnd'],
22872 // swipe
22873 ['swipe', 'onSwipe'],
22874 // pinch
22875 ['pinchstart', 'onPinchStart'], ['pinch', 'onPinch'], ['pinchend', 'onPinchEnd']];
22876 // 默认标签
22877 var TagElements = [['group', Rect], ['text', Text], ['circle', Circle], ['path', Path], ['ellipse', Ellipse], ['rect', Rect], ['image', Image], ['line', Line], ['polyline', SmoothPolyline], ['polygon', Polygon], ['arc', Arc], ['marker', Marker], ['sector', Sector]];
22878 TagElements.map(function (_a) {
22879 var type = _a[0],
22880 ShapeClass = _a[1];
22881 registerTag(type, ShapeClass);
22882 });
22883 // 注册 css 属性,不能注册已有属性,比如 r width等
22884 var SECTOR_CSS_PROPERTY = [{
22885 name: 'r0',
22886 inherits: false,
22887 interpolable: true,
22888 syntax: PropertySyntax.LENGTH_PERCENTAGE
22889 }, {
22890 name: 'startAngle',
22891 inherits: false,
22892 interpolable: true,
22893 syntax: PropertySyntax.ANGLE
22894 }, {
22895 name: 'endAngle',
22896 inherits: false,
22897 interpolable: true,
22898 syntax: PropertySyntax.ANGLE
22899 }];
22900 SECTOR_CSS_PROPERTY.forEach(function (property) {
22901 CSS.registerProperty(property);
22902 });
22903 function createShape(type, props) {
22904 if (!type) return null;
22905 var ShapeClass = getTag(type);
22906 if (!ShapeClass) return null;
22907 // const result = checkCSSRule(type, originStyle);
22908 var shape = new ShapeClass(props);
22909 // @ts-ignore
22910 shape.gesture = addEvent(shape, props);
22911 return shape;
22912 }
22913 function updateShape(shape, props, lastProps) {
22914 // @ts-ignore
22915 var gesture = shape.gesture;
22916 // 如果 shape 上存在 gesture,说明是 jsx 标签创建的元素,才需要更新事件
22917 if (gesture) {
22918 // 先清除上次 props 绑定的事件
22919 EVENT_LIST.forEach(function (_a) {
22920 var eventName = _a[0],
22921 handlerName = _a[1];
22922 if (!lastProps[handlerName]) return;
22923 gesture.off(eventName, lastProps[handlerName]);
22924 });
22925 // 绑定最新的事件
22926 EVENT_LIST.forEach(function (_a) {
22927 var eventName = _a[0],
22928 handlerName = _a[1];
22929 if (!props[handlerName]) return;
22930 gesture.on(eventName, props[handlerName]);
22931 });
22932 }
22933 return shape;
22934 }
22935 function addEvent(shape, props) {
22936 var gesture = new Gesture(shape);
22937 EVENT_LIST.forEach(function (_a) {
22938 var eventName = _a[0],
22939 handlerName = _a[1];
22940 if (!props[handlerName]) return;
22941 gesture.on(eventName, props[handlerName]);
22942 });
22943 return gesture;
22944 }
22945
22946 function _typeof(o) {
22947 "@babel/helpers - typeof";
22948
22949 return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
22950 return typeof o;
22951 } : function (o) {
22952 return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
22953 }, _typeof(o);
22954 }
22955
22956 function objToString(obj) {
22957 return Object.prototype.toString.call(obj);
22958 }
22959 function objectKeys(obj) {
22960 return Object.keys(obj);
22961 }
22962 function equal(a, b) {
22963 if (a === b) return true;
22964 if (_typeof(a) !== _typeof(b)) {
22965 return false;
22966 }
22967 // null 和 undefined
22968 if (a == null || b == null) {
22969 return false;
22970 }
22971 // 特殊处理NaN
22972 if (Number.isNaN(a) && Number.isNaN(b)) {
22973 return true;
22974 }
22975 if (objToString(a) !== objToString(b)) {
22976 return false;
22977 }
22978 // 函数不相等,也认为不同
22979 if (isFunction(a)) {
22980 return false;
22981 }
22982 // 值类型,Number String Boolean
22983 if (_typeof(a) !== 'object') {
22984 return false;
22985 }
22986 if (isArray(a)) {
22987 if (a.length !== b.length) {
22988 return false;
22989 }
22990 for (var i = a.length - 1; i >= 0; i--) {
22991 if (!equal(a[i], b[i])) {
22992 return false;
22993 }
22994 }
22995 return true;
22996 }
22997 if (!isPlainObject(a)) {
22998 return false;
22999 }
23000 var ka = objectKeys(a);
23001 var kb = objectKeys(b);
23002 // having the same number of owned properties (keys incorporates hasOwnProperty)
23003 if (ka.length !== kb.length) {
23004 return false;
23005 }
23006 // the same set of keys (although not necessarily the same order),
23007 ka.sort();
23008 kb.sort();
23009 // ~~~cheap key test
23010 for (var i = ka.length - 1; i >= 0; i--) {
23011 if (ka[i] != kb[i]) {
23012 return false;
23013 }
23014 }
23015 // equivalent values for every corresponding key, and ~~~possibly expensive deep test
23016 for (var i = ka.length - 1; i >= 0; i--) {
23017 var key = ka[i];
23018 if (!equal(a[key], b[key])) {
23019 return false;
23020 }
23021 }
23022 return true;
23023 }
23024
23025 var FunctionComponent = 0;
23026 var ClassComponent = 1;
23027 var Shape$1 = 2;
23028 function getWorkTag(type) {
23029 if (isString(type)) {
23030 return Shape$1;
23031 }
23032 if (type.prototype && type.prototype.isF2Component) {
23033 return ClassComponent;
23034 }
23035 return FunctionComponent;
23036 }
23037
23038 // 查找 transform 最近的 shape 元素
23039 function findClosestShapeNode(vNode) {
23040 var tag = vNode.tag,
23041 children = vNode.children;
23042 if (tag === Shape$1) {
23043 return vNode;
23044 }
23045 var shapeNode;
23046 Children.map(children, function (child) {
23047 if (shapeNode) return;
23048 shapeNode = findClosestShapeNode(child);
23049 });
23050 return shapeNode;
23051 }
23052
23053 var eventemitter3$1 = createCommonjsModule(function (module) {
23054
23055 var has = Object.prototype.hasOwnProperty
23056 , prefix = '~';
23057
23058 /**
23059 * Constructor to create a storage for our `EE` objects.
23060 * An `Events` instance is a plain object whose properties are event names.
23061 *
23062 * @constructor
23063 * @private
23064 */
23065 function Events() {}
23066
23067 //
23068 // We try to not inherit from `Object.prototype`. In some engines creating an
23069 // instance in this way is faster than calling `Object.create(null)` directly.
23070 // If `Object.create(null)` is not supported we prefix the event names with a
23071 // character to make sure that the built-in object properties are not
23072 // overridden or used as an attack vector.
23073 //
23074 if (Object.create) {
23075 Events.prototype = Object.create(null);
23076
23077 //
23078 // This hack is needed because the `__proto__` property is still inherited in
23079 // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.
23080 //
23081 if (!new Events().__proto__) prefix = false;
23082 }
23083
23084 /**
23085 * Representation of a single event listener.
23086 *
23087 * @param {Function} fn The listener function.
23088 * @param {*} context The context to invoke the listener with.
23089 * @param {Boolean} [once=false] Specify if the listener is a one-time listener.
23090 * @constructor
23091 * @private
23092 */
23093 function EE(fn, context, once) {
23094 this.fn = fn;
23095 this.context = context;
23096 this.once = once || false;
23097 }
23098
23099 /**
23100 * Add a listener for a given event.
23101 *
23102 * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
23103 * @param {(String|Symbol)} event The event name.
23104 * @param {Function} fn The listener function.
23105 * @param {*} context The context to invoke the listener with.
23106 * @param {Boolean} once Specify if the listener is a one-time listener.
23107 * @returns {EventEmitter}
23108 * @private
23109 */
23110 function addListener(emitter, event, fn, context, once) {
23111 if (typeof fn !== 'function') {
23112 throw new TypeError('The listener must be a function');
23113 }
23114
23115 var listener = new EE(fn, context || emitter, once)
23116 , evt = prefix ? prefix + event : event;
23117
23118 if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;
23119 else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);
23120 else emitter._events[evt] = [emitter._events[evt], listener];
23121
23122 return emitter;
23123 }
23124
23125 /**
23126 * Clear event by name.
23127 *
23128 * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
23129 * @param {(String|Symbol)} evt The Event name.
23130 * @private
23131 */
23132 function clearEvent(emitter, evt) {
23133 if (--emitter._eventsCount === 0) emitter._events = new Events();
23134 else delete emitter._events[evt];
23135 }
23136
23137 /**
23138 * Minimal `EventEmitter` interface that is molded against the Node.js
23139 * `EventEmitter` interface.
23140 *
23141 * @constructor
23142 * @public
23143 */
23144 function EventEmitter() {
23145 this._events = new Events();
23146 this._eventsCount = 0;
23147 }
23148
23149 /**
23150 * Return an array listing the events for which the emitter has registered
23151 * listeners.
23152 *
23153 * @returns {Array}
23154 * @public
23155 */
23156 EventEmitter.prototype.eventNames = function eventNames() {
23157 var names = []
23158 , events
23159 , name;
23160
23161 if (this._eventsCount === 0) return names;
23162
23163 for (name in (events = this._events)) {
23164 if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
23165 }
23166
23167 if (Object.getOwnPropertySymbols) {
23168 return names.concat(Object.getOwnPropertySymbols(events));
23169 }
23170
23171 return names;
23172 };
23173
23174 /**
23175 * Return the listeners registered for a given event.
23176 *
23177 * @param {(String|Symbol)} event The event name.
23178 * @returns {Array} The registered listeners.
23179 * @public
23180 */
23181 EventEmitter.prototype.listeners = function listeners(event) {
23182 var evt = prefix ? prefix + event : event
23183 , handlers = this._events[evt];
23184
23185 if (!handlers) return [];
23186 if (handlers.fn) return [handlers.fn];
23187
23188 for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {
23189 ee[i] = handlers[i].fn;
23190 }
23191
23192 return ee;
23193 };
23194
23195 /**
23196 * Return the number of listeners listening to a given event.
23197 *
23198 * @param {(String|Symbol)} event The event name.
23199 * @returns {Number} The number of listeners.
23200 * @public
23201 */
23202 EventEmitter.prototype.listenerCount = function listenerCount(event) {
23203 var evt = prefix ? prefix + event : event
23204 , listeners = this._events[evt];
23205
23206 if (!listeners) return 0;
23207 if (listeners.fn) return 1;
23208 return listeners.length;
23209 };
23210
23211 /**
23212 * Calls each of the listeners registered for a given event.
23213 *
23214 * @param {(String|Symbol)} event The event name.
23215 * @returns {Boolean} `true` if the event had listeners, else `false`.
23216 * @public
23217 */
23218 EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
23219 var evt = prefix ? prefix + event : event;
23220
23221 if (!this._events[evt]) return false;
23222
23223 var listeners = this._events[evt]
23224 , len = arguments.length
23225 , args
23226 , i;
23227
23228 if (listeners.fn) {
23229 if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);
23230
23231 switch (len) {
23232 case 1: return listeners.fn.call(listeners.context), true;
23233 case 2: return listeners.fn.call(listeners.context, a1), true;
23234 case 3: return listeners.fn.call(listeners.context, a1, a2), true;
23235 case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;
23236 case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
23237 case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
23238 }
23239
23240 for (i = 1, args = new Array(len -1); i < len; i++) {
23241 args[i - 1] = arguments[i];
23242 }
23243
23244 listeners.fn.apply(listeners.context, args);
23245 } else {
23246 var length = listeners.length
23247 , j;
23248
23249 for (i = 0; i < length; i++) {
23250 if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);
23251
23252 switch (len) {
23253 case 1: listeners[i].fn.call(listeners[i].context); break;
23254 case 2: listeners[i].fn.call(listeners[i].context, a1); break;
23255 case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;
23256 case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;
23257 default:
23258 if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {
23259 args[j - 1] = arguments[j];
23260 }
23261
23262 listeners[i].fn.apply(listeners[i].context, args);
23263 }
23264 }
23265 }
23266
23267 return true;
23268 };
23269
23270 /**
23271 * Add a listener for a given event.
23272 *
23273 * @param {(String|Symbol)} event The event name.
23274 * @param {Function} fn The listener function.
23275 * @param {*} [context=this] The context to invoke the listener with.
23276 * @returns {EventEmitter} `this`.
23277 * @public
23278 */
23279 EventEmitter.prototype.on = function on(event, fn, context) {
23280 return addListener(this, event, fn, context, false);
23281 };
23282
23283 /**
23284 * Add a one-time listener for a given event.
23285 *
23286 * @param {(String|Symbol)} event The event name.
23287 * @param {Function} fn The listener function.
23288 * @param {*} [context=this] The context to invoke the listener with.
23289 * @returns {EventEmitter} `this`.
23290 * @public
23291 */
23292 EventEmitter.prototype.once = function once(event, fn, context) {
23293 return addListener(this, event, fn, context, true);
23294 };
23295
23296 /**
23297 * Remove the listeners of a given event.
23298 *
23299 * @param {(String|Symbol)} event The event name.
23300 * @param {Function} fn Only remove the listeners that match this function.
23301 * @param {*} context Only remove the listeners that have this context.
23302 * @param {Boolean} once Only remove one-time listeners.
23303 * @returns {EventEmitter} `this`.
23304 * @public
23305 */
23306 EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
23307 var evt = prefix ? prefix + event : event;
23308
23309 if (!this._events[evt]) return this;
23310 if (!fn) {
23311 clearEvent(this, evt);
23312 return this;
23313 }
23314
23315 var listeners = this._events[evt];
23316
23317 if (listeners.fn) {
23318 if (
23319 listeners.fn === fn &&
23320 (!once || listeners.once) &&
23321 (!context || listeners.context === context)
23322 ) {
23323 clearEvent(this, evt);
23324 }
23325 } else {
23326 for (var i = 0, events = [], length = listeners.length; i < length; i++) {
23327 if (
23328 listeners[i].fn !== fn ||
23329 (once && !listeners[i].once) ||
23330 (context && listeners[i].context !== context)
23331 ) {
23332 events.push(listeners[i]);
23333 }
23334 }
23335
23336 //
23337 // Reset the array, or remove it completely if we have no more listeners.
23338 //
23339 if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;
23340 else clearEvent(this, evt);
23341 }
23342
23343 return this;
23344 };
23345
23346 /**
23347 * Remove all listeners, or those of the specified event.
23348 *
23349 * @param {(String|Symbol)} [event] The event name.
23350 * @returns {EventEmitter} `this`.
23351 * @public
23352 */
23353 EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
23354 var evt;
23355
23356 if (event) {
23357 evt = prefix ? prefix + event : event;
23358 if (this._events[evt]) clearEvent(this, evt);
23359 } else {
23360 this._events = new Events();
23361 this._eventsCount = 0;
23362 }
23363
23364 return this;
23365 };
23366
23367 //
23368 // Alias methods names because people roll like that.
23369 //
23370 EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
23371 EventEmitter.prototype.addListener = EventEmitter.prototype.on;
23372
23373 //
23374 // Expose the prefix.
23375 //
23376 EventEmitter.prefixed = prefix;
23377
23378 //
23379 // Allow `EventEmitter` to be imported as module namespace.
23380 //
23381 EventEmitter.EventEmitter = EventEmitter;
23382
23383 //
23384 // Expose the module.
23385 //
23386 {
23387 module.exports = EventEmitter;
23388 }
23389 });
23390
23391 function applyStyle(shape, style) {
23392 if (!style) return;
23393 Object.keys(style).forEach(function (key) {
23394 // 特殊处理 clip 和 offset
23395 if (key === 'clip' || key === 'offset') {
23396 var effect = style[key];
23397 // value 为 ref
23398 if (isDisplayObject(effect === null || effect === void 0 ? void 0 : effect.current)) {
23399 shape.setAttribute("".concat(key, "Path"), effect.current);
23400 return;
23401 }
23402 var effectConfig = isFunction(effect) ? effect(style) : effect;
23403 if (effectConfig) {
23404 var type = effectConfig.type,
23405 style_1 = effectConfig.style;
23406 var effectShape = createShape(type, {
23407 style: style_1
23408 });
23409 shape.setAttribute("".concat(key, "Path"), effectShape);
23410 }
23411 } else {
23412 shape.setAttribute(key, style[key]);
23413 }
23414 });
23415 }
23416
23417 var Animator = /** @class */function (_super) {
23418 __extends(Animator, _super);
23419 function Animator() {
23420 return _super.call(this) || this;
23421 }
23422 Animator.prototype.animate = function (shape, start, end, effect) {
23423 this.shape = shape;
23424 this.start = start;
23425 this.end = end;
23426 this.effect = effect;
23427 };
23428 // 首次播放
23429 Animator.prototype.run = function () {
23430 var _a = this,
23431 vNode = _a.vNode,
23432 shape = _a.shape,
23433 start = _a.start,
23434 end = _a.end,
23435 effect = _a.effect,
23436 children = _a.children;
23437 var animations = [];
23438 if (effect) {
23439 var _b = effect.property,
23440 property = _b === void 0 ? [] : _b,
23441 easing = effect.easing,
23442 duration = effect.duration,
23443 delay = effect.delay,
23444 iterations = effect.iterations,
23445 clip = effect.clip,
23446 _c = effect.direction,
23447 direction = _c === void 0 ? 'normal' : _c,
23448 onFrame_1 = effect.onFrame,
23449 onEnd_1 = effect.onEnd;
23450 // shape 动画
23451 if ((property.length || onFrame_1) && duration > 0) {
23452 // 应用样式
23453 var style = __assign(__assign({}, omit(start, property)), omit(end, property));
23454 applyStyle(shape, style);
23455 // 开始帧
23456 var keyframeStart = property.reduce(function (prev, cur) {
23457 prev[cur] = start[cur];
23458 return prev;
23459 }, {});
23460 // 结束帧
23461 var keyframeEnd = pick(end, property);
23462 var animation = shape.animate([keyframeStart, keyframeEnd], {
23463 fill: 'both',
23464 easing: easing,
23465 duration: duration,
23466 delay: delay,
23467 iterations: iterations,
23468 direction: direction
23469 });
23470 if (animation) {
23471 var onframe_1 = onFrame_1 ? function (e) {
23472 var animationTarget = e.target;
23473 var effect = animationTarget.effect;
23474 var timing = effect.getTiming();
23475 var duration = timing.duration;
23476 var delay = timing.delay;
23477 var t = e.currentTime > delay ? (e.currentTime - delay) / duration : 0;
23478 var shape = effect.target;
23479 // 动画的一些上下文信息
23480 var context = {
23481 t: t,
23482 start: start,
23483 end: end,
23484 animation: animationTarget,
23485 shape: shape
23486 };
23487 applyStyle(shape, onFrame_1(t, context));
23488 } : null;
23489 animation.onframe = onframe_1;
23490 animation.onfinish = onframe_1 || onEnd_1 ? function (e) {
23491 onframe_1 && onframe_1(e);
23492 onEnd_1 && onEnd_1(e);
23493 } : null;
23494 // 过滤无限循环的动画
23495 if (iterations !== Infinity) {
23496 animations.push(animation);
23497 }
23498 } else {
23499 // 如果没有执行动画,直接应用结束样式
23500 applyStyle(shape, end);
23501 }
23502 } else {
23503 // 直接应用结束样式
23504 applyStyle(shape, end);
23505 }
23506 // clip 动画
23507 if (clip) {
23508 var clipConfig = isFunction(clip) ? clip(end) : clip;
23509 if (clipConfig) {
23510 var clipType = clipConfig.type,
23511 _d = clipConfig.deleteAfterComplete,
23512 deleteAfterComplete = _d === void 0 ? true : _d,
23513 clipStyle = clipConfig.style,
23514 _e = clipConfig.property,
23515 clipProperty = _e === void 0 ? [] : _e,
23516 clipEasing = clipConfig.easing,
23517 clipDuration = clipConfig.duration,
23518 clipDelay = clipConfig.delay,
23519 clipIterations = clipConfig.iterations,
23520 clipStart = clipConfig.start,
23521 clipEnd = clipConfig.end,
23522 clipDirection = clipConfig.direction;
23523 if (clipProperty.length && (clipDuration || duration) > 0) {
23524 var clipStartStyle_1 = __assign(__assign({}, clipStyle), clipStart);
23525 var clipEndStyle = __assign(__assign({}, clipStyle), clipEnd);
23526 // 开始帧
23527 var clipKeyframeStart = clipProperty.reduce(function (prev, cur) {
23528 prev[cur] = clipStartStyle_1[cur];
23529 return prev;
23530 }, {});
23531 // 结束帧
23532 var clipKeyframeEnd = pick(clipEndStyle, clipProperty);
23533 var clipShape_1 = createShape(clipType, {
23534 style: clipStartStyle_1
23535 });
23536 shape.setAttribute('clipPath', clipShape_1);
23537 // g 中 clip 为全局,且如果要在 clip上加动画,需要手动加到canvas上
23538 shape.ownerDocument.documentElement.appendChild(clipShape_1);
23539 var clipAnimation = clipShape_1.animate([clipKeyframeStart, clipKeyframeEnd], {
23540 fill: 'both',
23541 easing: clipEasing || easing,
23542 duration: clipDuration || duration,
23543 delay: clipDelay || delay,
23544 iterations: clipIterations || iterations,
23545 direction: clipDirection || direction
23546 });
23547 // 过滤无限循环的动画
23548 if (clipAnimation) {
23549 var clipFinished = clipAnimation.finished;
23550 deleteAfterComplete && clipFinished.then(function () {
23551 // 删掉 clip
23552 shape.setAttribute('clipPath', null);
23553 clipShape_1.destroy();
23554 });
23555 if ((clipIterations || iterations) !== Infinity) {
23556 animations.push(clipAnimation);
23557 }
23558 } else {
23559 // 没有动画,直接删掉 clip
23560 shape.setAttribute('clipPath', null);
23561 clipShape_1.destroy();
23562 }
23563 }
23564 }
23565 }
23566 }
23567 if (children && children.length) {
23568 children.forEach(function (child) {
23569 if (!child) return;
23570 var childAnimator = child.run();
23571 if (childAnimator) {
23572 animations.push.apply(animations, childAnimator);
23573 }
23574 });
23575 }
23576 this.animations = animations;
23577 // TODO:这段代码放这个位置感觉挺奇怪,看看是否有更合适的地方
23578 if (vNode) {
23579 var component = vNode.component;
23580 if (vNode && vNode.component) {
23581 // @ts-ignore
23582 component.animationWillPlay && component.animationWillPlay();
23583 }
23584 }
23585 this.endEmit(animations);
23586 return animations;
23587 };
23588 Animator.prototype.play = function () {
23589 var animations = this.animations;
23590 if (!animations || !animations.length) return;
23591 animations.forEach(function (d) {
23592 d.play();
23593 });
23594 };
23595 Animator.prototype.pause = function () {
23596 var animations = this.animations;
23597 if (!animations || !animations.length) return;
23598 animations.forEach(function (d) {
23599 d.pause();
23600 });
23601 };
23602 Animator.prototype.goTo = function (frame) {
23603 var animations = this.animations;
23604 if (!animations || !animations.length) return;
23605 animations.forEach(function (d) {
23606 d.currentTime = frame;
23607 });
23608 };
23609 Animator.prototype.finish = function () {
23610 var animations = this.animations;
23611 if (!animations || !animations.length) return;
23612 animations.forEach(function (d) {
23613 d.finish();
23614 });
23615 };
23616 Animator.prototype.setPlaybackRate = function (speed) {
23617 var animations = this.animations;
23618 if (!animations || !animations.length) return;
23619 animations.forEach(function (d) {
23620 d.playbackRate = speed;
23621 });
23622 };
23623 Animator.prototype.endEmit = function (animations) {
23624 var _this = this;
23625 if (!animations.length) {
23626 this.emit('end');
23627 return null;
23628 }
23629 var finished = Promise.all(animations.map(function (d) {
23630 return d.finished;
23631 }));
23632 finished.then(function () {
23633 _this.emit('end');
23634 });
23635 };
23636 Animator.prototype.reset = function (shape) {
23637 this.shape = shape;
23638 this.start = null;
23639 this.end = null;
23640 this.effect = null;
23641 this.children = null;
23642 };
23643 Animator.prototype.clone = function () {
23644 // 浅拷贝
23645 var animator = new Animator();
23646 animator.shape = this.shape;
23647 animator.start = this.start;
23648 animator.end = this.end;
23649 animator.effect = this.effect;
23650 animator.children = this.children;
23651 animator.vNode = this.vNode;
23652 return animator;
23653 };
23654 return Animator;
23655 }(eventemitter3$1);
23656
23657 function findAllShapeNode(vNode) {
23658 var shapeNodes = [];
23659 Children.map(vNode, function (node) {
23660 if (!node) return;
23661 var tag = node.tag,
23662 type = node.type,
23663 children = node.children;
23664 if (tag === Shape$1 && type !== 'group') {
23665 shapeNodes.push(node);
23666 }
23667 if (children) {
23668 shapeNodes.push.apply(shapeNodes, findAllShapeNode(children));
23669 }
23670 });
23671 return shapeNodes;
23672 }
23673 function morphShape(lastNode, nextNode, animator) {
23674 var nextProps = nextNode.props,
23675 nextShape = nextNode.shape,
23676 nextStyle = nextNode.style;
23677 var lastShape = lastNode.shape,
23678 lastStyle = lastNode.style,
23679 lastAnimation = lastNode.animator;
23680 // 形变动画之前先把原 shape 销毁
23681 lastShape.destroy();
23682 var animate = nextProps.animate,
23683 animation = nextProps.animation;
23684 var animationEffect = animation ? animation.update : null;
23685 if (animate === false || !animationEffect) {
23686 return animator;
23687 }
23688 animator = animator || new Animator();
23689 // shape 形变
23690 var start = animationEffect.start,
23691 end = animationEffect.end,
23692 _a = animationEffect.property,
23693 property = _a === void 0 ? [] : _a;
23694 var nextParsedStyle = nextShape.parsedStyle;
23695 var lastParsedStyle = lastShape.parsedStyle;
23696 var lastPath = convertToPath(lastShape);
23697 var nextPath = convertToPath(nextShape);
23698 var startStyle = __assign(__assign(__assign({}, lastStyle), start), {
23699 path: lastPath
23700 });
23701 var endStyle = __assign(__assign(__assign({}, nextStyle), end), {
23702 path: nextPath
23703 });
23704 var pathShape = createShape('path', {
23705 style: __assign(__assign({}, startStyle), {
23706 path: ''
23707 })
23708 });
23709 // 形变双方都有的属性才能动画
23710 var animateProperty = property.filter(function (key) {
23711 return nextParsedStyle.hasOwnProperty(key) && lastParsedStyle.hasOwnProperty(key);
23712 }).concat('path');
23713 animator.animate(pathShape, startStyle, endStyle, __assign(__assign({}, animationEffect), {
23714 property: animateProperty
23715 }));
23716 var timeline = (nextNode === null || nextNode === void 0 ? void 0 : nextNode.context).timeline;
23717 timeline && timeline.delete(lastAnimation);
23718 animator.once('end', function () {
23719 if (nextShape.destroyed) {
23720 return;
23721 }
23722 applyStyle(nextShape, endStyle);
23723 pathShape.replaceWith(nextShape);
23724 });
23725 return animator;
23726 }
23727 function appearAnimation(vNode) {
23728 return Children.map(vNode, function (node) {
23729 if (!node) return;
23730 var tag = node.tag,
23731 shape = node.shape,
23732 style = node.style,
23733 children = node.children,
23734 animate = node.animate,
23735 props = node.props,
23736 animator = node.animator;
23737 animator.reset(shape);
23738 // 有叶子节点,先执行叶子节点
23739 animator.children = children ? createAnimation(node, children, null) : null;
23740 // 不需要执行动画
23741 if (animate === false || tag !== Shape$1) {
23742 applyStyle(shape, style);
23743 return animator;
23744 }
23745 var animation = props.animation;
23746 var animationEffect = animation ? animation.appear : null;
23747 if (!animationEffect) {
23748 // 没有动画直接应用样式
23749 applyStyle(shape, style);
23750 return animator;
23751 }
23752 var _a = animationEffect.start,
23753 start = _a === void 0 ? {} : _a,
23754 end = animationEffect.end;
23755 var endStyle = __assign(__assign({}, style), end);
23756 animator.animate(shape, start, endStyle, animationEffect);
23757 return animator;
23758 });
23759 }
23760 function updateAnimation(nextNode, lastNode) {
23761 var nextTag = nextNode.tag,
23762 nextType = nextNode.type,
23763 nextStyle = nextNode.style,
23764 nextChildren = nextNode.children,
23765 nextProps = nextNode.props,
23766 nextShape = nextNode.shape,
23767 animator = nextNode.animator,
23768 animate = nextNode.animate;
23769 var lastTag = lastNode.tag,
23770 lastType = lastNode.type,
23771 lastStyle = lastNode.style,
23772 lastChildren = lastNode.children,
23773 lastShape = lastNode.shape;
23774 animator.reset(nextShape);
23775 // 先处理叶子节点
23776 animator.children = createAnimation(nextNode, nextChildren, lastChildren);
23777 var animation = nextProps.animation;
23778 var animationEffect = animation ? animation.update : null;
23779 // 类型相同
23780 if (nextType === lastType) {
23781 // 清除之前的样式
23782 var resetStyle = lastStyle ? Object.keys(lastStyle).reduce(function (prev, cur) {
23783 prev[cur] = '';
23784 return prev;
23785 }, {}) : null;
23786 // 需要更新的样式
23787 var style = __assign(__assign({}, resetStyle), nextStyle);
23788 // 组件,直接更新
23789 if (nextTag !== Shape$1) {
23790 applyStyle(nextShape, style);
23791 return animator;
23792 }
23793 // 样式无改变,无更新
23794 if (isEqual(nextStyle, lastStyle)) {
23795 return animator;
23796 }
23797 // 没有动画直接应用样式
23798 if (animate === false || !animationEffect) {
23799 applyStyle(nextShape, style);
23800 return animator;
23801 }
23802 var start = animationEffect.start,
23803 end = animationEffect.end;
23804 var startStyle = __assign(__assign({}, lastStyle), start);
23805 var endStyle = __assign(__assign({}, style), end);
23806 animator.animate(nextShape, startStyle, endStyle, animationEffect);
23807 return animator;
23808 }
23809 // 无法处理形变
23810 if (nextTag !== Shape$1 || lastTag !== Shape$1) {
23811 lastShape.destroy();
23812 return animator;
23813 }
23814 // 从 shape 到 group
23815 if (nextType === 'group') {
23816 var shapeNodes = findAllShapeNode(nextNode.children);
23817 return shapeNodes.map(function (node) {
23818 return morphShape(lastNode, node);
23819 });
23820 }
23821 // 从 group 到 shape
23822 if (lastType === 'group') {
23823 var shapeNodes = findAllShapeNode(lastNode.children);
23824 return shapeNodes.map(function (node) {
23825 return morphShape(node, nextNode);
23826 });
23827 }
23828 // 没有动画直接应用样式
23829 if (animate === false || !animationEffect) {
23830 applyStyle(nextShape, nextStyle);
23831 return animator;
23832 }
23833 return morphShape(lastNode, nextNode, animator);
23834 }
23835 function destroyAnimation(node) {
23836 return Children.map(node, function (vNode) {
23837 if (!vNode) return null;
23838 var tag = vNode.tag,
23839 shape = vNode.shape,
23840 children = vNode.children,
23841 animate = vNode.animate,
23842 style = vNode.style,
23843 props = vNode.props,
23844 animator = vNode.animator,
23845 context = vNode.context;
23846 var timeline = context.timeline;
23847 if (shape.destroyed) {
23848 return null;
23849 }
23850 // 重置
23851 animator.reset(shape);
23852 // 先处理叶子节点
23853 var childrenAnimation = children ? Children.toArray(children).map(function (child) {
23854 return destroyAnimation(child);
23855 }).filter(Boolean) : null;
23856 // 不需要动画直接删除
23857 if (animate === false) {
23858 shape.destroy();
23859 return animator;
23860 }
23861 var animation = props.animation;
23862 var animationEffect = animation ? animation.leave : null;
23863 // 没有叶子节点的动画, 直接删除
23864 if (!(childrenAnimation && childrenAnimation.length) && !animationEffect) {
23865 shape.destroy();
23866 return animator;
23867 }
23868 animator.children = childrenAnimation;
23869 // 图形有动画
23870 if (animationEffect && tag === Shape$1) {
23871 var start = animationEffect.start,
23872 _a = animationEffect.end,
23873 end = _a === void 0 ? {} : _a;
23874 var startStyle = __assign(__assign({}, style), start);
23875 var endStyle = end;
23876 animator.animate(shape, startStyle, endStyle, animationEffect);
23877 timeline && timeline.delete(animator.animations);
23878 }
23879 // 动画结束后,删除图形(包括子元素动画)
23880 animator.once('end', function () {
23881 shape.destroy();
23882 });
23883 return animator;
23884 });
23885 }
23886 function createAnimator(nextNode, lastNode) {
23887 if (!nextNode && !lastNode) {
23888 return null;
23889 }
23890 // delete 动画
23891 if (!nextNode && lastNode) {
23892 return destroyAnimation(lastNode);
23893 }
23894 // 如果有 transform 则从 transform 比
23895 var transform = nextNode.transform;
23896 if (transform) {
23897 var closestShapeNode = findClosestShapeNode(nextNode);
23898 nextNode.transform = null;
23899 closestShapeNode.transform = transform;
23900 }
23901 if (nextNode.transform) {
23902 if (!lastNode) {
23903 return updateAnimation(nextNode, nextNode.transform);
23904 }
23905 return [updateAnimation(nextNode, nextNode.transform), destroyAnimation(lastNode)];
23906 }
23907 // appear 动画
23908 if (nextNode && !lastNode) {
23909 return appearAnimation(nextNode);
23910 }
23911 // update 动画
23912 return updateAnimation(nextNode, lastNode);
23913 }
23914 function insertShape(parent, shape, nextSibling) {
23915 if (nextSibling) {
23916 parent.insertBefore(shape, nextSibling);
23917 } else {
23918 parent.appendChild(shape);
23919 }
23920 }
23921 // 处理 children 的动画
23922 function createAnimation(parent, nextChildren, lastChildren) {
23923 if (!nextChildren && !lastChildren) {
23924 return [];
23925 }
23926 var parentShape = parent.shape;
23927 // 上一个处理的元素
23928 var prevSibling;
23929 var childrenAnimator = [];
23930 Children.compare(nextChildren, lastChildren, function (nextNode, lastNode) {
23931 // shape 层才执行动画
23932 var animator = createAnimator(nextNode, lastNode);
23933 Children.map(animator, function (item) {
23934 if (!item) return;
23935 childrenAnimator.push(item);
23936 var shape = item.shape;
23937 if (!shape || shape.destroyed) return;
23938 var nextSibling;
23939 // 更新文档流
23940 if (!prevSibling) {
23941 nextSibling = parentShape.firstChild;
23942 } else {
23943 nextSibling = prevSibling.nextSibling;
23944 }
23945 if (nextSibling !== shape) {
23946 insertShape(parentShape, shape, nextSibling);
23947 }
23948 prevSibling = shape;
23949 });
23950 });
23951 return childrenAnimator;
23952 }
23953 function calAnimationTime(childrenAnimation, keyFrame, parentEffect) {
23954 if (!childrenAnimation) return {
23955 animators: null,
23956 time: 0
23957 };
23958 var animators = [];
23959 var time = 0;
23960 Children.map(childrenAnimation, function (item) {
23961 if (!item) return;
23962 var animator = item.clone();
23963 var vNode = animator.vNode,
23964 children = animator.children;
23965 var _a = keyFrame[vNode === null || vNode === void 0 ? void 0 : vNode.key] || {},
23966 duration = _a.duration,
23967 delay = _a.delay;
23968 var globalEffect = mix(parentEffect || {}, {
23969 duration: duration,
23970 delay: delay
23971 });
23972 var effect = __assign(__assign({}, animator.effect), globalEffect);
23973 animator.effect = effect;
23974 // computed time
23975 var _b = effect.duration,
23976 gDuration = _b === void 0 ? 0 : _b,
23977 _c = effect.delay,
23978 gDelay = _c === void 0 ? 0 : _c;
23979 var animUnits = calAnimationTime(children, keyFrame, globalEffect);
23980 time = Math.max(time, gDuration + gDelay, animUnits.time);
23981 animator.children = animUnits.animators;
23982 animators.push(animator);
23983 });
23984 return {
23985 animators: animators,
23986 time: time
23987 };
23988 }
23989
23990 var rect = (function (layout) {
23991 var left = layout.left,
23992 top = layout.top,
23993 width = layout.width,
23994 height = layout.height;
23995 return {
23996 x: left,
23997 y: top,
23998 width: width,
23999 height: height
24000 };
24001 });
24002
24003 var line = (function (layout) {
24004 var left = layout.left,
24005 top = layout.top,
24006 width = layout.width,
24007 height = layout.height;
24008 return {
24009 x1: left,
24010 y1: top,
24011 x2: left + width,
24012 y2: top + height
24013 };
24014 });
24015
24016 var text = (function (layout) {
24017 var height = layout.height,
24018 left = layout.left,
24019 top = layout.top;
24020 return {
24021 x: left,
24022 y: top + height / 2,
24023 // 通过middle + top 才能比较好的实现文本对齐
24024 textBaseline: 'middle'
24025 };
24026 });
24027
24028 var circle = (function (layout) {
24029 var left = layout.left,
24030 top = layout.top,
24031 width = layout.width;
24032 var r = width / 2;
24033 return {
24034 cx: left + r,
24035 cy: top + r,
24036 r: r
24037 };
24038 });
24039
24040 var marker = (function (layout) {
24041 var left = layout.left,
24042 top = layout.top,
24043 width = layout.width;
24044 var r = width / 2;
24045 return {
24046 x: left + r,
24047 y: top,
24048 radius: r
24049 };
24050 });
24051
24052 var map$2 = {
24053 rect: rect,
24054 line: line,
24055 text: text,
24056 circle: circle,
24057 marker: marker,
24058 group: rect
24059 };
24060 var getShapeAttrs = (function (type, layout) {
24061 if (!layout) return null;
24062 var fn = map$2[type] || rect;
24063 return fn(layout);
24064 });
24065
24066 /* eslint-disable */
24067 // @ts-nocheck
24068 // from css-layout
24069 var CSS_UNDEFINED;
24070 var CSS_DIRECTION_INHERIT = 'inherit';
24071 var CSS_DIRECTION_LTR = 'ltr';
24072 var CSS_DIRECTION_RTL = 'rtl';
24073 var CSS_FLEX_DIRECTION_ROW = 'row';
24074 var CSS_FLEX_DIRECTION_ROW_REVERSE = 'row-reverse';
24075 var CSS_FLEX_DIRECTION_COLUMN = 'column';
24076 var CSS_FLEX_DIRECTION_COLUMN_REVERSE = 'column-reverse';
24077 var CSS_JUSTIFY_FLEX_START = 'flex-start';
24078 var CSS_JUSTIFY_CENTER = 'center';
24079 var CSS_JUSTIFY_FLEX_END = 'flex-end';
24080 var CSS_JUSTIFY_SPACE_BETWEEN = 'space-between';
24081 var CSS_JUSTIFY_SPACE_AROUND = 'space-around';
24082 var CSS_ALIGN_FLEX_START = 'flex-start';
24083 var CSS_ALIGN_CENTER = 'center';
24084 var CSS_ALIGN_FLEX_END = 'flex-end';
24085 var CSS_ALIGN_STRETCH = 'stretch';
24086 var CSS_POSITION_RELATIVE = 'relative';
24087 var CSS_POSITION_ABSOLUTE = 'absolute';
24088 var leading = {
24089 row: 'left',
24090 'row-reverse': 'right',
24091 column: 'top',
24092 'column-reverse': 'bottom'
24093 };
24094 var trailing = {
24095 row: 'right',
24096 'row-reverse': 'left',
24097 column: 'bottom',
24098 'column-reverse': 'top'
24099 };
24100 var pos = {
24101 row: 'left',
24102 'row-reverse': 'right',
24103 column: 'top',
24104 'column-reverse': 'bottom'
24105 };
24106 var dim = {
24107 row: 'width',
24108 'row-reverse': 'width',
24109 column: 'height',
24110 'column-reverse': 'height'
24111 };
24112 // When transpiled to Java / C the node type has layout, children and style
24113 // properties. For the JavaScript version this function adds these properties
24114 // if they don't already exist.
24115 function fillNodes(node) {
24116 if (!node.layout || node.isDirty) {
24117 node.layout = {
24118 width: undefined,
24119 height: undefined,
24120 top: 0,
24121 left: 0,
24122 right: 0,
24123 bottom: 0
24124 };
24125 }
24126 if (!node.style) {
24127 node.style = {};
24128 }
24129 if (!node.children) {
24130 node.children = [];
24131 }
24132 node.children.forEach(fillNodes);
24133 return node;
24134 }
24135 function isUndefined$1(value) {
24136 return value === undefined;
24137 }
24138 function isRowDirection(flexDirection) {
24139 return flexDirection === CSS_FLEX_DIRECTION_ROW || flexDirection === CSS_FLEX_DIRECTION_ROW_REVERSE;
24140 }
24141 function isColumnDirection(flexDirection) {
24142 return flexDirection === CSS_FLEX_DIRECTION_COLUMN || flexDirection === CSS_FLEX_DIRECTION_COLUMN_REVERSE;
24143 }
24144 function getLeadingMargin(node, axis) {
24145 if (node.style.marginStart !== undefined && isRowDirection(axis)) {
24146 return node.style.marginStart;
24147 }
24148 var value = null;
24149 switch (axis) {
24150 case 'row':
24151 value = node.style.marginLeft;
24152 break;
24153 case 'row-reverse':
24154 value = node.style.marginRight;
24155 break;
24156 case 'column':
24157 value = node.style.marginTop;
24158 break;
24159 case 'column-reverse':
24160 value = node.style.marginBottom;
24161 break;
24162 }
24163 if (value !== undefined) {
24164 return value;
24165 }
24166 if (node.style.margin !== undefined) {
24167 return node.style.margin;
24168 }
24169 return 0;
24170 }
24171 function getTrailingMargin(node, axis) {
24172 if (node.style.marginEnd !== undefined && isRowDirection(axis)) {
24173 return node.style.marginEnd;
24174 }
24175 var value = null;
24176 switch (axis) {
24177 case 'row':
24178 value = node.style.marginRight;
24179 break;
24180 case 'row-reverse':
24181 value = node.style.marginLeft;
24182 break;
24183 case 'column':
24184 value = node.style.marginBottom;
24185 break;
24186 case 'column-reverse':
24187 value = node.style.marginTop;
24188 break;
24189 }
24190 if (value != null) {
24191 return value;
24192 }
24193 if (node.style.margin !== undefined) {
24194 return node.style.margin;
24195 }
24196 return 0;
24197 }
24198 function getLeadingPadding(node, axis) {
24199 if (node.style.paddingStart !== undefined && node.style.paddingStart >= 0 && isRowDirection(axis)) {
24200 return node.style.paddingStart;
24201 }
24202 var value = null;
24203 switch (axis) {
24204 case 'row':
24205 value = node.style.paddingLeft;
24206 break;
24207 case 'row-reverse':
24208 value = node.style.paddingRight;
24209 break;
24210 case 'column':
24211 value = node.style.paddingTop;
24212 break;
24213 case 'column-reverse':
24214 value = node.style.paddingBottom;
24215 break;
24216 }
24217 if (value != null && value >= 0) {
24218 return value;
24219 }
24220 if (node.style.padding !== undefined && node.style.padding >= 0) {
24221 return node.style.padding;
24222 }
24223 return 0;
24224 }
24225 function getTrailingPadding(node, axis) {
24226 if (node.style.paddingEnd !== undefined && node.style.paddingEnd >= 0 && isRowDirection(axis)) {
24227 return node.style.paddingEnd;
24228 }
24229 var value = null;
24230 switch (axis) {
24231 case 'row':
24232 value = node.style.paddingRight;
24233 break;
24234 case 'row-reverse':
24235 value = node.style.paddingLeft;
24236 break;
24237 case 'column':
24238 value = node.style.paddingBottom;
24239 break;
24240 case 'column-reverse':
24241 value = node.style.paddingTop;
24242 break;
24243 }
24244 if (value != null && value >= 0) {
24245 return value;
24246 }
24247 if (node.style.padding !== undefined && node.style.padding >= 0) {
24248 return node.style.padding;
24249 }
24250 return 0;
24251 }
24252 function getLeadingBorder(node, axis) {
24253 if (node.style.borderStartWidth !== undefined && node.style.borderStartWidth >= 0 && isRowDirection(axis)) {
24254 return node.style.borderStartWidth;
24255 }
24256 var value = null;
24257 switch (axis) {
24258 case 'row':
24259 value = node.style.borderLeftWidth;
24260 break;
24261 case 'row-reverse':
24262 value = node.style.borderRightWidth;
24263 break;
24264 case 'column':
24265 value = node.style.borderTopWidth;
24266 break;
24267 case 'column-reverse':
24268 value = node.style.borderBottomWidth;
24269 break;
24270 }
24271 if (value != null && value >= 0) {
24272 return value;
24273 }
24274 if (node.style.borderWidth !== undefined && node.style.borderWidth >= 0) {
24275 return node.style.borderWidth;
24276 }
24277 return 0;
24278 }
24279 function getTrailingBorder(node, axis) {
24280 if (node.style.borderEndWidth !== undefined && node.style.borderEndWidth >= 0 && isRowDirection(axis)) {
24281 return node.style.borderEndWidth;
24282 }
24283 var value = null;
24284 switch (axis) {
24285 case 'row':
24286 value = node.style.borderRightWidth;
24287 break;
24288 case 'row-reverse':
24289 value = node.style.borderLeftWidth;
24290 break;
24291 case 'column':
24292 value = node.style.borderBottomWidth;
24293 break;
24294 case 'column-reverse':
24295 value = node.style.borderTopWidth;
24296 break;
24297 }
24298 if (value != null && value >= 0) {
24299 return value;
24300 }
24301 if (node.style.borderWidth !== undefined && node.style.borderWidth >= 0) {
24302 return node.style.borderWidth;
24303 }
24304 return 0;
24305 }
24306 function getLeadingPaddingAndBorder(node, axis) {
24307 return getLeadingPadding(node, axis) + getLeadingBorder(node, axis);
24308 }
24309 function getTrailingPaddingAndBorder(node, axis) {
24310 return getTrailingPadding(node, axis) + getTrailingBorder(node, axis);
24311 }
24312 function getBorderAxis(node, axis) {
24313 return getLeadingBorder(node, axis) + getTrailingBorder(node, axis);
24314 }
24315 function getMarginAxis(node, axis) {
24316 return getLeadingMargin(node, axis) + getTrailingMargin(node, axis);
24317 }
24318 function getPaddingAndBorderAxis(node, axis) {
24319 return getLeadingPaddingAndBorder(node, axis) + getTrailingPaddingAndBorder(node, axis);
24320 }
24321 function getJustifyContent(node) {
24322 if (node.style.justifyContent) {
24323 return node.style.justifyContent;
24324 }
24325 return 'flex-start';
24326 }
24327 function getAlignContent(node) {
24328 if (node.style.alignContent) {
24329 return node.style.alignContent;
24330 }
24331 return 'flex-start';
24332 }
24333 function getAlignItem(node, child) {
24334 if (child.style.alignSelf) {
24335 return child.style.alignSelf;
24336 }
24337 if (node.style.alignItems) {
24338 return node.style.alignItems;
24339 }
24340 return 'stretch';
24341 }
24342 function resolveAxis(axis, direction) {
24343 if (direction === CSS_DIRECTION_RTL) {
24344 if (axis === CSS_FLEX_DIRECTION_ROW) {
24345 return CSS_FLEX_DIRECTION_ROW_REVERSE;
24346 } else if (axis === CSS_FLEX_DIRECTION_ROW_REVERSE) {
24347 return CSS_FLEX_DIRECTION_ROW;
24348 }
24349 }
24350 return axis;
24351 }
24352 function resolveDirection(node, parentDirection) {
24353 var direction;
24354 if (node.style.direction) {
24355 direction = node.style.direction;
24356 } else {
24357 direction = CSS_DIRECTION_INHERIT;
24358 }
24359 if (direction === CSS_DIRECTION_INHERIT) {
24360 direction = parentDirection === undefined ? CSS_DIRECTION_LTR : parentDirection;
24361 }
24362 return direction;
24363 }
24364 function getFlexDirection(node) {
24365 if (node.style.flexDirection) {
24366 return node.style.flexDirection;
24367 }
24368 return CSS_FLEX_DIRECTION_COLUMN;
24369 }
24370 function getCrossFlexDirection(flexDirection, direction) {
24371 if (isColumnDirection(flexDirection)) {
24372 return resolveAxis(CSS_FLEX_DIRECTION_ROW, direction);
24373 } else {
24374 return CSS_FLEX_DIRECTION_COLUMN;
24375 }
24376 }
24377 function getPositionType(node) {
24378 if (node.style.position) {
24379 return node.style.position;
24380 }
24381 return 'relative';
24382 }
24383 function isFlex(node) {
24384 return getPositionType(node) === CSS_POSITION_RELATIVE && node.style.flex > 0;
24385 }
24386 function isFlexWrap(node) {
24387 return node.style.flexWrap === 'wrap';
24388 }
24389 function getDimWithMargin(node, axis) {
24390 return node.layout[dim[axis]] + getMarginAxis(node, axis);
24391 }
24392 function isDimDefined(node, axis) {
24393 return node.style[dim[axis]] !== undefined && node.style[dim[axis]] >= 0;
24394 }
24395 function isPosDefined(node, pos) {
24396 return node.style[pos] !== undefined;
24397 }
24398 function isMeasureDefined(node) {
24399 return node.style.measure !== undefined;
24400 }
24401 function getPosition(node, pos) {
24402 if (node.style[pos] !== undefined) {
24403 return node.style[pos];
24404 }
24405 return 0;
24406 }
24407 function boundAxis(node, axis, value) {
24408 var min = {
24409 row: node.style.minWidth,
24410 'row-reverse': node.style.minWidth,
24411 column: node.style.minHeight,
24412 'column-reverse': node.style.minHeight
24413 }[axis];
24414 var max = {
24415 row: node.style.maxWidth,
24416 'row-reverse': node.style.maxWidth,
24417 column: node.style.maxHeight,
24418 'column-reverse': node.style.maxHeight
24419 }[axis];
24420 var boundValue = value;
24421 if (max !== undefined && max >= 0 && boundValue > max) {
24422 boundValue = max;
24423 }
24424 if (min !== undefined && min >= 0 && boundValue < min) {
24425 boundValue = min;
24426 }
24427 return boundValue;
24428 }
24429 function fmaxf(a, b) {
24430 if (a > b) {
24431 return a;
24432 }
24433 return b;
24434 }
24435 // When the user specifically sets a value for width or height
24436 function setDimensionFromStyle(node, axis) {
24437 // The parent already computed us a width or height. We just skip it
24438 if (node.layout[dim[axis]] !== undefined) {
24439 return;
24440 }
24441 // We only run if there's a width or height defined
24442 if (!isDimDefined(node, axis)) {
24443 return;
24444 }
24445 // The dimensions can never be smaller than the padding and border
24446 node.layout[dim[axis]] = fmaxf(boundAxis(node, axis, node.style[dim[axis]]), getPaddingAndBorderAxis(node, axis));
24447 }
24448 function setTrailingPosition(node, child, axis) {
24449 child.layout[trailing[axis]] = node.layout[dim[axis]] - child.layout[dim[axis]] - child.layout[pos[axis]];
24450 }
24451 // If both left and right are defined, then use left. Otherwise return
24452 // +left or -right depending on which is defined.
24453 function getRelativePosition(node, axis) {
24454 if (node.style[leading[axis]] !== undefined) {
24455 return getPosition(node, leading[axis]);
24456 }
24457 return -getPosition(node, trailing[axis]);
24458 }
24459 function layoutNodeImpl(node, parentMaxWidth, /*css_direction_t*/parentDirection) {
24460 var /*css_direction_t*/direction = resolveDirection(node, parentDirection);
24461 var /*(c)!css_flex_direction_t*/ /*(java)!int*/mainAxis = resolveAxis(getFlexDirection(node), direction);
24462 var /*(c)!css_flex_direction_t*/ /*(java)!int*/crossAxis = getCrossFlexDirection(mainAxis, direction);
24463 var /*(c)!css_flex_direction_t*/ /*(java)!int*/resolvedRowAxis = resolveAxis(CSS_FLEX_DIRECTION_ROW, direction);
24464 // Handle width and height style attributes
24465 setDimensionFromStyle(node, mainAxis);
24466 setDimensionFromStyle(node, crossAxis);
24467 // Set the resolved resolution in the node's layout
24468 node.layout.direction = direction;
24469 // The position is set by the parent, but we need to complete it with a
24470 // delta composed of the margin and left/top/right/bottom
24471 node.layout[leading[mainAxis]] += getLeadingMargin(node, mainAxis) + getRelativePosition(node, mainAxis);
24472 node.layout[trailing[mainAxis]] += getTrailingMargin(node, mainAxis) + getRelativePosition(node, mainAxis);
24473 node.layout[leading[crossAxis]] += getLeadingMargin(node, crossAxis) + getRelativePosition(node, crossAxis);
24474 node.layout[trailing[crossAxis]] += getTrailingMargin(node, crossAxis) + getRelativePosition(node, crossAxis);
24475 // Inline immutable values from the target node to avoid excessive method
24476 // invocations during the layout calculation.
24477 var /*int*/childCount = node.children.length;
24478 var /*float*/paddingAndBorderAxisResolvedRow = getPaddingAndBorderAxis(node, resolvedRowAxis);
24479 if (isMeasureDefined(node)) {
24480 var /*bool*/isResolvedRowDimDefined = !isUndefined$1(node.layout[dim[resolvedRowAxis]]);
24481 var /*float*/width = CSS_UNDEFINED;
24482 if (isDimDefined(node, resolvedRowAxis)) {
24483 width = node.style.width;
24484 } else if (isResolvedRowDimDefined) {
24485 width = node.layout[dim[resolvedRowAxis]];
24486 } else {
24487 width = parentMaxWidth - getMarginAxis(node, resolvedRowAxis);
24488 }
24489 width -= paddingAndBorderAxisResolvedRow;
24490 // We only need to give a dimension for the text if we haven't got any
24491 // for it computed yet. It can either be from the style attribute or because
24492 // the element is flexible.
24493 var /*bool*/isRowUndefined = !isDimDefined(node, resolvedRowAxis) && !isResolvedRowDimDefined;
24494 var /*bool*/isColumnUndefined = !isDimDefined(node, CSS_FLEX_DIRECTION_COLUMN) && isUndefined$1(node.layout[dim[CSS_FLEX_DIRECTION_COLUMN]]);
24495 // Let's not measure the text if we already know both dimensions
24496 if (isRowUndefined || isColumnUndefined) {
24497 var /*css_dim_t*/measureDim = node.style.measure(/*(c)!node->context,*/
24498 /*(java)!layoutContext.measureOutput,*/
24499 width);
24500 if (isRowUndefined) {
24501 node.layout.width = measureDim.width + paddingAndBorderAxisResolvedRow;
24502 }
24503 if (isColumnUndefined) {
24504 node.layout.height = measureDim.height + getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN);
24505 }
24506 }
24507 if (childCount === 0) {
24508 return;
24509 }
24510 }
24511 var /*bool*/isNodeFlexWrap = isFlexWrap(node);
24512 var /*css_justify_t*/justifyContent = getJustifyContent(node);
24513 var /*float*/leadingPaddingAndBorderMain = getLeadingPaddingAndBorder(node, mainAxis);
24514 var /*float*/leadingPaddingAndBorderCross = getLeadingPaddingAndBorder(node, crossAxis);
24515 var /*float*/paddingAndBorderAxisMain = getPaddingAndBorderAxis(node, mainAxis);
24516 var /*float*/paddingAndBorderAxisCross = getPaddingAndBorderAxis(node, crossAxis);
24517 var /*bool*/isMainDimDefined = !isUndefined$1(node.layout[dim[mainAxis]]);
24518 var /*bool*/isCrossDimDefined = !isUndefined$1(node.layout[dim[crossAxis]]);
24519 var /*bool*/isMainRowDirection = isRowDirection(mainAxis);
24520 var /*int*/i;
24521 var /*int*/ii;
24522 var /*css_node_t**/child;
24523 var /*(c)!css_flex_direction_t*/ /*(java)!int*/axis;
24524 var /*css_node_t**/firstAbsoluteChild = null;
24525 var /*css_node_t**/currentAbsoluteChild = null;
24526 var /*float*/definedMainDim = CSS_UNDEFINED;
24527 if (isMainDimDefined) {
24528 definedMainDim = node.layout[dim[mainAxis]] - paddingAndBorderAxisMain;
24529 }
24530 // We want to execute the next two loops one per line with flex-wrap
24531 var /*int*/startLine = 0;
24532 var /*int*/endLine = 0;
24533 // var/*int*/ nextOffset = 0;
24534 var /*int*/alreadyComputedNextLayout = 0;
24535 // We aggregate the total dimensions of the container in those two variables
24536 var /*float*/linesCrossDim = 0;
24537 var /*float*/linesMainDim = 0;
24538 var /*int*/linesCount = 0;
24539 while (endLine < childCount) {
24540 // <Loop A> Layout non flexible children and count children by type
24541 // mainContentDim is accumulation of the dimensions and margin of all the
24542 // non flexible children. This will be used in order to either set the
24543 // dimensions of the node if none already exist, or to compute the
24544 // remaining space left for the flexible children.
24545 var /*float*/mainContentDim = 0;
24546 // There are three kind of children, non flexible, flexible and absolute.
24547 // We need to know how many there are in order to distribute the space.
24548 var /*int*/flexibleChildrenCount = 0;
24549 var /*float*/totalFlexible = 0;
24550 var /*int*/nonFlexibleChildrenCount = 0;
24551 // Use the line loop to position children in the main axis for as long
24552 // as they are using a simple stacking behaviour. Children that are
24553 // immediately stacked in the initial loop will not be touched again
24554 // in <Loop C>.
24555 var /*bool*/isSimpleStackMain = isMainDimDefined && justifyContent === CSS_JUSTIFY_FLEX_START || !isMainDimDefined && justifyContent !== CSS_JUSTIFY_CENTER;
24556 var /*int*/firstComplexMain = isSimpleStackMain ? childCount : startLine;
24557 // Use the initial line loop to position children in the cross axis for
24558 // as long as they are relatively positioned with alignment STRETCH or
24559 // FLEX_START. Children that are immediately stacked in the initial loop
24560 // will not be touched again in <Loop D>.
24561 var /*bool*/isSimpleStackCross = true;
24562 var /*int*/firstComplexCross = childCount;
24563 var /*css_node_t**/firstFlexChild = null;
24564 var /*css_node_t**/currentFlexChild = null;
24565 var /*float*/mainDim = leadingPaddingAndBorderMain;
24566 var /*float*/crossDim = 0;
24567 var /*float*/maxWidth;
24568 for (i = startLine; i < childCount; ++i) {
24569 child = node.children[i];
24570 child.lineIndex = linesCount;
24571 child.nextAbsoluteChild = null;
24572 child.nextFlexChild = null;
24573 var /*css_align_t*/alignItem = getAlignItem(node, child);
24574 // Pre-fill cross axis dimensions when the child is using stretch before
24575 // we call the recursive layout pass
24576 if (alignItem === CSS_ALIGN_STRETCH && getPositionType(child) === CSS_POSITION_RELATIVE && isCrossDimDefined && !isDimDefined(child, crossAxis)) {
24577 child.layout[dim[crossAxis]] = fmaxf(boundAxis(child, crossAxis, node.layout[dim[crossAxis]] - paddingAndBorderAxisCross - getMarginAxis(child, crossAxis)),
24578 // You never want to go smaller than padding
24579 getPaddingAndBorderAxis(child, crossAxis));
24580 } else if (getPositionType(child) === CSS_POSITION_ABSOLUTE) {
24581 // Store a private linked list of absolutely positioned children
24582 // so that we can efficiently traverse them later.
24583 if (firstAbsoluteChild === null) {
24584 firstAbsoluteChild = child;
24585 }
24586 if (currentAbsoluteChild !== null) {
24587 currentAbsoluteChild.nextAbsoluteChild = child;
24588 }
24589 currentAbsoluteChild = child;
24590 // Pre-fill dimensions when using absolute position and both offsets for the axis are defined (either both
24591 // left and right or top and bottom).
24592 for (ii = 0; ii < 2; ii++) {
24593 axis = ii !== 0 ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN;
24594 if (!isUndefined$1(node.layout[dim[axis]]) && !isDimDefined(child, axis) && isPosDefined(child, leading[axis]) && isPosDefined(child, trailing[axis])) {
24595 child.layout[dim[axis]] = fmaxf(boundAxis(child, axis, node.layout[dim[axis]] - getPaddingAndBorderAxis(node, axis) - getMarginAxis(child, axis) - getPosition(child, leading[axis]) - getPosition(child, trailing[axis])),
24596 // You never want to go smaller than padding
24597 getPaddingAndBorderAxis(child, axis));
24598 }
24599 }
24600 }
24601 var /*float*/nextContentDim = 0;
24602 // It only makes sense to consider a child flexible if we have a computed
24603 // dimension for the node.
24604 if (isMainDimDefined && isFlex(child)) {
24605 flexibleChildrenCount++;
24606 totalFlexible += child.style.flex;
24607 // Store a private linked list of flexible children so that we can
24608 // efficiently traverse them later.
24609 if (firstFlexChild === null) {
24610 firstFlexChild = child;
24611 }
24612 if (currentFlexChild !== null) {
24613 currentFlexChild.nextFlexChild = child;
24614 }
24615 currentFlexChild = child;
24616 // Even if we don't know its exact size yet, we already know the padding,
24617 // border and margin. We'll use this partial information, which represents
24618 // the smallest possible size for the child, to compute the remaining
24619 // available space.
24620 nextContentDim = getPaddingAndBorderAxis(child, mainAxis) + getMarginAxis(child, mainAxis);
24621 } else {
24622 maxWidth = CSS_UNDEFINED;
24623 if (!isMainRowDirection) {
24624 if (isDimDefined(node, resolvedRowAxis)) {
24625 maxWidth = node.layout[dim[resolvedRowAxis]] - paddingAndBorderAxisResolvedRow;
24626 } else {
24627 maxWidth = parentMaxWidth - getMarginAxis(node, resolvedRowAxis) - paddingAndBorderAxisResolvedRow;
24628 }
24629 }
24630 // This is the main recursive call. We layout non flexible children.
24631 if (alreadyComputedNextLayout === 0) {
24632 layoutNode(/*(java)!layoutContext, */child, maxWidth, direction);
24633 }
24634 // Absolute positioned elements do not take part of the layout, so we
24635 // don't use them to compute mainContentDim
24636 if (getPositionType(child) === CSS_POSITION_RELATIVE) {
24637 nonFlexibleChildrenCount++;
24638 // At this point we know the final size and margin of the element.
24639 nextContentDim = getDimWithMargin(child, mainAxis);
24640 }
24641 }
24642 // The element we are about to add would make us go to the next line
24643 if (isNodeFlexWrap && isMainDimDefined && mainContentDim + nextContentDim > definedMainDim &&
24644 // If there's only one element, then it's bigger than the content
24645 // and needs its own line
24646 i !== startLine) {
24647 nonFlexibleChildrenCount--;
24648 alreadyComputedNextLayout = 1;
24649 break;
24650 }
24651 // Disable simple stacking in the main axis for the current line as
24652 // we found a non-trivial child. The remaining children will be laid out
24653 // in <Loop C>.
24654 if (isSimpleStackMain && (getPositionType(child) !== CSS_POSITION_RELATIVE || isFlex(child))) {
24655 isSimpleStackMain = false;
24656 firstComplexMain = i;
24657 }
24658 // Disable simple stacking in the cross axis for the current line as
24659 // we found a non-trivial child. The remaining children will be laid out
24660 // in <Loop D>.
24661 if (isSimpleStackCross && (getPositionType(child) !== CSS_POSITION_RELATIVE || alignItem !== CSS_ALIGN_STRETCH && alignItem !== CSS_ALIGN_FLEX_START || isUndefined$1(child.layout[dim[crossAxis]]))) {
24662 isSimpleStackCross = false;
24663 firstComplexCross = i;
24664 }
24665 if (isSimpleStackMain) {
24666 child.layout[pos[mainAxis]] += mainDim;
24667 if (isMainDimDefined) {
24668 setTrailingPosition(node, child, mainAxis);
24669 }
24670 mainDim += getDimWithMargin(child, mainAxis);
24671 crossDim = fmaxf(crossDim, boundAxis(child, crossAxis, getDimWithMargin(child, crossAxis)));
24672 }
24673 if (isSimpleStackCross) {
24674 child.layout[pos[crossAxis]] += linesCrossDim + leadingPaddingAndBorderCross;
24675 if (isCrossDimDefined) {
24676 setTrailingPosition(node, child, crossAxis);
24677 }
24678 }
24679 alreadyComputedNextLayout = 0;
24680 mainContentDim += nextContentDim;
24681 endLine = i + 1;
24682 }
24683 // <Loop B> Layout flexible children and allocate empty space
24684 // In order to position the elements in the main axis, we have two
24685 // controls. The space between the beginning and the first element
24686 // and the space between each two elements.
24687 var /*float*/leadingMainDim = 0;
24688 var /*float*/betweenMainDim = 0;
24689 // The remaining available space that needs to be allocated
24690 var /*float*/remainingMainDim = 0;
24691 if (isMainDimDefined) {
24692 remainingMainDim = definedMainDim - mainContentDim;
24693 } else {
24694 remainingMainDim = fmaxf(mainContentDim, 0) - mainContentDim;
24695 }
24696 // If there are flexible children in the mix, they are going to fill the
24697 // remaining space
24698 if (flexibleChildrenCount !== 0) {
24699 var /*float*/flexibleMainDim = remainingMainDim / totalFlexible;
24700 var /*float*/baseMainDim;
24701 var /*float*/boundMainDim;
24702 // If the flex share of remaining space doesn't meet min/max bounds,
24703 // remove this child from flex calculations.
24704 currentFlexChild = firstFlexChild;
24705 while (currentFlexChild !== null) {
24706 baseMainDim = flexibleMainDim * currentFlexChild.style.flex + getPaddingAndBorderAxis(currentFlexChild, mainAxis);
24707 boundMainDim = boundAxis(currentFlexChild, mainAxis, baseMainDim);
24708 if (baseMainDim !== boundMainDim) {
24709 remainingMainDim -= boundMainDim;
24710 totalFlexible -= currentFlexChild.style.flex;
24711 }
24712 currentFlexChild = currentFlexChild.nextFlexChild;
24713 }
24714 flexibleMainDim = remainingMainDim / totalFlexible;
24715 // The non flexible children can overflow the container, in this case
24716 // we should just assume that there is no space available.
24717 if (flexibleMainDim < 0) {
24718 flexibleMainDim = 0;
24719 }
24720 currentFlexChild = firstFlexChild;
24721 while (currentFlexChild !== null) {
24722 // At this point we know the final size of the element in the main
24723 // dimension
24724 currentFlexChild.layout[dim[mainAxis]] = boundAxis(currentFlexChild, mainAxis, flexibleMainDim * currentFlexChild.style.flex + getPaddingAndBorderAxis(currentFlexChild, mainAxis));
24725 maxWidth = CSS_UNDEFINED;
24726 if (isDimDefined(node, resolvedRowAxis)) {
24727 maxWidth = node.layout[dim[resolvedRowAxis]] - paddingAndBorderAxisResolvedRow;
24728 } else if (!isMainRowDirection) {
24729 maxWidth = parentMaxWidth - getMarginAxis(node, resolvedRowAxis) - paddingAndBorderAxisResolvedRow;
24730 }
24731 // And we recursively call the layout algorithm for this child
24732 layoutNode(/*(java)!layoutContext, */currentFlexChild, maxWidth, direction);
24733 child = currentFlexChild;
24734 currentFlexChild = currentFlexChild.nextFlexChild;
24735 child.nextFlexChild = null;
24736 }
24737 // We use justifyContent to figure out how to allocate the remaining
24738 // space available
24739 } else if (justifyContent !== CSS_JUSTIFY_FLEX_START) {
24740 if (justifyContent === CSS_JUSTIFY_CENTER) {
24741 leadingMainDim = remainingMainDim / 2;
24742 } else if (justifyContent === CSS_JUSTIFY_FLEX_END) {
24743 leadingMainDim = remainingMainDim;
24744 } else if (justifyContent === CSS_JUSTIFY_SPACE_BETWEEN) {
24745 remainingMainDim = fmaxf(remainingMainDim, 0);
24746 if (flexibleChildrenCount + nonFlexibleChildrenCount - 1 !== 0) {
24747 betweenMainDim = remainingMainDim / (flexibleChildrenCount + nonFlexibleChildrenCount - 1);
24748 } else {
24749 betweenMainDim = 0;
24750 }
24751 } else if (justifyContent === CSS_JUSTIFY_SPACE_AROUND) {
24752 // Space on the edges is half of the space between elements
24753 betweenMainDim = remainingMainDim / (flexibleChildrenCount + nonFlexibleChildrenCount);
24754 leadingMainDim = betweenMainDim / 2;
24755 }
24756 }
24757 // <Loop C> Position elements in the main axis and compute dimensions
24758 // At this point, all the children have their dimensions set. We need to
24759 // find their position. In order to do that, we accumulate data in
24760 // variables that are also useful to compute the total dimensions of the
24761 // container!
24762 mainDim += leadingMainDim;
24763 for (i = firstComplexMain; i < endLine; ++i) {
24764 child = node.children[i];
24765 if (getPositionType(child) === CSS_POSITION_ABSOLUTE && isPosDefined(child, leading[mainAxis])) {
24766 // In case the child is position absolute and has left/top being
24767 // defined, we override the position to whatever the user said
24768 // (and margin/border).
24769 child.layout[pos[mainAxis]] = getPosition(child, leading[mainAxis]) + getLeadingBorder(node, mainAxis) + getLeadingMargin(child, mainAxis);
24770 } else {
24771 // If the child is position absolute (without top/left) or relative,
24772 // we put it at the current accumulated offset.
24773 child.layout[pos[mainAxis]] += mainDim;
24774 // Define the trailing position accordingly.
24775 if (isMainDimDefined) {
24776 setTrailingPosition(node, child, mainAxis);
24777 }
24778 // Now that we placed the element, we need to update the variables
24779 // We only need to do that for relative elements. Absolute elements
24780 // do not take part in that phase.
24781 if (getPositionType(child) === CSS_POSITION_RELATIVE) {
24782 // The main dimension is the sum of all the elements dimension plus
24783 // the spacing.
24784 mainDim += betweenMainDim + getDimWithMargin(child, mainAxis);
24785 // The cross dimension is the max of the elements dimension since there
24786 // can only be one element in that cross dimension.
24787 crossDim = fmaxf(crossDim, boundAxis(child, crossAxis, getDimWithMargin(child, crossAxis)));
24788 }
24789 }
24790 }
24791 var /*float*/containerCrossAxis = node.layout[dim[crossAxis]];
24792 if (!isCrossDimDefined) {
24793 containerCrossAxis = fmaxf(
24794 // For the cross dim, we add both sides at the end because the value
24795 // is aggregate via a max function. Intermediate negative values
24796 // can mess this computation otherwise
24797 boundAxis(node, crossAxis, crossDim + paddingAndBorderAxisCross), paddingAndBorderAxisCross);
24798 }
24799 // <Loop D> Position elements in the cross axis
24800 for (i = firstComplexCross; i < endLine; ++i) {
24801 child = node.children[i];
24802 if (getPositionType(child) === CSS_POSITION_ABSOLUTE && isPosDefined(child, leading[crossAxis])) {
24803 // In case the child is absolutely positionned and has a
24804 // top/left/bottom/right being set, we override all the previously
24805 // computed positions to set it correctly.
24806 child.layout[pos[crossAxis]] = getPosition(child, leading[crossAxis]) + getLeadingBorder(node, crossAxis) + getLeadingMargin(child, crossAxis);
24807 } else {
24808 var /*float*/leadingCrossDim = leadingPaddingAndBorderCross;
24809 // For a relative children, we're either using alignItems (parent) or
24810 // alignSelf (child) in order to determine the position in the cross axis
24811 if (getPositionType(child) === CSS_POSITION_RELATIVE) {
24812 // This variable is intentionally re-defined as the code is transpiled to a block scope language
24813 var /*css_align_t*/alignItem = getAlignItem(node, child);
24814 if (alignItem === CSS_ALIGN_STRETCH) {
24815 // You can only stretch if the dimension has not already been set
24816 // previously.
24817 if (isUndefined$1(child.layout[dim[crossAxis]])) {
24818 child.layout[dim[crossAxis]] = fmaxf(boundAxis(child, crossAxis, containerCrossAxis - paddingAndBorderAxisCross - getMarginAxis(child, crossAxis)),
24819 // You never want to go smaller than padding
24820 getPaddingAndBorderAxis(child, crossAxis));
24821 }
24822 } else if (alignItem !== CSS_ALIGN_FLEX_START) {
24823 // The remaining space between the parent dimensions+padding and child
24824 // dimensions+margin.
24825 var /*float*/remainingCrossDim = containerCrossAxis - paddingAndBorderAxisCross - getDimWithMargin(child, crossAxis);
24826 if (alignItem === CSS_ALIGN_CENTER) {
24827 leadingCrossDim += remainingCrossDim / 2;
24828 } else {
24829 // CSS_ALIGN_FLEX_END
24830 leadingCrossDim += remainingCrossDim;
24831 }
24832 }
24833 }
24834 // And we apply the position
24835 child.layout[pos[crossAxis]] += linesCrossDim + leadingCrossDim;
24836 // Define the trailing position accordingly.
24837 if (isCrossDimDefined) {
24838 setTrailingPosition(node, child, crossAxis);
24839 }
24840 }
24841 }
24842 linesCrossDim += crossDim;
24843 linesMainDim = fmaxf(linesMainDim, mainDim);
24844 linesCount += 1;
24845 startLine = endLine;
24846 }
24847 // <Loop E>
24848 //
24849 // Note(prenaux): More than one line, we need to layout the crossAxis
24850 // according to alignContent.
24851 //
24852 // Note that we could probably remove <Loop D> and handle the one line case
24853 // here too, but for the moment this is safer since it won't interfere with
24854 // previously working code.
24855 //
24856 // See specs:
24857 // http://www.w3.org/TR/2012/CR-css3-flexbox-20120918/#layout-algorithm
24858 // section 9.4
24859 //
24860 if (linesCount > 1 && isCrossDimDefined) {
24861 var /*float*/nodeCrossAxisInnerSize = node.layout[dim[crossAxis]] - paddingAndBorderAxisCross;
24862 var /*float*/remainingAlignContentDim = nodeCrossAxisInnerSize - linesCrossDim;
24863 var /*float*/crossDimLead = 0;
24864 var /*float*/currentLead = leadingPaddingAndBorderCross;
24865 var /*css_align_t*/alignContent = getAlignContent(node);
24866 if (alignContent === CSS_ALIGN_FLEX_END) {
24867 currentLead += remainingAlignContentDim;
24868 } else if (alignContent === CSS_ALIGN_CENTER) {
24869 currentLead += remainingAlignContentDim / 2;
24870 } else if (alignContent === CSS_ALIGN_STRETCH) {
24871 if (nodeCrossAxisInnerSize > linesCrossDim) {
24872 crossDimLead = remainingAlignContentDim / linesCount;
24873 }
24874 }
24875 var /*int*/endIndex = 0;
24876 for (i = 0; i < linesCount; ++i) {
24877 var /*int*/startIndex = endIndex;
24878 // compute the line's height and find the endIndex
24879 var /*float*/lineHeight = 0;
24880 for (ii = startIndex; ii < childCount; ++ii) {
24881 child = node.children[ii];
24882 if (getPositionType(child) !== CSS_POSITION_RELATIVE) {
24883 continue;
24884 }
24885 if (child.lineIndex !== i) {
24886 break;
24887 }
24888 if (!isUndefined$1(child.layout[dim[crossAxis]])) {
24889 lineHeight = fmaxf(lineHeight, child.layout[dim[crossAxis]] + getMarginAxis(child, crossAxis));
24890 }
24891 }
24892 endIndex = ii;
24893 lineHeight += crossDimLead;
24894 for (ii = startIndex; ii < endIndex; ++ii) {
24895 child = node.children[ii];
24896 if (getPositionType(child) !== CSS_POSITION_RELATIVE) {
24897 continue;
24898 }
24899 var /*css_align_t*/alignContentAlignItem = getAlignItem(node, child);
24900 if (alignContentAlignItem === CSS_ALIGN_FLEX_START) {
24901 child.layout[pos[crossAxis]] = currentLead + getLeadingMargin(child, crossAxis);
24902 } else if (alignContentAlignItem === CSS_ALIGN_FLEX_END) {
24903 child.layout[pos[crossAxis]] = currentLead + lineHeight - getTrailingMargin(child, crossAxis) - child.layout[dim[crossAxis]];
24904 } else if (alignContentAlignItem === CSS_ALIGN_CENTER) {
24905 var /*float*/childHeight = child.layout[dim[crossAxis]];
24906 child.layout[pos[crossAxis]] = currentLead + (lineHeight - childHeight) / 2;
24907 } else if (alignContentAlignItem === CSS_ALIGN_STRETCH) {
24908 child.layout[pos[crossAxis]] = currentLead + getLeadingMargin(child, crossAxis);
24909 // TODO(prenaux): Correctly set the height of items with undefined
24910 // (auto) crossAxis dimension.
24911 }
24912 }
24913 currentLead += lineHeight;
24914 }
24915 }
24916 var /*bool*/needsMainTrailingPos = false;
24917 var /*bool*/needsCrossTrailingPos = false;
24918 // If the user didn't specify a width or height, and it has not been set
24919 // by the container, then we set it via the children.
24920 if (!isMainDimDefined) {
24921 node.layout[dim[mainAxis]] = fmaxf(
24922 // We're missing the last padding at this point to get the final
24923 // dimension
24924 boundAxis(node, mainAxis, linesMainDim + getTrailingPaddingAndBorder(node, mainAxis)),
24925 // We can never assign a width smaller than the padding and borders
24926 paddingAndBorderAxisMain);
24927 if (mainAxis === CSS_FLEX_DIRECTION_ROW_REVERSE || mainAxis === CSS_FLEX_DIRECTION_COLUMN_REVERSE) {
24928 needsMainTrailingPos = true;
24929 }
24930 }
24931 if (!isCrossDimDefined) {
24932 node.layout[dim[crossAxis]] = fmaxf(
24933 // For the cross dim, we add both sides at the end because the value
24934 // is aggregate via a max function. Intermediate negative values
24935 // can mess this computation otherwise
24936 boundAxis(node, crossAxis, linesCrossDim + paddingAndBorderAxisCross), paddingAndBorderAxisCross);
24937 if (crossAxis === CSS_FLEX_DIRECTION_ROW_REVERSE || crossAxis === CSS_FLEX_DIRECTION_COLUMN_REVERSE) {
24938 needsCrossTrailingPos = true;
24939 }
24940 }
24941 // <Loop F> Set trailing position if necessary
24942 if (needsMainTrailingPos || needsCrossTrailingPos) {
24943 for (i = 0; i < childCount; ++i) {
24944 child = node.children[i];
24945 if (needsMainTrailingPos) {
24946 setTrailingPosition(node, child, mainAxis);
24947 }
24948 if (needsCrossTrailingPos) {
24949 setTrailingPosition(node, child, crossAxis);
24950 }
24951 }
24952 }
24953 // <Loop G> Calculate dimensions for absolutely positioned elements
24954 currentAbsoluteChild = firstAbsoluteChild;
24955 while (currentAbsoluteChild !== null) {
24956 // Pre-fill dimensions when using absolute position and both offsets for
24957 // the axis are defined (either both left and right or top and bottom).
24958 for (ii = 0; ii < 2; ii++) {
24959 axis = ii !== 0 ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN;
24960 if (!isUndefined$1(node.layout[dim[axis]]) && !isDimDefined(currentAbsoluteChild, axis) && isPosDefined(currentAbsoluteChild, leading[axis]) && isPosDefined(currentAbsoluteChild, trailing[axis])) {
24961 currentAbsoluteChild.layout[dim[axis]] = fmaxf(boundAxis(currentAbsoluteChild, axis, node.layout[dim[axis]] - getBorderAxis(node, axis) - getMarginAxis(currentAbsoluteChild, axis) - getPosition(currentAbsoluteChild, leading[axis]) - getPosition(currentAbsoluteChild, trailing[axis])),
24962 // You never want to go smaller than padding
24963 getPaddingAndBorderAxis(currentAbsoluteChild, axis));
24964 }
24965 if (isPosDefined(currentAbsoluteChild, trailing[axis]) && !isPosDefined(currentAbsoluteChild, leading[axis])) {
24966 currentAbsoluteChild.layout[leading[axis]] = node.layout[dim[axis]] - currentAbsoluteChild.layout[dim[axis]] - getPosition(currentAbsoluteChild, trailing[axis]);
24967 }
24968 }
24969 child = currentAbsoluteChild;
24970 currentAbsoluteChild = currentAbsoluteChild.nextAbsoluteChild;
24971 child.nextAbsoluteChild = null;
24972 }
24973 }
24974 // 在外层做的margin补丁
24975 function saveMargin(node) {
24976 var style = node.style;
24977 var margin = {};
24978 ['marginTop', 'marginRight', 'marginBottom', 'marginLeft' // 只支持marginLeft
24979 ].forEach(function (key) {
24980 // 只处理百分号
24981 var value = style[key];
24982 if (value && /^-?\d+%$/.test(value)) {
24983 margin[key] = value;
24984 style[key] = 0;
24985 }
24986 });
24987 node.margin = margin;
24988 }
24989 function percent2Num(value) {
24990 var percent = Number(value.substr(0, value.length - 1));
24991 return percent / 100;
24992 }
24993 function layoutMargin(node) {
24994 var margin = node.margin,
24995 layout = node.layout;
24996 Object.keys(margin).forEach(function (key) {
24997 var percent = percent2Num(margin[key]);
24998 if ((key === 'marginLeft' || key === 'marginRight') && layout.width) {
24999 layout.left += layout.width * percent;
25000 } else if ((key === 'marginTop' || key === 'marginBottom') && layout.height) {
25001 layout.top += layout.height * percent;
25002 }
25003 });
25004 }
25005 function layoutNode(node, parentMaxWidth, parentDirection) {
25006 node.shouldUpdate = true;
25007 // hack
25008 saveMargin(node);
25009 var direction = node.style.direction || CSS_DIRECTION_LTR;
25010 var skipLayout = !node.isDirty && node.lastLayout && node.lastLayout.requestedHeight === node.layout.height && node.lastLayout.requestedWidth === node.layout.width && node.lastLayout.parentMaxWidth === parentMaxWidth && node.lastLayout.direction === direction;
25011 if (skipLayout) {
25012 node.layout.width = node.lastLayout.width;
25013 node.layout.height = node.lastLayout.height;
25014 node.layout.top = node.lastLayout.top;
25015 node.layout.left = node.lastLayout.left;
25016 } else {
25017 if (!node.lastLayout) {
25018 node.lastLayout = {};
25019 }
25020 node.lastLayout.requestedWidth = node.layout.width;
25021 node.lastLayout.requestedHeight = node.layout.height;
25022 node.lastLayout.parentMaxWidth = parentMaxWidth;
25023 node.lastLayout.direction = direction;
25024 // Reset child layouts
25025 node.children.forEach(function (child) {
25026 child.layout.width = undefined;
25027 child.layout.height = undefined;
25028 child.layout.top = 0;
25029 child.layout.left = 0;
25030 });
25031 layoutNodeImpl(node, parentMaxWidth, parentDirection);
25032 node.lastLayout.width = node.layout.width;
25033 node.lastLayout.height = node.layout.height;
25034 node.lastLayout.top = node.layout.top;
25035 node.lastLayout.left = node.layout.left;
25036 }
25037 // hack
25038 layoutMargin(node);
25039 }
25040 /* eslint-enable */
25041 function computeLayout(node) {
25042 if (!node) return node;
25043 fillNodes(node);
25044 layoutNode(node, null, null);
25045 return node;
25046 }
25047
25048 function createMeasure(style, measureText) {
25049 return function /* width */
25050 () {
25051 var text = style.text,
25052 width = style.width,
25053 height = style.height;
25054 var outputWidth = width;
25055 var outputHeight = height;
25056 if (!isNumber(width) || !isNumber(height)) {
25057 var _a = measureText(text, style),
25058 measureWidth = _a.width,
25059 measureHeight = _a.height;
25060 if (!isNumber(width)) {
25061 outputWidth = measureWidth;
25062 }
25063 if (!isNumber(height)) {
25064 outputHeight = measureHeight;
25065 }
25066 }
25067 return {
25068 width: outputWidth,
25069 height: outputHeight
25070 };
25071 };
25072 }
25073 function getChildrenLayout(nodeTree) {
25074 if (!nodeTree) return;
25075 var left = 0;
25076 var top = 0;
25077 var right = 0;
25078 var bottom = 0;
25079 var width = 0;
25080 var height = 0;
25081 nodeTree.forEach(function (node) {
25082 var layout = node.layout;
25083 if (!layout) return;
25084 left = Math.min(left, layout.left);
25085 top = Math.min(top, layout.top);
25086 right = Math.min(right, layout.left + layout.width);
25087 bottom = Math.min(bottom, layout.top + layout.height);
25088 width = Math.max(width, layout.width);
25089 height = Math.max(height, layout.height);
25090 });
25091 return {
25092 left: left,
25093 top: top,
25094 right: right,
25095 bottom: bottom,
25096 width: width,
25097 height: height
25098 };
25099 }
25100 var NodeTree = /** @class */function () {
25101 function NodeTree(node) {
25102 var className = node.className,
25103 children = node.children,
25104 layout = node.layout;
25105 var nodeChildren = children && children.length ? children.map(function (child) {
25106 return new NodeTree(child);
25107 }) : undefined;
25108 var nodeLayout = layout ? layout : getChildrenLayout(nodeChildren);
25109 this.children = nodeChildren;
25110 this.layout = nodeLayout;
25111 this.className = className;
25112 }
25113 NodeTree.prototype.getElementsByClassName = function (targetClassName) {
25114 var result = [];
25115 var _a = this,
25116 className = _a.className,
25117 children = _a.children;
25118 if (className === targetClassName) {
25119 result.push(this);
25120 }
25121 if (children) {
25122 children.forEach(function (child) {
25123 result.push.apply(result, child.getElementsByClassName(targetClassName));
25124 });
25125 }
25126 return result;
25127 };
25128 return NodeTree;
25129 }();
25130 // 展开数组
25131 function extendMap(arr, fn) {
25132 if (!arr) {
25133 return arr;
25134 }
25135 var newArray = [];
25136 if (!isArray(arr)) {
25137 var rst = fn(arr);
25138 if (!rst) {
25139 return newArray;
25140 }
25141 if (isArray(rst)) {
25142 newArray = newArray.concat(rst);
25143 } else {
25144 newArray.push(rst);
25145 }
25146 return newArray;
25147 }
25148 for (var i = 0; i < arr.length; i++) {
25149 var element = arr[i];
25150 if (isArray(element)) {
25151 newArray = newArray.concat(extendMap(element, fn));
25152 } else if (element) {
25153 var rst = fn(element);
25154 if (!rst) {
25155 continue;
25156 }
25157 if (isArray(rst)) {
25158 newArray = newArray.concat(rst);
25159 } else {
25160 newArray.push(rst);
25161 }
25162 }
25163 }
25164 return newArray;
25165 }
25166 // 主要是把function节点,全部转换成string标签节点
25167 function renderJSXElement(element, context, updater) {
25168 if (!element) return element;
25169 var px2hd = context.px2hd,
25170 measureText = context.measureText;
25171 var type = element.type,
25172 props = element.props;
25173 var tag = getWorkTag(type);
25174 // 只处理 function 组件
25175 if (tag === FunctionComponent) {
25176 // @ts-ignore
25177 var newElement = type(element.props, context, updater);
25178 // return element if type is string
25179 return renderJSXElement(newElement, context, updater);
25180 }
25181 var className = props.className,
25182 _a = props.style,
25183 customStyle = _a === void 0 ? {} : _a,
25184 attrs = props.attrs,
25185 newChildren = props.children;
25186 var style = px2hd(__assign(__assign({}, customStyle), attrs));
25187 // 文本需要计算文本的宽高来进行flex布局
25188 if (type === 'text') {
25189 style.measure = createMeasure(style, measureText);
25190 }
25191 // render children first
25192 var nextChildren = newChildren ? Children.toArray(newChildren).map(function (child) {
25193 return renderJSXElement(child, context, updater);
25194 }) : [];
25195 return {
25196 type: type,
25197 className: className,
25198 children: nextChildren.filter(Boolean),
25199 style: style
25200 };
25201 }
25202 // 计算布局
25203 function computeLayout$1(component, newChildren) {
25204 var context = component.context,
25205 updater = component.updater;
25206 var nodeTree = renderJSXElement(newChildren, context, updater);
25207 computeLayout(nodeTree);
25208 // 构造一个 NodeTree, 方便外部使用
25209 return new NodeTree(nodeTree);
25210 }
25211 function createChildNodeTree(parent, vNodeChildren) {
25212 var tag = parent.tag;
25213 var children = extendMap(vNodeChildren, function (child) {
25214 var childTag = child.tag,
25215 childStyle = child.style,
25216 childChildren = child.children;
25217 // 如果组件的根节点不是 flex, 则该组件不需要计算 flex 布局
25218 if (tag !== Shape$1 && childTag === Shape$1 && childStyle.display !== 'flex') {
25219 return null;
25220 }
25221 // 如果子组件不是 shape,则布局计算时,忽略当前节点
25222 if (childTag !== Shape$1) {
25223 return createChildNodeTree(child, childChildren);
25224 }
25225 return createNodeTree(child);
25226 });
25227 return children;
25228 }
25229 // 创建组件的布局树
25230 function createNodeTree(vNode) {
25231 var tag = vNode.tag,
25232 type = vNode.type,
25233 style = vNode.style,
25234 context = vNode.context,
25235 vNodeChildren = vNode.children;
25236 var measureText = context.measureText;
25237 var children = createChildNodeTree(vNode, vNodeChildren);
25238 // 文本需要计算文本的宽高来进行flex布局
25239 if (type === 'text') {
25240 style.measure = createMeasure(style, measureText);
25241 }
25242 return {
25243 tag: tag,
25244 type: type,
25245 style: style,
25246 children: children,
25247 // 保留对 vNode 的引用,用于把布局结果回填
25248 vNode: vNode
25249 };
25250 }
25251 function fillElementLayout(node) {
25252 var type = node.type,
25253 style = node.style,
25254 vNode = node.vNode,
25255 children = node.children,
25256 layout = node.layout;
25257 var attrs = getShapeAttrs(type, layout);
25258 if (style.measure) {
25259 delete style.measure;
25260 }
25261 // 更新布局和样式
25262 vNode.layout = layout;
25263 vNode.style = __assign(__assign({}, attrs), style);
25264 if (!children || !children.length) {
25265 return;
25266 }
25267 for (var i = 0, len = children.length; i < len; i++) {
25268 var child = children[i];
25269 fillElementLayout(child);
25270 }
25271 }
25272 function fillComponentLayout(vNode) {
25273 var layout = vNode.layout,
25274 vNodeChildren = vNode.children;
25275 Children.map(vNodeChildren, function (child) {
25276 if (!child) {
25277 return;
25278 }
25279 var childTag = child.tag,
25280 childLayout = child.layout,
25281 style = child.style;
25282 if (childTag !== Shape$1 && layout && !childLayout) {
25283 child.layout = layout;
25284 child.style = __assign({
25285 width: layout.width,
25286 height: layout.height
25287 }, style);
25288 }
25289 fillComponentLayout(child);
25290 });
25291 }
25292
25293 function pickElement(element) {
25294 if (!element) return element;
25295 return Children.map(element, function (item) {
25296 if (!item) return item;
25297 // 只需要这几个元素就可以了
25298 return pick(item, ['key', 'ref', 'type', 'props']);
25299 });
25300 }
25301 function getStyle$1(tagType, props, context) {
25302 var _a = props.style,
25303 customStyle = _a === void 0 ? {} : _a,
25304 attrs = props.attrs,
25305 zIndex = props.zIndex;
25306 if (tagType === Shape$1) {
25307 return context.px2hd(__assign(__assign({}, customStyle), attrs));
25308 }
25309 if (isNumber(zIndex)) {
25310 return {
25311 zIndex: zIndex
25312 };
25313 }
25314 return {};
25315 }
25316 // vnode 上的 context 做父子节点的 context 传递
25317 function readVNodeContext(vNodeType, parentContext) {
25318 // @ts-ignore
25319 var contextInjecter = vNodeType.contextInjecter;
25320 if (!contextInjecter) {
25321 return parentContext;
25322 }
25323 // copy parentContext
25324 return __assign({}, parentContext);
25325 }
25326 // component 上的 context 是实际使用的 context
25327 function readComponentContext(vNodeType, vNodeContext) {
25328 // @ts-ignore
25329 var contextType = vNodeType.contextType;
25330 if (!contextType) {
25331 return vNodeContext;
25332 }
25333 var _currentValue = contextType._currentValue;
25334 if (!_currentValue) {
25335 return vNodeContext;
25336 }
25337 return _currentValue;
25338 }
25339 function createVNode(parent, vNode) {
25340 var canvas = parent.canvas,
25341 parentContext = parent.context,
25342 updater = parent.updater,
25343 parentAnimate = parent.animate;
25344 var ref = vNode.ref,
25345 type = vNode.type,
25346 originProps = vNode.props;
25347 var animate = originProps.animate,
25348 transformFrom = originProps.transformFrom,
25349 props = __rest(originProps, ["animate", "transformFrom"]);
25350 var tag = getWorkTag(type);
25351 var context = readVNodeContext(type, parentContext);
25352 var animator = new Animator();
25353 var style = getStyle$1(tag, props, context);
25354 animator.vNode = vNode;
25355 vNode.parent = parent;
25356 vNode.tag = tag;
25357 vNode.style = style;
25358 vNode.context = context;
25359 vNode.updater = updater;
25360 vNode.canvas = canvas;
25361 vNode.animate = isBoolean(animate) ? animate : parentAnimate;
25362 vNode.animator = animator;
25363 // shape 标签
25364 if (tag === Shape$1) {
25365 var shape = createShape(type, __assign(__assign({}, props), {
25366 style: style
25367 }));
25368 if (ref) {
25369 ref.current = shape;
25370 }
25371 // @ts-ignore
25372 shape._vNode = vNode; // shape 保留 vNode 的引用
25373 vNode.shape = shape;
25374 } else {
25375 var componentContext = readComponentContext(type, context);
25376 // 组件
25377 var component = void 0;
25378 if (tag === ClassComponent) {
25379 // @ts-ignore
25380 component = new type(props, componentContext, updater);
25381 } else {
25382 component = new Component(props, componentContext, updater);
25383 component.render = function () {
25384 // @ts-ignore update的时候用最新的context
25385 return type(this.props, this.context, updater);
25386 };
25387 }
25388 var group = new Group();
25389 component.container = group;
25390 // 设置ref
25391 if (ref) {
25392 ref.current = component;
25393 }
25394 component.context = componentContext;
25395 component.updater = updater;
25396 component.animator = animator;
25397 component._vNode = vNode;
25398 vNode.shape = group;
25399 vNode.component = component;
25400 }
25401 if (transformFrom && transformFrom.current) {
25402 var transformVNode = transformFrom.current._vNode;
25403 vNode.transform = findClosestShapeNode(transformVNode);
25404 if (vNode.transform) {
25405 vNode.transform.parent.children = null;
25406 }
25407 }
25408 return vNode;
25409 }
25410 function updateVNode(parent, nextNode, lastNode) {
25411 var canvas = parent.canvas,
25412 context = parent.context,
25413 updater = parent.updater,
25414 parentAnimate = parent.animate;
25415 var tag = lastNode.tag,
25416 animator = lastNode.animator,
25417 component = lastNode.component,
25418 shape = lastNode.shape,
25419 children = lastNode.children,
25420 lastProps = lastNode.props;
25421 var type = nextNode.type,
25422 props = nextNode.props;
25423 var animate = props.animate;
25424 animator.vNode = nextNode;
25425 nextNode.parent = parent;
25426 nextNode.tag = tag;
25427 nextNode.canvas = canvas;
25428 nextNode.context = readVNodeContext(type, context);
25429 nextNode.updater = updater;
25430 nextNode.component = component;
25431 nextNode.shape = updateShape(shape, props, lastProps);
25432 nextNode.parent = parent;
25433 nextNode.children = children;
25434 nextNode.animate = isBoolean(animate) ? animate : parentAnimate;
25435 nextNode.animator = animator;
25436 nextNode.style = getStyle$1(tag, props, context);
25437 // 更新 component
25438 if (component) {
25439 component._vNode = nextNode;
25440 } else {
25441 // 说明是 shape 标签
25442 // @ts-ignore
25443 shape._vNode = nextNode;
25444 }
25445 return nextNode;
25446 }
25447 function createElement(parent, element) {
25448 return Children.map(element, function (el) {
25449 if (!el) return el;
25450 return createVNode(parent, el);
25451 });
25452 }
25453 function destroyElement(vNode) {
25454 Children.map(vNode, function (node) {
25455 if (!node) return;
25456 var component = node.component,
25457 children = node.children;
25458 if (component) {
25459 component.willUnmount();
25460 destroyElement(children);
25461 component.didUnmount();
25462 component.destroy();
25463 } else {
25464 destroyElement(children);
25465 }
25466 });
25467 }
25468 function updateElement(parent, nextElement, lastElement) {
25469 var nextType = nextElement.type,
25470 nextProps = nextElement.props;
25471 var lastType = lastElement.type,
25472 lastProps = lastElement.props;
25473 if (nextType === lastType) {
25474 var nextVNode_1 = updateVNode(parent, nextElement, lastElement);
25475 // props 无变化 和 context 都无变化
25476 if (equal(nextProps, lastProps) && parent.context === lastElement.context) {
25477 return null;
25478 }
25479 return nextVNode_1;
25480 }
25481 var nextVNode = createVNode(parent, nextElement);
25482 destroyElement(lastElement);
25483 return nextVNode;
25484 }
25485 function diffElement(parent, nextElement, lastElement) {
25486 if (!nextElement && !lastElement) {
25487 return null;
25488 }
25489 // 删除
25490 if (!nextElement && lastElement) {
25491 destroyElement(lastElement);
25492 return null;
25493 }
25494 // 新建
25495 if (nextElement && !lastElement) {
25496 return createElement(parent, nextElement);
25497 }
25498 // 更新
25499 return updateElement(parent, nextElement, lastElement);
25500 }
25501 function renderComponentNodes(componentNodes) {
25502 if (!componentNodes || !componentNodes.length) {
25503 return;
25504 }
25505 // 1. shouldUpdate & willReceiveProps
25506 var shouldProcessChildren = componentNodes.filter(function (node) {
25507 var type = node.type,
25508 component = node.component,
25509 props = node.props,
25510 context = node.context,
25511 layout = node.layout;
25512 // 更新组件 layout
25513 component.layout = layout;
25514 // 新创建的 component
25515 if (!component.isMounted) return true;
25516 // 不需要更新
25517 if (component.shouldUpdate(props) === false) {
25518 return false;
25519 }
25520 var componentContext = readComponentContext(type, context);
25521 component.willReceiveProps(props, componentContext);
25522 component.props = props;
25523 component.context = context;
25524 return true;
25525 });
25526 if (!shouldProcessChildren.length) {
25527 return;
25528 }
25529 // 2. willMount / willUpdate
25530 shouldProcessChildren.forEach(function (child) {
25531 var component = child.component;
25532 if (!component.isMounted) {
25533 component.willMount();
25534 } else {
25535 component.willUpdate();
25536 }
25537 });
25538 // 3. render
25539 shouldProcessChildren.forEach(function (child) {
25540 var canvas = child.canvas,
25541 component = child.component,
25542 children = child.children;
25543 var newChildren = canvas.toRawChildren(component.render());
25544 renderChildren(child, newChildren, children);
25545 if (!component.isMounted) {
25546 component.didMount();
25547 component.isMounted = true;
25548 } else {
25549 component.didUpdate();
25550 }
25551 });
25552 }
25553 function renderVNode(vNode, nextChildren, lastChildren) {
25554 var component = vNode.component;
25555 // 不修改原始对象,这里重新 pick 一次,
25556 var newChildren = pickElement(nextChildren);
25557 // 设置新的 children
25558 vNode.children = newChildren;
25559 // 如果是组件,需要同时更新组件的 children
25560 // 等同于 vNode.tag === ClassComponent || vNode.tag === FunctionComponent
25561 if (component) {
25562 component.children = newChildren;
25563 }
25564 var componentNodeChildren = [];
25565 Children.compare(newChildren, lastChildren, function (next, last) {
25566 var element = diffElement(vNode, next, last);
25567 Children.map(element, function (child) {
25568 if (!child) return;
25569 var tag = child.tag,
25570 childProps = child.props,
25571 childLastChildren = child.children;
25572 var childrenNode = [];
25573 if (tag === Shape$1) {
25574 childrenNode = renderVNode(child, childProps.children, childLastChildren);
25575 } else {
25576 childrenNode = [child];
25577 }
25578 componentNodeChildren = componentNodeChildren.concat(childrenNode);
25579 });
25580 });
25581 return componentNodeChildren;
25582 }
25583 function renderChildren(parent, nextChildren, lastChildren) {
25584 // 返回的都是 classComponent 的节点
25585 var componentNodeChildren = renderVNode(parent, nextChildren, lastChildren);
25586 // 计算 flex 布局
25587 var nodeTree = createNodeTree(parent);
25588 computeLayout(nodeTree);
25589 fillElementLayout(nodeTree);
25590 fillComponentLayout(parent);
25591 var newChildren = parent.children;
25592 if (!componentNodeChildren.length) {
25593 return newChildren;
25594 }
25595 renderComponentNodes(componentNodeChildren);
25596 return newChildren;
25597 }
25598 function render(vNode) {
25599 var lastChildren = vNode.children,
25600 props = vNode.props;
25601 var nextChildren = props.children;
25602 // render 节点
25603 var children = renderChildren(vNode, nextChildren, lastChildren);
25604 // 创建动画
25605 var childrenAnimation = createAnimation(vNode, children, lastChildren);
25606 // 执行动画
25607 if (childrenAnimation.length) {
25608 childrenAnimation.forEach(function (animator) {
25609 animator.run();
25610 });
25611 }
25612 }
25613 // setState 触发的更新
25614 function updateComponents(components) {
25615 if (!components.length) return;
25616 components.forEach(function (component) {
25617 var vNode = component._vNode,
25618 lastChildren = component.children,
25619 props = component.props,
25620 animator = component.animator;
25621 // 是否需要更新
25622 if (component.shouldUpdate(props) === false) {
25623 return false;
25624 }
25625 component.willUpdate();
25626 var canvas = vNode.canvas;
25627 var newChildren = canvas.toRawChildren(component.render());
25628 var nextChildren = renderChildren(vNode, newChildren, lastChildren);
25629 // 更新 children
25630 component.children = nextChildren;
25631 vNode.children = nextChildren;
25632 // 创建动画
25633 var childrenAnimation = createAnimation(vNode, nextChildren, lastChildren);
25634 if (childrenAnimation.length) {
25635 animator.children = childrenAnimation;
25636 }
25637 // 执行动画
25638 animator.run();
25639 component.didUpdate();
25640 });
25641 }
25642 function getUpdateAnimation(component, newChildren, keyFrame) {
25643 var preNode = component.preNode;
25644 var lastChildren = preNode.children,
25645 props = preNode.props;
25646 // 是否需要更新
25647 if (component.shouldUpdate(props) === false) {
25648 return false;
25649 }
25650 component.willUpdate();
25651 var nextChildren = renderChildren(preNode, newChildren, lastChildren);
25652 // 更新 children
25653 component.preNode.children = nextChildren;
25654 // 创建动画
25655 var childrenAnimation = createAnimation(preNode, nextChildren, lastChildren);
25656 component.didUpdate();
25657 // 处理 animator
25658 var animUnits = calAnimationTime(childrenAnimation, keyFrame);
25659 return animUnits;
25660 }
25661
25662 function generatePath$6(context, parsedStyle) {
25663 var r = parsedStyle.r;
25664 context.arc(r, r, r, 0, Math.PI * 2, false);
25665 }
25666
25667 function generatePath$5(context, parsedStyle) {
25668 var rxInPixels = parsedStyle.rx, ryInPixels = parsedStyle.ry;
25669 var rx = rxInPixels;
25670 var ry = ryInPixels;
25671 // @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/ellipse
25672 if (context.ellipse) {
25673 context.ellipse(rx, ry, rx, ry, 0, 0, Math.PI * 2, false);
25674 }
25675 else {
25676 // 如果不支持,则使用圆来绘制,进行变形
25677 var r = rx > ry ? rx : ry;
25678 var scaleX = rx > ry ? 1 : rx / ry;
25679 var scaleY = rx > ry ? ry / rx : 1;
25680 context.save();
25681 context.scale(scaleX, scaleY);
25682 context.arc(r, r, r, 0, Math.PI * 2);
25683 }
25684 }
25685
25686 function generatePath$4(context, parsedStyle) {
25687 var x1 = parsedStyle.x1, y1 = parsedStyle.y1, x2 = parsedStyle.x2, y2 = parsedStyle.y2, _a = parsedStyle.defX, defX = _a === void 0 ? 0 : _a, _b = parsedStyle.defY, defY = _b === void 0 ? 0 : _b, markerStart = parsedStyle.markerStart, markerEnd = parsedStyle.markerEnd, markerStartOffset = parsedStyle.markerStartOffset, markerEndOffset = parsedStyle.markerEndOffset;
25688 var startOffsetX = 0;
25689 var startOffsetY = 0;
25690 var endOffsetX = 0;
25691 var endOffsetY = 0;
25692 var rad = 0;
25693 var x;
25694 var y;
25695 if (markerStart && isDisplayObject(markerStart) && markerStartOffset) {
25696 x = x2 - x1;
25697 y = y2 - y1;
25698 rad = Math.atan2(y, x);
25699 startOffsetX = Math.cos(rad) * (markerStartOffset || 0);
25700 startOffsetY = Math.sin(rad) * (markerStartOffset || 0);
25701 }
25702 if (markerEnd && isDisplayObject(markerEnd) && markerEndOffset) {
25703 x = x1 - x2;
25704 y = y1 - y2;
25705 rad = Math.atan2(y, x);
25706 endOffsetX = Math.cos(rad) * (markerEndOffset || 0);
25707 endOffsetY = Math.sin(rad) * (markerEndOffset || 0);
25708 }
25709 context.moveTo(x1 - defX + startOffsetX, y1 - defY + startOffsetY);
25710 context.lineTo(x2 - defX + endOffsetX, y2 - defY + endOffsetY);
25711 }
25712
25713 function generatePath$3(context, parsedStyle) {
25714 var _a = parsedStyle.defX, defX = _a === void 0 ? 0 : _a, _b = parsedStyle.defY, defY = _b === void 0 ? 0 : _b, markerStart = parsedStyle.markerStart, markerEnd = parsedStyle.markerEnd, markerStartOffset = parsedStyle.markerStartOffset, markerEndOffset = parsedStyle.markerEndOffset;
25715 var _c = parsedStyle.path, absolutePath = _c.absolutePath, segments = _c.segments;
25716 var startOffsetX = 0;
25717 var startOffsetY = 0;
25718 var endOffsetX = 0;
25719 var endOffsetY = 0;
25720 var rad = 0;
25721 var x;
25722 var y;
25723 if (markerStart && isDisplayObject(markerStart) && markerStartOffset) {
25724 var _d = __read(markerStart.parentNode.getStartTangent(), 2), p1 = _d[0], p2 = _d[1];
25725 x = p1[0] - p2[0];
25726 y = p1[1] - p2[1];
25727 rad = Math.atan2(y, x);
25728 startOffsetX = Math.cos(rad) * (markerStartOffset || 0);
25729 startOffsetY = Math.sin(rad) * (markerStartOffset || 0);
25730 }
25731 if (markerEnd && isDisplayObject(markerEnd) && markerEndOffset) {
25732 var _e = __read(markerEnd.parentNode.getEndTangent(), 2), p1 = _e[0], p2 = _e[1];
25733 x = p1[0] - p2[0];
25734 y = p1[1] - p2[1];
25735 rad = Math.atan2(y, x);
25736 endOffsetX = Math.cos(rad) * (markerEndOffset || 0);
25737 endOffsetY = Math.sin(rad) * (markerEndOffset || 0);
25738 }
25739 for (var i = 0; i < absolutePath.length; i++) {
25740 var params = absolutePath[i];
25741 var command = params[0];
25742 var nextSegment = absolutePath[i + 1];
25743 var useStartOffset = i === 0 && (startOffsetX !== 0 || startOffsetY !== 0);
25744 var useEndOffset = (i === absolutePath.length - 1 ||
25745 (nextSegment && (nextSegment[0] === 'M' || nextSegment[0] === 'Z'))) &&
25746 endOffsetX !== 0 &&
25747 endOffsetY !== 0;
25748 switch (command) {
25749 case 'M':
25750 // Use start marker offset
25751 if (useStartOffset) {
25752 context.moveTo(params[1] - defX + startOffsetX, params[2] - defY + startOffsetY);
25753 context.lineTo(params[1] - defX, params[2] - defY);
25754 }
25755 else {
25756 context.moveTo(params[1] - defX, params[2] - defY);
25757 }
25758 break;
25759 case 'L':
25760 if (useEndOffset) {
25761 context.lineTo(params[1] - defX + endOffsetX, params[2] - defY + endOffsetY);
25762 }
25763 else {
25764 context.lineTo(params[1] - defX, params[2] - defY);
25765 }
25766 break;
25767 case 'Q':
25768 context.quadraticCurveTo(params[1] - defX, params[2] - defY, params[3] - defX, params[4] - defY);
25769 if (useEndOffset) {
25770 context.lineTo(params[3] - defX + endOffsetX, params[4] - defY + endOffsetY);
25771 }
25772 break;
25773 case 'C':
25774 context.bezierCurveTo(params[1] - defX, params[2] - defY, params[3] - defX, params[4] - defY, params[5] - defX, params[6] - defY);
25775 if (useEndOffset) {
25776 context.lineTo(params[5] - defX + endOffsetX, params[6] - defY + endOffsetY);
25777 }
25778 break;
25779 case 'A': {
25780 var arcParams = segments[i].arcParams;
25781 var cx = arcParams.cx, cy = arcParams.cy, rx = arcParams.rx, ry = arcParams.ry, startAngle = arcParams.startAngle, endAngle = arcParams.endAngle, xRotation = arcParams.xRotation, sweepFlag = arcParams.sweepFlag;
25782 // @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/ellipse
25783 if (context.ellipse) {
25784 context.ellipse(cx - defX, cy - defY, rx, ry, xRotation, startAngle, endAngle, !!(1 - sweepFlag));
25785 }
25786 else {
25787 // @see https://stackoverflow.com/a/47494351
25788 var r = rx > ry ? rx : ry;
25789 var scaleX = rx > ry ? 1 : rx / ry;
25790 var scaleY = rx > ry ? ry / rx : 1;
25791 context.translate(cx - defX, cy - defY);
25792 context.rotate(xRotation);
25793 context.scale(scaleX, scaleY);
25794 context.arc(0, 0, r, startAngle, endAngle, !!(1 - sweepFlag));
25795 context.scale(1 / scaleX, 1 / scaleY);
25796 context.rotate(-xRotation);
25797 context.translate(-(cx - defX), -(cy - defY));
25798 }
25799 if (useEndOffset) {
25800 context.lineTo(params[6] - defX + endOffsetX, params[7] - defY + endOffsetY);
25801 }
25802 break;
25803 }
25804 case 'Z':
25805 context.closePath();
25806 break;
25807 }
25808 }
25809 }
25810
25811 function generatePath$2(context, parsedStyle) {
25812 var _a = parsedStyle.defX, defX = _a === void 0 ? 0 : _a, _b = parsedStyle.defY, defY = _b === void 0 ? 0 : _b, markerStart = parsedStyle.markerStart, markerEnd = parsedStyle.markerEnd, markerStartOffset = parsedStyle.markerStartOffset, markerEndOffset = parsedStyle.markerEndOffset;
25813 var points = parsedStyle.points.points;
25814 var length = points.length;
25815 var x1 = points[0][0] - defX;
25816 var y1 = points[0][1] - defY;
25817 var x2 = points[length - 1][0] - defX;
25818 var y2 = points[length - 1][1] - defY;
25819 var startOffsetX = 0;
25820 var startOffsetY = 0;
25821 var endOffsetX = 0;
25822 var endOffsetY = 0;
25823 var rad = 0;
25824 var x;
25825 var y;
25826 if (markerStart && isDisplayObject(markerStart) && markerStartOffset) {
25827 x = points[1][0] - points[0][0];
25828 y = points[1][1] - points[0][1];
25829 rad = Math.atan2(y, x);
25830 startOffsetX = Math.cos(rad) * (markerStartOffset || 0);
25831 startOffsetY = Math.sin(rad) * (markerStartOffset || 0);
25832 }
25833 if (markerEnd && isDisplayObject(markerEnd) && markerEndOffset) {
25834 x = points[length - 1][0] - points[0][0];
25835 y = points[length - 1][1] - points[0][1];
25836 rad = Math.atan2(y, x);
25837 endOffsetX = Math.cos(rad) * (markerEndOffset || 0);
25838 endOffsetY = Math.sin(rad) * (markerEndOffset || 0);
25839 }
25840 context.moveTo(x1 + (startOffsetX || endOffsetX), y1 + (startOffsetY || endOffsetY));
25841 for (var i = 1; i < length - 1; i++) {
25842 var point = points[i];
25843 context.lineTo(point[0] - defX, point[1] - defY);
25844 }
25845 context.lineTo(x2, y2);
25846 }
25847
25848 function generatePath$1(context, parsedStyle) {
25849 var _a = parsedStyle.defX, defX = _a === void 0 ? 0 : _a, _b = parsedStyle.defY, defY = _b === void 0 ? 0 : _b, markerStart = parsedStyle.markerStart, markerEnd = parsedStyle.markerEnd, markerStartOffset = parsedStyle.markerStartOffset, markerEndOffset = parsedStyle.markerEndOffset;
25850 var points = parsedStyle.points.points;
25851 var length = points.length;
25852 var x1 = points[0][0] - defX;
25853 var y1 = points[0][1] - defY;
25854 var x2 = points[length - 1][0] - defX;
25855 var y2 = points[length - 1][1] - defY;
25856 var startOffsetX = 0;
25857 var startOffsetY = 0;
25858 var endOffsetX = 0;
25859 var endOffsetY = 0;
25860 var rad = 0;
25861 var x;
25862 var y;
25863 if (markerStart && isDisplayObject(markerStart) && markerStartOffset) {
25864 x = points[1][0] - points[0][0];
25865 y = points[1][1] - points[0][1];
25866 rad = Math.atan2(y, x);
25867 startOffsetX = Math.cos(rad) * (markerStartOffset || 0);
25868 startOffsetY = Math.sin(rad) * (markerStartOffset || 0);
25869 }
25870 if (markerEnd && isDisplayObject(markerEnd) && markerEndOffset) {
25871 x = points[length - 2][0] - points[length - 1][0];
25872 y = points[length - 2][1] - points[length - 1][1];
25873 rad = Math.atan2(y, x);
25874 endOffsetX = Math.cos(rad) * (markerEndOffset || 0);
25875 endOffsetY = Math.sin(rad) * (markerEndOffset || 0);
25876 }
25877 context.moveTo(x1 + startOffsetX, y1 + startOffsetY);
25878 for (var i = 1; i < length - 1; i++) {
25879 var point = points[i];
25880 context.lineTo(point[0] - defX, point[1] - defY);
25881 }
25882 context.lineTo(x2 + endOffsetX, y2 + endOffsetY);
25883 }
25884
25885 function generatePath(context, parsedStyle) {
25886 var radius = parsedStyle.radius, width = parsedStyle.width, height = parsedStyle.height;
25887 var w = width;
25888 var h = height;
25889 var hasRadius = radius && radius.some(function (r) { return r !== 0; });
25890 if (!hasRadius) {
25891 // Canvas support negative width/height of rect
25892 context.rect(0, 0, w, h);
25893 }
25894 else {
25895 var signX = width > 0 ? 1 : -1;
25896 var signY = height > 0 ? 1 : -1;
25897 var sweepFlag = signX + signY === 0;
25898 var _a = __read(radius.map(function (r) {
25899 return clamp(r, 0, Math.min(Math.abs(w) / 2, Math.abs(h) / 2));
25900 }), 4), tlr = _a[0], trr = _a[1], brr = _a[2], blr = _a[3];
25901 context.moveTo(signX * tlr, 0);
25902 context.lineTo(w - signX * trr, 0);
25903 if (trr !== 0) {
25904 context.arc(w - signX * trr, signY * trr, trr, (-signY * Math.PI) / 2, signX > 0 ? 0 : Math.PI, sweepFlag);
25905 }
25906 context.lineTo(w, h - signY * brr);
25907 if (brr !== 0) {
25908 context.arc(w - signX * brr, h - signY * brr, brr, signX > 0 ? 0 : Math.PI, signY > 0 ? Math.PI / 2 : 1.5 * Math.PI, sweepFlag);
25909 }
25910 context.lineTo(signX * blr, h);
25911 if (blr !== 0) {
25912 context.arc(signX * blr, h - signY * blr, blr, signY > 0 ? Math.PI / 2 : -Math.PI / 2, signX > 0 ? Math.PI : 0, sweepFlag);
25913 }
25914 context.lineTo(0, signY * tlr);
25915 if (tlr !== 0) {
25916 context.arc(signX * tlr, signY * tlr, tlr, signX > 0 ? Math.PI : 0, signY > 0 ? Math.PI * 1.5 : Math.PI / 2, sweepFlag);
25917 }
25918 }
25919 }
25920
25921 var Plugin = /** @class */ (function (_super) {
25922 __extends(Plugin, _super);
25923 function Plugin() {
25924 var _this = _super.apply(this, __spreadArray([], __read(arguments), false)) || this;
25925 _this.name = 'canvas-path-generator';
25926 return _this;
25927 }
25928 Plugin.prototype.init = function () {
25929 var _a;
25930 var pathGeneratorFactory = (_a = {},
25931 _a[Shape.CIRCLE] = generatePath$6,
25932 _a[Shape.ELLIPSE] = generatePath$5,
25933 _a[Shape.RECT] = generatePath,
25934 _a[Shape.LINE] = generatePath$4,
25935 _a[Shape.POLYLINE] = generatePath$1,
25936 _a[Shape.POLYGON] = generatePath$2,
25937 _a[Shape.PATH] = generatePath$3,
25938 _a[Shape.TEXT] = undefined,
25939 _a[Shape.GROUP] = undefined,
25940 _a[Shape.IMAGE] = undefined,
25941 _a[Shape.HTML] = undefined,
25942 _a[Shape.MESH] = undefined,
25943 _a);
25944 // @ts-ignore
25945 this.context.pathGeneratorFactory = pathGeneratorFactory;
25946 };
25947 Plugin.prototype.destroy = function () {
25948 // @ts-ignore
25949 delete this.context.pathGeneratorFactory;
25950 };
25951 return Plugin;
25952 }(AbstractRendererPlugin));
25953
25954 var tmpVec3a = create$2();
25955 var tmpVec3b = create$2();
25956 var tmpVec3c = create$2();
25957 var tmpMat4$1 = create$1();
25958 /**
25959 * pick shape(s) with Mouse/Touch event
25960 *
25961 * 1. find AABB with r-tree
25962 * 2. do math calculation with geometry in an accurate way
25963 */
25964 var CanvasPickerPlugin = /** @class */ (function () {
25965 function CanvasPickerPlugin() {
25966 var _this = this;
25967 this.isHit = function (displayObject, position, worldTransform, isClipPath) {
25968 // use picker for current shape's type
25969 var pick = _this.context.pointInPathPickerFactory[displayObject.nodeName];
25970 if (pick) {
25971 // invert with world matrix
25972 var invertWorldMat = invert(tmpMat4$1, worldTransform);
25973 // transform client position to local space, do picking in local space
25974 var localPosition = transformMat4(tmpVec3b, set$1(tmpVec3c, position[0], position[1], 0), invertWorldMat);
25975 // account for anchor
25976 var halfExtents = displayObject.getGeometryBounds().halfExtents;
25977 var anchor = displayObject.parsedStyle.anchor;
25978 localPosition[0] += ((anchor && anchor[0]) || 0) * halfExtents[0] * 2;
25979 localPosition[1] += ((anchor && anchor[1]) || 0) * halfExtents[1] * 2;
25980 if (pick(displayObject, new Point(localPosition[0], localPosition[1]), isClipPath, _this.isPointInPath, _this.context, _this.runtime)) {
25981 return true;
25982 }
25983 }
25984 return false;
25985 };
25986 /**
25987 * use native picking method
25988 * @see https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/isPointInPath
25989 */
25990 this.isPointInPath = function (displayObject, position) {
25991 var context = _this.runtime.offscreenCanvasCreator.getOrCreateContext(_this.context.config.offscreenCanvas);
25992 var generatePath = _this.context.pathGeneratorFactory[displayObject.nodeName];
25993 if (generatePath) {
25994 context.beginPath();
25995 generatePath(context, displayObject.parsedStyle);
25996 context.closePath();
25997 }
25998 return context.isPointInPath(position.x, position.y);
25999 };
26000 }
26001 CanvasPickerPlugin.prototype.apply = function (context, runtime) {
26002 var _this = this;
26003 var _a;
26004 var renderingService = context.renderingService, renderingContext = context.renderingContext;
26005 this.context = context;
26006 this.runtime = runtime;
26007 var document = (_a = renderingContext.root) === null || _a === void 0 ? void 0 : _a.ownerDocument;
26008 renderingService.hooks.pick.tapPromise(CanvasPickerPlugin.tag, function (result) { return __awaiter(_this, void 0, void 0, function () {
26009 return __generator(this, function (_a) {
26010 return [2 /*return*/, this.pick(document, result)];
26011 });
26012 }); });
26013 renderingService.hooks.pickSync.tap(CanvasPickerPlugin.tag, function (result) {
26014 return _this.pick(document, result);
26015 });
26016 };
26017 CanvasPickerPlugin.prototype.pick = function (document, result) {
26018 var e_1, _a;
26019 var topmost = result.topmost, _b = result.position, x = _b.x, y = _b.y;
26020 // position in world space
26021 var position = set$1(tmpVec3a, x, y, 0);
26022 // query by AABB first with spatial index(r-tree)
26023 var hitTestList = document.elementsFromBBox(position[0], position[1], position[0], position[1]);
26024 // test with clip path & origin shape
26025 // @see https://github.com/antvis/g/issues/1064
26026 var pickedDisplayObjects = [];
26027 try {
26028 for (var hitTestList_1 = __values(hitTestList), hitTestList_1_1 = hitTestList_1.next(); !hitTestList_1_1.done; hitTestList_1_1 = hitTestList_1.next()) {
26029 var displayObject = hitTestList_1_1.value;
26030 var worldTransform = displayObject.getWorldTransform();
26031 var isHitOriginShape = this.isHit(displayObject, position, worldTransform, false);
26032 if (isHitOriginShape) {
26033 // should look up in the ancestor node
26034 var clipped = findClosestClipPathTarget(displayObject);
26035 if (clipped) {
26036 var clipPath = clipped.parsedStyle.clipPath;
26037 var isHitClipPath = this.isHit(clipPath, position, clipPath.getWorldTransform(), true);
26038 if (isHitClipPath) {
26039 if (topmost) {
26040 result.picked = [displayObject];
26041 return result;
26042 }
26043 else {
26044 pickedDisplayObjects.push(displayObject);
26045 }
26046 }
26047 }
26048 else {
26049 if (topmost) {
26050 result.picked = [displayObject];
26051 return result;
26052 }
26053 else {
26054 pickedDisplayObjects.push(displayObject);
26055 }
26056 }
26057 }
26058 }
26059 }
26060 catch (e_1_1) { e_1 = { error: e_1_1 }; }
26061 finally {
26062 try {
26063 if (hitTestList_1_1 && !hitTestList_1_1.done && (_a = hitTestList_1.return)) _a.call(hitTestList_1);
26064 }
26065 finally { if (e_1) throw e_1.error; }
26066 }
26067 result.picked = pickedDisplayObjects;
26068 return result;
26069 };
26070 CanvasPickerPlugin.tag = 'CanvasPicker';
26071 return CanvasPickerPlugin;
26072 }());
26073
26074 function isPointInPath$7(displayObject, position, isClipPath) {
26075 var _a = displayObject.parsedStyle, r = _a.r, fill = _a.fill, stroke = _a.stroke, lineWidth = _a.lineWidth, increasedLineWidthForHitTesting = _a.increasedLineWidthForHitTesting, pointerEvents = _a.pointerEvents;
26076 var halfLineWidth = ((lineWidth || 0) + (increasedLineWidthForHitTesting || 0)) / 2;
26077 var absDistance = distance$1(r, r, position.x, position.y);
26078 var _b = __read(isFillOrStrokeAffected(pointerEvents, fill, stroke), 2), hasFill = _b[0], hasStroke = _b[1];
26079 if ((hasFill && hasStroke) || isClipPath) {
26080 return absDistance <= r + halfLineWidth;
26081 }
26082 if (hasFill) {
26083 return absDistance <= r;
26084 }
26085 if (hasStroke) {
26086 return absDistance >= r - halfLineWidth && absDistance <= r + halfLineWidth;
26087 }
26088 return false;
26089 }
26090
26091 function ellipseDistance(squareX, squareY, rx, ry) {
26092 return squareX / (rx * rx) + squareY / (ry * ry);
26093 }
26094 function isPointInPath$6(displayObject, position, isClipPath) {
26095 var _a = displayObject.parsedStyle, rx = _a.rx, ry = _a.ry, fill = _a.fill, stroke = _a.stroke, lineWidth = _a.lineWidth, increasedLineWidthForHitTesting = _a.increasedLineWidthForHitTesting, pointerEvents = _a.pointerEvents;
26096 var x = position.x, y = position.y;
26097 var _b = __read(isFillOrStrokeAffected(pointerEvents, fill, stroke), 2), hasFill = _b[0], hasStroke = _b[1];
26098 var halfLineWith = ((lineWidth || 0) + (increasedLineWidthForHitTesting || 0)) / 2;
26099 var squareX = (x - rx) * (x - rx);
26100 var squareY = (y - ry) * (y - ry);
26101 // 使用椭圆的公式: x*x/rx*rx + y*y/ry*ry = 1;
26102 if ((hasFill && hasStroke) || isClipPath) {
26103 return (ellipseDistance(squareX, squareY, rx + halfLineWith, ry + halfLineWith) <=
26104 1);
26105 }
26106 if (hasFill) {
26107 return ellipseDistance(squareX, squareY, rx, ry) <= 1;
26108 }
26109 if (hasStroke) {
26110 return (ellipseDistance(squareX, squareY, rx - halfLineWith, ry - halfLineWith) >=
26111 1 &&
26112 ellipseDistance(squareX, squareY, rx + halfLineWith, ry + halfLineWith) <=
26113 1);
26114 }
26115 return false;
26116 }
26117
26118 function inBox(minX, minY, width, height, x, y) {
26119 return x >= minX && x <= minX + width && y >= minY && y <= minY + height;
26120 }
26121 function inRect(minX, minY, width, height, lineWidth, x, y) {
26122 var halfWidth = lineWidth / 2;
26123 // 将四个边看做矩形来检测,比边的检测算法要快
26124 return (inBox(minX - halfWidth, minY - halfWidth, width, lineWidth, x, y) || // 上边
26125 inBox(minX + width - halfWidth, minY - halfWidth, lineWidth, height, x, y) || // 右边
26126 inBox(minX + halfWidth, minY + height - halfWidth, width, lineWidth, x, y) || // 下边
26127 inBox(minX - halfWidth, minY + halfWidth, lineWidth, height, x, y)); // 左边
26128 }
26129 function inArc(cx, cy, r, startAngle, endAngle, lineWidth, x, y) {
26130 var angle = (Math.atan2(y - cy, x - cx) + Math.PI * 2) % (Math.PI * 2); // 转换到 0 - 2 * Math.PI 之间
26131 // if (angle < startAngle || angle > endAngle) {
26132 // return false;
26133 // }
26134 var point = {
26135 x: cx + r * Math.cos(angle),
26136 y: cy + r * Math.sin(angle),
26137 };
26138 return distance$1(point.x, point.y, x, y) <= lineWidth / 2;
26139 }
26140 function inLine(x1, y1, x2, y2, lineWidth, x, y) {
26141 var minX = Math.min(x1, x2);
26142 var maxX = Math.max(x1, x2);
26143 var minY = Math.min(y1, y2);
26144 var maxY = Math.max(y1, y2);
26145 var halfWidth = lineWidth / 2;
26146 // 因为目前的方案是计算点到直线的距离,而有可能会在延长线上,所以要先判断是否在包围盒内
26147 // 这种方案会在水平或者竖直的情况下载线的延长线上有半 lineWidth 的误差
26148 if (!(x >= minX - halfWidth &&
26149 x <= maxX + halfWidth &&
26150 y >= minY - halfWidth &&
26151 y <= maxY + halfWidth)) {
26152 return false;
26153 }
26154 // 因为已经计算了包围盒,所以仅需要计算到直线的距离即可,可以显著提升性能
26155 return pointToLine(x1, y1, x2, y2, x, y) <= lineWidth / 2;
26156 }
26157 function inPolyline(points, lineWidth, x, y, isClose) {
26158 var count = points.length;
26159 if (count < 2) {
26160 return false;
26161 }
26162 for (var i = 0; i < count - 1; i++) {
26163 var x1 = points[i][0];
26164 var y1 = points[i][1];
26165 var x2 = points[i + 1][0];
26166 var y2 = points[i + 1][1];
26167 if (inLine(x1, y1, x2, y2, lineWidth, x, y)) {
26168 return true;
26169 }
26170 }
26171 // 如果封闭,则计算起始点和结束点的边
26172 if (isClose) {
26173 var first = points[0];
26174 var last = points[count - 1];
26175 if (inLine(first[0], first[1], last[0], last[1], lineWidth, x, y)) {
26176 return true;
26177 }
26178 }
26179 return false;
26180 }
26181 // 多边形的射线检测,参考:https://blog.csdn.net/WilliamSun0122/article/details/77994526
26182 var tolerance = 1e-6;
26183 // 三态函数,判断两个double在eps精度下的大小关系
26184 function dcmp(x) {
26185 if (Math.abs(x) < tolerance) {
26186 return 0;
26187 }
26188 return x < 0 ? -1 : 1;
26189 }
26190 // 判断点Q是否在p1和p2的线段上
26191 function onSegment(p1, p2, q) {
26192 if ((q[0] - p1[0]) * (p2[1] - p1[1]) === (p2[0] - p1[0]) * (q[1] - p1[1]) &&
26193 Math.min(p1[0], p2[0]) <= q[0] &&
26194 q[0] <= Math.max(p1[0], p2[0]) &&
26195 Math.min(p1[1], p2[1]) <= q[1] &&
26196 q[1] <= Math.max(p1[1], p2[1])) {
26197 return true;
26198 }
26199 return false;
26200 }
26201 // 判断点P在多边形内-射线法
26202 function inPolygon(points, x, y) {
26203 var isHit = false;
26204 var n = points.length;
26205 if (n <= 2) {
26206 // svg 中点小于 3 个时,不显示,也无法被拾取
26207 return false;
26208 }
26209 for (var i = 0; i < n; i++) {
26210 var p1 = points[i];
26211 var p2 = points[(i + 1) % n];
26212 if (onSegment(p1, p2, [x, y])) {
26213 // 点在多边形一条边上
26214 return true;
26215 }
26216 // 前一个判断min(p1[1],p2[1])<P.y<=max(p1[1],p2[1])
26217 // 后一个判断被测点 在 射线与边交点 的左边
26218 if (dcmp(p1[1] - y) > 0 !== dcmp(p2[1] - y) > 0 &&
26219 dcmp(x - ((y - p1[1]) * (p1[0] - p2[0])) / (p1[1] - p2[1]) - p1[0]) < 0) {
26220 isHit = !isHit;
26221 }
26222 }
26223 return isHit;
26224 }
26225 function inPolygons(polygons, x, y) {
26226 var isHit = false;
26227 for (var i = 0; i < polygons.length; i++) {
26228 var points = polygons[i];
26229 isHit = inPolygon(points, x, y);
26230 if (isHit) {
26231 break;
26232 }
26233 }
26234 return isHit;
26235 }
26236
26237 function isPointInPath$5(displayObject, position, isClipPath) {
26238 var _a = displayObject.parsedStyle, x1 = _a.x1, y1 = _a.y1, x2 = _a.x2, y2 = _a.y2, lineWidth = _a.lineWidth, increasedLineWidthForHitTesting = _a.increasedLineWidthForHitTesting, _b = _a.defX, x = _b === void 0 ? 0 : _b, _c = _a.defY, y = _c === void 0 ? 0 : _c, pointerEvents = _a.pointerEvents, fill = _a.fill, stroke = _a.stroke;
26239 var _d = __read(isFillOrStrokeAffected(pointerEvents, fill, stroke), 2), hasStroke = _d[1];
26240 if ((!hasStroke && !isClipPath) || !lineWidth) {
26241 return false;
26242 }
26243 return inLine(x1, y1, x2, y2, (lineWidth || 0) + (increasedLineWidthForHitTesting || 0), position.x + x, position.y + y);
26244 }
26245
26246 // TODO: replace it with method in @antv/util
26247 function isPointInStroke(segments, lineWidth, px, py, length) {
26248 var isHit = false;
26249 var halfWidth = lineWidth / 2;
26250 for (var i = 0; i < segments.length; i++) {
26251 var segment = segments[i];
26252 var currentPoint = segment.currentPoint, params = segment.params, prePoint = segment.prePoint, box = segment.box;
26253 // 如果在前面已经生成过包围盒,直接按照包围盒计算
26254 if (box &&
26255 !inBox(box.x - halfWidth, box.y - halfWidth, box.width + lineWidth, box.height + lineWidth, px, py)) {
26256 continue;
26257 }
26258 switch (segment.command) {
26259 // L 和 Z 都是直线, M 不进行拾取
26260 case 'L':
26261 case 'Z':
26262 isHit = inLine(prePoint[0], prePoint[1], currentPoint[0], currentPoint[1], lineWidth, px, py);
26263 if (isHit) {
26264 return true;
26265 }
26266 break;
26267 case 'Q':
26268 var qDistance = pointDistance(prePoint[0], prePoint[1], params[1], params[2], params[3], params[4], px, py);
26269 isHit = qDistance <= lineWidth / 2;
26270 if (isHit) {
26271 return true;
26272 }
26273 break;
26274 case 'C':
26275 var cDistance = pointDistance$3(prePoint[0], // 上一段结束位置, 即 C 的起始点
26276 prePoint[1], params[1], // 'C' 的参数,1、2 为第一个控制点,3、4 为第二个控制点,5、6 为结束点
26277 params[2], params[3], params[4], params[5], params[6], px, py, length);
26278 isHit = cDistance <= lineWidth / 2;
26279 if (isHit) {
26280 return true;
26281 }
26282 break;
26283 case 'A':
26284 // cache conversion result
26285 if (!segment.cubicParams) {
26286 segment.cubicParams = arcToCubic(prePoint[0], prePoint[1], params[1], params[2], params[3], params[4], params[5], params[6], params[7], undefined);
26287 }
26288 var args = segment.cubicParams;
26289 // fixArc
26290 var prePointInCubic = prePoint;
26291 for (var i_1 = 0; i_1 < args.length; i_1 += 6) {
26292 var cDistance_1 = pointDistance$3(prePointInCubic[0], // 上一段结束位置, 即 C 的起始点
26293 prePointInCubic[1], args[i_1], args[i_1 + 1], args[i_1 + 2], args[i_1 + 3], args[i_1 + 4], args[i_1 + 5], px, py, length);
26294 prePointInCubic = [args[i_1 + 4], args[i_1 + 5]];
26295 isHit = cDistance_1 <= lineWidth / 2;
26296 if (isHit) {
26297 return true;
26298 }
26299 }
26300 break;
26301 }
26302 }
26303 return isHit;
26304 }
26305 function isPointInPath$4(displayObject, position, isClipPath, isPointInPath, renderingPluginContext, runtime) {
26306 var _a = displayObject.parsedStyle, lineWidth = _a.lineWidth, increasedLineWidthForHitTesting = _a.increasedLineWidthForHitTesting, stroke = _a.stroke, fill = _a.fill, _b = _a.defX, x = _b === void 0 ? 0 : _b, _c = _a.defY, y = _c === void 0 ? 0 : _c, path = _a.path, pointerEvents = _a.pointerEvents;
26307 var segments = path.segments, hasArc = path.hasArc, polylines = path.polylines, polygons = path.polygons;
26308 var _d = __read(isFillOrStrokeAffected(pointerEvents,
26309 // Only a closed path can be filled.
26310 (polygons === null || polygons === void 0 ? void 0 : polygons.length) && fill, stroke), 2), hasFill = _d[0], hasStroke = _d[1];
26311 var totalLength = getOrCalculatePathTotalLength(displayObject);
26312 var isHit = false;
26313 if (hasFill || isClipPath) {
26314 if (hasArc) {
26315 // 存在曲线时,暂时使用 canvas 的 api 计算,后续可以进行多边形切割
26316 isHit = isPointInPath(displayObject, position);
26317 }
26318 else {
26319 // 提取出来的多边形包含闭合的和非闭合的,在这里统一按照多边形处理
26320 isHit =
26321 inPolygons(polygons, position.x + x, position.y + y) ||
26322 inPolygons(polylines, position.x + x, position.y + y);
26323 }
26324 return isHit;
26325 }
26326 else if (hasStroke || isClipPath) {
26327 isHit = isPointInStroke(segments, (lineWidth || 0) + (increasedLineWidthForHitTesting || 0), position.x + x, position.y + y, totalLength);
26328 }
26329 return isHit;
26330 }
26331
26332 function isPointInPath$3(displayObject, position, isClipPath) {
26333 var _a = displayObject.parsedStyle, stroke = _a.stroke, fill = _a.fill, lineWidth = _a.lineWidth, increasedLineWidthForHitTesting = _a.increasedLineWidthForHitTesting, points = _a.points, _b = _a.defX, x = _b === void 0 ? 0 : _b, _c = _a.defY, y = _c === void 0 ? 0 : _c, pointerEvents = _a.pointerEvents;
26334 var _d = __read(isFillOrStrokeAffected(pointerEvents, fill, stroke), 2), hasFill = _d[0], hasStroke = _d[1];
26335 var isHit = false;
26336 if (hasStroke || isClipPath) {
26337 isHit = inPolyline(points.points, (lineWidth || 0) + (increasedLineWidthForHitTesting || 0), position.x + x, position.y + y, true);
26338 }
26339 if (!isHit && (hasFill || isClipPath)) {
26340 isHit = inPolygon(points.points, position.x + x, position.y + y);
26341 }
26342 return isHit;
26343 }
26344
26345 function isPointInPath$2(displayObject, position, isClipPath) {
26346 var _a = displayObject.parsedStyle, lineWidth = _a.lineWidth, increasedLineWidthForHitTesting = _a.increasedLineWidthForHitTesting, points = _a.points, _b = _a.defX, x = _b === void 0 ? 0 : _b, _c = _a.defY, y = _c === void 0 ? 0 : _c, pointerEvents = _a.pointerEvents, fill = _a.fill, stroke = _a.stroke;
26347 var _d = __read(isFillOrStrokeAffected(pointerEvents, fill, stroke), 2), hasStroke = _d[1];
26348 if ((!hasStroke && !isClipPath) || !lineWidth) {
26349 return false;
26350 }
26351 return inPolyline(points.points, (lineWidth || 0) + (increasedLineWidthForHitTesting || 0), position.x + x, position.y + y, false);
26352 }
26353
26354 function isPointInPath$1(displayObject, position, isClipPath, isPointInPath, runtime) {
26355 var _a = displayObject.parsedStyle, radius = _a.radius, fill = _a.fill, stroke = _a.stroke, lineWidth = _a.lineWidth, increasedLineWidthForHitTesting = _a.increasedLineWidthForHitTesting, width = _a.width, height = _a.height, pointerEvents = _a.pointerEvents;
26356 var _b = __read(isFillOrStrokeAffected(pointerEvents, fill, stroke), 2), hasFill = _b[0], hasStroke = _b[1];
26357 var hasRadius = radius && radius.some(function (r) { return r !== 0; });
26358 var lineWidthForHitTesting = (lineWidth || 0) + (increasedLineWidthForHitTesting || 0);
26359 // 无圆角时的策略
26360 if (!hasRadius) {
26361 var halfWidth = lineWidthForHitTesting / 2;
26362 // 同时填充和带有边框
26363 if ((hasFill && hasStroke) || isClipPath) {
26364 return inBox(0 - halfWidth, 0 - halfWidth, width + halfWidth, height + halfWidth, position.x, position.y);
26365 }
26366 // 仅填充
26367 if (hasFill) {
26368 return inBox(0, 0, width, height, position.x, position.y);
26369 }
26370 if (hasStroke) {
26371 return inRect(0, 0, width, height, lineWidthForHitTesting, position.x, position.y);
26372 }
26373 }
26374 else {
26375 var isHit = false;
26376 if (hasStroke || isClipPath) {
26377 isHit = inRectWithRadius(0, 0, width, height, radius.map(function (r) {
26378 return clamp(r, 0, Math.min(Math.abs(width) / 2, Math.abs(height) / 2));
26379 }), lineWidthForHitTesting, position.x, position.y);
26380 }
26381 // 仅填充时带有圆角的矩形直接通过图形拾取
26382 // 以后可以改成纯数学的近似拾取,将圆弧切割成多边形
26383 if (!isHit && (hasFill || isClipPath)) {
26384 isHit = isPointInPath(displayObject, position);
26385 }
26386 return isHit;
26387 }
26388 return false;
26389 }
26390 function inRectWithRadius(minX, minY, width, height, radiusArray, lineWidth, x, y) {
26391 var _a = __read(radiusArray, 4), tlr = _a[0], trr = _a[1], brr = _a[2], blr = _a[3];
26392 return (inLine(minX + tlr, minY, minX + width - trr, minY, lineWidth, x, y) ||
26393 inLine(minX + width, minY + trr, minX + width, minY + height - brr, lineWidth, x, y) ||
26394 inLine(minX + width - brr, minY + height, minX + blr, minY + height, lineWidth, x, y) ||
26395 inLine(minX, minY + height - blr, minX, minY + tlr, lineWidth, x, y) ||
26396 inArc(minX + width - trr, minY + trr, trr, 1.5 * Math.PI, 2 * Math.PI, lineWidth, x, y) ||
26397 inArc(minX + width - brr, minY + height - brr, brr, 0, 0.5 * Math.PI, lineWidth, x, y) ||
26398 inArc(minX + blr, minY + height - blr, blr, 0.5 * Math.PI, Math.PI, lineWidth, x, y) ||
26399 inArc(minX + tlr, minY + tlr, tlr, Math.PI, 1.5 * Math.PI, lineWidth, x, y));
26400 }
26401
26402 function isPointInPath(displayObject, position, isClipPath, isPointInPath, renderingPluginContext, runtime) {
26403 var _a = displayObject.parsedStyle, pointerEvents = _a.pointerEvents, width = _a.width, height = _a.height;
26404 if (pointerEvents === 'non-transparent-pixel') {
26405 var offscreenCanvas = renderingPluginContext.config.offscreenCanvas;
26406 var canvas = runtime.offscreenCanvasCreator.getOrCreateCanvas(offscreenCanvas);
26407 var context = runtime.offscreenCanvasCreator.getOrCreateContext(offscreenCanvas, {
26408 willReadFrequently: true,
26409 });
26410 canvas.width = width;
26411 canvas.height = height;
26412 renderingPluginContext.defaultStyleRendererFactory[Shape.IMAGE].render(context, displayObject.parsedStyle, displayObject, undefined, undefined, undefined);
26413 var imagedata = context.getImageData(position.x, position.y, 1, 1).data;
26414 return imagedata.every(function (component) { return component !== 0; });
26415 }
26416 return true;
26417 }
26418
26419 var Plugin$1 = /** @class */ (function (_super) {
26420 __extends(Plugin, _super);
26421 function Plugin() {
26422 var _this = _super.apply(this, __spreadArray([], __read(arguments), false)) || this;
26423 _this.name = 'canvas-picker';
26424 return _this;
26425 }
26426 Plugin.prototype.init = function () {
26427 var _a;
26428 var trueFunc = function () { return true; };
26429 var pointInPathPickerFactory = (_a = {},
26430 _a[Shape.CIRCLE] = isPointInPath$7,
26431 _a[Shape.ELLIPSE] = isPointInPath$6,
26432 _a[Shape.RECT] = isPointInPath$1,
26433 _a[Shape.LINE] = isPointInPath$5,
26434 _a[Shape.POLYLINE] = isPointInPath$2,
26435 _a[Shape.POLYGON] = isPointInPath$3,
26436 _a[Shape.PATH] = isPointInPath$4,
26437 _a[Shape.TEXT] = trueFunc,
26438 _a[Shape.GROUP] = null,
26439 _a[Shape.IMAGE] = isPointInPath,
26440 _a[Shape.HTML] = null,
26441 _a[Shape.MESH] = null,
26442 _a);
26443 // @ts-ignore
26444 this.context.pointInPathPickerFactory = pointInPathPickerFactory;
26445 this.addRenderingPlugin(new CanvasPickerPlugin());
26446 };
26447 Plugin.prototype.destroy = function () {
26448 // @ts-ignore
26449 delete this.context.pointInPathPickerFactory;
26450 this.removeAllRenderingPlugins();
26451 };
26452 return Plugin;
26453 }(AbstractRendererPlugin));
26454
26455 /**
26456 * support 2 modes in rendering:
26457 * * immediate
26458 * * delayed: render at the end of frame with dirty-rectangle
26459 */
26460 var CanvasRendererPlugin = /** @class */ (function () {
26461 function CanvasRendererPlugin(canvasRendererPluginOptions) {
26462 this.canvasRendererPluginOptions = canvasRendererPluginOptions;
26463 this.removedRBushNodeAABBs = [];
26464 this.renderQueue = [];
26465 /**
26466 * This stack is only used by clipPath for now.
26467 */
26468 this.restoreStack = [];
26469 this.clearFullScreen = false;
26470 /**
26471 * view projection matrix
26472 */
26473 this.vpMatrix = create$1();
26474 this.dprMatrix = create$1();
26475 this.tmpMat4 = create$1();
26476 this.vec3a = create$2();
26477 this.vec3b = create$2();
26478 this.vec3c = create$2();
26479 this.vec3d = create$2();
26480 }
26481 CanvasRendererPlugin.prototype.apply = function (context, runtime) {
26482 var _this = this;
26483 this.context = context;
26484 var config = context.config, camera = context.camera, renderingService = context.renderingService, renderingContext = context.renderingContext, rBushRoot = context.rBushRoot,
26485 // @ts-ignore
26486 pathGeneratorFactory = context.pathGeneratorFactory;
26487 this.rBush = rBushRoot;
26488 this.pathGeneratorFactory = pathGeneratorFactory;
26489 var contextService = context.contextService;
26490 var canvas = renderingContext.root.ownerDocument.defaultView;
26491 var handleUnmounted = function (e) {
26492 var object = e.target;
26493 // remove r-bush node
26494 // @ts-ignore
26495 var rBushNode = object.rBushNode;
26496 if (rBushNode.aabb) {
26497 // save removed aabbs for dirty-rectangle rendering later
26498 _this.removedRBushNodeAABBs.push(rBushNode.aabb);
26499 }
26500 };
26501 var handleCulled = function (e) {
26502 var object = e.target;
26503 // @ts-ignore
26504 var rBushNode = object.rBushNode;
26505 if (rBushNode.aabb) {
26506 // save removed aabbs for dirty-rectangle rendering later
26507 _this.removedRBushNodeAABBs.push(rBushNode.aabb);
26508 }
26509 };
26510 renderingService.hooks.init.tap(CanvasRendererPlugin.tag, function () {
26511 canvas.addEventListener(ElementEvent.UNMOUNTED, handleUnmounted);
26512 canvas.addEventListener(ElementEvent.CULLED, handleCulled);
26513 // clear fullscreen
26514 var dpr = contextService.getDPR();
26515 var width = config.width, height = config.height;
26516 var context = contextService.getContext();
26517 _this.clearRect(context, 0, 0, width * dpr, height * dpr, config.background);
26518 });
26519 renderingService.hooks.destroy.tap(CanvasRendererPlugin.tag, function () {
26520 canvas.removeEventListener(ElementEvent.UNMOUNTED, handleUnmounted);
26521 canvas.removeEventListener(ElementEvent.CULLED, handleCulled);
26522 _this.renderQueue = [];
26523 _this.removedRBushNodeAABBs = [];
26524 _this.restoreStack = [];
26525 });
26526 renderingService.hooks.beginFrame.tap(CanvasRendererPlugin.tag, function () {
26527 var context = contextService.getContext();
26528 var dpr = contextService.getDPR();
26529 var width = config.width, height = config.height;
26530 var _a = _this.canvasRendererPluginOptions, dirtyObjectNumThreshold = _a.dirtyObjectNumThreshold, dirtyObjectRatioThreshold = _a.dirtyObjectRatioThreshold;
26531 // some heuristic conditions such as 80% object changed
26532 var _b = renderingService.getStats(), total = _b.total, rendered = _b.rendered;
26533 var ratio = rendered / total;
26534 _this.clearFullScreen =
26535 renderingService.disableDirtyRectangleRendering() ||
26536 (rendered > dirtyObjectNumThreshold &&
26537 ratio > dirtyObjectRatioThreshold);
26538 if (context) {
26539 context.resetTransform
26540 ? context.resetTransform()
26541 : context.setTransform(1, 0, 0, 1, 0, 0);
26542 if (_this.clearFullScreen) {
26543 _this.clearRect(context, 0, 0, width * dpr, height * dpr, config.background);
26544 }
26545 }
26546 });
26547 var renderByZIndex = function (object, context) {
26548 if (object.isVisible() && !object.isCulled()) {
26549 _this.renderDisplayObject(object, context, _this.context, _this.restoreStack, runtime);
26550 // if (object.renderable.) {
26551 // if we did a full screen rendering last frame
26552 _this.saveDirtyAABB(object);
26553 // }
26554 }
26555 var sorted = object.sortable.sorted || object.childNodes;
26556 // should account for z-index
26557 sorted.forEach(function (child) {
26558 renderByZIndex(child, context);
26559 });
26560 };
26561 // render at the end of frame
26562 renderingService.hooks.endFrame.tap(CanvasRendererPlugin.tag, function () {
26563 var context = contextService.getContext();
26564 // clear & clip dirty rectangle
26565 var dpr = contextService.getDPR();
26566 fromScaling(_this.dprMatrix, [dpr, dpr, 1]);
26567 multiply(_this.vpMatrix, _this.dprMatrix, camera.getOrthoMatrix());
26568 // if (this.clearFullScreen) {
26569 if (_this.clearFullScreen) {
26570 // console.log('canvas renderer fcp...');
26571 renderByZIndex(renderingContext.root, context);
26572 }
26573 else {
26574 // console.log('canvas renderer next...');
26575 // merge removed AABB
26576 var dirtyRenderBounds = _this.safeMergeAABB.apply(_this, __spreadArray([_this.mergeDirtyAABBs(_this.renderQueue)], __read(_this.removedRBushNodeAABBs.map(function (_a) {
26577 var minX = _a.minX, minY = _a.minY, maxX = _a.maxX, maxY = _a.maxY;
26578 var aabb = new AABB();
26579 aabb.setMinMax(
26580 // vec3.fromValues(minX, minY, 0),
26581 // vec3.fromValues(maxX, maxY, 0),
26582 [minX, minY, 0], [maxX, maxY, 0]);
26583 return aabb;
26584 })), false));
26585 _this.removedRBushNodeAABBs = [];
26586 if (AABB.isEmpty(dirtyRenderBounds)) {
26587 _this.renderQueue = [];
26588 return;
26589 }
26590 var dirtyRect = _this.convertAABB2Rect(dirtyRenderBounds);
26591 var x = dirtyRect.x, y = dirtyRect.y, width = dirtyRect.width, height = dirtyRect.height;
26592 var tl = transformMat4(_this.vec3a, [x, y, 0], _this.vpMatrix);
26593 var tr = transformMat4(_this.vec3b, [x + width, y, 0], _this.vpMatrix);
26594 var bl = transformMat4(_this.vec3c, [x, y + height, 0], _this.vpMatrix);
26595 var br = transformMat4(_this.vec3d, [x + width, y + height, 0], _this.vpMatrix);
26596 var minx = Math.min(tl[0], tr[0], br[0], bl[0]);
26597 var miny = Math.min(tl[1], tr[1], br[1], bl[1]);
26598 var maxx = Math.max(tl[0], tr[0], br[0], bl[0]);
26599 var maxy = Math.max(tl[1], tr[1], br[1], bl[1]);
26600 var ix = Math.floor(minx);
26601 var iy = Math.floor(miny);
26602 var iwidth = Math.ceil(maxx - minx);
26603 var iheight = Math.ceil(maxy - miny);
26604 context.save();
26605 _this.clearRect(context, ix, iy, iwidth, iheight, config.background);
26606 context.beginPath();
26607 context.rect(ix, iy, iwidth, iheight);
26608 context.clip();
26609 // @see https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Transformations
26610 context.setTransform(_this.vpMatrix[0], _this.vpMatrix[1], _this.vpMatrix[4], _this.vpMatrix[5], _this.vpMatrix[12], _this.vpMatrix[13]);
26611 // draw dirty rectangle
26612 var enableDirtyRectangleRenderingDebug = config.renderer.getConfig().enableDirtyRectangleRenderingDebug;
26613 if (enableDirtyRectangleRenderingDebug) {
26614 canvas.dispatchEvent(new CustomEvent(CanvasEvent.DIRTY_RECTANGLE, {
26615 dirtyRect: {
26616 x: ix,
26617 y: iy,
26618 width: iwidth,
26619 height: iheight,
26620 },
26621 }));
26622 }
26623 // search objects intersect with dirty rectangle
26624 var dirtyObjects = _this.searchDirtyObjects(dirtyRenderBounds);
26625 // do rendering
26626 dirtyObjects
26627 // sort by z-index
26628 .sort(function (a, b) { return a.sortable.renderOrder - b.sortable.renderOrder; })
26629 .forEach(function (object) {
26630 // culled object should not be rendered
26631 if (object && object.isVisible() && !object.isCulled()) {
26632 _this.renderDisplayObject(object, context, _this.context, _this.restoreStack, runtime);
26633 }
26634 });
26635 context.restore();
26636 // save dirty AABBs in last frame
26637 _this.renderQueue.forEach(function (object) {
26638 _this.saveDirtyAABB(object);
26639 });
26640 // clear queue
26641 _this.renderQueue = [];
26642 }
26643 // pop restore stack, eg. root -> parent -> child
26644 _this.restoreStack.forEach(function () {
26645 context.restore();
26646 });
26647 // clear restore stack
26648 _this.restoreStack = [];
26649 });
26650 renderingService.hooks.render.tap(CanvasRendererPlugin.tag, function (object) {
26651 if (!_this.clearFullScreen) {
26652 // render at the end of frame
26653 _this.renderQueue.push(object);
26654 }
26655 });
26656 };
26657 CanvasRendererPlugin.prototype.clearRect = function (context, x, y, width, height, background) {
26658 // clearRect is faster than fillRect @see https://stackoverflow.com/a/30830253
26659 context.clearRect(x, y, width, height);
26660 if (background) {
26661 context.fillStyle = background;
26662 context.fillRect(x, y, width, height);
26663 }
26664 };
26665 CanvasRendererPlugin.prototype.renderDisplayObject = function (object, context, canvasContext, restoreStack, runtime) {
26666 var nodeName = object.nodeName;
26667 // console.log('canvas render:', object);
26668 // restore to its ancestor
26669 var parent = restoreStack[restoreStack.length - 1];
26670 if (parent &&
26671 !(object.compareDocumentPosition(parent) & Node.DOCUMENT_POSITION_CONTAINS)) {
26672 context.restore();
26673 restoreStack.pop();
26674 }
26675 // @ts-ignore
26676 var styleRenderer = this.context.styleRendererFactory[nodeName];
26677 var generatePath = this.pathGeneratorFactory[nodeName];
26678 // clip path
26679 var clipPath = object.parsedStyle.clipPath;
26680 if (clipPath) {
26681 this.applyWorldTransform(context, clipPath);
26682 // generate path in local space
26683 var generatePath_1 = this.pathGeneratorFactory[clipPath.nodeName];
26684 if (generatePath_1) {
26685 context.save();
26686 // save clip
26687 restoreStack.push(object);
26688 context.beginPath();
26689 generatePath_1(context, clipPath.parsedStyle);
26690 context.closePath();
26691 context.clip();
26692 }
26693 }
26694 // fill & stroke
26695 if (styleRenderer) {
26696 this.applyWorldTransform(context, object);
26697 context.save();
26698 // apply attributes to context
26699 this.applyAttributesToContext(context, object);
26700 }
26701 if (generatePath) {
26702 context.beginPath();
26703 generatePath(context, object.parsedStyle);
26704 if (object.nodeName !== Shape.LINE &&
26705 object.nodeName !== Shape.PATH &&
26706 object.nodeName !== Shape.POLYLINE) {
26707 context.closePath();
26708 }
26709 }
26710 // fill & stroke
26711 if (styleRenderer) {
26712 styleRenderer.render(context, object.parsedStyle, object, canvasContext, this, runtime);
26713 // restore applied attributes, eg. shadowBlur shadowColor...
26714 context.restore();
26715 }
26716 // finish rendering, clear dirty flag
26717 object.renderable.dirty = false;
26718 };
26719 CanvasRendererPlugin.prototype.convertAABB2Rect = function (aabb) {
26720 var min = aabb.getMin();
26721 var max = aabb.getMax();
26722 // expand the rectangle a bit to avoid artifacts
26723 // @see https://www.yuque.com/antv/ou292n/bi8nix#ExvCu
26724 var minX = Math.floor(min[0]);
26725 var minY = Math.floor(min[1]);
26726 var maxX = Math.ceil(max[0]);
26727 var maxY = Math.ceil(max[1]);
26728 var width = maxX - minX;
26729 var height = maxY - minY;
26730 return { x: minX, y: minY, width: width, height: height };
26731 };
26732 /**
26733 * TODO: merge dirty rectangles with some strategies.
26734 * For now, we just simply merge all the rectangles into one.
26735 * @see https://idom.me/articles/841.html
26736 */
26737 CanvasRendererPlugin.prototype.mergeDirtyAABBs = function (dirtyObjects) {
26738 // merge into a big AABB
26739 // TODO: skip descendant if ancestor is caculated, but compareNodePosition is really slow
26740 var aabb = new AABB();
26741 dirtyObjects.forEach(function (object) {
26742 var renderBounds = object.getRenderBounds();
26743 aabb.add(renderBounds);
26744 var dirtyRenderBounds = object.renderable.dirtyRenderBounds;
26745 if (dirtyRenderBounds) {
26746 aabb.add(dirtyRenderBounds);
26747 }
26748 });
26749 return aabb;
26750 };
26751 CanvasRendererPlugin.prototype.searchDirtyObjects = function (dirtyRectangle) {
26752 // search in r-tree, get all affected nodes
26753 var _a = __read(dirtyRectangle.getMin(), 2), minX = _a[0], minY = _a[1];
26754 var _b = __read(dirtyRectangle.getMax(), 2), maxX = _b[0], maxY = _b[1];
26755 var rBushNodes = this.rBush.search({
26756 minX: minX,
26757 minY: minY,
26758 maxX: maxX,
26759 maxY: maxY,
26760 });
26761 return rBushNodes.map(function (_a) {
26762 var displayObject = _a.displayObject;
26763 return displayObject;
26764 });
26765 };
26766 CanvasRendererPlugin.prototype.saveDirtyAABB = function (object) {
26767 var renderable = object.renderable;
26768 if (!renderable.dirtyRenderBounds) {
26769 renderable.dirtyRenderBounds = new AABB();
26770 }
26771 var renderBounds = object.getRenderBounds();
26772 if (renderBounds) {
26773 // save last dirty aabb
26774 renderable.dirtyRenderBounds.update(renderBounds.center, renderBounds.halfExtents);
26775 }
26776 };
26777 /**
26778 * TODO: batch the same global attributes
26779 */
26780 CanvasRendererPlugin.prototype.applyAttributesToContext = function (context, object) {
26781 var _a = object.parsedStyle, stroke = _a.stroke, fill = _a.fill, opacity = _a.opacity, lineDash = _a.lineDash, lineDashOffset = _a.lineDashOffset;
26782 // @see https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/setLineDash
26783 if (lineDash) {
26784 context.setLineDash(lineDash);
26785 }
26786 // @see https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/lineDashOffset
26787 if (!isNil(lineDashOffset)) {
26788 context.lineDashOffset = lineDashOffset;
26789 }
26790 if (!isNil(opacity)) {
26791 context.globalAlpha *= opacity;
26792 }
26793 if (!isNil(stroke) &&
26794 !Array.isArray(stroke) &&
26795 !stroke.isNone) {
26796 context.strokeStyle = object.attributes.stroke;
26797 }
26798 if (!isNil(fill) && !Array.isArray(fill) && !fill.isNone) {
26799 context.fillStyle = object.attributes.fill;
26800 }
26801 };
26802 CanvasRendererPlugin.prototype.applyWorldTransform = function (context, object, matrix) {
26803 var tx = 0;
26804 var ty = 0;
26805 var anchor = (object.parsedStyle || {}).anchor;
26806 var anchorX = (anchor && anchor[0]) || 0;
26807 var anchorY = (anchor && anchor[1]) || 0;
26808 if (anchorX !== 0 || anchorY !== 0) {
26809 // const bounds = object.getGeometryBounds();
26810 var bounds = object.geometry.contentBounds;
26811 var width = (bounds && bounds.halfExtents[0] * 2) || 0;
26812 var height = (bounds && bounds.halfExtents[1] * 2) || 0;
26813 tx = -(anchorX * width);
26814 ty = -(anchorY * height);
26815 }
26816 // apply clip shape's RTS
26817 if (matrix) {
26818 copy(this.tmpMat4, object.getLocalTransform());
26819 this.vec3a[0] = tx;
26820 this.vec3a[1] = ty;
26821 this.vec3a[2] = 0;
26822 translate(this.tmpMat4, this.tmpMat4, this.vec3a);
26823 multiply(this.tmpMat4, matrix, this.tmpMat4);
26824 multiply(this.tmpMat4, this.vpMatrix, this.tmpMat4);
26825 }
26826 else {
26827 // apply RTS transformation in world space
26828 copy(this.tmpMat4, object.getWorldTransform());
26829 this.vec3a[0] = tx;
26830 this.vec3a[1] = ty;
26831 this.vec3a[2] = 0;
26832 translate(this.tmpMat4, this.tmpMat4, this.vec3a);
26833 multiply(this.tmpMat4, this.vpMatrix, this.tmpMat4);
26834 }
26835 // @see https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Transformations
26836 context.setTransform(this.tmpMat4[0], this.tmpMat4[1], this.tmpMat4[4], this.tmpMat4[5], this.tmpMat4[12], this.tmpMat4[13]);
26837 };
26838 CanvasRendererPlugin.prototype.safeMergeAABB = function () {
26839 var aabbs = [];
26840 for (var _i = 0; _i < arguments.length; _i++) {
26841 aabbs[_i] = arguments[_i];
26842 }
26843 var merged = new AABB();
26844 aabbs.forEach(function (aabb) {
26845 merged.add(aabb);
26846 });
26847 return merged;
26848 };
26849 CanvasRendererPlugin.tag = 'CanvasRenderer';
26850 return CanvasRendererPlugin;
26851 }());
26852
26853 var DefaultRenderer = /** @class */ (function () {
26854 function DefaultRenderer(imagePool) {
26855 this.imagePool = imagePool;
26856 }
26857 DefaultRenderer.prototype.render = function (context, parsedStyle, object, canvasContext, plugin, runtime) {
26858 var fill = parsedStyle.fill, fillRule = parsedStyle.fillRule, opacity = parsedStyle.opacity, fillOpacity = parsedStyle.fillOpacity, stroke = parsedStyle.stroke, strokeOpacity = parsedStyle.strokeOpacity, lineWidth = parsedStyle.lineWidth, lineCap = parsedStyle.lineCap, lineJoin = parsedStyle.lineJoin, shadowType = parsedStyle.shadowType, shadowColor = parsedStyle.shadowColor, shadowBlur = parsedStyle.shadowBlur, filter = parsedStyle.filter, miterLimit = parsedStyle.miterLimit;
26859 var hasFill = !isNil(fill) && !fill.isNone;
26860 var hasStroke = !isNil(stroke) && !stroke.isNone && lineWidth > 0;
26861 var isFillTransparent = fill.alpha === 0;
26862 var hasFilter = !!(filter && filter.length);
26863 var hasShadow = !isNil(shadowColor) && shadowBlur > 0;
26864 var nodeName = object.nodeName;
26865 var isInnerShadow = shadowType === 'inner';
26866 var shouldDrawShadowWithStroke = hasStroke &&
26867 hasShadow &&
26868 (nodeName === Shape.PATH ||
26869 nodeName === Shape.LINE ||
26870 nodeName === Shape.POLYLINE ||
26871 isFillTransparent ||
26872 isInnerShadow);
26873 if (hasFill) {
26874 context.globalAlpha = opacity * fillOpacity;
26875 if (!shouldDrawShadowWithStroke) {
26876 setShadowAndFilter(object, context, hasShadow);
26877 }
26878 this.fill(context, object, fill, fillRule, canvasContext, plugin, runtime);
26879 if (!shouldDrawShadowWithStroke) {
26880 this.clearShadowAndFilter(context, hasFilter, hasShadow);
26881 }
26882 }
26883 if (hasStroke) {
26884 context.globalAlpha = opacity * strokeOpacity;
26885 context.lineWidth = lineWidth;
26886 if (!isNil(miterLimit)) {
26887 context.miterLimit = miterLimit;
26888 }
26889 if (!isNil(lineCap)) {
26890 context.lineCap = lineCap;
26891 }
26892 if (!isNil(lineJoin)) {
26893 context.lineJoin = lineJoin;
26894 }
26895 if (shouldDrawShadowWithStroke) {
26896 if (isInnerShadow) {
26897 context.globalCompositeOperation = 'source-atop';
26898 }
26899 setShadowAndFilter(object, context, true);
26900 if (isInnerShadow) {
26901 this.stroke(context, object, stroke, canvasContext, plugin, runtime);
26902 context.globalCompositeOperation = 'source-over';
26903 this.clearShadowAndFilter(context, hasFilter, true);
26904 }
26905 }
26906 this.stroke(context, object, stroke, canvasContext, plugin, runtime);
26907 }
26908 };
26909 DefaultRenderer.prototype.clearShadowAndFilter = function (context, hasFilter, hasShadow) {
26910 if (hasShadow) {
26911 context.shadowColor = 'transparent';
26912 context.shadowBlur = 0;
26913 }
26914 if (hasFilter) {
26915 // save drop-shadow filter
26916 var oldFilter = context.filter;
26917 if (!isNil(oldFilter) && oldFilter.indexOf('drop-shadow') > -1) {
26918 context.filter =
26919 oldFilter.replace(/drop-shadow\([^)]*\)/, '').trim() || 'none';
26920 }
26921 }
26922 };
26923 DefaultRenderer.prototype.fill = function (context, object, fill, fillRule, canvasContext, plugin, runtime) {
26924 var _this = this;
26925 if (Array.isArray(fill)) {
26926 fill.forEach(function (gradient) {
26927 context.fillStyle = _this.getColor(gradient, object, context);
26928 fillRule ? context.fill(fillRule) : context.fill();
26929 });
26930 }
26931 else {
26932 if (isPattern(fill)) {
26933 context.fillStyle = this.getPattern(fill, object, context, canvasContext, plugin, runtime);
26934 }
26935 fillRule ? context.fill(fillRule) : context.fill();
26936 }
26937 };
26938 DefaultRenderer.prototype.stroke = function (context, object, stroke, canvasContext, plugin, runtime) {
26939 var _this = this;
26940 if (Array.isArray(stroke)) {
26941 stroke.forEach(function (gradient) {
26942 context.strokeStyle = _this.getColor(gradient, object, context);
26943 context.stroke();
26944 });
26945 }
26946 else {
26947 if (isPattern(stroke)) {
26948 context.strokeStyle = this.getPattern(stroke, object, context, canvasContext, plugin, runtime);
26949 }
26950 context.stroke();
26951 }
26952 };
26953 DefaultRenderer.prototype.getPattern = function (pattern, object, context, canvasContext, plugin, runtime) {
26954 var $offscreenCanvas;
26955 var dpr;
26956 if (pattern.image.nodeName === 'rect') {
26957 var _a = pattern.image.parsedStyle, width = _a.width, height = _a.height;
26958 dpr = canvasContext.contextService.getDPR();
26959 var offscreenCanvas = canvasContext.config.offscreenCanvas;
26960 $offscreenCanvas = runtime.offscreenCanvasCreator.getOrCreateCanvas(offscreenCanvas);
26961 $offscreenCanvas.width = width * dpr;
26962 $offscreenCanvas.height = height * dpr;
26963 var offscreenCanvasContext_1 = runtime.offscreenCanvasCreator.getOrCreateContext(offscreenCanvas);
26964 var restoreStack_1 = [];
26965 // offscreenCanvasContext.scale(1 / dpr, 1 / dpr);
26966 pattern.image.forEach(function (object) {
26967 plugin.renderDisplayObject(object, offscreenCanvasContext_1, canvasContext, restoreStack_1, runtime);
26968 });
26969 restoreStack_1.forEach(function () {
26970 offscreenCanvasContext_1.restore();
26971 });
26972 }
26973 var canvasPattern = this.imagePool.getOrCreatePatternSync(pattern, context, $offscreenCanvas, dpr, function () {
26974 // set dirty rectangle flag
26975 object.renderable.dirty = true;
26976 canvasContext.renderingService.dirtify();
26977 });
26978 return canvasPattern;
26979 };
26980 DefaultRenderer.prototype.getColor = function (parsedColor, object, context) {
26981 var color;
26982 if (parsedColor.type === GradientType.LinearGradient ||
26983 parsedColor.type === GradientType.RadialGradient) {
26984 var bounds = object.getGeometryBounds();
26985 var width = (bounds && bounds.halfExtents[0] * 2) || 1;
26986 var height = (bounds && bounds.halfExtents[1] * 2) || 1;
26987 color = this.imagePool.getOrCreateGradient(__assign(__assign({ type: parsedColor.type }, parsedColor.value), { width: width, height: height }), context);
26988 }
26989 return color;
26990 };
26991 return DefaultRenderer;
26992 }());
26993 /**
26994 * apply before fill and stroke but only once
26995 */
26996 function setShadowAndFilter(object, context, hasShadow) {
26997 var _a = object.parsedStyle, filter = _a.filter, shadowColor = _a.shadowColor, shadowBlur = _a.shadowBlur, shadowOffsetX = _a.shadowOffsetX, shadowOffsetY = _a.shadowOffsetY;
26998 if (filter && filter.length) {
26999 // use raw filter string
27000 context.filter = object.style.filter;
27001 }
27002 if (hasShadow) {
27003 context.shadowColor = shadowColor.toString();
27004 context.shadowBlur = shadowBlur || 0;
27005 context.shadowOffsetX = shadowOffsetX || 0;
27006 context.shadowOffsetY = shadowOffsetY || 0;
27007 }
27008 }
27009
27010 var ImageRenderer = /** @class */ (function () {
27011 function ImageRenderer(imagePool) {
27012 this.imagePool = imagePool;
27013 }
27014 ImageRenderer.prototype.render = function (context, parsedStyle, object) {
27015 var width = parsedStyle.width, height = parsedStyle.height, img = parsedStyle.img, shadowColor = parsedStyle.shadowColor, shadowBlur = parsedStyle.shadowBlur;
27016 var image;
27017 var iw = width;
27018 var ih = height;
27019 if (isString(img)) {
27020 // image has been loaded in `mounted` hook
27021 image = this.imagePool.getImageSync(img);
27022 }
27023 else {
27024 iw || (iw = img.width);
27025 ih || (ih = img.height);
27026 image = img;
27027 }
27028 if (image) {
27029 var hasShadow = !isNil(shadowColor) && shadowBlur > 0;
27030 setShadowAndFilter(object, context, hasShadow);
27031 // node-canvas will throw the following err:
27032 // Error: Image given has not completed loading
27033 try {
27034 context.drawImage(image, 0, 0, iw, ih);
27035 }
27036 catch (e) { }
27037 }
27038 };
27039 return ImageRenderer;
27040 }());
27041
27042 var TextRenderer = /** @class */ (function () {
27043 function TextRenderer() {
27044 }
27045 TextRenderer.prototype.render = function (context, parsedStyle, object, canvasContext, plugin, runtime) {
27046 var _a = parsedStyle, lineWidth = _a.lineWidth, textAlign = _a.textAlign, textBaseline = _a.textBaseline, lineJoin = _a.lineJoin, miterLimit = _a.miterLimit, letterSpacing = _a.letterSpacing, stroke = _a.stroke, fill = _a.fill, fillOpacity = _a.fillOpacity, strokeOpacity = _a.strokeOpacity, opacity = _a.opacity, metrics = _a.metrics, dx = _a.dx, dy = _a.dy, shadowColor = _a.shadowColor, shadowBlur = _a.shadowBlur;
27047 var font = metrics.font, lines = metrics.lines, height = metrics.height, lineHeight = metrics.lineHeight, lineMetrics = metrics.lineMetrics;
27048 context.font = font;
27049 context.lineWidth = lineWidth;
27050 context.textAlign = textAlign === 'middle' ? 'center' : textAlign;
27051 var formattedTextBaseline = textBaseline;
27052 if (
27053 // formattedTextBaseline === 'bottom' ||
27054 !runtime.enableCSSParsing &&
27055 formattedTextBaseline === 'alphabetic') {
27056 formattedTextBaseline = 'bottom';
27057 }
27058 context.lineJoin = lineJoin;
27059 if (!isNil(miterLimit)) {
27060 context.miterLimit = miterLimit;
27061 }
27062 var linePositionY = 0;
27063 // handle vertical text baseline
27064 if (textBaseline === 'middle') {
27065 linePositionY = -height / 2 - lineHeight / 2;
27066 }
27067 else if (textBaseline === 'bottom' ||
27068 textBaseline === 'alphabetic' ||
27069 textBaseline === 'ideographic') {
27070 linePositionY = -height;
27071 }
27072 else if (textBaseline === 'top' || textBaseline === 'hanging') {
27073 linePositionY = -lineHeight;
27074 }
27075 // account for dx & dy
27076 var offsetX = dx || 0;
27077 linePositionY += dy || 0;
27078 if (lines.length === 1) {
27079 if (formattedTextBaseline === 'bottom') {
27080 formattedTextBaseline = 'middle';
27081 linePositionY -= 0.5 * height;
27082 }
27083 else if (formattedTextBaseline === 'top') {
27084 formattedTextBaseline = 'middle';
27085 linePositionY += 0.5 * height;
27086 }
27087 }
27088 context.textBaseline = formattedTextBaseline;
27089 var hasShadow = !isNil(shadowColor) && shadowBlur > 0;
27090 setShadowAndFilter(object, context, hasShadow);
27091 // draw lines line by line
27092 for (var i = 0; i < lines.length; i++) {
27093 var linePositionX = lineWidth / 2 + offsetX;
27094 linePositionY += lineHeight;
27095 // no need to re-position X, cause we already set text align
27096 // @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textAlign
27097 if (!isNil(stroke) && !stroke.isNone && lineWidth) {
27098 this.drawLetterSpacing(context, lines[i], lineMetrics[i], textAlign, linePositionX, linePositionY, letterSpacing, fillOpacity, strokeOpacity, opacity, true);
27099 }
27100 if (!isNil(fill)) {
27101 this.drawLetterSpacing(context, lines[i], lineMetrics[i], textAlign, linePositionX, linePositionY, letterSpacing, fillOpacity, strokeOpacity, opacity);
27102 }
27103 }
27104 };
27105 TextRenderer.prototype.drawLetterSpacing = function (context, text, lineMetrics, textAlign, x, y, letterSpacing, fillOpacity, strokeOpacity, opacity, isStroke) {
27106 if (isStroke === void 0) { isStroke = false; }
27107 // letterSpacing of 0 means normal, render all texts directly
27108 if (letterSpacing === 0) {
27109 if (isStroke) {
27110 this.strokeText(context, text, x, y, strokeOpacity);
27111 }
27112 else {
27113 this.fillText(context, text, x, y, fillOpacity, opacity);
27114 }
27115 return;
27116 }
27117 // draw text using left align
27118 var currentTextAlign = context.textAlign;
27119 context.textAlign = 'left';
27120 var currentPosition = x;
27121 if (textAlign === 'center' || textAlign === 'middle') {
27122 currentPosition = x - lineMetrics.width / 2;
27123 }
27124 else if (textAlign === 'right' || textAlign === 'end') {
27125 currentPosition = x - lineMetrics.width;
27126 }
27127 var stringArray = Array.from(text);
27128 var previousWidth = context.measureText(text).width;
27129 var currentWidth = 0;
27130 for (var i = 0; i < stringArray.length; ++i) {
27131 var currentChar = stringArray[i];
27132 if (isStroke) {
27133 this.strokeText(context, currentChar, currentPosition, y, strokeOpacity);
27134 }
27135 else {
27136 this.fillText(context, currentChar, currentPosition, y, fillOpacity, opacity);
27137 }
27138 currentWidth = context.measureText(text.substring(i + 1)).width;
27139 currentPosition += previousWidth - currentWidth + letterSpacing;
27140 previousWidth = currentWidth;
27141 }
27142 context.textAlign = currentTextAlign;
27143 };
27144 TextRenderer.prototype.fillText = function (context, text, x, y, fillOpacity, opacity) {
27145 var currentGlobalAlpha;
27146 var applyOpacity = !isNil(fillOpacity) && fillOpacity !== 1;
27147 if (applyOpacity) {
27148 currentGlobalAlpha = context.globalAlpha;
27149 context.globalAlpha = fillOpacity * opacity;
27150 }
27151 context.fillText(text, x, y);
27152 if (applyOpacity) {
27153 context.globalAlpha = currentGlobalAlpha;
27154 }
27155 };
27156 TextRenderer.prototype.strokeText = function (context, text, x, y, strokeOpacity) {
27157 var currentGlobalAlpha;
27158 var applyOpacity = !isNil(strokeOpacity) && strokeOpacity !== 1;
27159 if (applyOpacity) {
27160 currentGlobalAlpha = context.globalAlpha;
27161 context.globalAlpha = strokeOpacity;
27162 }
27163 context.strokeText(text, x, y);
27164 if (applyOpacity) {
27165 context.globalAlpha = currentGlobalAlpha;
27166 }
27167 };
27168 return TextRenderer;
27169 }());
27170
27171 var RectRenderer = /** @class */ (function (_super) {
27172 __extends(RectRenderer, _super);
27173 function RectRenderer() {
27174 return _super !== null && _super.apply(this, arguments) || this;
27175 }
27176 return RectRenderer;
27177 }(DefaultRenderer));
27178
27179 var CircleRenderer = /** @class */ (function (_super) {
27180 __extends(CircleRenderer, _super);
27181 function CircleRenderer() {
27182 return _super !== null && _super.apply(this, arguments) || this;
27183 }
27184 return CircleRenderer;
27185 }(DefaultRenderer));
27186
27187 var EllipseRenderer = /** @class */ (function (_super) {
27188 __extends(EllipseRenderer, _super);
27189 function EllipseRenderer() {
27190 return _super !== null && _super.apply(this, arguments) || this;
27191 }
27192 return EllipseRenderer;
27193 }(DefaultRenderer));
27194
27195 var LineRenderer = /** @class */ (function (_super) {
27196 __extends(LineRenderer, _super);
27197 function LineRenderer() {
27198 return _super !== null && _super.apply(this, arguments) || this;
27199 }
27200 return LineRenderer;
27201 }(DefaultRenderer));
27202
27203 var PolylineRenderer = /** @class */ (function (_super) {
27204 __extends(PolylineRenderer, _super);
27205 function PolylineRenderer() {
27206 return _super !== null && _super.apply(this, arguments) || this;
27207 }
27208 return PolylineRenderer;
27209 }(DefaultRenderer));
27210
27211 var PolygonRenderer = /** @class */ (function (_super) {
27212 __extends(PolygonRenderer, _super);
27213 function PolygonRenderer() {
27214 return _super !== null && _super.apply(this, arguments) || this;
27215 }
27216 return PolygonRenderer;
27217 }(DefaultRenderer));
27218
27219 var PathRenderer = /** @class */ (function (_super) {
27220 __extends(PathRenderer, _super);
27221 function PathRenderer() {
27222 return _super !== null && _super.apply(this, arguments) || this;
27223 }
27224 return PathRenderer;
27225 }(DefaultRenderer));
27226
27227 var Plugin$2 = /** @class */ (function (_super) {
27228 __extends(Plugin, _super);
27229 function Plugin(options) {
27230 if (options === void 0) { options = {}; }
27231 var _this = _super.call(this) || this;
27232 _this.options = options;
27233 _this.name = 'canvas-renderer';
27234 return _this;
27235 }
27236 Plugin.prototype.init = function () {
27237 var _a;
27238 var canvasRendererPluginOptions = __assign({ dirtyObjectNumThreshold: 500, dirtyObjectRatioThreshold: 0.8 }, this.options);
27239 // @ts-ignore
27240 var imagePool = this.context.imagePool;
27241 var defaultRenderer = new DefaultRenderer(imagePool);
27242 var defaultStyleRendererFactory = (_a = {},
27243 _a[Shape.CIRCLE] = defaultRenderer,
27244 _a[Shape.ELLIPSE] = defaultRenderer,
27245 _a[Shape.RECT] = defaultRenderer,
27246 _a[Shape.IMAGE] = new ImageRenderer(imagePool),
27247 _a[Shape.TEXT] = new TextRenderer(),
27248 _a[Shape.LINE] = defaultRenderer,
27249 _a[Shape.POLYLINE] = defaultRenderer,
27250 _a[Shape.POLYGON] = defaultRenderer,
27251 _a[Shape.PATH] = defaultRenderer,
27252 _a[Shape.GROUP] = undefined,
27253 _a[Shape.HTML] = undefined,
27254 _a[Shape.MESH] = undefined,
27255 _a);
27256 this.context.defaultStyleRendererFactory = defaultStyleRendererFactory;
27257 this.context.styleRendererFactory = defaultStyleRendererFactory;
27258 this.addRenderingPlugin(new CanvasRendererPlugin(canvasRendererPluginOptions));
27259 };
27260 Plugin.prototype.destroy = function () {
27261 this.removeAllRenderingPlugins();
27262 delete this.context.defaultStyleRendererFactory;
27263 delete this.context.styleRendererFactory;
27264 };
27265 return Plugin;
27266 }(AbstractRendererPlugin));
27267
27268 var DragndropPlugin = /** @class */ (function () {
27269 function DragndropPlugin(dragndropPluginOptions) {
27270 this.dragndropPluginOptions = dragndropPluginOptions;
27271 }
27272 DragndropPlugin.prototype.apply = function (context) {
27273 var _this = this;
27274 var renderingService = context.renderingService, renderingContext = context.renderingContext;
27275 var document = renderingContext.root.ownerDocument;
27276 // TODO: should we add an option like `draggable` to Canvas
27277 var canvas = document.defaultView;
27278 var handlePointerdown = function (event) {
27279 var target = event.target;
27280 var isDocument = target === document;
27281 var draggableEventTarget = isDocument && _this.dragndropPluginOptions.isDocumentDraggable
27282 ? document
27283 : target.closest && target.closest('[draggable=true]');
27284 // `draggable` may be set on ancestor nodes:
27285 // @see https://github.com/antvis/G/issues/1088
27286 if (draggableEventTarget) {
27287 // delay triggering dragstart event
27288 var dragstartTriggered_1 = false;
27289 var dragstartTimeStamp_1 = event.timeStamp;
27290 var dragstartClientCoordinates_1 = [
27291 event.clientX,
27292 event.clientY,
27293 ];
27294 var currentDroppable_1 = null;
27295 var lastDragClientCoordinates_1 = [event.clientX, event.clientY];
27296 // @ts-ignore
27297 // eslint-disable-next-line no-inner-declarations
27298 var handlePointermove_1 = function (event) { return __awaiter(_this, void 0, void 0, function () {
27299 var timeElapsed, distanceMoved, point, elementsBelow, elementBelow, droppableBelow;
27300 return __generator(this, function (_a) {
27301 switch (_a.label) {
27302 case 0:
27303 if (!dragstartTriggered_1) {
27304 timeElapsed = event.timeStamp - dragstartTimeStamp_1;
27305 distanceMoved = distanceSquareRoot([event.clientX, event.clientY], dragstartClientCoordinates_1);
27306 // check thresholds
27307 if (timeElapsed <=
27308 this.dragndropPluginOptions.dragstartTimeThreshold ||
27309 distanceMoved <=
27310 this.dragndropPluginOptions.dragstartDistanceThreshold) {
27311 return [2 /*return*/];
27312 }
27313 // @see https://developer.mozilla.org/zh-CN/docs/Web/API/Document/dragstart_event
27314 event.type = 'dragstart';
27315 draggableEventTarget.dispatchEvent(event);
27316 dragstartTriggered_1 = true;
27317 }
27318 // @see https://developer.mozilla.org/zh-CN/docs/Web/API/Document/drag_event
27319 event.type = 'drag';
27320 // @ts-ignore
27321 event.dx = event.clientX - lastDragClientCoordinates_1[0];
27322 // @ts-ignore
27323 event.dy = event.clientY - lastDragClientCoordinates_1[1];
27324 draggableEventTarget.dispatchEvent(event);
27325 lastDragClientCoordinates_1 = [event.clientX, event.clientY];
27326 if (!!isDocument) return [3 /*break*/, 2];
27327 point = this.dragndropPluginOptions.overlap === 'pointer'
27328 ? [event.canvasX, event.canvasY]
27329 : target.getBounds().center;
27330 return [4 /*yield*/, document.elementsFromPoint(point[0], point[1])];
27331 case 1:
27332 elementsBelow = _a.sent();
27333 elementBelow = elementsBelow[elementsBelow.indexOf(target) + 1];
27334 droppableBelow = (elementBelow === null || elementBelow === void 0 ? void 0 : elementBelow.closest('[droppable=true]')) ||
27335 (this.dragndropPluginOptions.isDocumentDroppable
27336 ? document
27337 : null);
27338 if (currentDroppable_1 !== droppableBelow) {
27339 if (currentDroppable_1) {
27340 // null when we were not over a droppable before this event
27341 // @see https://developer.mozilla.org/zh-CN/docs/Web/API/Document/dragleave_event
27342 event.type = 'dragleave';
27343 event.target = currentDroppable_1;
27344 currentDroppable_1.dispatchEvent(event);
27345 }
27346 if (droppableBelow) {
27347 // @see https://developer.mozilla.org/zh-CN/docs/Web/API/Document/dragleave_event
27348 event.type = 'dragenter';
27349 event.target = droppableBelow;
27350 droppableBelow.dispatchEvent(event);
27351 }
27352 currentDroppable_1 = droppableBelow;
27353 if (currentDroppable_1) {
27354 // null if we're not coming over a droppable now
27355 // @see https://developer.mozilla.org/zh-CN/docs/Web/API/Document/dragover_event
27356 event.type = 'dragover';
27357 event.target = currentDroppable_1;
27358 currentDroppable_1.dispatchEvent(event);
27359 }
27360 }
27361 _a.label = 2;
27362 case 2: return [2 /*return*/];
27363 }
27364 });
27365 }); };
27366 canvas.addEventListener('pointermove', handlePointermove_1);
27367 var stopDragging = function (originalPointerUpEvent) {
27368 if (dragstartTriggered_1) {
27369 // prevent click event being triggerd
27370 // @see https://github.com/antvis/G/issues/1091
27371 originalPointerUpEvent.detail = {
27372 preventClick: true,
27373 };
27374 // clone event first
27375 var event_1 = originalPointerUpEvent.clone();
27376 // drop should fire before dragend
27377 // @see https://javascript.tutorialink.com/is-there-a-defined-ordering-between-dragend-and-drop-events/
27378 if (currentDroppable_1) {
27379 // @see https://developer.mozilla.org/zh-CN/docs/Web/API/Document/drop_event
27380 event_1.type = 'drop';
27381 event_1.target = currentDroppable_1;
27382 currentDroppable_1.dispatchEvent(event_1);
27383 }
27384 // @see https://developer.mozilla.org/zh-CN/docs/Web/API/Document/dragend_event
27385 event_1.type = 'dragend';
27386 draggableEventTarget.dispatchEvent(event_1);
27387 dragstartTriggered_1 = false;
27388 }
27389 canvas.removeEventListener('pointermove', handlePointermove_1);
27390 };
27391 target.addEventListener('pointerup', stopDragging, { once: true });
27392 target.addEventListener('pointerupoutside', stopDragging, {
27393 once: true,
27394 });
27395 }
27396 };
27397 renderingService.hooks.init.tap(DragndropPlugin.tag, function () {
27398 canvas.addEventListener('pointerdown', handlePointerdown);
27399 });
27400 renderingService.hooks.destroy.tap(DragndropPlugin.tag, function () {
27401 canvas.removeEventListener('pointerdown', handlePointerdown);
27402 });
27403 };
27404 DragndropPlugin.tag = 'Dragndrop';
27405 return DragndropPlugin;
27406 }());
27407
27408 var Plugin$3 = /** @class */ (function (_super) {
27409 __extends(Plugin, _super);
27410 function Plugin(options) {
27411 if (options === void 0) { options = {}; }
27412 var _this = _super.call(this) || this;
27413 _this.options = options;
27414 _this.name = 'dragndrop';
27415 return _this;
27416 }
27417 Plugin.prototype.init = function () {
27418 this.addRenderingPlugin(new DragndropPlugin(__assign({ overlap: 'pointer', isDocumentDraggable: false, isDocumentDroppable: false, dragstartDistanceThreshold: 0, dragstartTimeThreshold: 0 }, this.options)));
27419 };
27420 Plugin.prototype.destroy = function () {
27421 this.removeAllRenderingPlugins();
27422 };
27423 Plugin.prototype.setOptions = function (options) {
27424 Object.assign(this.plugins[0].dragndropPluginOptions, options);
27425 };
27426 return Plugin;
27427 }(AbstractRendererPlugin));
27428
27429 var ImagePool = /** @class */ (function () {
27430 function ImagePool(canvasConfig) {
27431 this.canvasConfig = canvasConfig;
27432 this.imageCache = {};
27433 this.gradientCache = {};
27434 this.patternCache = {};
27435 }
27436 ImagePool.prototype.getImageSync = function (src, callback) {
27437 if (!this.imageCache[src]) {
27438 this.getOrCreateImage(src).then(function (img) {
27439 if (callback) {
27440 callback(img);
27441 }
27442 });
27443 }
27444 else {
27445 if (callback) {
27446 callback(this.imageCache[src]);
27447 }
27448 }
27449 return this.imageCache[src];
27450 };
27451 ImagePool.prototype.getOrCreateImage = function (src) {
27452 var _this = this;
27453 if (this.imageCache[src]) {
27454 return Promise.resolve(this.imageCache[src]);
27455 }
27456 // @see https://github.com/antvis/g/issues/938
27457 var createImage = this.canvasConfig.createImage;
27458 return new Promise(function (resolve, reject) {
27459 var image;
27460 if (createImage) {
27461 image = createImage(src);
27462 }
27463 else if (isBrowser) {
27464 image = new window.Image();
27465 }
27466 if (image) {
27467 image.onload = function () {
27468 _this.imageCache[src] = image;
27469 resolve(image);
27470 };
27471 image.onerror = function (ev) {
27472 reject(ev);
27473 };
27474 image.crossOrigin = 'Anonymous';
27475 image.src = src;
27476 }
27477 });
27478 };
27479 ImagePool.prototype.getOrCreatePatternSync = function (pattern, context, $offscreenCanvas, dpr, callback) {
27480 var patternKey = this.generatePatternKey(pattern);
27481 if (patternKey && this.patternCache[patternKey]) {
27482 return this.patternCache[patternKey];
27483 }
27484 var image = pattern.image, repetition = pattern.repetition, transform = pattern.transform;
27485 var src;
27486 var needScaleWithDPR = false;
27487 // Image URL
27488 if (isString(image)) {
27489 src = this.getImageSync(image, callback);
27490 }
27491 else if ($offscreenCanvas) {
27492 src = $offscreenCanvas;
27493 needScaleWithDPR = true;
27494 }
27495 else {
27496 src = image;
27497 }
27498 // @see https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/createPattern
27499 var canvasPattern = src && context.createPattern(src, repetition);
27500 if (canvasPattern) {
27501 var mat = void 0;
27502 // @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasPattern/setTransform
27503 if (transform) {
27504 mat = parsedTransformToMat4(parseTransform(transform), new DisplayObject({}));
27505 }
27506 else {
27507 mat = identity$1(create$1());
27508 }
27509 if (needScaleWithDPR) {
27510 scale(mat, mat, [1 / dpr, 1 / dpr, 1]);
27511 }
27512 canvasPattern.setTransform({
27513 a: mat[0],
27514 b: mat[1],
27515 c: mat[4],
27516 d: mat[5],
27517 e: mat[12],
27518 f: mat[13],
27519 });
27520 }
27521 if (patternKey && canvasPattern) {
27522 this.patternCache[patternKey] = canvasPattern;
27523 }
27524 return canvasPattern;
27525 };
27526 ImagePool.prototype.getOrCreateGradient = function (params, context) {
27527 var key = this.generateGradientKey(params);
27528 var type = params.type, steps = params.steps, width = params.width, height = params.height, angle = params.angle, cx = params.cx, cy = params.cy, size = params.size;
27529 if (this.gradientCache[key]) {
27530 return this.gradientCache[key];
27531 }
27532 var gradient = null;
27533 if (type === GradientType.LinearGradient) {
27534 var _a = computeLinearGradient(width, height, angle), x1 = _a.x1, y1 = _a.y1, x2 = _a.x2, y2 = _a.y2;
27535 // @see https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/createLinearGradient
27536 gradient = context.createLinearGradient(x1, y1, x2, y2);
27537 }
27538 else if (type === GradientType.RadialGradient) {
27539 var _b = computeRadialGradient(width, height, cx, cy, size), x = _b.x, y = _b.y, r = _b.r;
27540 // @see https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/createRadialGradient
27541 gradient = context.createRadialGradient(x, y, 0, x, y, r);
27542 }
27543 if (gradient) {
27544 steps.forEach(function (_a) {
27545 var offset = _a.offset, color = _a.color;
27546 if (offset.unit === UnitType.kPercentage) {
27547 gradient === null || gradient === void 0 ? void 0 : gradient.addColorStop(offset.value / 100, color.toString());
27548 }
27549 });
27550 this.gradientCache[key] = gradient;
27551 }
27552 return this.gradientCache[key];
27553 };
27554 ImagePool.prototype.generateGradientKey = function (params) {
27555 var type = params.type, width = params.width, height = params.height, steps = params.steps, angle = params.angle, cx = params.cx, cy = params.cy, size = params.size;
27556 return "gradient-".concat(type, "-").concat((angle === null || angle === void 0 ? void 0 : angle.toString()) || 0, "-").concat((cx === null || cx === void 0 ? void 0 : cx.toString()) || 0, "-").concat((cy === null || cy === void 0 ? void 0 : cy.toString()) || 0, "-").concat((size === null || size === void 0 ? void 0 : size.toString()) || 0, "-").concat(width, "-").concat(height, "-").concat(steps
27557 .map(function (_a) {
27558 var offset = _a.offset, color = _a.color;
27559 return "".concat(offset).concat(color);
27560 })
27561 .join('-'));
27562 };
27563 ImagePool.prototype.generatePatternKey = function (pattern) {
27564 var image = pattern.image, repetition = pattern.repetition;
27565 // only generate cache for Image
27566 if (isString(image)) {
27567 return "pattern-".concat(image, "-").concat(repetition);
27568 }
27569 else if (image.nodeName === 'rect') {
27570 return "pattern-".concat(image.entity, "-").concat(repetition);
27571 }
27572 };
27573 return ImagePool;
27574 }());
27575
27576 var LoadImagePlugin = /** @class */ (function () {
27577 function LoadImagePlugin() {
27578 }
27579 LoadImagePlugin.prototype.apply = function (context) {
27580 var renderingService = context.renderingService, renderingContext = context.renderingContext, imagePool = context.imagePool;
27581 var canvas = renderingContext.root.ownerDocument.defaultView;
27582 var calculateWithAspectRatio = function (object, imageWidth, imageHeight) {
27583 var _a = object.parsedStyle, width = _a.width, height = _a.height;
27584 if (width && !height) {
27585 object.setAttribute('height', (imageHeight / imageWidth) * width);
27586 }
27587 else if (!width && height) {
27588 object.setAttribute('width', (imageWidth / imageHeight) * height);
27589 }
27590 };
27591 var handleMounted = function (e) {
27592 var object = e.target;
27593 var nodeName = object.nodeName, attributes = object.attributes;
27594 if (nodeName === Shape.IMAGE) {
27595 var img = attributes.img, keepAspectRatio_1 = attributes.keepAspectRatio;
27596 if (isString(img)) {
27597 imagePool.getImageSync(img, function (_a) {
27598 var width = _a.width, height = _a.height;
27599 if (keepAspectRatio_1) {
27600 calculateWithAspectRatio(object, width, height);
27601 }
27602 // set dirty rectangle flag
27603 object.renderable.dirty = true;
27604 renderingService.dirtify();
27605 });
27606 }
27607 }
27608 };
27609 var handleAttributeChanged = function (e) {
27610 var object = e.target;
27611 var attrName = e.attrName, newValue = e.newValue;
27612 if (object.nodeName === Shape.IMAGE) {
27613 if (attrName === 'img') {
27614 if (isString(newValue)) {
27615 imagePool.getOrCreateImage(newValue).then(function (_a) {
27616 var width = _a.width, height = _a.height;
27617 if (object.attributes.keepAspectRatio) {
27618 calculateWithAspectRatio(object, width, height);
27619 }
27620 // set dirty rectangle flag
27621 object.renderable.dirty = true;
27622 renderingService.dirtify();
27623 });
27624 }
27625 }
27626 }
27627 };
27628 renderingService.hooks.init.tap(LoadImagePlugin.tag, function () {
27629 canvas.addEventListener(ElementEvent.MOUNTED, handleMounted);
27630 canvas.addEventListener(ElementEvent.ATTR_MODIFIED, handleAttributeChanged);
27631 });
27632 renderingService.hooks.destroy.tap(LoadImagePlugin.tag, function () {
27633 canvas.removeEventListener(ElementEvent.MOUNTED, handleMounted);
27634 canvas.removeEventListener(ElementEvent.ATTR_MODIFIED, handleAttributeChanged);
27635 });
27636 };
27637 LoadImagePlugin.tag = 'LoadImage';
27638 return LoadImagePlugin;
27639 }());
27640
27641 var Plugin$4 = /** @class */ (function (_super) {
27642 __extends(Plugin, _super);
27643 function Plugin() {
27644 var _this = _super.apply(this, __spreadArray([], __read(arguments), false)) || this;
27645 _this.name = 'image-loader';
27646 return _this;
27647 }
27648 Plugin.prototype.init = function () {
27649 // @ts-ignore
27650 this.context.imagePool = new ImagePool(this.context.config);
27651 this.addRenderingPlugin(new LoadImagePlugin());
27652 };
27653 Plugin.prototype.destroy = function () {
27654 this.removeAllRenderingPlugins();
27655 };
27656 return Plugin;
27657 }(AbstractRendererPlugin));
27658
27659 /**
27660 * listen to mouse/touch/pointer events on DOM wrapper, trigger pointer events
27661 */
27662 var MobileInteractionPlugin = /** @class */ (function () {
27663 function MobileInteractionPlugin() {
27664 }
27665 MobileInteractionPlugin.prototype.apply = function (context) {
27666 var renderingService = context.renderingService, contextService = context.contextService, config = context.config;
27667 // 获取小程序上下文
27668 var canvasEl = contextService.getDomElement();
27669 var onPointerDown = function (ev) {
27670 renderingService.hooks.pointerDown.call(ev);
27671 };
27672 var onPointerUp = function (ev) {
27673 renderingService.hooks.pointerUp.call(ev);
27674 };
27675 var onPointerMove = function (ev) {
27676 // 触发 G 定义的标准 pointerMove 事件
27677 renderingService.hooks.pointerMove.call(ev);
27678 };
27679 var onPointerOver = function (ev) {
27680 renderingService.hooks.pointerOver.call(ev);
27681 };
27682 var onPointerOut = function (ev) {
27683 renderingService.hooks.pointerOut.call(ev);
27684 };
27685 var onClick = function (ev) {
27686 renderingService.hooks.click.call(ev);
27687 };
27688 var onPointerCancel = function (ev) {
27689 renderingService.hooks.pointerCancel.call(ev);
27690 };
27691 renderingService.hooks.init.tap(MobileInteractionPlugin.tag, function () {
27692 // 基于小程序上下文的事件监听方式,绑定事件监听,可以参考下面基于 DOM 的方式
27693 canvasEl.addEventListener('touchstart', onPointerDown, true);
27694 canvasEl.addEventListener('touchend', onPointerUp, true);
27695 canvasEl.addEventListener('touchmove', onPointerMove, true);
27696 canvasEl.addEventListener('touchcancel', onPointerCancel, true);
27697 // FIXME: 这里不应该只在 canvasEl 上监听 mousemove 和 mouseup,而应该在更高层级的节点上例如 document 监听。
27698 // 否则无法判断是否移出了 canvasEl
27699 // canvasEl.addEventListener('mousemove', onPointerMove, true);
27700 // canvasEl.addEventListener('mousedown', onPointerDown, true);
27701 canvasEl.addEventListener('mouseout', onPointerOut, true);
27702 canvasEl.addEventListener('mouseover', onPointerOver, true);
27703 // canvasEl.addEventListener('mouseup', onPointerUp, true);
27704 if (config.useNativeClickEvent) {
27705 canvasEl.addEventListener('click', onClick, true);
27706 }
27707 });
27708 renderingService.hooks.destroy.tap(MobileInteractionPlugin.tag, function () {
27709 // 基于小程序上下文的事件监听方式,移除事件监听
27710 canvasEl.removeEventListener('touchstart', onPointerDown, true);
27711 canvasEl.removeEventListener('touchend', onPointerUp, true);
27712 canvasEl.removeEventListener('touchmove', onPointerMove, true);
27713 canvasEl.removeEventListener('touchcancel', onPointerCancel, true);
27714 // canvasEl.removeEventListener('mousemove', onPointerMove, true);
27715 // canvasEl.removeEventListener('mousedown', onPointerDown, true);
27716 canvasEl.removeEventListener('mouseout', onPointerOut, true);
27717 canvasEl.removeEventListener('mouseover', onPointerOver, true);
27718 // canvasEl.removeEventListener('mouseup', onPointerUp, true);
27719 if (config.useNativeClickEvent) {
27720 canvasEl.removeEventListener('click', onClick, true);
27721 }
27722 });
27723 };
27724 MobileInteractionPlugin.tag = 'MobileInteraction';
27725 return MobileInteractionPlugin;
27726 }());
27727
27728 var Plugin$5 = /** @class */ (function (_super) {
27729 __extends(Plugin, _super);
27730 function Plugin() {
27731 var _this = _super.apply(this, __spreadArray([], __read(arguments), false)) || this;
27732 _this.name = 'mobile-interaction';
27733 return _this;
27734 }
27735 Plugin.prototype.init = function () {
27736 this.addRenderingPlugin(new MobileInteractionPlugin());
27737 };
27738 Plugin.prototype.destroy = function () {
27739 this.removeAllRenderingPlugins();
27740 };
27741 return Plugin;
27742 }(AbstractRendererPlugin));
27743
27744 /**
27745 * TODO: use clock from g later.
27746 */
27747 var clock$1 = typeof performance === 'object' && performance.now ? performance : Date;
27748 // 计算滑动的方向
27749 var calcDirection = function (start, end) {
27750 var xDistance = end.x - start.x;
27751 var yDistance = end.y - start.y;
27752 // x 的距离大于y 说明是横向,否则就是纵向
27753 if (Math.abs(xDistance) > Math.abs(yDistance)) {
27754 return xDistance > 0 ? 'right' : 'left';
27755 }
27756 return yDistance > 0 ? 'down' : 'up';
27757 };
27758 // 计算2点之间的距离
27759 var calcDistance = function (point1, point2) {
27760 var xDistance = Math.abs(point2.x - point1.x);
27761 var yDistance = Math.abs(point2.y - point1.y);
27762 return Math.sqrt(xDistance * xDistance + yDistance * yDistance);
27763 };
27764 var getCenter = function (point1, point2) {
27765 var x = point1.x + (point2.x - point1.x) / 2;
27766 var y = point1.y + (point2.y - point1.y) / 2;
27767 return { x: x, y: y };
27768 };
27769
27770 var PRESS_DELAY = 250;
27771 var GesturePlugin = /** @class */ (function () {
27772 function GesturePlugin(options) {
27773 var _this = this;
27774 this.options = options;
27775 this.evCache = [];
27776 this.startPoints = [];
27777 // 用来记录当前触发的事件
27778 this.processEvent = {};
27779 this.throttleTimer = 0;
27780 this.emitThrottles = [];
27781 this._start = function (ev, target) {
27782 var _a;
27783 // 每次触点开始都重置事件
27784 _this.reset();
27785 // 记录touch start 的时间
27786 _this.startTime = clock$1.now();
27787 var _b = _this, evCache = _b.evCache, startPoints = _b.startPoints;
27788 if (ev) {
27789 var pointerId_1 = ev.pointerId, x = ev.x, y = ev.y;
27790 // evcache 已经存在的 pointerId, 做替换
27791 var existIdx = evCache.findIndex(function (item) { return pointerId_1 === item.pointerId; });
27792 if (existIdx !== -1) {
27793 evCache.splice(existIdx, 1);
27794 }
27795 // evCache 不存在的 pointerId, 添加
27796 evCache.push({
27797 pointerId: pointerId_1,
27798 x: x,
27799 y: y,
27800 ev: ev,
27801 });
27802 // @ts-ignore 对齐touches evCache 存在,touches 不存在,移除
27803 var evTouches = __spreadArray([], __read((((_a = ev.nativeEvent) === null || _a === void 0 ? void 0 : _a.touches) || [])), false);
27804 var _loop_1 = function (i) {
27805 var isInTouches = evTouches.find(function (touch) {
27806 return evCache[i].pointerId === touch.identifier;
27807 });
27808 // 在touches中存在
27809 if (isInTouches) {
27810 return "continue";
27811 }
27812 // 在touches中不存在
27813 evCache.splice(i, 1);
27814 };
27815 for (var i = evCache.length - 1; i > -1; i--) {
27816 _loop_1(i);
27817 }
27818 }
27819 // 重置 startPoints
27820 startPoints.length = evCache.length;
27821 for (var i = 0; i < evCache.length; i++) {
27822 var _c = evCache[i], x = _c.x, y = _c.y;
27823 var point = { x: x, y: y };
27824 startPoints[i] = point;
27825 }
27826 // 单指事件
27827 if (startPoints.length === 1) {
27828 var event_1 = evCache[0].ev;
27829 // 如果touchstart后停顿250ms, 则也触发press事件
27830 // @ts-ignore
27831 _this.pressTimeout = setTimeout(function () {
27832 // 这里固定触发press事件
27833 var eventType = 'press';
27834 var direction = 'none';
27835 event_1.direction = direction;
27836 event_1.deltaX = 0;
27837 event_1.deltaY = 0;
27838 event_1.points = startPoints;
27839 _this.emitStart(eventType, event_1, target);
27840 event_1.type = eventType;
27841 target.dispatchEvent(event_1);
27842 _this.eventType = eventType;
27843 _this.direction = direction;
27844 _this.movingTarget = target;
27845 }, PRESS_DELAY);
27846 return;
27847 }
27848 // 目前只处理双指
27849 _this.startDistance = calcDistance(startPoints[0], startPoints[1]);
27850 _this.center = getCenter(startPoints[0], startPoints[1]);
27851 };
27852 this._move = function (ev, target) {
27853 _this.clearPressTimeout();
27854 var _a = _this, startPoints = _a.startPoints, evCache = _a.evCache;
27855 if (!startPoints.length)
27856 return;
27857 var x = ev.x, y = ev.y, pointerId = ev.pointerId;
27858 // Find this event in the cache and update its record with this event
27859 for (var i = 0, len = evCache.length; i < len; i++) {
27860 if (pointerId === evCache[i].pointerId) {
27861 evCache[i] = {
27862 pointerId: pointerId,
27863 x: x,
27864 y: y,
27865 ev: ev,
27866 };
27867 break;
27868 }
27869 }
27870 var point = { x: x, y: y };
27871 var points = evCache.map(function (ev) {
27872 return { x: ev.x, y: ev.y };
27873 });
27874 // 记录最后2次move的时间和坐标,为了给swipe事件用
27875 var now = clock$1.now();
27876 _this.prevMoveTime = _this.lastMoveTime;
27877 _this.prevMovePoint = _this.lastMovePoint;
27878 _this.lastMoveTime = now;
27879 _this.lastMovePoint = point;
27880 if (startPoints.length === 1) {
27881 var startPoint = startPoints[0];
27882 var deltaX = x - startPoint.x;
27883 var deltaY = y - startPoint.y;
27884 var direction = _this.direction || calcDirection(startPoint, point);
27885 _this.direction = direction;
27886 // 获取press或者pan的事件类型
27887 // press 按住滑动, pan表示平移
27888 // 如果start后立刻move,则触发pan, 如果有停顿,则触发press
27889 var eventType = _this.getEventType(point, target, ev);
27890 ev.direction = direction;
27891 ev.deltaX = deltaX;
27892 ev.deltaY = deltaY;
27893 ev.points = points;
27894 _this.emitStart(eventType, ev, target);
27895 ev.type = eventType;
27896 _this.refreshAndGetTarget(target).dispatchEvent(ev);
27897 return;
27898 }
27899 // 多指触控
27900 var startDistance = _this.startDistance;
27901 var currentDistance = calcDistance(points[0], points[1]);
27902 // 缩放比例
27903 ev.zoom = currentDistance / startDistance;
27904 ev.center = _this.center;
27905 ev.points = points;
27906 // 触发缩放事件
27907 _this.emitStart('pinch', ev, target);
27908 // touch 多指会被拆成多个手指的 move, 会触发多次 move,所以这里需要做节流
27909 _this._throttleEmit('pinch', ev, target);
27910 };
27911 this._end = function (ev, target) {
27912 var _a = _this, evCache = _a.evCache, startPoints = _a.startPoints;
27913 var points = evCache.map(function (ev) {
27914 return { x: ev.x, y: ev.y };
27915 });
27916 ev.points = points;
27917 _this.emitEnd(ev, _this.refreshAndGetTarget(target));
27918 // 单指
27919 if (evCache.length === 1) {
27920 // swipe事件处理, 在end之后触发
27921 var now = clock$1.now();
27922 var lastMoveTime = _this.lastMoveTime;
27923 // 做这个判断是为了最后一次touchmove后到end前,是否还有一个停顿的过程
27924 // 100 是拍的一个值,理论这个值会很短,一般不卡顿的话在10ms以内
27925 if (now - lastMoveTime < 100) {
27926 var prevMoveTime = _this.prevMoveTime || _this.startTime;
27927 var intervalTime = lastMoveTime - prevMoveTime;
27928 // 时间间隔一定要大于0, 否则计算没意义
27929 if (intervalTime > 0) {
27930 var prevMovePoint = _this.prevMovePoint || startPoints[0];
27931 var lastMovePoint = _this.lastMovePoint || startPoints[0];
27932 // move速率
27933 var velocity = calcDistance(prevMovePoint, lastMovePoint) / intervalTime;
27934 // 0.3 是参考hammerjs的设置
27935 if (velocity > 0.3) {
27936 ev.velocity = velocity;
27937 ev.direction = calcDirection(prevMovePoint, lastMovePoint);
27938 ev.type = 'swipe';
27939 target.dispatchEvent(ev);
27940 }
27941 }
27942 }
27943 }
27944 // remove event from cache
27945 for (var i = 0, len = evCache.length; i < len; i++) {
27946 if (evCache[i].pointerId === ev.pointerId) {
27947 evCache.splice(i, 1);
27948 startPoints.splice(i, 1);
27949 break;
27950 }
27951 }
27952 _this.reset();
27953 // 多指离开 1 指后,重新触发一次start
27954 if (evCache.length > 0) {
27955 _this._start(undefined, target);
27956 }
27957 };
27958 this._cancel = function (ev, target) {
27959 var evCache = _this.evCache;
27960 var points = evCache.map(function (ev) {
27961 return { x: ev.x, y: ev.y };
27962 });
27963 ev.points = points;
27964 _this.emitEnd(ev, _this.refreshAndGetTarget(target));
27965 _this.evCache = [];
27966 _this.reset();
27967 };
27968 }
27969 GesturePlugin.prototype.apply = function (context) {
27970 var _this = this;
27971 var renderingService = context.renderingService, renderingContext = context.renderingContext;
27972 var document = renderingContext.root.ownerDocument;
27973 var canvas = document.defaultView;
27974 this.canvas = canvas;
27975 var getGestureEventTarget = function (target) {
27976 var isDocument = target === document;
27977 return isDocument && _this.options.isDocumentGestureEnabled
27978 ? document
27979 : target;
27980 };
27981 var handlePointermove = function (ev) {
27982 var target = getGestureEventTarget(ev.target);
27983 target && _this._move(ev, target);
27984 };
27985 var handlePointerdown = function (ev) {
27986 var target = getGestureEventTarget(ev.target);
27987 target && _this._start(ev, target);
27988 };
27989 var handlePointerup = function (ev) {
27990 var target = getGestureEventTarget(ev.target);
27991 target && _this._end(ev, target);
27992 };
27993 var handlePointercancel = function (ev) {
27994 var target = getGestureEventTarget(ev.target);
27995 target && _this._cancel(ev, target);
27996 };
27997 var handlePointercanceloutside = function (ev) {
27998 var target = getGestureEventTarget(ev.target);
27999 target && _this._end(ev, target);
28000 };
28001 renderingService.hooks.init.tap(GesturePlugin.tag, function () {
28002 canvas.addEventListener('pointermove', handlePointermove);
28003 canvas.addEventListener('pointerdown', handlePointerdown);
28004 canvas.addEventListener('pointerup', handlePointerup);
28005 canvas.addEventListener('pointercancel', handlePointercancel);
28006 canvas.addEventListener('pointerupoutside', handlePointercanceloutside);
28007 });
28008 renderingService.hooks.destroy.tap(GesturePlugin.tag, function () {
28009 canvas.removeEventListener('pointermove', handlePointermove);
28010 canvas.removeEventListener('pointerdown', handlePointerdown);
28011 canvas.removeEventListener('pointerup', handlePointerup);
28012 canvas.removeEventListener('pointercancel', handlePointercancel);
28013 canvas.removeEventListener('pointerupoutside', handlePointercanceloutside);
28014 });
28015 };
28016 GesturePlugin.prototype.getEventType = function (point, target, ev) {
28017 var _a = this, eventType = _a.eventType, startTime = _a.startTime, startPoints = _a.startPoints;
28018 if (eventType) {
28019 return eventType;
28020 }
28021 // move的时候缓存节点,后续move和end都会使用这个target派发事件
28022 this.movingTarget = target;
28023 // 冒泡路径中是否有pan事件
28024 this.isPanListenerInPath = ev.path.some(function (ele) { var _a, _b; return !!((_b = (_a = ele.emitter) === null || _a === void 0 ? void 0 : _a.eventNames()) === null || _b === void 0 ? void 0 : _b.includes('pan')); });
28025 var type;
28026 // 如果没有pan事件的监听,默认都是press
28027 if (!this.isPanListenerInPath) {
28028 type = 'press';
28029 }
28030 else {
28031 // 如果有pan事件的处理,press则需要停顿250ms, 且移动距离小于10
28032 var now = clock$1.now();
28033 if (now - startTime > PRESS_DELAY &&
28034 calcDistance(startPoints[0], point) < 10) {
28035 type = 'press';
28036 }
28037 else {
28038 type = 'pan';
28039 }
28040 }
28041 this.eventType = type;
28042 return type;
28043 };
28044 GesturePlugin.prototype.enable = function (eventType) {
28045 this.processEvent[eventType] = true;
28046 };
28047 // 是否进行中的事件
28048 GesturePlugin.prototype.isProcess = function (eventType) {
28049 return this.processEvent[eventType];
28050 };
28051 // 触发start事件
28052 GesturePlugin.prototype.emitStart = function (type, ev, target) {
28053 if (this.isProcess(type)) {
28054 return;
28055 }
28056 this.enable(type);
28057 ev.type = "".concat(type, "start");
28058 target.dispatchEvent(ev);
28059 };
28060 // 触发事件
28061 GesturePlugin.prototype._throttleEmit = function (type, ev, target) {
28062 var _this = this;
28063 // 主要是节流处理
28064 this.pushEvent(type, ev);
28065 var _a = this, throttleTimer = _a.throttleTimer, emitThrottles = _a.emitThrottles, processEvent = _a.processEvent;
28066 if (throttleTimer) {
28067 return;
28068 }
28069 this.throttleTimer = this.canvas.requestAnimationFrame(function () {
28070 for (var i = 0, len = emitThrottles.length; i < len; i++) {
28071 var _a = emitThrottles[i], type_1 = _a.type, ev_1 = _a.ev;
28072 if (processEvent[type_1]) {
28073 ev_1.type = type_1;
28074 target.dispatchEvent(ev_1);
28075 }
28076 }
28077 // 清空
28078 _this.throttleTimer = 0;
28079 _this.emitThrottles.length = 0;
28080 });
28081 };
28082 // 触发end事件
28083 GesturePlugin.prototype.emitEnd = function (ev, target) {
28084 var processEvent = this.processEvent;
28085 Object.keys(processEvent).forEach(function (type) {
28086 ev.type = "".concat(type, "end");
28087 target.dispatchEvent(ev);
28088 delete processEvent[type];
28089 });
28090 };
28091 GesturePlugin.prototype.pushEvent = function (type, ev) {
28092 var emitThrottles = this.emitThrottles;
28093 var newEvent = { type: type, ev: ev };
28094 for (var i = 0, len = emitThrottles.length; i < len; i++) {
28095 if (emitThrottles[i].type === type) {
28096 emitThrottles.splice(i, 1, newEvent);
28097 return;
28098 }
28099 }
28100 emitThrottles.push(newEvent);
28101 };
28102 GesturePlugin.prototype.clearPressTimeout = function () {
28103 if (this.pressTimeout) {
28104 clearTimeout(this.pressTimeout);
28105 this.pressTimeout = null;
28106 }
28107 };
28108 GesturePlugin.prototype.refreshAndGetTarget = function (target) {
28109 if (this.movingTarget) {
28110 // @ts-ignore
28111 if (this.movingTarget && !this.movingTarget.isConnected) {
28112 this.movingTarget = target;
28113 }
28114 return this.movingTarget;
28115 }
28116 return target;
28117 };
28118 GesturePlugin.prototype.reset = function () {
28119 this.clearPressTimeout();
28120 this.startTime = 0;
28121 this.startDistance = 0;
28122 this.direction = null;
28123 this.eventType = null;
28124 this.prevMoveTime = 0;
28125 this.prevMovePoint = null;
28126 this.lastMoveTime = 0;
28127 this.lastMovePoint = null;
28128 this.movingTarget = null;
28129 this.isPanListenerInPath = null;
28130 };
28131 GesturePlugin.tag = 'Gesture';
28132 return GesturePlugin;
28133 }());
28134
28135 var Plugin$6 = /** @class */ (function (_super) {
28136 __extends(Plugin, _super);
28137 function Plugin(options) {
28138 if (options === void 0) { options = {}; }
28139 var _this = _super.call(this) || this;
28140 _this.options = options;
28141 _this.name = 'gesture';
28142 return _this;
28143 }
28144 Plugin.prototype.init = function () {
28145 this.addRenderingPlugin(new GesturePlugin(__assign({ isDocumentGestureEnabled: false }, this.options)));
28146 };
28147 Plugin.prototype.destroy = function () {
28148 this.removeAllRenderingPlugins();
28149 };
28150 return Plugin;
28151 }(AbstractRendererPlugin));
28152
28153 function isCanvasElement(el) {
28154 if (!el || typeof el !== 'object')
28155 return false;
28156 if (el.nodeType === 1 && el.nodeName) {
28157 // HTMLCanvasElement
28158 return true;
28159 }
28160 // CanvasElement
28161 return !!el.isCanvasElement;
28162 }
28163
28164 var Canvas2DContextService = /** @class */ (function () {
28165 function Canvas2DContextService(context) {
28166 this.canvasConfig = context.config;
28167 }
28168 Canvas2DContextService.prototype.init = function () {
28169 return __awaiter(this, void 0, void 0, function () {
28170 var _a, canvas, devicePixelRatio, dpr;
28171 return __generator(this, function (_b) {
28172 _a = this.canvasConfig, canvas = _a.canvas, devicePixelRatio = _a.devicePixelRatio;
28173 this.$canvas = canvas;
28174 // 实际获取到小程序环境的上下文
28175 this.context = this.$canvas.getContext('2d');
28176 dpr = devicePixelRatio || 1;
28177 dpr = dpr >= 1 ? Math.ceil(dpr) : 1;
28178 this.dpr = dpr;
28179 this.resize(this.canvasConfig.width, this.canvasConfig.height);
28180 return [2 /*return*/];
28181 });
28182 });
28183 };
28184 Canvas2DContextService.prototype.getContext = function () {
28185 return this.context;
28186 };
28187 Canvas2DContextService.prototype.getDomElement = function () {
28188 return this.$canvas;
28189 };
28190 Canvas2DContextService.prototype.getDPR = function () {
28191 return this.dpr;
28192 };
28193 Canvas2DContextService.prototype.getBoundingClientRect = function () {
28194 if (this.$canvas.getBoundingClientRect) {
28195 return this.$canvas.getBoundingClientRect();
28196 }
28197 };
28198 Canvas2DContextService.prototype.destroy = function () {
28199 // TODO: 小程序环境销毁 context
28200 this.context = null;
28201 this.$canvas = null;
28202 };
28203 Canvas2DContextService.prototype.resize = function (width, height) {
28204 var devicePixelRatio = this.canvasConfig.devicePixelRatio;
28205 var pixelRatio = devicePixelRatio;
28206 var canvasDOM = this.$canvas; // HTMLCanvasElement or canvasElement
28207 // 浏览器环境设置style样式
28208 if (canvasDOM.style) {
28209 canvasDOM.style.width = width + 'px';
28210 canvasDOM.style.height = height + 'px';
28211 }
28212 if (isCanvasElement(canvasDOM)) {
28213 canvasDOM.width = width * pixelRatio;
28214 canvasDOM.height = height * pixelRatio;
28215 if (pixelRatio !== 1) {
28216 this.context.scale(pixelRatio, pixelRatio);
28217 }
28218 }
28219 };
28220 Canvas2DContextService.prototype.applyCursorStyle = function (cursor) {
28221 // 小程序环境无需设置鼠标样式
28222 };
28223 Canvas2DContextService.prototype.toDataURL = function (options) {
28224 return __awaiter(this, void 0, void 0, function () {
28225 var type, encoderOptions;
28226 return __generator(this, function (_a) {
28227 type = options.type, encoderOptions = options.encoderOptions;
28228 return [2 /*return*/, this.context.canvas.toDataURL(type, encoderOptions)];
28229 });
28230 });
28231 };
28232 return Canvas2DContextService;
28233 }());
28234
28235 var ContextRegisterPlugin = /** @class */ (function (_super) {
28236 __extends(ContextRegisterPlugin, _super);
28237 function ContextRegisterPlugin() {
28238 var _this = _super.apply(this, __spreadArray([], __read(arguments), false)) || this;
28239 _this.name = 'mobile-canvas-context-register';
28240 return _this;
28241 }
28242 ContextRegisterPlugin.prototype.init = function () {
28243 this.context.ContextService = Canvas2DContextService;
28244 };
28245 ContextRegisterPlugin.prototype.destroy = function () {
28246 delete this.context.ContextService;
28247 };
28248 return ContextRegisterPlugin;
28249 }(AbstractRendererPlugin));
28250
28251 var Renderer = /** @class */ (function (_super) {
28252 __extends(Renderer, _super);
28253 function Renderer(config) {
28254 var _this = _super.call(this, config) || this;
28255 // register Canvas2DContext
28256 _this.registerPlugin(new ContextRegisterPlugin());
28257 _this.registerPlugin(new Plugin$4());
28258 _this.registerPlugin(new Plugin());
28259 // enable rendering with Canvas2D API
28260 _this.registerPlugin(new Plugin$2());
28261 _this.registerPlugin(new Plugin$5());
28262 // enable picking with Canvas2D API
28263 _this.registerPlugin(new Plugin$1());
28264 _this.registerPlugin(new Plugin$3({
28265 isDocumentDraggable: isNil(config === null || config === void 0 ? void 0 : config.isDocumentDraggable)
28266 ? true
28267 : config.isDocumentDraggable,
28268 isDocumentDroppable: isNil(config === null || config === void 0 ? void 0 : config.isDocumentDroppable)
28269 ? true
28270 : config.isDocumentDroppable,
28271 dragstartDistanceThreshold: isNil(config === null || config === void 0 ? void 0 : config.dragstartDistanceThreshold)
28272 ? 10
28273 : config.dragstartDistanceThreshold,
28274 dragstartTimeThreshold: isNil(config === null || config === void 0 ? void 0 : config.dragstartTimeThreshold)
28275 ? 50
28276 : config.dragstartTimeThreshold,
28277 }));
28278 _this.registerPlugin(new Plugin$6({
28279 isDocumentGestureEnabled: true,
28280 }));
28281 return _this;
28282 }
28283 return Renderer;
28284 }(AbstractRenderer));
28285
28286 // 实现jsx-classic 入口
28287 function jsx(type, config) {
28288 var children = [];
28289 for (var _i = 2; _i < arguments.length; _i++) {
28290 children[_i - 2] = arguments[_i];
28291 }
28292 var _a = config || {},
28293 key = _a.key,
28294 ref = _a.ref,
28295 props = __rest(_a, ["key", "ref"]);
28296 // 保持和automatic模式一致
28297 if (children.length) {
28298 props.children = children.length === 1 ? children[0] : children;
28299 }
28300 return {
28301 key: key,
28302 ref: ref,
28303 type: type,
28304 props: props
28305 };
28306 }
28307
28308 var fragment = (function (props) {
28309 return props.children;
28310 });
28311
28312 var CanvasElement = /** @class */ (function () {
28313 function CanvasElement(ctx) {
28314 this.isCanvasElement = true;
28315 this.emitter = new eventemitter3();
28316 this.context = ctx;
28317 // 有可能是 node canvas 创建的 context 对象
28318 var canvas = ctx.canvas || {};
28319 this.width = canvas.width || 0;
28320 this.height = canvas.height || 0;
28321 }
28322 CanvasElement.prototype.getContext = function (contextId, contextAttributes) {
28323 return this.context;
28324 };
28325 CanvasElement.prototype.getBoundingClientRect = function () {
28326 var width = this.width;
28327 var height = this.height;
28328 // 默认都处理成可视窗口的顶部位置
28329 return {
28330 top: 0,
28331 right: width,
28332 bottom: height,
28333 left: 0,
28334 width: width,
28335 height: height,
28336 x: 0,
28337 y: 0,
28338 };
28339 };
28340 CanvasElement.prototype.addEventListener = function (type, listener, options) {
28341 // TODO: implement options
28342 this.emitter.on(type, listener);
28343 };
28344 CanvasElement.prototype.removeEventListener = function (type, listener, options) {
28345 this.emitter.off(type, listener);
28346 };
28347 /**
28348 * @see https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventTarget-dispatchEvent
28349 */
28350 CanvasElement.prototype.dispatchEvent = function (e) {
28351 this.emitter.emit(e.type, e);
28352 return true;
28353 };
28354 return CanvasElement;
28355 }());
28356 function supportEventListener(canvas) {
28357 if (!canvas) {
28358 return false;
28359 }
28360 // 非 HTMLCanvasElement
28361 if (canvas.nodeType !== 1 ||
28362 !canvas.nodeName ||
28363 canvas.nodeName.toLowerCase() !== 'canvas') {
28364 return false;
28365 }
28366 // 微信小程序canvas.getContext('2d')时也是CanvasRenderingContext2D
28367 // 也会有ctx.canvas, 而且nodeType也是1,所以还要在看下是否支持addEventListener
28368 var support = false;
28369 try {
28370 canvas.addEventListener('eventTest', function () {
28371 support = true;
28372 });
28373 canvas.dispatchEvent(new Event('eventTest'));
28374 }
28375 catch (error) {
28376 support = false;
28377 }
28378 return support;
28379 }
28380 function createMobileCanvasElement(ctx) {
28381 if (!ctx) {
28382 return null;
28383 }
28384 if (supportEventListener(ctx.canvas)) {
28385 return ctx.canvas;
28386 }
28387 return new CanvasElement(ctx);
28388 }
28389
28390 function createUpdater(canvas) {
28391 var setStateQueue = [];
28392 function process() {
28393 var item;
28394 var renderComponents = [];
28395 var renderCallbackQueue = [];
28396 while (item = setStateQueue.shift()) {
28397 var state = item.state,
28398 component = item.component,
28399 callback = item.callback;
28400 // 组件已销毁,不再触发 setState
28401 if (component.destroyed) {
28402 continue;
28403 }
28404 // 如果没有prevState,则将当前的state作为初始的prevState
28405 if (!component.prevState) {
28406 component.prevState = Object.assign({}, component.state);
28407 }
28408 // 如果stateChange是一个方法,也就是setState的第二种形式
28409 if (typeof state === 'function') {
28410 Object.assign(component.state, state(component.prevState, component.props));
28411 } else {
28412 // 如果stateChange是一个对象,则直接合并到setState中
28413 Object.assign(component.state, state);
28414 }
28415 component.prevState = component.state;
28416 if (typeof callback === 'function') {
28417 renderCallbackQueue.push({
28418 callback: callback,
28419 component: component
28420 });
28421 }
28422 if (renderComponents.indexOf(component) < 0) {
28423 renderComponents.push(component);
28424 }
28425 }
28426 canvas.updateComponents(renderComponents);
28427 // callback queue
28428 commitRenderQueue(renderCallbackQueue);
28429 }
28430 function enqueueSetState(component, state, callback) {
28431 if (setStateQueue.length === 0) {
28432 setTimeout(process, 0);
28433 }
28434 setStateQueue.push({
28435 component: component,
28436 state: state,
28437 callback: callback
28438 });
28439 }
28440 function commitRenderQueue(callbackQueue) {
28441 for (var i = 0; i < callbackQueue.length; i++) {
28442 var _a = callbackQueue[i],
28443 callback = _a.callback,
28444 component = _a.component;
28445 callback.call(component);
28446 }
28447 }
28448 var updater = {
28449 // isMounted: function(publicInstance) {
28450 // return false;
28451 // },
28452 enqueueForceUpdate: enqueueSetState,
28453 // enqueueReplaceState: function(publicInstance, completeState) {
28454 // },
28455 enqueueSetState: enqueueSetState
28456 };
28457 return updater;
28458 }
28459
28460 var THEME = {
28461 fontSize: '24px',
28462 fontFamily: '"Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif',
28463 pixelRatio: 1,
28464 padding: [0, 0, 0, 0]
28465 };
28466
28467 var elementStyle = {
28468 fillStyle: 'String',
28469 font: 'String',
28470 globalAlpha: 'Number',
28471 lineCap: 'String',
28472 lineWidth: ['Number', 'String'],
28473 lineJoin: 'String',
28474 miterLimit: 'Number',
28475 shadowBlur: 'Number',
28476 shadowColor: 'String',
28477 shadowOffsetX: 'Number',
28478 shadowOffsetY: 'Number',
28479 strokeStyle: 'String',
28480 textAlign: 'String',
28481 textBaseline: 'String',
28482 lineDash: ['Array', 'Number'],
28483 shadow: 'String',
28484 matrix: 'Array',
28485 stroke: 'String',
28486 fill: ['String', 'Object'],
28487 opacity: 'Number',
28488 fillOpacity: 'Number',
28489 strokeOpacity: 'Number'
28490 };
28491 // css规则表 TODO:补充 / 多种类型
28492 var DEFAULT_CSS_RULE = {
28493 group: __assign({}, elementStyle),
28494 text: __assign(__assign({}, elementStyle), {
28495 x: 'Number',
28496 y: 'Number',
28497 text: 'String',
28498 width: 'Number',
28499 height: 'Number',
28500 fontSize: ['Number', 'String'],
28501 fontFamily: 'String',
28502 fontStyle: 'String',
28503 fontWeight: ['Number', 'String'],
28504 fontVariant: 'String'
28505 }),
28506 circle: __assign(__assign({}, elementStyle), {
28507 cx: 'Number',
28508 cy: 'Number',
28509 r: 'Number'
28510 }),
28511 path: __assign({}, elementStyle),
28512 ellipse: __assign(__assign({}, elementStyle), {
28513 cy: 'Number',
28514 cx: 'Number',
28515 ry: 'Number',
28516 rx: 'Number'
28517 }),
28518 rect: __assign(__assign({}, elementStyle), {
28519 width: 'Number',
28520 height: 'Number',
28521 x: 'Number',
28522 y: 'Number',
28523 radius: ['Array', 'Number']
28524 }),
28525 image: __assign(__assign({}, elementStyle), {
28526 width: 'Number',
28527 height: 'Number',
28528 x: 'Number',
28529 y: 'Number',
28530 img: 'String',
28531 src: 'String'
28532 }),
28533 line: __assign(__assign({}, elementStyle), {
28534 x1: 'Number',
28535 x2: 'Number',
28536 y1: 'Number',
28537 y2: 'Number'
28538 }),
28539 polyline: __assign(__assign({}, elementStyle), {
28540 points: 'Array',
28541 smooth: 'Boolean'
28542 }),
28543 polygon: __assign(__assign({}, elementStyle), {
28544 points: 'Array'
28545 }),
28546 arc: __assign(__assign({}, elementStyle), {
28547 x: 'Number',
28548 y: 'Number',
28549 r: 'Number',
28550 startAngle: ['Number', 'String'],
28551 endAngle: ['Number', 'String'],
28552 anticlockwise: 'Boolean'
28553 }),
28554 marker: __assign(__assign({}, elementStyle), {
28555 x: 'Number',
28556 y: 'Number',
28557 radius: 'Number',
28558 symbol: 'String'
28559 }),
28560 sector: __assign(__assign({}, elementStyle), {
28561 x: 'Number',
28562 y: 'Number',
28563 startAngle: ['Number', 'String'],
28564 endAngle: ['Number', 'String'],
28565 r: 'Number',
28566 r0: 'Number',
28567 anticlockwise: 'Boolean'
28568 })
28569 };
28570 function checkCSSRule(type, style) {
28571 if (!style) {
28572 return style;
28573 }
28574 var cssStyle = {};
28575 Object.keys(style).forEach(function (key) {
28576 var value = style[key];
28577 if (isNil(value)) {
28578 return;
28579 }
28580 var rule = DEFAULT_CSS_RULE[type] && DEFAULT_CSS_RULE[type][key];
28581 if (!rule) {
28582 cssStyle[key] = value;
28583 return;
28584 }
28585 var valueType = Object.prototype.toString.call(value);
28586 if (isArray(rule)) {
28587 for (var i = 0, len = rule.length; i < len; i++) {
28588 if (valueType === "[object ".concat(rule[i], "]")) {
28589 cssStyle[key] = value;
28590 return;
28591 }
28592 }
28593 // 没有匹配的类型
28594 return;
28595 }
28596 // string
28597 if (valueType === "[object ".concat(rule, "]")) {
28598 cssStyle[key] = value;
28599 }
28600 });
28601 return cssStyle;
28602 }
28603
28604 // 默认设置50
28605 var ONE_REM;
28606 try {
28607 // xgraph下这段会抛错
28608 ONE_REM = parseInt(document.documentElement.style.fontSize, 10) || 50;
28609 } catch (e) {
28610 ONE_REM = 50;
28611 }
28612 var SCALE = ONE_REM / 100;
28613 /**
28614 * 像素转换
28615 * @param {Number} px - 750视觉稿像素
28616 * @return {Number} 屏幕上实际像素
28617 */
28618 function defaultPx2hd(px) {
28619 if (!px) {
28620 return 0;
28621 }
28622 return Number((px * SCALE).toFixed(1));
28623 }
28624 function parsePadding(padding) {
28625 if (isNumber(padding)) {
28626 return [padding, padding, padding, padding];
28627 }
28628 var top = padding[0];
28629 var right = isNumber(padding[1]) ? padding[1] : padding[0];
28630 var bottom = isNumber(padding[2]) ? padding[2] : top;
28631 var left = isNumber(padding[3]) ? padding[3] : right;
28632 return [top, right, bottom, left];
28633 }
28634 function batch2hd(px2hd) {
28635 var _batchPx2hd = function batchPx2hd(value) {
28636 // 处理带px的数据
28637 if (isString(value) && /^-?\d+(\.\d+)?px$/.test(value)) {
28638 var num = value.substr(0, value.length - 2);
28639 return px2hd(Number(num));
28640 }
28641 if (isArray(value)) {
28642 return value.map(function (v) {
28643 return _batchPx2hd(v);
28644 });
28645 }
28646 if (isPlainObject(value)) {
28647 var result = {};
28648 for (var key in value) {
28649 if (value.hasOwnProperty(key)) {
28650 var rst = _batchPx2hd(value[key]);
28651 if (!rst) {
28652 result[key] = rst;
28653 continue;
28654 }
28655 if (key === 'padding' || key === 'margin') {
28656 var paddingArray = parsePadding(rst);
28657 result[key] = paddingArray;
28658 result["".concat(key, "Top")] = paddingArray[0];
28659 result["".concat(key, "Right")] = paddingArray[1];
28660 result["".concat(key, "Bottom")] = paddingArray[2];
28661 result["".concat(key, "Left")] = paddingArray[3];
28662 continue;
28663 }
28664 result[key] = rst;
28665 }
28666 }
28667 return result;
28668 }
28669 // 默认直接返回
28670 return value;
28671 };
28672 return _batchPx2hd;
28673 }
28674 var px2hd = batch2hd(defaultPx2hd);
28675
28676 /**
28677 * @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationPlaybackEvent
28678 */
28679 // @ts-ignore
28680 var AnimationEvent = /** @class */ (function (_super) {
28681 __extends(AnimationEvent, _super);
28682 function AnimationEvent(manager, target, currentTime, timelineTime) {
28683 var _this = _super.call(this, manager) || this;
28684 _this.currentTime = currentTime;
28685 _this.timelineTime = timelineTime;
28686 // @ts-ignore
28687 _this.target = target;
28688 _this.type = 'finish';
28689 _this.bubbles = false;
28690 // @ts-ignore
28691 _this.currentTarget = target;
28692 _this.defaultPrevented = false;
28693 _this.eventPhase = _this.AT_TARGET;
28694 _this.timeStamp = Date.now();
28695 _this.currentTime = currentTime;
28696 _this.timelineTime = timelineTime;
28697 return _this;
28698 }
28699 return AnimationEvent;
28700 }(FederatedEvent));
28701
28702 var sequenceNumber = 0;
28703 /**
28704 * @see https://developer.mozilla.org/en-US/docs/Web/API/Animation/Animation
28705 */
28706 var Animation = /** @class */ (function () {
28707 function Animation(effect, timeline) {
28708 var _a;
28709 this.currentTimePending = false;
28710 /**
28711 * @see https://developer.mozilla.org/en-US/docs/Web/API/Animation/playState
28712 */
28713 // playState: AnimationPlayState;
28714 this._idle = true;
28715 this._paused = false;
28716 this._finishedFlag = true;
28717 /**
28718 * @see https://developer.mozilla.org/en-US/docs/Web/API/Animation/currentTime
28719 */
28720 this._currentTime = 0;
28721 this._playbackRate = 1;
28722 this._inTimeline = true;
28723 this.effect = effect;
28724 effect.animation = this;
28725 this.timeline = timeline;
28726 this.id = "".concat(sequenceNumber++);
28727 this._inEffect = !!this.effect.update(0);
28728 this._totalDuration = Number((_a = this.effect) === null || _a === void 0 ? void 0 : _a.getComputedTiming().endTime);
28729 this._holdTime = 0;
28730 this._paused = false;
28731 this.oldPlayState = 'idle';
28732 this.updatePromises();
28733 }
28734 Object.defineProperty(Animation.prototype, "pending", {
28735 // animation: InternalAnimation | null;
28736 /**
28737 * @see https://developer.mozilla.org/en-US/docs/Web/API/Animation/pending
28738 */
28739 get: function () {
28740 return ((this._startTime === null && !this._paused && this.playbackRate !== 0) ||
28741 this.currentTimePending);
28742 },
28743 enumerable: false,
28744 configurable: true
28745 });
28746 Object.defineProperty(Animation.prototype, "playState", {
28747 get: function () {
28748 if (this._idle)
28749 return 'idle';
28750 if (this._isFinished)
28751 return 'finished';
28752 if (this._paused)
28753 return 'paused';
28754 return 'running';
28755 },
28756 enumerable: false,
28757 configurable: true
28758 });
28759 Object.defineProperty(Animation.prototype, "ready", {
28760 /**
28761 * @see https://developer.mozilla.org/en-US/docs/Web/API/Animation/ready
28762 * @example
28763 animation.pause();
28764 animation.ready.then(function() {
28765 // Displays 'running'
28766 alert(animation.playState);
28767 });
28768 animation.play();
28769 */
28770 get: function () {
28771 var _this = this;
28772 if (!this.readyPromise) {
28773 if (this.timeline.animationsWithPromises.indexOf(this) === -1) {
28774 this.timeline.animationsWithPromises.push(this);
28775 }
28776 this.readyPromise = new Promise(function (resolve, reject) {
28777 _this.resolveReadyPromise = function () {
28778 resolve(_this);
28779 };
28780 _this.rejectReadyPromise = function () {
28781 reject(new Error());
28782 };
28783 });
28784 if (!this.pending) {
28785 this.resolveReadyPromise();
28786 }
28787 }
28788 return this.readyPromise;
28789 },
28790 enumerable: false,
28791 configurable: true
28792 });
28793 Object.defineProperty(Animation.prototype, "finished", {
28794 /**
28795 * @see https://developer.mozilla.org/en-US/docs/Web/API/Animation/finished
28796 * @example
28797 Promise.all(
28798 elem.getAnimations().map(
28799 function(animation) {
28800 return animation.finished
28801 }
28802 )
28803 ).then(
28804 function() {
28805 return elem.remove();
28806 }
28807 );
28808 */
28809 get: function () {
28810 var _this = this;
28811 if (!this.finishedPromise) {
28812 if (this.timeline.animationsWithPromises.indexOf(this) === -1) {
28813 this.timeline.animationsWithPromises.push(this);
28814 }
28815 this.finishedPromise = new Promise(function (resolve, reject) {
28816 _this.resolveFinishedPromise = function () {
28817 resolve(_this);
28818 };
28819 _this.rejectFinishedPromise = function () {
28820 reject(new Error());
28821 };
28822 });
28823 if (this.playState === 'finished') {
28824 this.resolveFinishedPromise();
28825 }
28826 }
28827 return this.finishedPromise;
28828 },
28829 enumerable: false,
28830 configurable: true
28831 });
28832 Object.defineProperty(Animation.prototype, "currentTime", {
28833 get: function () {
28834 this.updatePromises();
28835 return this._idle || this.currentTimePending ? null : this._currentTime;
28836 },
28837 set: function (newTime) {
28838 var _a;
28839 newTime = Number(newTime);
28840 if (isNaN(newTime))
28841 return;
28842 this.timeline.restart();
28843 if (!this._paused && this._startTime !== null) {
28844 this._startTime =
28845 Number((_a = this.timeline) === null || _a === void 0 ? void 0 : _a.currentTime) - newTime / this.playbackRate;
28846 }
28847 this.currentTimePending = false;
28848 if (this._currentTime === newTime) {
28849 return;
28850 }
28851 if (this._idle) {
28852 this._idle = false;
28853 this._paused = true;
28854 }
28855 this.tickCurrentTime(newTime, true);
28856 this.timeline.applyDirtiedAnimation(this);
28857 },
28858 enumerable: false,
28859 configurable: true
28860 });
28861 Object.defineProperty(Animation.prototype, "startTime", {
28862 get: function () {
28863 return this._startTime;
28864 },
28865 set: function (newTime) {
28866 if (newTime !== null) {
28867 this.updatePromises();
28868 newTime = Number(newTime);
28869 if (isNaN(newTime))
28870 return;
28871 if (this._paused || this._idle)
28872 return;
28873 this._startTime = newTime;
28874 this.tickCurrentTime((Number(this.timeline.currentTime) - this._startTime) *
28875 this.playbackRate);
28876 this.timeline.applyDirtiedAnimation(this);
28877 this.updatePromises();
28878 }
28879 },
28880 enumerable: false,
28881 configurable: true
28882 });
28883 Object.defineProperty(Animation.prototype, "playbackRate", {
28884 get: function () {
28885 return this._playbackRate;
28886 },
28887 set: function (value) {
28888 if (value === this._playbackRate) {
28889 return;
28890 }
28891 this.updatePromises();
28892 var oldCurrentTime = this.currentTime;
28893 this._playbackRate = value;
28894 this.startTime = null;
28895 if (this.playState !== 'paused' && this.playState !== 'idle') {
28896 this._finishedFlag = false;
28897 this._idle = false;
28898 this.ensureAlive();
28899 this.timeline.applyDirtiedAnimation(this);
28900 }
28901 if (oldCurrentTime !== null) {
28902 this.currentTime = oldCurrentTime;
28903 }
28904 this.updatePromises();
28905 },
28906 enumerable: false,
28907 configurable: true
28908 });
28909 Object.defineProperty(Animation.prototype, "_isFinished", {
28910 get: function () {
28911 return (!this._idle &&
28912 ((this._playbackRate > 0 &&
28913 Number(this._currentTime) >= this._totalDuration) ||
28914 (this._playbackRate < 0 && Number(this._currentTime) <= 0)));
28915 },
28916 enumerable: false,
28917 configurable: true
28918 });
28919 Object.defineProperty(Animation.prototype, "totalDuration", {
28920 get: function () {
28921 return this._totalDuration;
28922 },
28923 enumerable: false,
28924 configurable: true
28925 });
28926 Object.defineProperty(Animation.prototype, "_needsTick", {
28927 get: function () {
28928 return this.pending || this.playState === 'running' || !this._finishedFlag;
28929 },
28930 enumerable: false,
28931 configurable: true
28932 });
28933 /**
28934 * state machine,
28935 * resolve/reject ready/finished Promise according to current state
28936 */
28937 Animation.prototype.updatePromises = function () {
28938 var oldPlayState = this.oldPlayState;
28939 var newPlayState = this.pending ? 'pending' : this.playState;
28940 if (this.readyPromise && newPlayState !== oldPlayState) {
28941 if (newPlayState === 'idle') {
28942 this.rejectReadyPromise();
28943 this.readyPromise = undefined;
28944 }
28945 else if (oldPlayState === 'pending') {
28946 this.resolveReadyPromise();
28947 }
28948 else if (newPlayState === 'pending') {
28949 this.readyPromise = undefined;
28950 }
28951 }
28952 if (this.finishedPromise && newPlayState !== oldPlayState) {
28953 if (newPlayState === 'idle') {
28954 this.rejectFinishedPromise();
28955 this.finishedPromise = undefined;
28956 }
28957 else if (newPlayState === 'finished') {
28958 this.resolveFinishedPromise();
28959 }
28960 else if (oldPlayState === 'finished') {
28961 this.finishedPromise = undefined;
28962 }
28963 }
28964 this.oldPlayState = newPlayState;
28965 return this.readyPromise || this.finishedPromise;
28966 };
28967 Animation.prototype.play = function () {
28968 this.updatePromises();
28969 this._paused = false;
28970 if (this._isFinished || this._idle) {
28971 this.rewind();
28972 this._startTime = null;
28973 }
28974 this._finishedFlag = false;
28975 this._idle = false;
28976 this.ensureAlive();
28977 this.timeline.applyDirtiedAnimation(this);
28978 if (this.timeline.animations.indexOf(this) === -1) {
28979 this.timeline.animations.push(this);
28980 }
28981 this.updatePromises();
28982 };
28983 Animation.prototype.pause = function () {
28984 this.updatePromises();
28985 if (this.currentTime) {
28986 this._holdTime = this.currentTime;
28987 }
28988 if (!this._isFinished && !this._paused && !this._idle) {
28989 this.currentTimePending = true;
28990 }
28991 else if (this._idle) {
28992 this.rewind();
28993 this._idle = false;
28994 }
28995 this._startTime = null;
28996 this._paused = true;
28997 this.updatePromises();
28998 };
28999 Animation.prototype.finish = function () {
29000 this.updatePromises();
29001 if (this._idle)
29002 return;
29003 this.currentTime = this._playbackRate > 0 ? this._totalDuration : 0;
29004 this._startTime = this._totalDuration - this.currentTime;
29005 this.currentTimePending = false;
29006 this.timeline.applyDirtiedAnimation(this);
29007 this.updatePromises();
29008 };
29009 Animation.prototype.cancel = function () {
29010 var _this = this;
29011 this.updatePromises();
29012 if (!this._inEffect)
29013 return;
29014 this._inEffect = false;
29015 this._idle = true;
29016 this._paused = false;
29017 this._finishedFlag = true;
29018 this._currentTime = 0;
29019 this._startTime = null;
29020 this.effect.update(null);
29021 // effects are invalid after cancellation as the animation state
29022 // needs to un-apply.
29023 this.timeline.applyDirtiedAnimation(this);
29024 this.updatePromises();
29025 /**
29026 * 1. Reject the current finished promise with a DOMException named "AbortError".
29027 * 2. Let current finished promise be a new promise
29028 * @see https://w3c.github.io/csswg-drafts/web-animations-1/#canceling-an-animation-section
29029 */
29030 // if (this.finishedPromise) {
29031 // this.rejectFinishedPromise();
29032 // this.finishedPromise = undefined;
29033 // }
29034 if (this.oncancel) {
29035 var event_1 = new AnimationEvent(null, this, this.currentTime, null);
29036 setTimeout(function () {
29037 _this.oncancel(event_1);
29038 });
29039 }
29040 };
29041 Animation.prototype.reverse = function () {
29042 this.updatePromises();
29043 var oldCurrentTime = this.currentTime;
29044 this.playbackRate *= -1;
29045 this.play();
29046 if (oldCurrentTime !== null) {
29047 this.currentTime = oldCurrentTime;
29048 }
29049 this.updatePromises();
29050 };
29051 /**
29052 * @see https://developer.mozilla.org/en-US/docs/Web/API/Animation/updatePlaybackRate
29053 */
29054 Animation.prototype.updatePlaybackRate = function (playbackRate) {
29055 this.playbackRate = playbackRate;
29056 };
29057 Animation.prototype.targetAnimations = function () {
29058 var _a;
29059 var target = (_a = this.effect) === null || _a === void 0 ? void 0 : _a.target;
29060 return target.getAnimations();
29061 };
29062 Animation.prototype.markTarget = function () {
29063 var animations = this.targetAnimations();
29064 if (animations.indexOf(this) === -1) {
29065 animations.push(this);
29066 }
29067 };
29068 Animation.prototype.unmarkTarget = function () {
29069 var animations = this.targetAnimations();
29070 var index = animations.indexOf(this);
29071 if (index !== -1) {
29072 animations.splice(index, 1);
29073 }
29074 };
29075 Animation.prototype.tick = function (timelineTime, isAnimationFrame) {
29076 if (!this._idle && !this._paused) {
29077 if (this._startTime === null) {
29078 if (isAnimationFrame) {
29079 this.startTime = timelineTime - this._currentTime / this.playbackRate;
29080 }
29081 }
29082 else if (!this._isFinished) {
29083 this.tickCurrentTime((timelineTime - this._startTime) * this.playbackRate);
29084 }
29085 }
29086 if (isAnimationFrame) {
29087 this.currentTimePending = false;
29088 this.fireEvents(timelineTime);
29089 }
29090 };
29091 Animation.prototype.rewind = function () {
29092 if (this.playbackRate >= 0) {
29093 this.currentTime = 0;
29094 }
29095 else if (this._totalDuration < Infinity) {
29096 this.currentTime = this._totalDuration;
29097 }
29098 else {
29099 throw new Error('Unable to rewind negative playback rate animation with infinite duration');
29100 }
29101 };
29102 Animation.prototype.persist = function () {
29103 throw new Error(ERROR_MSG_METHOD_NOT_IMPLEMENTED);
29104 };
29105 Animation.prototype.addEventListener = function (type, listener, options) {
29106 throw new Error(ERROR_MSG_METHOD_NOT_IMPLEMENTED);
29107 };
29108 Animation.prototype.removeEventListener = function (type, listener, options) {
29109 throw new Error(ERROR_MSG_METHOD_NOT_IMPLEMENTED);
29110 };
29111 Animation.prototype.dispatchEvent = function (event) {
29112 throw new Error(ERROR_MSG_METHOD_NOT_IMPLEMENTED);
29113 };
29114 // replaceState: AnimationReplaceState;
29115 Animation.prototype.commitStyles = function () {
29116 throw new Error(ERROR_MSG_METHOD_NOT_IMPLEMENTED);
29117 };
29118 Animation.prototype.ensureAlive = function () {
29119 var _a, _b;
29120 // If an animation is playing backwards and is not fill backwards/both
29121 // then it should go out of effect when it reaches the start of its
29122 // active interval (currentTime === 0).
29123 if (this.playbackRate < 0 && this.currentTime === 0) {
29124 this._inEffect = !!((_a = this.effect) === null || _a === void 0 ? void 0 : _a.update(-1));
29125 }
29126 else {
29127 this._inEffect = !!((_b = this.effect) === null || _b === void 0 ? void 0 : _b.update(this.currentTime));
29128 }
29129 if (!this._inTimeline && (this._inEffect || !this._finishedFlag)) {
29130 this._inTimeline = true;
29131 this.timeline.animations.push(this);
29132 }
29133 };
29134 Animation.prototype.tickCurrentTime = function (newTime, ignoreLimit) {
29135 if (newTime !== this._currentTime) {
29136 this._currentTime = newTime;
29137 if (this._isFinished && !ignoreLimit) {
29138 this._currentTime = this._playbackRate > 0 ? this._totalDuration : 0;
29139 }
29140 this.ensureAlive();
29141 }
29142 };
29143 Animation.prototype.fireEvents = function (baseTime) {
29144 var _this = this;
29145 if (this._isFinished) {
29146 if (!this._finishedFlag) {
29147 if (this.onfinish) {
29148 var event_2 = new AnimationEvent(null, this, this.currentTime, baseTime);
29149 setTimeout(function () {
29150 if (_this.onfinish) {
29151 _this.onfinish(event_2);
29152 }
29153 });
29154 }
29155 this._finishedFlag = true;
29156 }
29157 }
29158 else {
29159 if (this.onframe && this.playState === 'running') {
29160 var event_3 = new AnimationEvent(null, this, this.currentTime, baseTime);
29161 this.onframe(event_3);
29162 }
29163 this._finishedFlag = false;
29164 }
29165 };
29166 return Animation;
29167 }());
29168
29169 /**
29170 * https://github.com/gre/bezier-easing
29171 * BezierEasing - use bezier curve for transition easing function
29172 * by Gaëtan Renaudeau 2014 - 2015 – MIT License
29173 */
29174 // These values are established by empiricism with tests (tradeoff: performance VS precision)
29175 var NEWTON_ITERATIONS = 4;
29176 var NEWTON_MIN_SLOPE = 0.001;
29177 var SUBDIVISION_PRECISION = 0.0000001;
29178 var SUBDIVISION_MAX_ITERATIONS = 10;
29179 var kSplineTableSize = 11;
29180 var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
29181 var float32ArraySupported = typeof Float32Array === 'function';
29182 var A = function (aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; };
29183 var B = function (aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; };
29184 var C = function (aA1) { return 3.0 * aA1; };
29185 // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
29186 var calcBezier = function (aT, aA1, aA2) {
29187 return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
29188 };
29189 // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
29190 var getSlope = function (aT, aA1, aA2) {
29191 return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
29192 };
29193 var binarySubdivide = function (aX, aA, aB, mX1, mX2) {
29194 var currentX, currentT, i = 0;
29195 do {
29196 currentT = aA + (aB - aA) / 2.0;
29197 currentX = calcBezier(currentT, mX1, mX2) - aX;
29198 if (currentX > 0.0)
29199 aB = currentT;
29200 else
29201 aA = currentT;
29202 } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
29203 return currentT;
29204 };
29205 var newtonRaphsonIterate = function (aX, aGuessT, mX1, mX2) {
29206 for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
29207 var currentSlope = getSlope(aGuessT, mX1, mX2);
29208 if (currentSlope === 0.0)
29209 return aGuessT;
29210 var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
29211 aGuessT -= currentX / currentSlope;
29212 }
29213 return aGuessT;
29214 };
29215 var bezier = function (mX1, mY1, mX2, mY2) {
29216 if (!(0 <= mX1 && mX1 <= 1 && 0 <= mX2 && mX2 <= 1))
29217 throw new Error('bezier x values must be in [0, 1] range');
29218 if (mX1 === mY1 && mX2 === mY2)
29219 return function (t) { return t; };
29220 // Precompute samples table
29221 var sampleValues = float32ArraySupported
29222 ? new Float32Array(kSplineTableSize)
29223 : new Array(kSplineTableSize);
29224 for (var i = 0; i < kSplineTableSize; ++i) {
29225 sampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
29226 }
29227 var getTForX = function (aX) {
29228 var intervalStart = 0.0;
29229 var currentSample = 1;
29230 var lastSample = kSplineTableSize - 1;
29231 for (; currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample)
29232 intervalStart += kSampleStepSize;
29233 --currentSample;
29234 // Interpolate to provide an initial guess for t
29235 var dist = (aX - sampleValues[currentSample]) /
29236 (sampleValues[currentSample + 1] - sampleValues[currentSample]);
29237 var guessForT = intervalStart + dist * kSampleStepSize;
29238 var initialSlope = getSlope(guessForT, mX1, mX2);
29239 if (initialSlope >= NEWTON_MIN_SLOPE)
29240 return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
29241 else if (initialSlope === 0.0)
29242 return guessForT;
29243 else {
29244 return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
29245 }
29246 };
29247 return function (t) {
29248 // Because JavaScript number are imprecise, we should guarantee the extremes are right.
29249 if (t === 0 || t === 1)
29250 return t;
29251 return calcBezier(getTForX(t), mY1, mY2);
29252 };
29253 };
29254
29255 var convertToDash = function (str) {
29256 str = str.replace(/([A-Z])/g, function (letter) { return "-".concat(letter.toLowerCase()); });
29257 // Remove first dash
29258 return str.charAt(0) === '-' ? str.substring(1) : str;
29259 };
29260 /**
29261 Easing Functions from anime.js, they are tried and true, so, its better to use them instead of other alternatives
29262 */
29263 var Quad = function (t) { return Math.pow(t, 2); };
29264 var Cubic = function (t) { return Math.pow(t, 3); };
29265 var Quart = function (t) { return Math.pow(t, 4); };
29266 var Quint = function (t) { return Math.pow(t, 5); };
29267 var Expo = function (t) { return Math.pow(t, 6); };
29268 var Sine = function (t) { return 1 - Math.cos((t * Math.PI) / 2); };
29269 var Circ = function (t) { return 1 - Math.sqrt(1 - t * t); };
29270 var Back = function (t) { return t * t * (3 * t - 2); };
29271 var Bounce = function (t) {
29272 var pow2, b = 4;
29273 while (t < ((pow2 = Math.pow(2, --b)) - 1) / 11) { }
29274 return 1 / Math.pow(4, 3 - b) - 7.5625 * Math.pow((pow2 * 3 - 2) / 22 - t, 2);
29275 };
29276 var Elastic = function (t, params) {
29277 if (params === void 0) { params = []; }
29278 var _a = __read(params, 2), _b = _a[0], amplitude = _b === void 0 ? 1 : _b, _c = _a[1], period = _c === void 0 ? 0.5 : _c;
29279 var a = clamp(Number(amplitude), 1, 10);
29280 var p = clamp(Number(period), 0.1, 2);
29281 if (t === 0 || t === 1)
29282 return t;
29283 return (-a *
29284 Math.pow(2, 10 * (t - 1)) *
29285 Math.sin(((t - 1 - (p / (Math.PI * 2)) * Math.asin(1 / a)) * (Math.PI * 2)) / p));
29286 };
29287 var Spring = function (t, params, duration) {
29288 if (params === void 0) { params = []; }
29289 var _a = __read(params, 4), _b = _a[0], mass = _b === void 0 ? 1 : _b, _c = _a[1], stiffness = _c === void 0 ? 100 : _c, _d = _a[2], damping = _d === void 0 ? 10 : _d, _e = _a[3], velocity = _e === void 0 ? 0 : _e;
29290 mass = clamp(mass, 0.1, 1000);
29291 stiffness = clamp(stiffness, 0.1, 1000);
29292 damping = clamp(damping, 0.1, 1000);
29293 velocity = clamp(velocity, 0.1, 1000);
29294 var w0 = Math.sqrt(stiffness / mass);
29295 var zeta = damping / (2 * Math.sqrt(stiffness * mass));
29296 var wd = zeta < 1 ? w0 * Math.sqrt(1 - zeta * zeta) : 0;
29297 var a = 1;
29298 var b = zeta < 1 ? (zeta * w0 + -velocity) / wd : -velocity + w0;
29299 var progress = duration ? (duration * t) / 1000 : t;
29300 if (zeta < 1) {
29301 progress =
29302 Math.exp(-progress * zeta * w0) * (a * Math.cos(wd * progress) + b * Math.sin(wd * progress));
29303 }
29304 else {
29305 progress = (a + b * progress) * Math.exp(-progress * w0);
29306 }
29307 if (t === 0 || t === 1)
29308 return t;
29309 return 1 - progress;
29310 };
29311 /**
29312 * Cache the durations at set easing parameters
29313 */
29314 // export const EasingDurationCache: Map<string | TypeEasingFunction, number> = new Map();
29315 /**
29316 * The threshold for an infinite loop
29317 */
29318 // const INTINITE_LOOP_LIMIT = 10000;
29319 /** Convert easing parameters to Array of numbers, e.g. "spring(2, 500)" to [2, 500] */
29320 // export const parseEasingParameters = (str: string) => {
29321 // const match = /(\(|\s)([^)]+)\)?/.exec(str);
29322 // return match
29323 // ? match[2].split(',').map((value) => {
29324 // const num = parseFloat(value);
29325 // return !Number.isNaN(num) ? num : value.trim();
29326 // })
29327 // : [];
29328 // };
29329 /**
29330 * The spring easing function will only look smooth at certain durations, with certain parameters.
29331 * This functions returns the optimal duration to create a smooth springy animation based on physics
29332 *
29333 * Note: it can also be used to determine the optimal duration of other types of easing function, but be careful of 'in-'
29334 * easing functions, because of the nature of the function it can sometimes create an infinite loop, I suggest only using
29335 * `getEasingDuration` for `spring`, specifically 'out-spring' and 'spring'
29336 */
29337 // export const getEasingDuration = (easing: string | TypeEasingFunction = 'spring') => {
29338 // if (EasingDurationCache.has(easing)) return EasingDurationCache.get(easing);
29339 // // eslint-disable-next-line @typescript-eslint/no-use-before-define
29340 // const easingFunction = typeof easing == 'function' ? easing : getEasingFunction(easing as string);
29341 // const params = typeof easing == 'function' ? [] : parseEasingParameters(easing);
29342 // const frame = 1 / 6;
29343 // let elapsed = 0;
29344 // let rest = 0;
29345 // let count = 0;
29346 // while (++count < INTINITE_LOOP_LIMIT) {
29347 // elapsed += frame;
29348 // if (easingFunction(elapsed, params, undefined) === 1) {
29349 // rest++;
29350 // if (rest >= 16) break;
29351 // } else {
29352 // rest = 0;
29353 // }
29354 // }
29355 // const duration = elapsed * frame * 1000;
29356 // EasingDurationCache.set(easing, duration);
29357 // return duration;
29358 // };
29359 /**
29360 These Easing Functions are based off of the Sozi Project's easing functions
29361 https://github.com/sozi-projects/Sozi/blob/d72e44ebd580dc7579d1e177406ad41e632f961d/src/js/player/Timing.js
29362 */
29363 var Steps = function (t, params) {
29364 if (params === void 0) { params = []; }
29365 var _a = __read(params, 2), _b = _a[0], steps = _b === void 0 ? 10 : _b, type = _a[1];
29366 var trunc = type == 'start' ? Math.ceil : Math.floor;
29367 return trunc(clamp(t, 0, 1) * steps) / steps;
29368 };
29369 // @ts-ignore
29370 var Bezier = function (t, params) {
29371 if (params === void 0) { params = []; }
29372 var _a = __read(params, 4), mX1 = _a[0], mY1 = _a[1], mX2 = _a[2], mY2 = _a[3];
29373 return bezier(mX1, mY1, mX2, mY2)(t);
29374 };
29375 /** The default `ease-in` easing function */
29376 var easein = bezier(0.42, 0.0, 1.0, 1.0);
29377 /** Converts easing functions to their `out`counter parts */
29378 var EaseOut = function (ease) {
29379 return function (t, params, duration) {
29380 if (params === void 0) { params = []; }
29381 return 1 - ease(1 - t, params, duration);
29382 };
29383 };
29384 /** Converts easing functions to their `in-out` counter parts */
29385 var EaseInOut = function (ease) {
29386 return function (t, params, duration) {
29387 if (params === void 0) { params = []; }
29388 return t < 0.5 ? ease(t * 2, params, duration) / 2 : 1 - ease(t * -2 + 2, params, duration) / 2;
29389 };
29390 };
29391 /** Converts easing functions to their `out-in` counter parts */
29392 var EaseOutIn = function (ease) {
29393 return function (t, params, duration) {
29394 if (params === void 0) { params = []; }
29395 return t < 0.5
29396 ? (1 - ease(1 - t * 2, params, duration)) / 2
29397 : (ease(t * 2 - 1, params, duration) + 1) / 2;
29398 };
29399 };
29400 var EasingFunctions = {
29401 steps: Steps,
29402 'step-start': function (t) { return Steps(t, [1, 'start']); },
29403 'step-end': function (t) { return Steps(t, [1, 'end']); },
29404 linear: function (t) { return t; },
29405 'cubic-bezier': Bezier,
29406 ease: function (t) { return Bezier(t, [0.25, 0.1, 0.25, 1.0]); },
29407 in: easein,
29408 out: EaseOut(easein),
29409 'in-out': EaseInOut(easein),
29410 'out-in': EaseOutIn(easein),
29411 'in-quad': Quad,
29412 'out-quad': EaseOut(Quad),
29413 'in-out-quad': EaseInOut(Quad),
29414 'out-in-quad': EaseOutIn(Quad),
29415 'in-cubic': Cubic,
29416 'out-cubic': EaseOut(Cubic),
29417 'in-out-cubic': EaseInOut(Cubic),
29418 'out-in-cubic': EaseOutIn(Cubic),
29419 'in-quart': Quart,
29420 'out-quart': EaseOut(Quart),
29421 'in-out-quart': EaseInOut(Quart),
29422 'out-in-quart': EaseOutIn(Quart),
29423 'in-quint': Quint,
29424 'out-quint': EaseOut(Quint),
29425 'in-out-quint': EaseInOut(Quint),
29426 'out-in-quint': EaseOutIn(Quint),
29427 'in-expo': Expo,
29428 'out-expo': EaseOut(Expo),
29429 'in-out-expo': EaseInOut(Expo),
29430 'out-in-expo': EaseOutIn(Expo),
29431 'in-sine': Sine,
29432 'out-sine': EaseOut(Sine),
29433 'in-out-sine': EaseInOut(Sine),
29434 'out-in-sine': EaseOutIn(Sine),
29435 'in-circ': Circ,
29436 'out-circ': EaseOut(Circ),
29437 'in-out-circ': EaseInOut(Circ),
29438 'out-in-circ': EaseOutIn(Circ),
29439 'in-back': Back,
29440 'out-back': EaseOut(Back),
29441 'in-out-back': EaseInOut(Back),
29442 'out-in-back': EaseOutIn(Back),
29443 'in-bounce': Bounce,
29444 'out-bounce': EaseOut(Bounce),
29445 'in-out-bounce': EaseInOut(Bounce),
29446 'out-in-bounce': EaseOutIn(Bounce),
29447 'in-elastic': Elastic,
29448 'out-elastic': EaseOut(Elastic),
29449 'in-out-elastic': EaseInOut(Elastic),
29450 'out-in-elastic': EaseOutIn(Elastic),
29451 spring: Spring,
29452 'spring-in': Spring,
29453 'spring-out': EaseOut(Spring),
29454 'spring-in-out': EaseInOut(Spring),
29455 'spring-out-in': EaseOutIn(Spring),
29456 };
29457 /**
29458 * Convert string easing to their proper form
29459 */
29460 var complexEasingSyntax = function (ease) {
29461 return convertToDash(ease)
29462 .replace(/^ease-/, '') // Remove the "ease-" keyword
29463 .replace(/(\(|\s).+/, '') // Remove the function brackets and parameters
29464 .toLowerCase()
29465 .trim();
29466 };
29467 /** Re-maps a number from one range to another. Numbers outside the range are not clamped to 0 and 1, because out-of-range values are often intentional and useful. */
29468 var getEasingFunction = function (ease) {
29469 return EasingFunctions[complexEasingSyntax(ease)] || EasingFunctions.linear;
29470 };
29471 // /**
29472 // * Allows you to register new easing functions
29473 // */
29474 // export const registerEasingFunction = (key: string, fn: TypeEasingFunction) => {
29475 // Object.assign(EasingFunctions, {
29476 // [key]: fn,
29477 // });
29478 // };
29479 // /**
29480 // * Allows you to register multiple new easing functions
29481 // */
29482 // export const registerEasingFunctions = (...obj: typeof EasingFunctions[]) => {
29483 // Object.assign(EasingFunctions, ...obj);
29484 // };
29485
29486 var linear = function (x) {
29487 return x;
29488 };
29489 var Start = 1;
29490 var Middle = 0.5;
29491 var End = 0;
29492 function step(count, pos) {
29493 return function (x) {
29494 if (x >= 1) {
29495 return 1;
29496 }
29497 var stepSize = 1 / count;
29498 x += pos * stepSize;
29499 return x - (x % stepSize);
29500 };
29501 }
29502 var numberString = '\\s*(-?\\d+\\.?\\d*|-?\\.\\d+)\\s*';
29503 var cubicBezierRe = new RegExp('cubic-bezier\\(' +
29504 numberString +
29505 ',' +
29506 numberString +
29507 ',' +
29508 numberString +
29509 ',' +
29510 numberString +
29511 '\\)');
29512 var step1Re = /steps\(\s*(\d+)\s*\)/;
29513 var step2Re = /steps\(\s*(\d+)\s*,\s*(start|middle|end)\s*\)/;
29514 function parseEasingFunction(normalizedEasing) {
29515 var cubicData = cubicBezierRe.exec(normalizedEasing);
29516 if (cubicData) {
29517 // @ts-ignore
29518 return bezier.apply(void 0, __spreadArray([], __read(cubicData.slice(1).map(Number)), false));
29519 }
29520 var step1Data = step1Re.exec(normalizedEasing);
29521 if (step1Data) {
29522 return step(Number(step1Data[1]), End);
29523 }
29524 var step2Data = step2Re.exec(normalizedEasing);
29525 if (step2Data) {
29526 // @ts-ignore
29527 return step(Number(step2Data[1]), { start: Start, middle: Middle, end: End }[step2Data[2]]);
29528 }
29529 return getEasingFunction(normalizedEasing);
29530 }
29531 function calculateActiveDuration(timing) {
29532 // @ts-ignore
29533 return Math.abs(repeatedDuration(timing) / (timing.playbackRate || 1));
29534 }
29535 function repeatedDuration(timing) {
29536 var _a;
29537 // https://drafts.csswg.org/web-animations/#calculating-the-active-duration
29538 if (timing.duration === 0 || timing.iterations === 0) {
29539 return 0;
29540 }
29541 // @see https://developer.mozilla.org/en-US/docs/Web/API/EffectTiming/duration#value
29542 // if (timing.duration === 'auto') {
29543 // timing.duration = 0;
29544 // }
29545 return (timing.duration === 'auto' ? 0 : Number(timing.duration)) * ((_a = timing.iterations) !== null && _a !== void 0 ? _a : 1);
29546 }
29547 var PhaseNone = 0;
29548 var PhaseBefore = 1;
29549 var PhaseAfter = 2;
29550 var PhaseActive = 3;
29551 function calculatePhase(activeDuration, localTime, timing) {
29552 // https://drafts.csswg.org/web-animations/#animation-effect-phases-and-states
29553 if (localTime === null) {
29554 return PhaseNone;
29555 }
29556 var endTime = timing.endTime;
29557 if (localTime < Math.min(timing.delay, endTime)) {
29558 return PhaseBefore;
29559 }
29560 if (localTime >= Math.min(timing.delay + activeDuration + timing.endDelay, endTime)) {
29561 return PhaseAfter;
29562 }
29563 return PhaseActive;
29564 }
29565 function calculateActiveTime(activeDuration, fillMode, localTime, phase, delay) {
29566 // https://drafts.csswg.org/web-animations/#calculating-the-active-time
29567 switch (phase) {
29568 case PhaseBefore:
29569 if (fillMode === 'backwards' || fillMode === 'both')
29570 return 0;
29571 return null;
29572 case PhaseActive:
29573 return localTime - delay;
29574 case PhaseAfter:
29575 if (fillMode === 'forwards' || fillMode === 'both')
29576 return activeDuration;
29577 return null;
29578 case PhaseNone:
29579 return null;
29580 }
29581 }
29582 function calculateOverallProgress(iterationDuration, phase, iterations, activeTime, iterationStart) {
29583 // https://drafts.csswg.org/web-animations/#calculating-the-overall-progress
29584 var overallProgress = iterationStart;
29585 if (iterationDuration === 0) {
29586 if (phase !== PhaseBefore) {
29587 overallProgress += iterations;
29588 }
29589 }
29590 else {
29591 overallProgress += activeTime / iterationDuration;
29592 }
29593 return overallProgress;
29594 }
29595 function calculateSimpleIterationProgress(overallProgress, iterationStart, phase, iterations, activeTime, iterationDuration) {
29596 // https://drafts.csswg.org/web-animations/#calculating-the-simple-iteration-progress
29597 var simpleIterationProgress = overallProgress === Infinity ? iterationStart % 1 : overallProgress % 1;
29598 if (simpleIterationProgress === 0 &&
29599 phase === PhaseAfter &&
29600 iterations !== 0 &&
29601 (activeTime !== 0 || iterationDuration === 0)) {
29602 simpleIterationProgress = 1;
29603 }
29604 return simpleIterationProgress;
29605 }
29606 function calculateCurrentIteration(phase, iterations, simpleIterationProgress, overallProgress) {
29607 // https://drafts.csswg.org/web-animations/#calculating-the-current-iteration
29608 if (phase === PhaseAfter && iterations === Infinity) {
29609 return Infinity;
29610 }
29611 if (simpleIterationProgress === 1) {
29612 return Math.floor(overallProgress) - 1;
29613 }
29614 return Math.floor(overallProgress);
29615 }
29616 function calculateDirectedProgress(playbackDirection, currentIteration, simpleIterationProgress) {
29617 // https://drafts.csswg.org/web-animations/#calculating-the-directed-progress
29618 var currentDirection = playbackDirection;
29619 if (playbackDirection !== 'normal' && playbackDirection !== 'reverse') {
29620 var d = currentIteration;
29621 if (playbackDirection === 'alternate-reverse') {
29622 d += 1;
29623 }
29624 currentDirection = 'normal';
29625 if (d !== Infinity && d % 2 !== 0) {
29626 currentDirection = 'reverse';
29627 }
29628 }
29629 if (currentDirection === 'normal') {
29630 return simpleIterationProgress;
29631 }
29632 return 1 - simpleIterationProgress;
29633 }
29634 function calculateIterationProgress(activeDuration, localTime, timing) {
29635 var phase = calculatePhase(activeDuration, localTime, timing);
29636 var activeTime = calculateActiveTime(activeDuration, timing.fill, localTime, phase, timing.delay);
29637 if (activeTime === null)
29638 return null;
29639 var duration = timing.duration === 'auto' ? 0 : timing.duration;
29640 var overallProgress = calculateOverallProgress(duration, phase, timing.iterations, activeTime, timing.iterationStart);
29641 var simpleIterationProgress = calculateSimpleIterationProgress(overallProgress, timing.iterationStart, phase, timing.iterations, activeTime, duration);
29642 var currentIteration = calculateCurrentIteration(phase, timing.iterations, simpleIterationProgress, overallProgress);
29643 var directedProgress = calculateDirectedProgress(timing.direction, currentIteration, simpleIterationProgress);
29644 timing.currentIteration = currentIteration;
29645 timing.progress = directedProgress;
29646 // https://drafts.csswg.org/web-animations/#calculating-the-transformed-progress
29647 // https://drafts.csswg.org/web-animations/#calculating-the-iteration-progress
29648 return timing.easingFunction(directedProgress);
29649 }
29650
29651 function convertEffectInput(keyframes, timing, target) {
29652 var propertySpecificKeyframeGroups = makePropertySpecificKeyframeGroups(keyframes, timing);
29653 var interpolations = makeInterpolations(propertySpecificKeyframeGroups, target);
29654 return function (target, fraction) {
29655 if (fraction !== null) {
29656 interpolations
29657 .filter(function (interpolation) {
29658 return (fraction >= interpolation.applyFrom &&
29659 fraction < interpolation.applyTo);
29660 })
29661 .forEach(function (interpolation) {
29662 var offsetFraction = fraction - interpolation.startOffset;
29663 var localDuration = interpolation.endOffset - interpolation.startOffset;
29664 var scaledLocalTime = localDuration === 0
29665 ? 0
29666 : interpolation.easingFunction(offsetFraction / localDuration);
29667 // apply updated attribute
29668 target.setAttribute(interpolation.property, interpolation.interpolation(scaledLocalTime), false, false);
29669 // if (interpolation.property === 'visibility') {
29670 // console.log(
29671 // scaledLocalTime,
29672 // interpolation.interpolation(scaledLocalTime),
29673 // );
29674 // }
29675 });
29676 }
29677 else {
29678 for (var property in propertySpecificKeyframeGroups)
29679 if (isNotReservedWord(property)) {
29680 // clear attribute
29681 target.setAttribute(property, null);
29682 }
29683 }
29684 };
29685 }
29686 function isNotReservedWord(member) {
29687 return (member !== 'offset' &&
29688 member !== 'easing' &&
29689 member !== 'composite' &&
29690 member !== 'computedOffset');
29691 }
29692 function makePropertySpecificKeyframeGroups(keyframes, timing) {
29693 var propertySpecificKeyframeGroups = {};
29694 for (var i = 0; i < keyframes.length; i++) {
29695 for (var member in keyframes[i]) {
29696 if (isNotReservedWord(member)) {
29697 var propertySpecificKeyframe = {
29698 offset: keyframes[i].offset,
29699 computedOffset: keyframes[i].computedOffset,
29700 easing: keyframes[i].easing,
29701 easingFunction: parseEasingFunction(keyframes[i].easing) || timing.easingFunction,
29702 value: keyframes[i][member],
29703 };
29704 propertySpecificKeyframeGroups[member] =
29705 propertySpecificKeyframeGroups[member] || [];
29706 propertySpecificKeyframeGroups[member].push(propertySpecificKeyframe);
29707 }
29708 }
29709 }
29710 return propertySpecificKeyframeGroups;
29711 }
29712 function makeInterpolations(propertySpecificKeyframeGroups, target) {
29713 var interpolations = [];
29714 for (var groupName in propertySpecificKeyframeGroups) {
29715 var keyframes = propertySpecificKeyframeGroups[groupName];
29716 for (var i = 0; i < keyframes.length - 1; i++) {
29717 var startIndex = i;
29718 var endIndex = i + 1;
29719 var startOffset = keyframes[startIndex].computedOffset;
29720 var endOffset = keyframes[endIndex].computedOffset;
29721 var applyFrom = startOffset;
29722 var applyTo = endOffset;
29723 if (i === 0) {
29724 applyFrom = -Infinity;
29725 if (endOffset === 0) {
29726 endIndex = startIndex;
29727 }
29728 }
29729 if (i === keyframes.length - 2) {
29730 applyTo = Infinity;
29731 if (startOffset === 1) {
29732 startIndex = endIndex;
29733 }
29734 }
29735 interpolations.push({
29736 applyFrom: applyFrom,
29737 applyTo: applyTo,
29738 startOffset: keyframes[startIndex].computedOffset,
29739 endOffset: keyframes[endIndex].computedOffset,
29740 easingFunction: keyframes[startIndex].easingFunction,
29741 property: groupName,
29742 interpolation: propertyInterpolation(groupName, keyframes[startIndex].value, keyframes[endIndex].value, target),
29743 });
29744 }
29745 }
29746 interpolations.sort(function (leftInterpolation, rightInterpolation) {
29747 return leftInterpolation.startOffset - rightInterpolation.startOffset;
29748 });
29749 return interpolations;
29750 }
29751 var InterpolationFactory = function (from, to,
29752 // eslint-disable-next-line @typescript-eslint/ban-types
29753 convertToString) {
29754 return function (f) {
29755 var interpolated = interpolate(from, to, f);
29756 return !runtime.enableCSSParsing && isNumber(interpolated)
29757 ? interpolated
29758 : convertToString(interpolated);
29759 };
29760 };
29761 function propertyInterpolation(property, left, right, target) {
29762 var metadata = propertyMetadataCache[property];
29763 // discrete step
29764 // if (property === 'visibility') {
29765 // return function (t: number) {
29766 // if (t === 0) return left;
29767 // if (t === 1) return right;
29768 // debugger;
29769 // return t < 0.5 ? left : right;
29770 // };
29771 // }
29772 if (metadata && metadata.syntax && metadata.int) {
29773 var propertyHandler = runtime.styleValueRegistry.getPropertySyntax(metadata.syntax);
29774 if (propertyHandler) {
29775 var usedLeft = void 0;
29776 var usedRight = void 0;
29777 if (runtime.enableCSSParsing) {
29778 var computedLeft = runtime.styleValueRegistry.parseProperty(property, left, target, false);
29779 var computedRight = runtime.styleValueRegistry.parseProperty(property, right, target, false);
29780 usedLeft = runtime.styleValueRegistry.computeProperty(property, computedLeft, target, false);
29781 usedRight = runtime.styleValueRegistry.computeProperty(property, computedRight, target, false);
29782 }
29783 else {
29784 var parser = propertyHandler.parserWithCSSDisabled;
29785 usedLeft = parser ? parser(left, target) : left;
29786 usedRight = parser ? parser(right, target) : right;
29787 }
29788 // merger [left, right, n2string()]
29789 var interpolationArgs = propertyHandler.mixer(usedLeft, usedRight, target);
29790 if (interpolationArgs) {
29791 var interp_1 = InterpolationFactory.apply(void 0, __spreadArray([], __read(interpolationArgs), false));
29792 return function (t) {
29793 if (t === 0)
29794 return left;
29795 if (t === 1)
29796 return right;
29797 return interp_1(t);
29798 };
29799 }
29800 }
29801 }
29802 // eslint-disable-next-line @typescript-eslint/no-use-before-define
29803 return InterpolationFactory(false, true, function (bool) {
29804 return bool ? right : left;
29805 });
29806 }
29807 /**
29808 * interpolate with number, boolean, number[], boolean[]
29809 */
29810 function interpolate(from, to, f) {
29811 if (typeof from === 'number' && typeof to === 'number') {
29812 return from * (1 - f) + to * f;
29813 }
29814 if ((typeof from === 'boolean' && typeof to === 'boolean') ||
29815 (typeof from === 'string' && typeof to === 'string') // skip string, eg. path ['M', 10, 10]
29816 ) {
29817 return f < 0.5 ? from : to;
29818 }
29819 if (Array.isArray(from) && Array.isArray(to)) {
29820 // interpolate arrays/matrix
29821 var fromLength = from.length;
29822 var toLength = to.length;
29823 var length_1 = Math.max(fromLength, toLength);
29824 var r = [];
29825 for (var i = 0; i < length_1; i++) {
29826 r.push(interpolate(from[i < fromLength ? i : fromLength - 1], to[i < toLength ? i : toLength - 1], f));
29827 }
29828 return r;
29829 }
29830 throw new Error('Mismatched interpolation arguments ' + from + ':' + to);
29831 }
29832
29833 /**
29834 * @see https://developer.mozilla.org/en-US/docs/Web/API/EffectTiming
29835 */
29836 var AnimationEffectTiming = /** @class */ (function () {
29837 function AnimationEffectTiming() {
29838 /**
29839 * @see https://developer.mozilla.org/en-US/docs/Web/API/EffectTiming/delay
29840 */
29841 this.delay = 0;
29842 /**
29843 * @see https://developer.mozilla.org/en-US/docs/Web/API/EffectTiming/direction
29844 */
29845 this.direction = 'normal';
29846 /**
29847 * @see https://developer.mozilla.org/en-US/docs/Web/API/EffectTiming/duration
29848 */
29849 this.duration = 'auto';
29850 /**
29851 * @see https://developer.mozilla.org/en-US/docs/Web/API/EffectTiming/easing
29852 */
29853 this._easing = 'linear';
29854 this.easingFunction = linear;
29855 /**
29856 * @see https://developer.mozilla.org/en-US/docs/Web/API/EffectTiming/endDelay
29857 */
29858 this.endDelay = 0;
29859 /**
29860 * @see https://developer.mozilla.org/en-US/docs/Web/API/EffectTiming/fill
29861 */
29862 this.fill = 'auto';
29863 /**
29864 * @see https://developer.mozilla.org/en-US/docs/Web/API/EffectTiming/iterationStart
29865 */
29866 this.iterationStart = 0;
29867 /**
29868 * @see https://developer.mozilla.org/en-US/docs/Web/API/EffectTiming/iterations
29869 */
29870 this.iterations = 1;
29871 this.currentIteration = null;
29872 this.progress = null;
29873 }
29874 Object.defineProperty(AnimationEffectTiming.prototype, "easing", {
29875 get: function () {
29876 return this._easing;
29877 },
29878 set: function (value) {
29879 this.easingFunction = parseEasingFunction(value);
29880 this._easing = value;
29881 },
29882 enumerable: false,
29883 configurable: true
29884 });
29885 return AnimationEffectTiming;
29886 }());
29887
29888 /**
29889 * @example
29890 {
29891 translateY: [200, 300],
29892 scale: [1, 10],
29893 }
29894
29895 * groups' length can be different, the following config should generate 3 frames:
29896 @example
29897 {
29898 translateY: [200, 300, 400],
29899 scale: [1, 10],
29900 }
29901 */
29902 function convertToArrayForm(effectInput) {
29903 var normalizedEffectInput = [];
29904 for (var property in effectInput) {
29905 // skip reserved props
29906 if (property in ['easing', 'offset', 'composite']) {
29907 continue;
29908 }
29909 // @ts-ignore
29910 var values = effectInput[property];
29911 if (!Array.isArray(values)) {
29912 values = [values];
29913 }
29914 var numKeyframes = values.length;
29915 for (var i = 0; i < numKeyframes; i++) {
29916 if (!normalizedEffectInput[i]) {
29917 var keyframe = {};
29918 if ('offset' in effectInput) {
29919 keyframe.offset = Number(effectInput.offset);
29920 }
29921 if ('easing' in effectInput) {
29922 // @ts-ignore
29923 keyframe.easing = effectInput.easing;
29924 }
29925 if ('composite' in effectInput) {
29926 // @ts-ignore
29927 keyframe.composite = effectInput.composite;
29928 }
29929 normalizedEffectInput[i] = keyframe;
29930 }
29931 if (values[i] !== undefined && values[i] !== null) {
29932 normalizedEffectInput[i][property] = values[i];
29933 }
29934 }
29935 }
29936 normalizedEffectInput.sort(function (a, b) {
29937 return (a.computedOffset || 0) - (b.computedOffset || 0);
29938 });
29939 return normalizedEffectInput;
29940 }
29941 function normalizeKeyframes(effectInput, timing) {
29942 if (effectInput === null) {
29943 return [];
29944 }
29945 if (!Array.isArray(effectInput)) {
29946 effectInput = convertToArrayForm(effectInput);
29947 }
29948 var keyframes = effectInput.map(function (originalKeyframe) {
29949 var keyframe = {};
29950 if (timing === null || timing === void 0 ? void 0 : timing.composite) {
29951 // This will be auto if the composite operation specified on the effect is being used.
29952 // @see https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API/Keyframe_Formats
29953 keyframe.composite = 'auto';
29954 }
29955 for (var member in originalKeyframe) {
29956 var memberValue = originalKeyframe[member];
29957 if (member === 'offset') {
29958 if (memberValue !== null) {
29959 memberValue = Number(memberValue);
29960 if (!isFinite(memberValue))
29961 throw new Error('Keyframe offsets must be numbers.');
29962 if (memberValue < 0 || memberValue > 1)
29963 throw new Error('Keyframe offsets must be between 0 and 1.');
29964 keyframe.computedOffset = memberValue;
29965 }
29966 }
29967 else if (member === 'composite') {
29968 // TODO: Support add & accumulate in KeyframeEffect.composite
29969 // @see https://developer.mozilla.org/en-US/docs/Web/API/KeyframeEffect/composite
29970 if (['replace', 'add', 'accumulate', 'auto'].indexOf(memberValue) === -1) {
29971 throw new Error("".concat(memberValue, " compositing is not supported"));
29972 }
29973 }
29974 else ;
29975 // assign to keyframe, no need to parse shorthand value
29976 keyframe[member] = memberValue;
29977 }
29978 if (keyframe.offset === undefined) {
29979 keyframe.offset = null;
29980 }
29981 if (keyframe.easing === undefined) {
29982 // override with timing.easing
29983 keyframe.easing = (timing === null || timing === void 0 ? void 0 : timing.easing) || 'linear';
29984 }
29985 if (keyframe.composite === undefined) {
29986 keyframe.composite = 'auto';
29987 }
29988 return keyframe;
29989 });
29990 var everyFrameHasOffset = true;
29991 var previousOffset = -Infinity;
29992 for (var i = 0; i < keyframes.length; i++) {
29993 var offset = keyframes[i].offset;
29994 if (!isNil(offset)) {
29995 if (offset < previousOffset) {
29996 throw new TypeError('Keyframes are not loosely sorted by offset. Sort or specify offsets.');
29997 }
29998 previousOffset = offset;
29999 }
30000 else {
30001 everyFrameHasOffset = false;
30002 }
30003 }
30004 keyframes = keyframes.filter(function (keyframe) {
30005 return Number(keyframe.offset) >= 0 && Number(keyframe.offset) <= 1;
30006 });
30007 function spaceKeyframes() {
30008 var _a, _b;
30009 var length = keyframes.length;
30010 keyframes[length - 1].computedOffset = Number((_a = keyframes[length - 1].offset) !== null && _a !== void 0 ? _a : 1);
30011 if (length > 1) {
30012 keyframes[0].computedOffset = Number((_b = keyframes[0].offset) !== null && _b !== void 0 ? _b : 0);
30013 }
30014 var previousIndex = 0;
30015 var previousOffset = Number(keyframes[0].computedOffset);
30016 for (var i = 1; i < length; i++) {
30017 var offset = keyframes[i].computedOffset;
30018 if (!isNil(offset) && !isNil(previousOffset)) {
30019 for (var j = 1; j < i - previousIndex; j++)
30020 keyframes[previousIndex + j].computedOffset =
30021 previousOffset + ((Number(offset) - previousOffset) * j) / (i - previousIndex);
30022 previousIndex = i;
30023 previousOffset = Number(offset);
30024 }
30025 }
30026 }
30027 if (!everyFrameHasOffset)
30028 spaceKeyframes();
30029 return keyframes;
30030 }
30031
30032 var fills = 'backwards|forwards|both|none'.split('|');
30033 var directions = 'reverse|alternate|alternate-reverse'.split('|');
30034 function makeTiming(timingInput, forGroup) {
30035 var timing = new AnimationEffectTiming();
30036 if (forGroup) {
30037 timing.fill = 'both';
30038 timing.duration = 'auto';
30039 }
30040 if (typeof timingInput === 'number' && !isNaN(timingInput)) {
30041 timing.duration = timingInput;
30042 }
30043 else if (timingInput !== undefined) {
30044 Object.keys(timingInput).forEach(function (property) {
30045 if (timingInput[property] !== undefined &&
30046 timingInput[property] !== null &&
30047 timingInput[property] !== 'auto') {
30048 if (typeof timing[property] === 'number' || property === 'duration') {
30049 if (typeof timingInput[property] !== 'number' ||
30050 isNaN(timingInput[property])) {
30051 return;
30052 }
30053 }
30054 if (property === 'fill' &&
30055 fills.indexOf(timingInput[property]) === -1) {
30056 return;
30057 }
30058 if (property === 'direction' &&
30059 directions.indexOf(timingInput[property]) === -1) {
30060 return;
30061 }
30062 // @ts-ignore
30063 timing[property] = timingInput[property];
30064 }
30065 });
30066 }
30067 return timing;
30068 }
30069 function normalizeTimingInput(timingInput, forGroup) {
30070 timingInput = numericTimingToObject(timingInput !== null && timingInput !== void 0 ? timingInput : { duration: 'auto' });
30071 return makeTiming(timingInput, forGroup);
30072 }
30073 function numericTimingToObject(timingInput) {
30074 if (typeof timingInput === 'number') {
30075 if (isNaN(timingInput)) {
30076 timingInput = { duration: 'auto' };
30077 }
30078 else {
30079 timingInput = { duration: timingInput };
30080 }
30081 }
30082 return timingInput;
30083 }
30084 /**
30085 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyframeEffect
30086 * @example
30087 const circleDownKeyframes = new KeyframeEffect(
30088 circle, // element to animate
30089 [
30090 { transform: 'translateY(0)' }, // keyframe
30091 { transform: 'translateY(100)' } // keyframe
30092 ],
30093 { duration: 3000, fill: 'forwards' } // keyframe options
30094 );
30095 *
30096 */
30097 var KeyframeEffect = /** @class */ (function () {
30098 function KeyframeEffect(target, effectInput, timingInput) {
30099 var _this = this;
30100 this.composite = 'replace';
30101 this.iterationComposite = 'replace';
30102 this.target = target;
30103 this.timing = normalizeTimingInput(timingInput, false);
30104 this.timing.effect = this;
30105 this.timing.activeDuration = calculateActiveDuration(this.timing);
30106 this.timing.endTime = Math.max(0, this.timing.delay + this.timing.activeDuration + this.timing.endDelay);
30107 this.normalizedKeyframes = normalizeKeyframes(effectInput, this.timing);
30108 this.interpolations = convertEffectInput(this.normalizedKeyframes, this.timing, this.target);
30109 // 不支持 proxy 时降级成 this.timing
30110 var Proxy = runtime.globalThis.Proxy;
30111 this.computedTiming = Proxy
30112 ? new Proxy(this.timing, {
30113 get: function (target, prop) {
30114 if (prop === 'duration') {
30115 return target.duration === 'auto' ? 0 : target.duration;
30116 }
30117 else if (prop === 'fill') {
30118 return target.fill === 'auto' ? 'none' : target.fill;
30119 }
30120 else if (prop === 'localTime') {
30121 return (_this.animation && _this.animation.currentTime) || null;
30122 }
30123 else if (prop === 'currentIteration') {
30124 if (!_this.animation || _this.animation.playState !== 'running') {
30125 return null;
30126 }
30127 return target.currentIteration || 0;
30128 }
30129 else if (prop === 'progress') {
30130 if (!_this.animation || _this.animation.playState !== 'running') {
30131 return null;
30132 }
30133 return target.progress || 0;
30134 }
30135 return target[prop];
30136 },
30137 set: function () {
30138 return true;
30139 },
30140 })
30141 : this.timing;
30142 }
30143 KeyframeEffect.prototype.applyInterpolations = function () {
30144 this.interpolations(this.target, Number(this.timeFraction));
30145 };
30146 KeyframeEffect.prototype.update = function (localTime) {
30147 if (localTime === null) {
30148 return false;
30149 }
30150 this.timeFraction = calculateIterationProgress(this.timing.activeDuration, localTime, this.timing);
30151 return this.timeFraction !== null;
30152 };
30153 KeyframeEffect.prototype.getKeyframes = function () {
30154 return this.normalizedKeyframes;
30155 };
30156 KeyframeEffect.prototype.setKeyframes = function (keyframes) {
30157 this.normalizedKeyframes = normalizeKeyframes(keyframes);
30158 };
30159 /**
30160 * @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEffect/getComputedTiming
30161 */
30162 KeyframeEffect.prototype.getComputedTiming = function () {
30163 return this.computedTiming;
30164 };
30165 /**
30166 * @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEffect/getTiming
30167 */
30168 KeyframeEffect.prototype.getTiming = function () {
30169 return this.timing;
30170 };
30171 /**
30172 * @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEffect/updateTiming
30173 */
30174 KeyframeEffect.prototype.updateTiming = function (timing) {
30175 var _this = this;
30176 Object.keys(timing || {}).forEach(function (name) {
30177 _this.timing[name] = timing[name];
30178 });
30179 };
30180 return KeyframeEffect;
30181 }());
30182
30183 function compareAnimations(leftAnimation, rightAnimation) {
30184 return Number(leftAnimation.id) - Number(rightAnimation.id);
30185 }
30186 /**
30187 * @see https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/web-animations-js/index.d.ts
30188 */
30189 var AnimationTimeline = /** @class */ (function () {
30190 function AnimationTimeline(document) {
30191 var _this = this;
30192 this.document = document;
30193 /**
30194 * all active animations
30195 */
30196 this.animations = [];
30197 this.ticking = false;
30198 this.timelineTicking = false;
30199 this.hasRestartedThisFrame = false;
30200 this.animationsWithPromises = [];
30201 this.inTick = false;
30202 this.pendingEffects = [];
30203 this.currentTime = null;
30204 this.rafId = 0;
30205 this.rafCallbacks = [];
30206 this.webAnimationsNextTick = function (t) {
30207 _this.currentTime = t;
30208 _this.discardAnimations();
30209 if (_this.animations.length === 0) {
30210 _this.timelineTicking = false;
30211 }
30212 else {
30213 _this.requestAnimationFrame(_this.webAnimationsNextTick);
30214 }
30215 };
30216 this.processRafCallbacks = function (t) {
30217 var processing = _this.rafCallbacks;
30218 _this.rafCallbacks = [];
30219 if (t < Number(_this.currentTime))
30220 t = Number(_this.currentTime);
30221 _this.animations.sort(compareAnimations);
30222 _this.animations = _this.tick(t, true, _this.animations)[0];
30223 processing.forEach(function (entry) {
30224 entry[1](t);
30225 });
30226 _this.applyPendingEffects();
30227 };
30228 }
30229 AnimationTimeline.prototype.getAnimations = function () {
30230 this.discardAnimations();
30231 return this.animations.slice();
30232 };
30233 AnimationTimeline.prototype.isTicking = function () {
30234 return this.inTick;
30235 };
30236 AnimationTimeline.prototype.play = function (target, keyframes, options) {
30237 var effect = new KeyframeEffect(target, keyframes, options);
30238 var animation = new Animation(effect, this);
30239 this.animations.push(animation);
30240 this.restartWebAnimationsNextTick();
30241 animation.updatePromises();
30242 animation.play();
30243 animation.updatePromises();
30244 return animation;
30245 };
30246 // RAF is supposed to be the last script to occur before frame rendering but not
30247 // all browsers behave like this. This function is for synchonously updating an
30248 // animation's effects whenever its state is mutated by script to work around
30249 // incorrect script execution ordering by the browser.
30250 AnimationTimeline.prototype.applyDirtiedAnimation = function (animation) {
30251 var _this = this;
30252 if (this.inTick) {
30253 return;
30254 }
30255 // update active animations in displayobject
30256 animation.markTarget();
30257 var animations = animation.targetAnimations();
30258 animations.sort(compareAnimations);
30259 // clear inactive animations
30260 var inactiveAnimations = this.tick(Number(this.currentTime), false, animations.slice())[1];
30261 inactiveAnimations.forEach(function (animation) {
30262 var index = _this.animations.indexOf(animation);
30263 if (index !== -1) {
30264 _this.animations.splice(index, 1);
30265 }
30266 });
30267 this.applyPendingEffects();
30268 };
30269 AnimationTimeline.prototype.restart = function () {
30270 if (!this.ticking) {
30271 this.ticking = true;
30272 this.requestAnimationFrame(function () { });
30273 this.hasRestartedThisFrame = true;
30274 }
30275 return this.hasRestartedThisFrame;
30276 };
30277 AnimationTimeline.prototype.destroy = function () {
30278 this.document.defaultView.cancelAnimationFrame(this.frameId);
30279 };
30280 AnimationTimeline.prototype.applyPendingEffects = function () {
30281 this.pendingEffects.forEach(function (effect) {
30282 effect === null || effect === void 0 ? void 0 : effect.applyInterpolations();
30283 });
30284 this.pendingEffects = [];
30285 };
30286 AnimationTimeline.prototype.updateAnimationsPromises = function () {
30287 this.animationsWithPromises = this.animationsWithPromises.filter(function (animation) {
30288 return animation.updatePromises();
30289 });
30290 };
30291 AnimationTimeline.prototype.discardAnimations = function () {
30292 this.updateAnimationsPromises();
30293 this.animations = this.animations.filter(function (animation) {
30294 return animation.playState !== 'finished' && animation.playState !== 'idle';
30295 });
30296 };
30297 AnimationTimeline.prototype.restartWebAnimationsNextTick = function () {
30298 if (!this.timelineTicking) {
30299 this.timelineTicking = true;
30300 this.requestAnimationFrame(this.webAnimationsNextTick);
30301 }
30302 };
30303 AnimationTimeline.prototype.rAF = function (f) {
30304 var id = this.rafId++;
30305 if (this.rafCallbacks.length === 0) {
30306 this.frameId = this.document.defaultView.requestAnimationFrame(this.processRafCallbacks);
30307 }
30308 this.rafCallbacks.push([id, f]);
30309 return id;
30310 };
30311 AnimationTimeline.prototype.requestAnimationFrame = function (f) {
30312 var _this = this;
30313 return this.rAF(function (x) {
30314 _this.updateAnimationsPromises();
30315 f(x);
30316 _this.updateAnimationsPromises();
30317 });
30318 };
30319 AnimationTimeline.prototype.tick = function (t, isAnimationFrame, updatingAnimations) {
30320 var _a, _b;
30321 var _this = this;
30322 this.inTick = true;
30323 this.hasRestartedThisFrame = false;
30324 this.currentTime = t;
30325 this.ticking = false;
30326 var newPendingClears = [];
30327 var newPendingEffects = [];
30328 var activeAnimations = [];
30329 var inactiveAnimations = [];
30330 updatingAnimations.forEach(function (animation) {
30331 animation.tick(t, isAnimationFrame);
30332 if (!animation._inEffect) {
30333 newPendingClears.push(animation.effect);
30334 animation.unmarkTarget();
30335 }
30336 else {
30337 newPendingEffects.push(animation.effect);
30338 animation.markTarget();
30339 }
30340 if (animation._needsTick)
30341 _this.ticking = true;
30342 var alive = animation._inEffect || animation._needsTick;
30343 animation._inTimeline = alive;
30344 if (alive) {
30345 activeAnimations.push(animation);
30346 }
30347 else {
30348 inactiveAnimations.push(animation);
30349 }
30350 });
30351 (_a = this.pendingEffects).push.apply(_a, __spreadArray([], __read(newPendingClears), false));
30352 (_b = this.pendingEffects).push.apply(_b, __spreadArray([], __read(newPendingEffects), false));
30353 if (this.ticking)
30354 this.requestAnimationFrame(function () { });
30355 this.inTick = false;
30356 return [activeAnimations, inactiveAnimations];
30357 };
30358 return AnimationTimeline;
30359 }());
30360
30361 runtime.EasingFunction = parseEasingFunction;
30362 runtime.AnimationTimeline = AnimationTimeline;
30363
30364 function measureText(container, px2hd, theme) {
30365 return function (text, font) {
30366 var _a = font || {},
30367 _b = _a.fontSize,
30368 fontSize = _b === void 0 ? theme.fontSize : _b,
30369 _c = _a.fontFamily,
30370 fontFamily = _c === void 0 ? theme.fontFamily : _c,
30371 _d = _a.fontWeight,
30372 fontWeight = _d === void 0 ? theme.fontWeight : _d,
30373 _e = _a.fontVariant,
30374 fontVariant = _e === void 0 ? theme.fontVariant : _e,
30375 _f = _a.fontStyle,
30376 fontStyle = _f === void 0 ? theme.fontStyle : _f,
30377 _g = _a.textAlign,
30378 textAlign = _g === void 0 ? theme.textAlign : _g,
30379 _h = _a.textBaseline,
30380 textBaseline = _h === void 0 ? theme.textBaseline : _h,
30381 _j = _a.lineWidth,
30382 lineWidth = _j === void 0 ? 1 : _j;
30383 var style = {
30384 x: 0,
30385 y: 0,
30386 fontSize: px2hd(fontSize),
30387 fontFamily: fontFamily,
30388 fontStyle: fontStyle,
30389 fontWeight: fontWeight,
30390 fontVariant: fontVariant,
30391 text: text,
30392 textAlign: textAlign,
30393 textBaseline: textBaseline,
30394 lineWidth: lineWidth,
30395 visibility: 'hidden'
30396 };
30397 var result = checkCSSRule('text', style);
30398 var shape = new Text({
30399 style: result
30400 });
30401 container.appendChild(shape);
30402 var _k = shape.getBBox(),
30403 width = _k.width,
30404 height = _k.height;
30405 shape.remove();
30406 return {
30407 width: width,
30408 height: height
30409 };
30410 };
30411 }
30412 function computeLayout$2(style) {
30413 var left = style.left,
30414 top = style.top,
30415 width = style.width,
30416 height = style.height,
30417 padding = style.padding;
30418 var paddingTop = padding[0],
30419 paddingRight = padding[1],
30420 paddingBottom = padding[2],
30421 paddingLeft = padding[3];
30422 return {
30423 left: left + paddingLeft,
30424 top: top + paddingTop,
30425 width: width - paddingLeft - paddingRight,
30426 height: height - paddingTop - paddingBottom
30427 };
30428 }
30429 // 顶层Canvas标签
30430 var Canvas$1 = /** @class */function () {
30431 function Canvas$1(props) {
30432 var context = props.context,
30433 _a = props.renderer,
30434 renderer = _a === void 0 ? new Renderer() : _a,
30435 width = props.width,
30436 height = props.height,
30437 customTheme = props.theme,
30438 customPx2hd = props.px2hd,
30439 customPixelRatio = props.pixelRatio,
30440 landscape = props.landscape,
30441 rendererContainer = props.container,
30442 // style: customStyle,
30443 _b = props.animate,
30444 // style: customStyle,
30445 animate = _b === void 0 ? true : _b,
30446 createImage = props.createImage,
30447 requestAnimationFrame = props.requestAnimationFrame,
30448 cancelAnimationFrame = props.cancelAnimationFrame,
30449 offscreenCanvas = props.offscreenCanvas,
30450 isTouchEvent = props.isTouchEvent,
30451 isMouseEvent = props.isMouseEvent,
30452 _c = props.useNativeClickEvent,
30453 useNativeClickEvent = _c === void 0 ? true : _c,
30454 onRender = props.onRender;
30455 var px2hd$1 = isFunction(customPx2hd) ? batch2hd(customPx2hd) : px2hd;
30456 // 初始化主题
30457 var theme = px2hd$1(__assign(__assign({}, THEME), customTheme));
30458 var pixelRatio = theme.pixelRatio,
30459 fontSize = theme.fontSize,
30460 fontFamily = theme.fontFamily;
30461 var devicePixelRatio = customPixelRatio ? customPixelRatio : pixelRatio;
30462 // 组件更新器
30463 var updater = createUpdater(this);
30464 var canvasElement = createMobileCanvasElement(context);
30465 var canvas = new Canvas({
30466 container: rendererContainer,
30467 canvas: canvasElement,
30468 devicePixelRatio: devicePixelRatio,
30469 renderer: renderer,
30470 width: width,
30471 height: height,
30472 supportsTouchEvents: true,
30473 // https://caniuse.com/?search=PointerEvent ios 13 以下不支持 Pointer
30474 supportsPointerEvents: runtime.globalThis.PointerEvent ? true : false,
30475 // 允许在canvas外部触发
30476 alwaysTriggerPointerEventOnCanvas: true,
30477 createImage: createImage,
30478 requestAnimationFrame: requestAnimationFrame,
30479 cancelAnimationFrame: cancelAnimationFrame,
30480 useNativeClickEvent: useNativeClickEvent,
30481 offscreenCanvas: offscreenCanvas,
30482 isTouchEvent: isTouchEvent,
30483 isMouseEvent: isMouseEvent
30484 });
30485 onRender && canvas.addEventListener('rerender', function () {
30486 return onRender(canvas);
30487 }, {
30488 once: true
30489 });
30490 var container = canvas.getRoot();
30491 var _d = canvas.getConfig(),
30492 canvasWidth = _d.width,
30493 canvasHeight = _d.height;
30494 // 设置默认的全局样式
30495 container.setAttribute('fontSize', fontSize);
30496 container.setAttribute('fontFamily', fontFamily);
30497 var gesture = new Gesture(container);
30498 // 供全局使用的一些变量
30499 var componentContext = {
30500 ctx: context,
30501 root: this,
30502 canvas: canvas,
30503 px2hd: px2hd$1,
30504 theme: theme,
30505 gesture: gesture,
30506 measureText: measureText(container, px2hd$1, theme),
30507 timeline: null
30508 };
30509 var vNode = {
30510 key: undefined,
30511 tag: ClassComponent,
30512 // style: layout,
30513 // @ts-ignore
30514 type: Canvas$1,
30515 props: props,
30516 shape: container,
30517 animate: animate,
30518 // @ts-ignore
30519 component: this,
30520 canvas: this,
30521 context: componentContext,
30522 updater: updater
30523 };
30524 this._ee = new eventemitter3$1();
30525 this.props = props;
30526 this.context = componentContext;
30527 this.updater = updater;
30528 this.gesture = gesture;
30529 this.theme = theme;
30530 this.canvas = canvas;
30531 this.container = container;
30532 this.el = canvasElement;
30533 this.vNode = vNode;
30534 // todo: 横屏事件逻辑
30535 this.landscape = landscape;
30536 this.updateLayout(__assign(__assign({}, props), {
30537 width: canvasWidth,
30538 height: canvasHeight
30539 }));
30540 }
30541 Canvas$1.prototype.updateComponents = function (components) {
30542 updateComponents(components);
30543 };
30544 Canvas$1.prototype.update = function (nextProps) {
30545 return __awaiter(this, void 0, void 0, function () {
30546 var _a, props, vNode, _b, animate;
30547 return __generator(this, function (_c) {
30548 switch (_c.label) {
30549 case 0:
30550 _a = this, props = _a.props, vNode = _a.vNode;
30551 if (equal(nextProps, props)) {
30552 return [2 /*return*/];
30553 }
30554 _b = props.animate, animate = _b === void 0 ? true : _b;
30555 this.props = nextProps;
30556 vNode.props = nextProps;
30557 vNode.animate = animate;
30558 return [4 /*yield*/, this.render()];
30559 case 1:
30560 _c.sent();
30561 return [2 /*return*/];
30562 }
30563 });
30564 });
30565 };
30566 Canvas$1.prototype.render = function () {
30567 return __awaiter(this, void 0, void 0, function () {
30568 var _a, canvas, vNode;
30569 return __generator(this, function (_b) {
30570 switch (_b.label) {
30571 case 0:
30572 _a = this, canvas = _a.canvas, vNode = _a.vNode;
30573 return [4 /*yield*/, canvas.ready];
30574 case 1:
30575 _b.sent();
30576 render(vNode);
30577 return [2 /*return*/];
30578 }
30579 });
30580 });
30581 };
30582 Canvas$1.prototype.emit = function (type, event) {
30583 this._ee.emit(type, event);
30584 };
30585 Canvas$1.prototype.on = function (type, listener) {
30586 this._ee.on(type, listener);
30587 };
30588 Canvas$1.prototype.off = function (type, listener) {
30589 this._ee.off(type, listener);
30590 };
30591 Canvas$1.prototype.getCanvasEl = function () {
30592 return this.el;
30593 };
30594 Canvas$1.prototype.resize = function (width, height) {
30595 return __awaiter(this, void 0, void 0, function () {
30596 var canvas;
30597 return __generator(this, function (_a) {
30598 switch (_a.label) {
30599 case 0:
30600 canvas = this.canvas;
30601 canvas.resize(width, height);
30602 this.updateLayout(__assign(__assign({}, this.props), {
30603 width: width,
30604 height: height
30605 }));
30606 return [4 /*yield*/, this.render()];
30607 case 1:
30608 _a.sent();
30609 return [2 /*return*/];
30610 }
30611 });
30612 });
30613 };
30614 Canvas$1.prototype.toDataURL = function (type, encoderOptions) {
30615 return __awaiter(this, void 0, void 0, function () {
30616 var canvas;
30617 return __generator(this, function (_a) {
30618 canvas = this.canvas;
30619 return [2 /*return*/, new Promise(function (resolve) {
30620 canvas.addEventListener('rerender', function () {
30621 canvas.getContextService().toDataURL({
30622 type: type,
30623 encoderOptions: encoderOptions
30624 }).then(resolve);
30625 }, {
30626 once: true
30627 });
30628 })];
30629 });
30630 });
30631 };
30632 Canvas$1.prototype.updateLayout = function (props) {
30633 var width = props.width,
30634 height = props.height;
30635 var _a = this.context,
30636 px2hd = _a.px2hd,
30637 theme = _a.theme;
30638 var style = px2hd(__assign({
30639 left: 0,
30640 top: 0,
30641 width: width,
30642 height: height,
30643 padding: theme.padding
30644 }, props.style));
30645 var layout = computeLayout$2(style);
30646 var left = layout.left,
30647 top = layout.top;
30648 // 设置 container 的位置
30649 this.container.setAttribute('x', left);
30650 this.container.setAttribute('y', top);
30651 this.context = __assign(__assign({}, this.context), {
30652 left: left,
30653 top: top,
30654 width: layout.width,
30655 height: layout.height
30656 });
30657 this.vNode = __assign(__assign({}, this.vNode), {
30658 style: layout,
30659 context: this.context
30660 });
30661 };
30662 Canvas$1.prototype.toRawChildren = function (children) {
30663 return children;
30664 };
30665 Canvas$1.prototype.destroy = function () {
30666 var _a = this,
30667 canvas = _a.canvas,
30668 children = _a.children,
30669 el = _a.el;
30670 destroyElement(children);
30671 // 需要清理 canvas 画布内容,否则会导致 spa 应用 ios 下 canvas 白屏
30672 // https://stackoverflow.com/questions/52532614/total-canvas-memory-use-exceeds-the-maximum-limit-safari-12
30673 // https://github.com/antvis/F2/issues/630
30674 el.width = 0;
30675 el.height = 0;
30676 this.props = null;
30677 this.context = null;
30678 this.updater = null;
30679 this.theme = null;
30680 this.canvas = null;
30681 this.container = null;
30682 this.el = null;
30683 this.vNode = null;
30684 // 销毁也需要等 ready
30685 canvas.ready.then(function () {
30686 canvas.destroy();
30687 });
30688 };
30689 return Canvas$1;
30690 }();
30691
30692 function createRef() {
30693 var ref = {
30694 current: null
30695 };
30696 return ref;
30697 }
30698
30699 function createContext(defaultValue) {
30700 // 创建 Context 对象
30701 var context = {
30702 _currentValue: defaultValue
30703 };
30704 // 定义 Provider 组件
30705 var Provider = function Provider(_a) {
30706 var value = _a.value,
30707 children = _a.children;
30708 context._currentValue = value;
30709 return children;
30710 };
30711 // Injecter 可以往全局的 context 注入内容
30712 var Injecter = function Injecter(_a, context) {
30713 var children = _a.children,
30714 props = __rest(_a, ["children"]);
30715 Object.assign(context, props);
30716 return children;
30717 };
30718 Injecter.contextInjecter = context;
30719 // 定义 Consumer 组件
30720 var Consumer = function Consumer(_a) {
30721 var children = _a.children;
30722 return children(context._currentValue);
30723 };
30724 context.Provider = Provider;
30725 context.Injecter = Injecter;
30726 context.Consumer = Consumer;
30727 return context;
30728 }
30729
30730 var Timeline = /** @class */function (_super) {
30731 __extends(Timeline, _super);
30732 function Timeline(props) {
30733 var _this = _super.call(this, props) || this;
30734 _this.next = function () {
30735 var _a = _this,
30736 state = _a.state,
30737 props = _a.props;
30738 var index = state.index,
30739 count = state.count,
30740 delay = state.delay,
30741 autoPlay = state.autoPlay;
30742 var loop = props.loop;
30743 if (autoPlay === false) {
30744 return;
30745 }
30746 var next = loop ? (index + 1) % count : index + 1;
30747 if (next >= count) {
30748 return;
30749 }
30750 _this.timer = setTimeout(function () {
30751 _this.setState({
30752 index: next
30753 });
30754 }, delay || 0);
30755 };
30756 var delay = props.delay,
30757 _a = props.start,
30758 start = _a === void 0 ? 0 : _a,
30759 children = props.children,
30760 autoPlay = props.autoPlay;
30761 var count = Children.toArray(children).length;
30762 _this.state = {
30763 delay: delay,
30764 count: count,
30765 index: start,
30766 autoPlay: autoPlay
30767 };
30768 return _this;
30769 }
30770 Timeline.prototype.didMount = function () {
30771 this.animator.on('end', this.next);
30772 };
30773 Timeline.prototype.willReceiveProps = function (nextProps) {
30774 var nextStart = nextProps.start,
30775 nextDelay = nextProps.delay,
30776 nextAutoPlay = nextProps.autoPlay;
30777 var _a = this.state,
30778 index = _a.index,
30779 delay = _a.delay,
30780 autoPlay = _a.autoPlay;
30781 if (isNumber(nextStart) || nextDelay !== delay || nextAutoPlay !== autoPlay) {
30782 // 更新时清除 setTimeout
30783 clearTimeout(this.timer);
30784 this.setState({
30785 delay: nextDelay,
30786 index: isNumber(nextStart) ? nextStart : index,
30787 autoPlay: nextAutoPlay
30788 });
30789 }
30790 };
30791 Timeline.prototype.didUnmount = function () {
30792 this.animator.off('end', this.next);
30793 };
30794 Timeline.prototype.render = function () {
30795 var _a = this,
30796 state = _a.state,
30797 props = _a.props;
30798 var children = props.children;
30799 var index = state.index;
30800 var childrenArray = Children.toArray(children);
30801 return childrenArray[index];
30802 };
30803 return Timeline;
30804 }(Component);
30805
30806 var Timeline$1 = /** @class */function (_super) {
30807 __extends(Timeline, _super);
30808 function Timeline(props) {
30809 var _this = _super.call(this) || this;
30810 _this.animUnits = [];
30811 _this.frame = 0;
30812 _this.playState = 'play';
30813 _this.next = function () {
30814 var _a = _this,
30815 frame = _a.frame,
30816 playState = _a.playState,
30817 endFrame = _a.endFrame,
30818 speed = _a.speed;
30819 if (playState !== 'play') return;
30820 _this.frame = frame + 1;
30821 if (frame < endFrame) {
30822 _this.drawFrame();
30823 _this.animator.run();
30824 _this.setPlaybackRate(speed);
30825 } else {
30826 _this.emit('end');
30827 _this.playState = 'finish';
30828 }
30829 };
30830 var animUnits = props.animUnits,
30831 playState = props.playState,
30832 root = props.root,
30833 _a = props.speed,
30834 speed = _a === void 0 ? 1 : _a,
30835 time = props.time;
30836 _this.animator = new Animator();
30837 var rootShape = new Group();
30838 _this.animator.reset(rootShape);
30839 root.appendChild(rootShape);
30840 _this.animUnits = animUnits;
30841 _this.playState = playState;
30842 _this.endFrame = animUnits.length - 1;
30843 _this.speed = speed;
30844 _this.time = time;
30845 _this.totalDuration = animUnits.reduce(function (accumulator, current) {
30846 return accumulator + current.time;
30847 }, 0);
30848 return _this;
30849 }
30850 Timeline.prototype.start = function () {
30851 var _a = this,
30852 animator = _a.animator,
30853 frame = _a.frame,
30854 playState = _a.playState,
30855 endFrame = _a.endFrame,
30856 time = _a.time,
30857 speed = _a.speed;
30858 animator.on('end', this.next);
30859 if (frame < endFrame && playState === 'finish') {
30860 this.setFinishState();
30861 return;
30862 }
30863 this.drawFrame();
30864 this.animator.run();
30865 this.setPlayState(playState);
30866 time && this.goTo(time);
30867 this.setPlaybackRate(speed);
30868 };
30869 Timeline.prototype.drawFrame = function () {
30870 var _a = this,
30871 animator = _a.animator,
30872 animUnits = _a.animUnits,
30873 frame = _a.frame;
30874 var childAnimator = animUnits[frame].animators;
30875 animator.shape.removeChildren();
30876 childAnimator.map(function (d) {
30877 animator.shape.appendChild(d === null || d === void 0 ? void 0 : d.shape);
30878 });
30879 animator.children = childAnimator;
30880 };
30881 Timeline.prototype.setPlayState = function (state) {
30882 var animator = this.animator;
30883 switch (state) {
30884 case 'play':
30885 animator.play();
30886 break;
30887 case 'pause':
30888 animator.pause();
30889 break;
30890 case 'finish':
30891 animator.finish();
30892 break;
30893 }
30894 };
30895 Timeline.prototype.setPlaybackRate = function (speed) {
30896 var animator = this.animator;
30897 this.speed = speed;
30898 animator.setPlaybackRate(speed);
30899 };
30900 Timeline.prototype.getPlayState = function () {
30901 return this.playState;
30902 };
30903 Timeline.prototype.updateState = function (state) {
30904 // 播放状态不同
30905 if (state === 'finish') {
30906 this.setFinishState();
30907 return;
30908 }
30909 this.playState = state;
30910 this.setPlayState(state);
30911 };
30912 Timeline.prototype.clear = function () {
30913 this.animator = null;
30914 this.animUnits = [];
30915 this.playState = null;
30916 this.endFrame = null;
30917 };
30918 Timeline.prototype.goTo = function (time) {
30919 var _a = this,
30920 frame = _a.frame,
30921 animUnits = _a.animUnits,
30922 playState = _a.playState,
30923 totalDuration = _a.totalDuration;
30924 // 超出了总时长
30925 if (time > totalDuration && playState !== 'finish') {
30926 this.setFinishState();
30927 return;
30928 }
30929 var target;
30930 for (target = 0; target < animUnits.length; target++) {
30931 var cur = animUnits[target];
30932 if (time > cur.time) {
30933 time -= cur.time; // 计算剩余时间
30934 } else {
30935 break;
30936 }
30937 }
30938 if (frame !== target) {
30939 this.frame = target;
30940 this.drawFrame();
30941 // 结束当前动画
30942 this.setPlayState('finish');
30943 this.animator.run();
30944 this.setPlayState(playState);
30945 }
30946 this.animator.goTo(time);
30947 };
30948 Timeline.prototype.setFinishState = function () {
30949 var endFrame = this.endFrame;
30950 this.frame = endFrame;
30951 this.drawFrame();
30952 this.animator.run();
30953 this.setPlayState('finish');
30954 this.playState = 'finish';
30955 this.frame = endFrame + 1;
30956 this.animator.animations = [];
30957 };
30958 return Timeline;
30959 }(eventemitter3$1);
30960
30961 function generateFrameElement(cur, element) {
30962 if (!element) return;
30963 return Children.map(element, function (child) {
30964 var key = child.key,
30965 props = child.props;
30966 var newProps = cur[key] ? cur[key].to : {};
30967 var children = generateFrameElement(cur, props.children);
30968 return Children.cloneElement(child, __assign(__assign({}, newProps), {
30969 children: children
30970 }));
30971 });
30972 }
30973
30974 function cloneNode(vnode) {
30975 return Children.map(vnode, function (child) {
30976 if (!child) {
30977 return;
30978 }
30979 var shape = child.shape,
30980 children = child.children,
30981 animator = child.animator;
30982 var _a = animator.end,
30983 end = _a === void 0 ? {} : _a;
30984 // 拿到上一帧的snapshot
30985 var snapshot = shape.cloneNode();
30986 applyStyle(snapshot, end);
30987 return __assign(__assign({}, child), {
30988 shape: snapshot,
30989 children: cloneNode(children)
30990 });
30991 });
30992 }
30993 var Player = /** @class */function (_super) {
30994 __extends(Player, _super);
30995 function Player(props) {
30996 return _super.call(this, props) || this;
30997 }
30998 Player.prototype.didMount = function () {
30999 var _this = this;
31000 var _a = this.props,
31001 keyFrames = _a.keyFrames,
31002 children = _a.children,
31003 state = _a.state,
31004 onend = _a.onend,
31005 goTo = _a.goTo,
31006 speed = _a.speed;
31007 this.playerFrames = keyFrames.reduce(function (array, cur) {
31008 var frames = generateFrameElement(cur, array[array.length - 1] || children);
31009 array.push(frames);
31010 return array;
31011 }, []);
31012 var array = this.playerFrames.map(function (cur, index) {
31013 var keyFrame = keyFrames[index];
31014 _this.preNode = cloneNode(_this.preNode || _this._vNode);
31015 var animUnits = getUpdateAnimation(_this, cur, keyFrame) || {};
31016 return animUnits;
31017 });
31018 this.timeline = new Timeline$1({
31019 animUnits: array,
31020 playState: state,
31021 root: this.context.canvas,
31022 speed: speed,
31023 time: goTo
31024 });
31025 this.timeline.start();
31026 onend && this.timeline.on('end', onend);
31027 };
31028 Player.prototype.willReceiveProps = function (nextProps, _context) {
31029 var _a = this,
31030 lastProps = _a.props,
31031 timeline = _a.timeline;
31032 var state = nextProps.state,
31033 nextTime = nextProps.goTo,
31034 newSpeed = nextProps.speed;
31035 var lastTime = lastProps.goTo,
31036 lastSpeed = lastProps.speed;
31037 if (!isEqual(state, timeline.getPlayState()) && timeline.getPlayState() === 'finish') {
31038 // 重播
31039 if (nextTime < timeline.totalDuration) {
31040 timeline.updateState(state);
31041 timeline.goTo(nextTime);
31042 }
31043 //保持结束播放状态
31044 return;
31045 }
31046 // state 更新
31047 if (!isEqual(state, timeline.getPlayState())) {
31048 timeline.updateState(state);
31049 }
31050 if (!isEqual(nextTime, lastTime)) {
31051 timeline.goTo(nextTime);
31052 }
31053 // 播放速度
31054 if (!isEqual(newSpeed, lastSpeed)) {
31055 timeline.setPlaybackRate(newSpeed);
31056 }
31057 };
31058 /*外部ref调用方式 */
31059 Player.prototype.setPlayState = function (state) {
31060 var timeline = this.timeline;
31061 timeline.updateState(state);
31062 };
31063 Player.prototype.goTo = function (time) {
31064 var timeline = this.timeline;
31065 timeline.goTo(time);
31066 };
31067 Player.prototype.setPlaybackRate = function (speed) {
31068 var timeline = this.timeline;
31069 timeline.setPlaybackRate(speed);
31070 };
31071 Player.prototype.render = function () {
31072 return null;
31073 };
31074 return Player;
31075 }(Component);
31076
31077 function transposedRect(_a) {
31078 var xMin = _a.xMin,
31079 xMax = _a.xMax,
31080 yMin = _a.yMin,
31081 yMax = _a.yMax;
31082 return {
31083 xMin: yMin,
31084 xMax: yMax,
31085 yMin: xMin,
31086 yMax: xMax
31087 };
31088 }
31089 function convertRect(_a) {
31090 var x = _a.x,
31091 y = _a.y,
31092 size = _a.size,
31093 y0 = _a.y0;
31094 var xMin;
31095 var xMax;
31096 if (isArray(x)) {
31097 xMin = x[0];
31098 xMax = x[1];
31099 } else {
31100 xMin = x - size / 2;
31101 xMax = x + size / 2;
31102 }
31103 var yMin;
31104 var yMax;
31105 if (isArray(y)) {
31106 if (y[0] === y[1]) {
31107 yMin = y[0];
31108 yMax = y[1];
31109 } else {
31110 yMin = Math.min(y[0], y[1]);
31111 yMax = Math.max(y[0], y[1]);
31112 }
31113 } else {
31114 yMin = Math.min(y0, y);
31115 yMax = Math.max(y0, y);
31116 }
31117 return {
31118 xMin: xMin,
31119 xMax: xMax,
31120 yMin: yMin,
31121 yMax: yMax
31122 };
31123 }
31124 /**
31125 * 直角坐标系
31126 * convert相关的方法,涉及将标准坐标系映射到实际坐标系内
31127 * transform相关的方法,是仅将某一种关键点转换成另一种关键点 (比如将x/y/size/y0转换成yMin/yMax/..)
31128 */
31129 var Base = /** @class */function () {
31130 function Base(option) {
31131 this.left = 0;
31132 this.top = 0;
31133 this.width = 0;
31134 this.height = 0;
31135 // x y 调换
31136 this.transposed = false;
31137 // x,y 的值域,在极坐标中对应的就是弧度和半径
31138 this.x = [0, 1];
31139 this.y = [0, 1];
31140 this.update(option);
31141 }
31142 Base.prototype.update = function (option) {
31143 mix(this, option);
31144 var _a = this,
31145 left = _a.left,
31146 top = _a.top,
31147 width = _a.width,
31148 height = _a.height;
31149 this.right = left + width;
31150 this.bottom = top + height;
31151 this.center = {
31152 x: left + width / 2,
31153 y: top + height / 2
31154 };
31155 return this;
31156 };
31157 // 是循环, 比如极坐标是以 2π 循环的
31158 Base.prototype.isCyclic = function () {
31159 return false;
31160 };
31161 Base.prototype._zoomVal = function (val, func) {
31162 return isArray(val) ? val.map(function (v) {
31163 return func(v);
31164 }) : func(val);
31165 };
31166 /**
31167 * 把归一后的值映射到对应的定义域
31168 * @param point
31169 */
31170 Base.prototype.convert = function (point) {
31171 var _a = this,
31172 transposed = _a.transposed,
31173 x = _a.x,
31174 y = _a.y;
31175 var xDim = transposed ? 'y' : 'x';
31176 var yDim = transposed ? 'x' : 'y';
31177 var pointX = point[xDim];
31178 var pointY = point[yDim];
31179 // 超出边界不绘制
31180 if (pointX < 0 || pointX > 1 || pointY < 0 || pointY > 1) {
31181 return {
31182 x: NaN,
31183 y: NaN
31184 };
31185 }
31186 return {
31187 x: this._zoomVal(point[xDim], function (v) {
31188 return x[0] + (x[1] - x[0]) * v;
31189 }),
31190 y: this._zoomVal(point[yDim], function (v) {
31191 return y[0] + (y[1] - y[0]) * v;
31192 })
31193 };
31194 };
31195 /**
31196 * convert 的反处理,把定义域的值,反处理到归一的值
31197 */
31198 Base.prototype.invert = function (point) {
31199 var _a;
31200 var _b = this,
31201 transposed = _b.transposed,
31202 x = _b.x,
31203 y = _b.y;
31204 var xDim = transposed ? 'y' : 'x';
31205 var yDim = transposed ? 'x' : 'y';
31206 return _a = {}, _a[xDim] = this._zoomVal(point.x, function (v) {
31207 return (v - x[0]) / (x[1] - x[0]);
31208 }), _a[yDim] = this._zoomVal(point.y, function (v) {
31209 return (v - y[0]) / (y[1] - y[0]);
31210 }), _a;
31211 };
31212 /**
31213 * 把归一化的值映射到 canvas 的坐标点
31214 * @param point
31215 * @returns
31216 */
31217 Base.prototype.convertPoint = function (point) {
31218 return this.convert(point);
31219 };
31220 /**
31221 * 把canvas坐标的点位映射回归一的值
31222 */
31223 Base.prototype.invertPoint = function (point) {
31224 return this.invert(point);
31225 };
31226 // 将标准坐标系下的矩形绘制关键点映射成实际绘制的坐标点
31227 Base.prototype.convertRect = function (rectPoint) {
31228 var _a = this,
31229 xRange = _a.x,
31230 yRange = _a.y,
31231 transposed = _a.transposed;
31232 var xStart = xRange[0],
31233 xEnd = xRange[1];
31234 var yStart = yRange[0],
31235 yEnd = yRange[1];
31236 var rect = convertRect(rectPoint);
31237 var _b = transposed ? transposedRect(rect) : rect,
31238 xMin = _b.xMin,
31239 xMax = _b.xMax,
31240 yMin = _b.yMin,
31241 yMax = _b.yMax;
31242 var x0 = xStart + (xEnd - xStart) * xMin;
31243 var x1 = xStart + (xEnd - xStart) * xMax;
31244 var y0 = yStart + (yEnd - yStart) * yMin;
31245 var y1 = yStart + (yEnd - yStart) * yMax;
31246 return {
31247 xMin: Math.min(x0, x1),
31248 xMax: Math.max(x0, x1),
31249 yMin: Math.min(y0, y1),
31250 yMax: Math.max(y0, y1)
31251 };
31252 };
31253 // 将已经映射好的矩形绘制关键点转换成实际绘制的坐标点
31254 Base.prototype.transformToRect = function (rectPoint) {
31255 var x = rectPoint.x,
31256 y = rectPoint.y,
31257 y0 = rectPoint.y0,
31258 size = rectPoint.size;
31259 var coordOrigin = this.convertPoint({
31260 x: 0,
31261 y: y0
31262 });
31263 var transposed = this.transposed;
31264 var _rectPoint = {
31265 size: size,
31266 x: transposed ? y : x,
31267 y: transposed ? x : y,
31268 y0: transposed ? coordOrigin.x : coordOrigin.y
31269 };
31270 var rect = convertRect(_rectPoint);
31271 var _a = transposed ? transposedRect(rect) : rect,
31272 xMin = _a.xMin,
31273 xMax = _a.xMax,
31274 yMin = _a.yMin,
31275 yMax = _a.yMax;
31276 return {
31277 xMin: xMin,
31278 xMax: xMax,
31279 yMin: yMin,
31280 yMax: yMax
31281 };
31282 };
31283 return Base;
31284 }();
31285
31286 var Rect$1 = /** @class */function (_super) {
31287 __extends(Rect, _super);
31288 function Rect() {
31289 var _this = _super !== null && _super.apply(this, arguments) || this;
31290 _this.type = 'rect';
31291 return _this;
31292 }
31293 Rect.prototype.update = function (option) {
31294 _super.prototype.update.call(this, option);
31295 var _a = this,
31296 left = _a.left,
31297 top = _a.top,
31298 width = _a.width,
31299 height = _a.height;
31300 var x = [left, left + width];
31301 var y = [top + height, top];
31302 this.x = x;
31303 this.y = y;
31304 return this;
31305 };
31306 return Rect;
31307 }(Base);
31308
31309 /**
31310 * expand Vec2
31311 */
31312 var vec2Direction = function vec2Direction(v1, v2) {
31313 return v1[0] * v2[1] - v2[0] * v1[1];
31314 };
31315 var vec2Zero = function vec2Zero(v) {
31316 return v[0] === 0 && v[1] === 0;
31317 };
31318 var vec2AngleTo = function vec2AngleTo(v1, v2, direction) {
31319 var angle$1 = angle(v1, v2);
31320 var angleLargeThanPI = vec2Direction(v1, v2) >= 0;
31321 if (direction) {
31322 if (angleLargeThanPI) {
31323 return Math.PI * 2 - angle$1;
31324 }
31325 return angle$1;
31326 }
31327 if (angleLargeThanPI) {
31328 return angle$1;
31329 }
31330 return Math.PI * 2 - angle$1;
31331 };
31332
31333 var Polar = /** @class */function (_super) {
31334 __extends(Polar, _super);
31335 function Polar() {
31336 var _this = _super !== null && _super.apply(this, arguments) || this;
31337 _this.type = 'polar';
31338 _this.isPolar = true;
31339 return _this;
31340 }
31341 Polar.prototype.update = function (option) {
31342 _super.prototype.update.call(this, option);
31343 if (!this.option) {
31344 this.option = option;
31345 }
31346 var _a = this.option,
31347 _b = _a.radius,
31348 radiusRatio = _b === void 0 ? 1 : _b,
31349 _c = _a.innerRadius,
31350 innerRadiusRatio = _c === void 0 ? 0 : _c;
31351 var _d = this,
31352 width = _d.width,
31353 height = _d.height,
31354 _e = _d.startAngle,
31355 startAngle = _e === void 0 ? -Math.PI / 2 : _e,
31356 _f = _d.endAngle,
31357 endAngle = _f === void 0 ? Math.PI * 3 / 2 : _f;
31358 // 半径取宽高的最小值
31359 var radius = radiusRatio * (Math.min(width, height) / 2);
31360 // 极坐标下 x 表示弧度, y 代表 半径
31361 var x = [startAngle, endAngle];
31362 var y = [innerRadiusRatio * radius, radius];
31363 this.x = x;
31364 this.y = y;
31365 this.startAngle = startAngle;
31366 this.endAngle = endAngle;
31367 this.radius = radius;
31368 this.innnerRadius = innerRadiusRatio * radius;
31369 return this;
31370 };
31371 Polar.prototype.isCyclic = function () {
31372 var _a = this,
31373 startAngle = _a.startAngle,
31374 endAngle = _a.endAngle;
31375 if (endAngle - startAngle < Math.PI * 2) {
31376 return false;
31377 }
31378 return true;
31379 };
31380 Polar.prototype.convertPoint = function (point) {
31381 var _a = this,
31382 center = _a.center,
31383 transposed = _a.transposed,
31384 x = _a.x,
31385 y = _a.y;
31386 var xDim = transposed ? 'y' : 'x';
31387 var yDim = transposed ? 'x' : 'y';
31388 var xStart = x[0],
31389 xEnd = x[1];
31390 var yStart = y[0],
31391 yEnd = y[1];
31392 var angle = xStart + (xEnd - xStart) * point[xDim];
31393 var radius = yStart + (yEnd - yStart) * point[yDim];
31394 return {
31395 x: center.x + Math.cos(angle) * radius,
31396 y: center.y + Math.sin(angle) * radius
31397 };
31398 };
31399 Polar.prototype.invertPoint = function (point) {
31400 var _a = this,
31401 center = _a.center,
31402 transposed = _a.transposed,
31403 x = _a.x,
31404 y = _a.y;
31405 var xDim = transposed ? 'y' : 'x';
31406 var yDim = transposed ? 'x' : 'y';
31407 var xStart = x[0],
31408 xEnd = x[1];
31409 var yStart = y[0],
31410 yEnd = y[1];
31411 var m = [1, 0, 0, 1, 0, 0];
31412 rotate(m, m, xStart);
31413 var startV = [1, 0];
31414 transformMat2d(startV, startV, m);
31415 startV = [startV[0], startV[1]];
31416 var pointV = [point.x - center.x, point.y - center.y];
31417 if (vec2Zero(pointV)) {
31418 return {
31419 x: 0,
31420 y: 0
31421 };
31422 }
31423 var theta = vec2AngleTo(startV, pointV, xEnd < xStart);
31424 if (Math.abs(theta - Math.PI * 2) < 0.001) {
31425 theta = 0;
31426 }
31427 var l = length$1(pointV);
31428 var percentX = theta / (xEnd - xStart);
31429 percentX = xEnd - xStart > 0 ? percentX : -percentX;
31430 var percentY = (l - yStart) / (yEnd - yStart);
31431 var rst = {};
31432 rst[xDim] = percentX;
31433 rst[yDim] = percentY;
31434 return rst;
31435 };
31436 return Polar;
31437 }(Base);
31438
31439 var coordMap = {
31440 rect: Rect$1,
31441 polar: Polar
31442 };
31443 var coordController = /** @class */function () {
31444 function coordController() {}
31445 coordController.prototype.getOption = function (cfg) {
31446 if (isString(cfg)) {
31447 return {
31448 type: coordMap[cfg] || Rect$1
31449 };
31450 }
31451 if (isFunction(cfg)) {
31452 return {
31453 type: cfg
31454 };
31455 }
31456 var type = (cfg || {}).type;
31457 return __assign(__assign({}, cfg), {
31458 // 默认直角坐标系
31459 type: isFunction(type) ? type : coordMap[type] || Rect$1
31460 });
31461 };
31462 coordController.prototype.create = function (cfg) {
31463 var layout = this.layout;
31464 var option = this.getOption(cfg);
31465 var type = option.type;
31466 var coord = new type(__assign(__assign({}, option), layout));
31467 this.coord = coord;
31468 return coord;
31469 };
31470 coordController.prototype.updateLayout = function (style) {
31471 var coord = this.coord;
31472 var left = style.left,
31473 top = style.top,
31474 width = style.width,
31475 height = style.height,
31476 padding = style.padding;
31477 var _a = padding || [0, 0, 0, 0],
31478 paddingTop = _a[0],
31479 paddingRight = _a[1],
31480 paddingBottom = _a[2],
31481 paddingLeft = _a[3];
31482 this.layout = {
31483 left: left + paddingLeft,
31484 top: top + paddingTop,
31485 width: width - paddingLeft - paddingRight,
31486 height: height - paddingTop - paddingBottom
31487 };
31488 if (coord) {
31489 coord.update(this.layout);
31490 }
31491 };
31492 coordController.prototype.useLayout = function (positionLayout) {
31493 var coord = this.coord;
31494 var position = positionLayout.position,
31495 boxWidth = positionLayout.width,
31496 boxHeight = positionLayout.height;
31497 var left = coord.left,
31498 top = coord.top,
31499 width = coord.width,
31500 height = coord.height;
31501 switch (position) {
31502 case 'left':
31503 left += boxWidth;
31504 width = Math.max(0, width - boxWidth);
31505 break;
31506 case 'right':
31507 width = Math.max(0, width - boxWidth);
31508 break;
31509 case 'top':
31510 top += boxHeight;
31511 height = Math.max(0, height - boxHeight);
31512 break;
31513 case 'bottom':
31514 height = Math.max(0, height - boxHeight);
31515 break;
31516 }
31517 coord.update({
31518 left: left,
31519 top: top,
31520 width: width,
31521 height: height
31522 });
31523 };
31524 coordController.prototype.update = function () {};
31525 coordController.prototype.getCoord = function () {
31526 return this.coord;
31527 };
31528 return coordController;
31529 }();
31530
31531 var methodCache = {};
31532 /**
31533 * 获取计算 ticks 的方法
31534 * @param key 键值
31535 * @returns 计算 ticks 的方法
31536 */
31537 function getTickMethod(key) {
31538 return methodCache[key];
31539 }
31540 /**
31541 * 注册计算 ticks 的方法
31542 * @param key 键值
31543 * @param method 方法
31544 */
31545 function registerTickMethod(key, method) {
31546 methodCache[key] = method;
31547 }
31548
31549 var Scale = /** @class */function () {
31550 function Scale(cfg) {
31551 /**
31552 * 度量的类型
31553 */
31554 this.type = 'base';
31555 /**
31556 * 是否分类类型的度量
31557 */
31558 this.isCategory = false;
31559 /**
31560 * 是否线性度量,有linear, time 度量
31561 */
31562 this.isLinear = false;
31563 /**
31564 * 是否连续类型的度量,linear,time,log, pow, quantile, quantize 都支持
31565 */
31566 this.isContinuous = false;
31567 /**
31568 * 是否是常量的度量,传入和传出一致
31569 */
31570 this.isIdentity = false;
31571 this.values = [];
31572 this.range = [0, 1];
31573 this.ticks = [];
31574 this.__cfg__ = cfg;
31575 this.initCfg();
31576 this.init();
31577 }
31578 // 对于原始值的必要转换,如分类、时间字段需转换成数值,用transform/map命名可能更好
31579 Scale.prototype.translate = function (v) {
31580 return v;
31581 };
31582 /** 重新初始化 */
31583 Scale.prototype.change = function (cfg) {
31584 // 覆盖配置项,而不替代
31585 mix(this.__cfg__, cfg);
31586 this.init();
31587 };
31588 Scale.prototype.clone = function () {
31589 return this.constructor(this.__cfg__);
31590 };
31591 /** 获取坐标轴需要的ticks */
31592 Scale.prototype.getTicks = function () {
31593 var _this = this;
31594 return map(this.ticks, function (tick, idx) {
31595 if (isObject(tick)) {
31596 // 仅当符合Tick类型时才有意义
31597 return tick;
31598 }
31599 return {
31600 text: _this.getText(tick, idx),
31601 tickValue: tick,
31602 value: _this.scale(tick) // scaled
31603 };
31604 });
31605 };
31606 /** 获取Tick的格式化结果 */
31607 Scale.prototype.getText = function (value, key) {
31608 var formatter = this.formatter;
31609 var res = formatter ? formatter(value, key) : value;
31610 if (isNil(res) || !isFunction(res.toString)) {
31611 return '';
31612 }
31613 return res.toString();
31614 };
31615 // 获取配置项中的值,当前 scale 上的值可能会被修改
31616 Scale.prototype.getConfig = function (key) {
31617 return this.__cfg__[key];
31618 };
31619 // scale初始化
31620 Scale.prototype.init = function () {
31621 mix(this, this.__cfg__);
31622 this.setDomain();
31623 if (isEmpty(this.getConfig('ticks'))) {
31624 this.ticks = this.calculateTicks();
31625 }
31626 };
31627 // 子类上覆盖某些属性,不能直接在类上声明,否则会被覆盖
31628 Scale.prototype.initCfg = function () {};
31629 Scale.prototype.setDomain = function () {};
31630 Scale.prototype.calculateTicks = function () {
31631 var tickMethod = this.tickMethod;
31632 var ticks = [];
31633 if (isString(tickMethod)) {
31634 var method = getTickMethod(tickMethod);
31635 if (!method) {
31636 throw new Error('There is no method to to calculate ticks!');
31637 }
31638 ticks = method(this);
31639 } else if (isFunction(tickMethod)) {
31640 ticks = tickMethod(this);
31641 }
31642 return ticks;
31643 };
31644 // range 的最小值
31645 Scale.prototype.rangeMin = function () {
31646 return this.range[0];
31647 };
31648 // range 的最大值
31649 Scale.prototype.rangeMax = function () {
31650 return this.range[1];
31651 };
31652 /** 定义域转 0~1 */
31653 Scale.prototype.calcPercent = function (value, min, max) {
31654 if (isNumber(value)) {
31655 return (value - min) / (max - min);
31656 }
31657 return NaN;
31658 };
31659 /** 0~1转定义域 */
31660 Scale.prototype.calcValue = function (percent, min, max) {
31661 return min + percent * (max - min);
31662 };
31663 return Scale;
31664 }();
31665
31666 /**
31667 * 分类度量
31668 * @class
31669 */
31670 var Category = /** @class */function (_super) {
31671 __extends(Category, _super);
31672 function Category() {
31673 var _this = _super !== null && _super.apply(this, arguments) || this;
31674 _this.type = 'cat';
31675 _this.isCategory = true;
31676 return _this;
31677 }
31678 Category.prototype.buildIndexMap = function () {
31679 if (!this.translateIndexMap) {
31680 this.translateIndexMap = new Map();
31681 // 重新构建缓存
31682 for (var i = 0; i < this.values.length; i++) {
31683 this.translateIndexMap.set(this.values[i], i);
31684 }
31685 }
31686 };
31687 Category.prototype.translate = function (value) {
31688 // 按需构建 map
31689 this.buildIndexMap();
31690 // 找得到
31691 var idx = this.translateIndexMap.get(value);
31692 if (idx === undefined) {
31693 idx = isNumber(value) ? value : NaN;
31694 }
31695 return idx;
31696 };
31697 Category.prototype.scale = function (value) {
31698 var order = this.translate(value);
31699 // 分类数据允许 0.5 范围内调整
31700 // if (order < this.min - 0.5 || order > this.max + 0.5) {
31701 // return NaN;
31702 // }
31703 var percent = this.calcPercent(order, this.min, this.max);
31704 return this.calcValue(percent, this.rangeMin(), this.rangeMax());
31705 };
31706 Category.prototype.invert = function (scaledValue) {
31707 var domainRange = this.max - this.min;
31708 var percent = this.calcPercent(scaledValue, this.rangeMin(), this.rangeMax());
31709 var idx = Math.round(domainRange * percent) + this.min;
31710 if (idx < this.min || idx > this.max) {
31711 return NaN;
31712 }
31713 return this.values[idx];
31714 };
31715 Category.prototype.getText = function (value) {
31716 var args = [];
31717 for (var _i = 1; _i < arguments.length; _i++) {
31718 args[_i - 1] = arguments[_i];
31719 }
31720 var v = value;
31721 // value为index
31722 if (isNumber(value) && !this.values.includes(value)) {
31723 v = this.values[v];
31724 }
31725 return _super.prototype.getText.apply(this, __spreadArray([v], args, false));
31726 };
31727 // 复写属性
31728 Category.prototype.initCfg = function () {
31729 this.tickMethod = 'cat';
31730 };
31731 // 设置 min, max
31732 Category.prototype.setDomain = function () {
31733 // 用户有可能设置 min
31734 if (isNil(this.getConfig('min'))) {
31735 this.min = 0;
31736 }
31737 if (isNil(this.getConfig('max'))) {
31738 var size = this.values.length;
31739 this.max = size > 1 ? size - 1 : size;
31740 }
31741 // scale.init 的时候清除缓存
31742 if (this.translateIndexMap) {
31743 this.translateIndexMap = undefined;
31744 }
31745 };
31746 return Category;
31747 }(Scale);
31748
31749 var token = /d{1,4}|M{1,4}|YY(?:YY)?|S{1,3}|Do|ZZ|Z|([HhMsDm])\1?|[aA]|"[^"]*"|'[^']*'/g;
31750 var literal = /\[([^]*?)\]/gm;
31751 function shorten(arr, sLen) {
31752 var newArr = [];
31753 for (var i = 0, len = arr.length; i < len; i++) {
31754 newArr.push(arr[i].substr(0, sLen));
31755 }
31756 return newArr;
31757 }
31758 function assign(origObj) {
31759 var args = [];
31760 for (var _i = 1; _i < arguments.length; _i++) {
31761 args[_i - 1] = arguments[_i];
31762 }
31763 for (var _a = 0, args_1 = args; _a < args_1.length; _a++) {
31764 var obj = args_1[_a];
31765 for (var key in obj) {
31766 // @ts-ignore ex
31767 origObj[key] = obj[key];
31768 }
31769 }
31770 return origObj;
31771 }
31772 var dayNames = [
31773 "Sunday",
31774 "Monday",
31775 "Tuesday",
31776 "Wednesday",
31777 "Thursday",
31778 "Friday",
31779 "Saturday"
31780 ];
31781 var monthNames = [
31782 "January",
31783 "February",
31784 "March",
31785 "April",
31786 "May",
31787 "June",
31788 "July",
31789 "August",
31790 "September",
31791 "October",
31792 "November",
31793 "December"
31794 ];
31795 var monthNamesShort = shorten(monthNames, 3);
31796 var dayNamesShort = shorten(dayNames, 3);
31797 var defaultI18n = {
31798 dayNamesShort: dayNamesShort,
31799 dayNames: dayNames,
31800 monthNamesShort: monthNamesShort,
31801 monthNames: monthNames,
31802 amPm: ["am", "pm"],
31803 DoFn: function (dayOfMonth) {
31804 return (dayOfMonth +
31805 ["th", "st", "nd", "rd"][dayOfMonth % 10 > 3
31806 ? 0
31807 : ((dayOfMonth - (dayOfMonth % 10) !== 10 ? 1 : 0) * dayOfMonth) % 10]);
31808 }
31809 };
31810 var globalI18n = assign({}, defaultI18n);
31811 var pad = function (val, len) {
31812 if (len === void 0) { len = 2; }
31813 val = String(val);
31814 while (val.length < len) {
31815 val = "0" + val;
31816 }
31817 return val;
31818 };
31819 var formatFlags = {
31820 D: function (dateObj) { return String(dateObj.getDate()); },
31821 DD: function (dateObj) { return pad(dateObj.getDate()); },
31822 Do: function (dateObj, i18n) {
31823 return i18n.DoFn(dateObj.getDate());
31824 },
31825 d: function (dateObj) { return String(dateObj.getDay()); },
31826 dd: function (dateObj) { return pad(dateObj.getDay()); },
31827 ddd: function (dateObj, i18n) {
31828 return i18n.dayNamesShort[dateObj.getDay()];
31829 },
31830 dddd: function (dateObj, i18n) {
31831 return i18n.dayNames[dateObj.getDay()];
31832 },
31833 M: function (dateObj) { return String(dateObj.getMonth() + 1); },
31834 MM: function (dateObj) { return pad(dateObj.getMonth() + 1); },
31835 MMM: function (dateObj, i18n) {
31836 return i18n.monthNamesShort[dateObj.getMonth()];
31837 },
31838 MMMM: function (dateObj, i18n) {
31839 return i18n.monthNames[dateObj.getMonth()];
31840 },
31841 YY: function (dateObj) {
31842 return pad(String(dateObj.getFullYear()), 4).substr(2);
31843 },
31844 YYYY: function (dateObj) { return pad(dateObj.getFullYear(), 4); },
31845 h: function (dateObj) { return String(dateObj.getHours() % 12 || 12); },
31846 hh: function (dateObj) { return pad(dateObj.getHours() % 12 || 12); },
31847 H: function (dateObj) { return String(dateObj.getHours()); },
31848 HH: function (dateObj) { return pad(dateObj.getHours()); },
31849 m: function (dateObj) { return String(dateObj.getMinutes()); },
31850 mm: function (dateObj) { return pad(dateObj.getMinutes()); },
31851 s: function (dateObj) { return String(dateObj.getSeconds()); },
31852 ss: function (dateObj) { return pad(dateObj.getSeconds()); },
31853 S: function (dateObj) {
31854 return String(Math.round(dateObj.getMilliseconds() / 100));
31855 },
31856 SS: function (dateObj) {
31857 return pad(Math.round(dateObj.getMilliseconds() / 10), 2);
31858 },
31859 SSS: function (dateObj) { return pad(dateObj.getMilliseconds(), 3); },
31860 a: function (dateObj, i18n) {
31861 return dateObj.getHours() < 12 ? i18n.amPm[0] : i18n.amPm[1];
31862 },
31863 A: function (dateObj, i18n) {
31864 return dateObj.getHours() < 12
31865 ? i18n.amPm[0].toUpperCase()
31866 : i18n.amPm[1].toUpperCase();
31867 },
31868 ZZ: function (dateObj) {
31869 var offset = dateObj.getTimezoneOffset();
31870 return ((offset > 0 ? "-" : "+") +
31871 pad(Math.floor(Math.abs(offset) / 60) * 100 + (Math.abs(offset) % 60), 4));
31872 },
31873 Z: function (dateObj) {
31874 var offset = dateObj.getTimezoneOffset();
31875 return ((offset > 0 ? "-" : "+") +
31876 pad(Math.floor(Math.abs(offset) / 60), 2) +
31877 ":" +
31878 pad(Math.abs(offset) % 60, 2));
31879 }
31880 };
31881 // Some common format strings
31882 var globalMasks = {
31883 default: "ddd MMM DD YYYY HH:mm:ss",
31884 shortDate: "M/D/YY",
31885 mediumDate: "MMM D, YYYY",
31886 longDate: "MMMM D, YYYY",
31887 fullDate: "dddd, MMMM D, YYYY",
31888 isoDate: "YYYY-MM-DD",
31889 isoDateTime: "YYYY-MM-DDTHH:mm:ssZ",
31890 shortTime: "HH:mm",
31891 mediumTime: "HH:mm:ss",
31892 longTime: "HH:mm:ss.SSS"
31893 };
31894 /***
31895 * Format a date
31896 * @method format
31897 * @param {Date|number} dateObj
31898 * @param {string} mask Format of the date, i.e. 'mm-dd-yy' or 'shortDate'
31899 * @returns {string} Formatted date string
31900 */
31901 var format = function (dateObj, mask, i18n) {
31902 if (mask === void 0) { mask = globalMasks["default"]; }
31903 if (i18n === void 0) { i18n = {}; }
31904 if (typeof dateObj === "number") {
31905 dateObj = new Date(dateObj);
31906 }
31907 if (Object.prototype.toString.call(dateObj) !== "[object Date]" ||
31908 isNaN(dateObj.getTime())) {
31909 throw new Error("Invalid Date pass to format");
31910 }
31911 mask = globalMasks[mask] || mask;
31912 var literals = [];
31913 // Make literals inactive by replacing them with @@@
31914 mask = mask.replace(literal, function ($0, $1) {
31915 literals.push($1);
31916 return "@@@";
31917 });
31918 var combinedI18nSettings = assign(assign({}, globalI18n), i18n);
31919 // Apply formatting rules
31920 mask = mask.replace(token, function ($0) {
31921 return formatFlags[$0](dateObj, combinedI18nSettings);
31922 });
31923 // Inline literal values back into the formatted value
31924 return mask.replace(/@@@/g, function () { return literals.shift(); });
31925 };
31926
31927 function timeFormat(time, mask) {
31928 return format(time, mask);
31929 }
31930 /**
31931 * 转换成时间戳
31932 * @param value 时间值
31933 */
31934 function toTimeStamp(value) {
31935 if (isString(value)) {
31936 if (value.indexOf('T') > 0) {
31937 value = new Date(value).getTime();
31938 } else {
31939 // new Date('2010/01/10') 和 new Date('2010-01-10') 的差别在于:
31940 // 如果仅有年月日时,前者是带有时区的: Fri Jan 10 2020 02:40:13 GMT+0800 (中国标准时间)
31941 // 后者会格式化成 Sun Jan 10 2010 08:00:00 GMT+0800 (中国标准时间)
31942 value = new Date(value.replace(/-/gi, '/')).getTime();
31943 }
31944 }
31945 if (isDate(value)) {
31946 value = value.getTime();
31947 }
31948 return value;
31949 }
31950
31951 /**
31952 * 时间分类度量
31953 * @class
31954 */
31955 var TimeCat = /** @class */function (_super) {
31956 __extends(TimeCat, _super);
31957 function TimeCat() {
31958 var _this = _super !== null && _super.apply(this, arguments) || this;
31959 _this.type = 'timeCat';
31960 return _this;
31961 }
31962 /**
31963 * @override
31964 */
31965 TimeCat.prototype.translate = function (value) {
31966 value = toTimeStamp(value);
31967 var index = this.values.indexOf(value);
31968 if (index === -1) {
31969 if (isNumber(value) && value < this.values.length) {
31970 index = value;
31971 } else {
31972 index = NaN;
31973 }
31974 }
31975 return index;
31976 };
31977 /**
31978 * 由于时间类型数据需要转换一下,所以复写 getText
31979 * @override
31980 */
31981 TimeCat.prototype.getText = function (value, tickIndex) {
31982 var index = this.translate(value);
31983 if (index > -1) {
31984 var result = this.values[index];
31985 var formatter = this.formatter;
31986 result = formatter ? formatter(result, tickIndex) : timeFormat(result, this.mask);
31987 return result;
31988 }
31989 return value;
31990 };
31991 TimeCat.prototype.initCfg = function () {
31992 this.tickMethod = 'time-cat';
31993 this.mask = 'YYYY-MM-DD';
31994 this.tickCount = 7; // 一般时间数据会显示 7, 14, 30 天的数字
31995 };
31996 TimeCat.prototype.setDomain = function () {
31997 var values = this.values;
31998 // 针对时间分类类型,会将时间统一转换为时间戳
31999 each(values, function (v, i) {
32000 values[i] = toTimeStamp(v);
32001 });
32002 values.sort(function (v1, v2) {
32003 return v1 - v2;
32004 });
32005 _super.prototype.setDomain.call(this);
32006 };
32007 return TimeCat;
32008 }(Category);
32009
32010 /**
32011 * 连续度量的基类
32012 * @class
32013 */
32014 var Continuous = /** @class */function (_super) {
32015 __extends(Continuous, _super);
32016 function Continuous() {
32017 var _this = _super !== null && _super.apply(this, arguments) || this;
32018 _this.isContinuous = true;
32019 return _this;
32020 }
32021 Continuous.prototype.scale = function (value) {
32022 if (isNil(value)) {
32023 return NaN;
32024 }
32025 var rangeMin = this.rangeMin();
32026 var rangeMax = this.rangeMax();
32027 var max = this.max;
32028 var min = this.min;
32029 if (max === min) {
32030 return rangeMin;
32031 }
32032 var percent = this.getScalePercent(value);
32033 return rangeMin + percent * (rangeMax - rangeMin);
32034 };
32035 Continuous.prototype.init = function () {
32036 _super.prototype.init.call(this);
32037 // init 完成后保证 min, max 包含 ticks 的范围
32038 var ticks = this.ticks;
32039 var firstTick = head(ticks);
32040 var lastTick = last(ticks);
32041 if (firstTick < this.min) {
32042 this.min = firstTick;
32043 }
32044 if (lastTick > this.max) {
32045 this.max = lastTick;
32046 }
32047 // strict-limit 方式
32048 if (!isNil(this.minLimit)) {
32049 this.min = firstTick;
32050 }
32051 if (!isNil(this.maxLimit)) {
32052 this.max = lastTick;
32053 }
32054 };
32055 Continuous.prototype.setDomain = function () {
32056 var _a = getRange(this.values),
32057 min = _a.min,
32058 max = _a.max;
32059 if (isNil(this.min)) {
32060 this.min = min;
32061 }
32062 if (isNil(this.max)) {
32063 this.max = max;
32064 }
32065 if (this.min > this.max) {
32066 this.min = min;
32067 this.max = max;
32068 }
32069 };
32070 Continuous.prototype.calculateTicks = function () {
32071 var _this = this;
32072 var ticks = _super.prototype.calculateTicks.call(this);
32073 if (!this.nice) {
32074 ticks = filter(ticks, function (tick) {
32075 return tick >= _this.min && tick <= _this.max;
32076 });
32077 }
32078 return ticks;
32079 };
32080 // 计算原始值值占的百分比
32081 Continuous.prototype.getScalePercent = function (value) {
32082 var max = this.max;
32083 var min = this.min;
32084 return (value - min) / (max - min);
32085 };
32086 Continuous.prototype.getInvertPercent = function (value) {
32087 return (value - this.rangeMin()) / (this.rangeMax() - this.rangeMin());
32088 };
32089 return Continuous;
32090 }(Scale);
32091
32092 /**
32093 * 线性度量
32094 * @class
32095 */
32096 var Linear = /** @class */function (_super) {
32097 __extends(Linear, _super);
32098 function Linear() {
32099 var _this = _super !== null && _super.apply(this, arguments) || this;
32100 _this.type = 'linear';
32101 _this.isLinear = true;
32102 return _this;
32103 }
32104 Linear.prototype.invert = function (value) {
32105 var percent = this.getInvertPercent(value);
32106 return this.min + percent * (this.max - this.min);
32107 };
32108 Linear.prototype.initCfg = function () {
32109 this.tickMethod = 'wilkinson-extended';
32110 this.nice = false;
32111 };
32112 return Linear;
32113 }(Continuous);
32114
32115 // 求以a为次幂,结果为b的基数,如 x^^a = b;求x
32116 // 虽然数学上 b 不支持负数,但是这里需要支持 负数
32117 function calBase(a, b) {
32118 var e = Math.E;
32119 var value;
32120 if (b >= 0) {
32121 value = Math.pow(e, Math.log(b) / a); // 使用换底公式求底
32122 } else {
32123 value = Math.pow(e, Math.log(-b) / a) * -1; // 使用换底公式求底
32124 }
32125 return value;
32126 }
32127 function log(a, b) {
32128 if (a === 1) {
32129 return 1;
32130 }
32131 return Math.log(b) / Math.log(a);
32132 }
32133 function getLogPositiveMin(values, base, max) {
32134 if (isNil(max)) {
32135 max = Math.max.apply(null, values);
32136 }
32137 var positiveMin = max;
32138 each(values, function (value) {
32139 if (value > 0 && value < positiveMin) {
32140 positiveMin = value;
32141 }
32142 });
32143 if (positiveMin === max) {
32144 positiveMin = max / base;
32145 }
32146 if (positiveMin > 1) {
32147 positiveMin = 1;
32148 }
32149 return positiveMin;
32150 }
32151
32152 /**
32153 * Log 度量,处理非均匀分布
32154 */
32155 var Log = /** @class */function (_super) {
32156 __extends(Log, _super);
32157 function Log() {
32158 var _this = _super !== null && _super.apply(this, arguments) || this;
32159 _this.type = 'log';
32160 return _this;
32161 }
32162 /**
32163 * @override
32164 */
32165 Log.prototype.invert = function (value) {
32166 var base = this.base;
32167 var max = log(base, this.max);
32168 var rangeMin = this.rangeMin();
32169 var range = this.rangeMax() - rangeMin;
32170 var min;
32171 var positiveMin = this.positiveMin;
32172 if (positiveMin) {
32173 if (value === 0) {
32174 return 0;
32175 }
32176 min = log(base, positiveMin / base);
32177 var appendPercent = 1 / (max - min) * range; // 0 到 positiveMin的占比
32178 if (value < appendPercent) {
32179 // 落到 0 - positiveMin 之间
32180 return value / appendPercent * positiveMin;
32181 }
32182 } else {
32183 min = log(base, this.min);
32184 }
32185 var percent = (value - rangeMin) / range;
32186 var tmp = percent * (max - min) + min;
32187 return Math.pow(base, tmp);
32188 };
32189 Log.prototype.initCfg = function () {
32190 this.tickMethod = 'log';
32191 this.base = 10;
32192 this.tickCount = 6;
32193 this.nice = true;
32194 };
32195 // 设置
32196 Log.prototype.setDomain = function () {
32197 _super.prototype.setDomain.call(this);
32198 var min = this.min;
32199 if (min < 0) {
32200 throw new Error('When you use log scale, the minimum value must be greater than zero!');
32201 }
32202 if (min === 0) {
32203 this.positiveMin = getLogPositiveMin(this.values, this.base, this.max);
32204 }
32205 };
32206 // 根据当前值获取占比
32207 Log.prototype.getScalePercent = function (value) {
32208 var max = this.max;
32209 var min = this.min;
32210 if (max === min) {
32211 return 0;
32212 }
32213 // 如果值小于等于0,则按照0处理
32214 if (value <= 0) {
32215 return 0;
32216 }
32217 var base = this.base;
32218 var positiveMin = this.positiveMin;
32219 // 如果min == 0, 则根据比0大的最小值,计算比例关系。这个最小值作为坐标轴上的第二个tick,第一个是0但是不显示
32220 if (positiveMin) {
32221 min = positiveMin * 1 / base;
32222 }
32223 var percent;
32224 // 如果数值小于次小值,那么就计算 value / 次小值 占整体的比例
32225 if (value < positiveMin) {
32226 percent = value / positiveMin / (log(base, max) - log(base, min));
32227 } else {
32228 percent = (log(base, value) - log(base, min)) / (log(base, max) - log(base, min));
32229 }
32230 return percent;
32231 };
32232 return Log;
32233 }(Continuous);
32234
32235 /**
32236 * Pow 度量,处理非均匀分布
32237 */
32238 var Pow = /** @class */function (_super) {
32239 __extends(Pow, _super);
32240 function Pow() {
32241 var _this = _super !== null && _super.apply(this, arguments) || this;
32242 _this.type = 'pow';
32243 return _this;
32244 }
32245 /**
32246 * @override
32247 */
32248 Pow.prototype.invert = function (value) {
32249 var percent = this.getInvertPercent(value);
32250 var exponent = this.exponent;
32251 var max = calBase(exponent, this.max);
32252 var min = calBase(exponent, this.min);
32253 var tmp = percent * (max - min) + min;
32254 var factor = tmp >= 0 ? 1 : -1;
32255 return Math.pow(tmp, exponent) * factor;
32256 };
32257 Pow.prototype.initCfg = function () {
32258 this.tickMethod = 'pow';
32259 this.exponent = 2;
32260 this.tickCount = 5;
32261 this.nice = true;
32262 };
32263 // 获取度量计算时,value占的定义域百分比
32264 Pow.prototype.getScalePercent = function (value) {
32265 var max = this.max;
32266 var min = this.min;
32267 if (max === min) {
32268 return 0;
32269 }
32270 var exponent = this.exponent;
32271 var percent = (calBase(exponent, value) - calBase(exponent, min)) / (calBase(exponent, max) - calBase(exponent, min));
32272 return percent;
32273 };
32274 return Pow;
32275 }(Continuous);
32276
32277 /**
32278 * 时间度量
32279 * @class
32280 */
32281 var Time = /** @class */function (_super) {
32282 __extends(Time, _super);
32283 function Time() {
32284 var _this = _super !== null && _super.apply(this, arguments) || this;
32285 _this.type = 'time';
32286 return _this;
32287 }
32288 /**
32289 * @override
32290 */
32291 Time.prototype.getText = function (value, index) {
32292 var numberValue = this.translate(value);
32293 var formatter = this.formatter;
32294 return formatter ? formatter(numberValue, index) : timeFormat(numberValue, this.mask);
32295 };
32296 /**
32297 * @override
32298 */
32299 Time.prototype.scale = function (value) {
32300 var v = value;
32301 if (isString(v) || isDate(v)) {
32302 v = this.translate(v);
32303 }
32304 return _super.prototype.scale.call(this, v);
32305 };
32306 /**
32307 * 将时间转换成数字
32308 * @override
32309 */
32310 Time.prototype.translate = function (v) {
32311 return toTimeStamp(v);
32312 };
32313 Time.prototype.initCfg = function () {
32314 this.tickMethod = 'time-pretty';
32315 this.mask = 'YYYY-MM-DD';
32316 this.tickCount = 7;
32317 this.nice = false;
32318 };
32319 Time.prototype.setDomain = function () {
32320 var values = this.values;
32321 // 是否设置了 min, max,而不是直接取 this.min, this.max
32322 var minConfig = this.getConfig('min');
32323 var maxConfig = this.getConfig('max');
32324 // 如果设置了 min,max 则转换成时间戳
32325 if (!isNil(minConfig) || !isNumber(minConfig)) {
32326 this.min = this.translate(this.min);
32327 }
32328 if (!isNil(maxConfig) || !isNumber(maxConfig)) {
32329 this.max = this.translate(this.max);
32330 }
32331 // 没有设置 min, max 时
32332 if (values && values.length) {
32333 // 重新计算最大最小值
32334 var timeStamps_1 = [];
32335 var min_1 = Infinity; // 最小值
32336 var secondMin_1 = min_1; // 次小值
32337 var max_1 = 0;
32338 // 使用一个循环,计算min,max,secondMin
32339 each(values, function (v) {
32340 var timeStamp = toTimeStamp(v);
32341 if (isNaN(timeStamp)) {
32342 throw new TypeError("Invalid Time: ".concat(v, " in time scale!"));
32343 }
32344 if (min_1 > timeStamp) {
32345 secondMin_1 = min_1;
32346 min_1 = timeStamp;
32347 } else if (secondMin_1 > timeStamp) {
32348 secondMin_1 = timeStamp;
32349 }
32350 if (max_1 < timeStamp) {
32351 max_1 = timeStamp;
32352 }
32353 timeStamps_1.push(timeStamp);
32354 });
32355 // 存在多个值时,设置最小间距
32356 if (values.length > 1) {
32357 this.minTickInterval = secondMin_1 - min_1;
32358 }
32359 if (isNil(minConfig)) {
32360 this.min = min_1;
32361 }
32362 if (isNil(maxConfig)) {
32363 this.max = max_1;
32364 }
32365 }
32366 };
32367 return Time;
32368 }(Linear);
32369
32370 /**
32371 * 分段度量
32372 */
32373 var Quantize = /** @class */function (_super) {
32374 __extends(Quantize, _super);
32375 function Quantize() {
32376 var _this = _super !== null && _super.apply(this, arguments) || this;
32377 _this.type = 'quantize';
32378 return _this;
32379 }
32380 Quantize.prototype.invert = function (value) {
32381 var ticks = this.ticks;
32382 var length = ticks.length;
32383 var percent = this.getInvertPercent(value);
32384 var minIndex = Math.floor(percent * (length - 1));
32385 // 最后一个
32386 if (minIndex >= length - 1) {
32387 return last(ticks);
32388 }
32389 // 超出左边界, 则取第一个
32390 if (minIndex < 0) {
32391 return head(ticks);
32392 }
32393 var minTick = ticks[minIndex];
32394 var nextTick = ticks[minIndex + 1];
32395 // 比当前值小的 tick 在度量上的占比
32396 var minIndexPercent = minIndex / (length - 1);
32397 var maxIndexPercent = (minIndex + 1) / (length - 1);
32398 return minTick + (percent - minIndexPercent) / (maxIndexPercent - minIndexPercent) * (nextTick - minTick);
32399 };
32400 Quantize.prototype.initCfg = function () {
32401 this.tickMethod = 'r-pretty';
32402 this.tickCount = 5;
32403 this.nice = true;
32404 };
32405 Quantize.prototype.calculateTicks = function () {
32406 var ticks = _super.prototype.calculateTicks.call(this);
32407 if (!this.nice) {
32408 // 如果 nice = false ,补充 min, max
32409 if (last(ticks) !== this.max) {
32410 ticks.push(this.max);
32411 }
32412 if (head(ticks) !== this.min) {
32413 ticks.unshift(this.min);
32414 }
32415 }
32416 return ticks;
32417 };
32418 // 计算当前值在刻度中的占比
32419 Quantize.prototype.getScalePercent = function (value) {
32420 var ticks = this.ticks;
32421 // 超出左边界
32422 if (value < head(ticks)) {
32423 return 0;
32424 }
32425 // 超出右边界
32426 if (value > last(ticks)) {
32427 return 1;
32428 }
32429 var minIndex = 0;
32430 each(ticks, function (tick, index) {
32431 if (value >= tick) {
32432 minIndex = index;
32433 } else {
32434 return false;
32435 }
32436 });
32437 return minIndex / (ticks.length - 1);
32438 };
32439 return Quantize;
32440 }(Continuous);
32441
32442 var Quantile = /** @class */function (_super) {
32443 __extends(Quantile, _super);
32444 function Quantile() {
32445 var _this = _super !== null && _super.apply(this, arguments) || this;
32446 _this.type = 'quantile';
32447 return _this;
32448 }
32449 Quantile.prototype.initCfg = function () {
32450 this.tickMethod = 'quantile';
32451 this.tickCount = 5;
32452 this.nice = true;
32453 };
32454 return Quantile;
32455 }(Quantize);
32456
32457 var map$3 = {};
32458 function getClass(key) {
32459 return map$3[key];
32460 }
32461 function registerClass(key, cls) {
32462 if (getClass(key)) {
32463 throw new Error("type '".concat(key, "' existed."));
32464 }
32465 map$3[key] = cls;
32466 }
32467
32468 /**
32469 * identity scale原则上是定义域和值域一致,scale/invert方法也是一致的
32470 * 参考R的实现:https://github.com/r-lib/scales/blob/master/R/pal-identity.r
32471 * 参考d3的实现(做了下转型):https://github.com/d3/d3-scale/blob/master/src/identity.js
32472 */
32473 var Identity = /** @class */function (_super) {
32474 __extends(Identity, _super);
32475 function Identity() {
32476 var _this = _super !== null && _super.apply(this, arguments) || this;
32477 _this.type = 'identity';
32478 _this.isIdentity = true;
32479 return _this;
32480 }
32481 Identity.prototype.calculateTicks = function () {
32482 return this.values;
32483 };
32484 Identity.prototype.scale = function (value) {
32485 // 如果传入的值不等于 identity 的值,则直接返回,用于一维图时的 dodge
32486 if (this.values[0] !== value && isNumber(value)) {
32487 return value;
32488 }
32489 return this.range[0];
32490 };
32491 Identity.prototype.invert = function (value) {
32492 var range = this.range;
32493 if (value < range[0] || value > range[1]) {
32494 return NaN;
32495 }
32496 return this.values[0];
32497 };
32498 return Identity;
32499 }(Scale);
32500
32501 // cat平均算法,保头保尾
32502 var CatTick = (function (cfg) {
32503 var values = cfg.values,
32504 tickCount = cfg.tickCount;
32505 if (!tickCount) {
32506 return values;
32507 }
32508 if (values.length <= 1) {
32509 return values;
32510 }
32511 // 获取间隔步长, 最小是1
32512 var step = Math.floor(values.length / (tickCount - 1)) || 1;
32513 var ticks = [];
32514 // 按间隔数取对应节点
32515 for (var index = 0; index < values.length; index = index + step) {
32516 ticks.push(values[index]);
32517 }
32518 var last = values[values.length - 1];
32519 // 如果最后一个tick不等于原数据的最后一个
32520 if (ticks[ticks.length - 1] !== last) {
32521 if (ticks.length >= tickCount) {
32522 // 如果当前的tick个数满足要求
32523 ticks[ticks.length - 1] = last;
32524 } else {
32525 // 不满足tickCount则直接加入最后一个
32526 ticks.push(last);
32527 }
32528 }
32529 return ticks;
32530 });
32531
32532 // 认为是nice的刻度
32533 var SNAP_COUNT_ARRAY = [1, 1.2, 1.5, 2, 2.2, 2.4, 2.5, 3, 4, 5, 6, 7.5, 8, 10];
32534 var DEFAULT_COUNT = 5; // 默认刻度值
32535 var LinearTick = (function (cfg) {
32536 var _a = cfg || {},
32537 tickCount = _a.tickCount,
32538 tickInterval = _a.tickInterval;
32539 var _b = cfg || {},
32540 min = _b.min,
32541 max = _b.max;
32542 min = isNaN(min) ? 0 : min;
32543 max = isNaN(max) ? 0 : max;
32544 var count = tickCount && tickCount >= 2 ? tickCount : DEFAULT_COUNT;
32545 // 计算interval, 优先取tickInterval
32546 var interval = tickInterval || getBestInterval({
32547 tickCount: count,
32548 max: max,
32549 min: min
32550 });
32551 // 通过interval计算最小tick
32552 var minTick = Math.floor(min / interval) * interval;
32553 // 如果指定了tickInterval, count 需要根据指定的tickInterval来算计
32554 if (tickInterval) {
32555 var intervalCount = Math.abs(Math.ceil((max - minTick) / tickInterval)) + 1;
32556 // tickCount 作为最小 count 处理
32557 count = Math.max(count, intervalCount);
32558 }
32559 var tickLength = 0;
32560 var fixedLength = getFixedLength(interval);
32561 if (min < 0 && max > 0 && count === 2) {
32562 return [toFixed(minTick, fixedLength), toFixed(Math.ceil(max / interval) * interval, fixedLength)];
32563 }
32564 var ticks = [];
32565 while (tickLength < count) {
32566 ticks.push(toFixed(minTick + tickLength * interval, fixedLength));
32567 tickLength++;
32568 }
32569 return ticks;
32570 });
32571 var DECIMAL_LENGTH = 12;
32572 function getFactor(number) {
32573 // 取正数
32574 number = Math.abs(number);
32575 var factor = 1;
32576 if (number === 0) {
32577 return factor;
32578 }
32579 // 小于1,逐渐放大
32580 if (number < 1) {
32581 var count = 0;
32582 while (number < 1) {
32583 factor = factor / 10;
32584 number = number * 10;
32585 count++;
32586 }
32587 // 浮点数计算出现问题
32588 if (factor.toString().length > DECIMAL_LENGTH) {
32589 factor = parseFloat(factor.toFixed(count));
32590 }
32591 return factor;
32592 }
32593 // 大于10逐渐缩小
32594 while (number > 10) {
32595 factor = factor * 10;
32596 number = number / 10;
32597 }
32598 return factor;
32599 }
32600 // 获取最佳匹配刻度
32601 function getBestInterval(_a) {
32602 var tickCount = _a.tickCount,
32603 min = _a.min,
32604 max = _a.max;
32605 // 如果最大最小相等,则直接按1处理
32606 if (min === max) {
32607 return 1 * getFactor(max);
32608 }
32609 // 1.计算平均刻度间隔
32610 var avgInterval = (max - min) / (tickCount - 1);
32611 // 2.数据标准归一化 映射到[1-10]区间
32612 var factor = getFactor(avgInterval);
32613 var calInterval = avgInterval / factor;
32614 var calMax = max / factor;
32615 var calMin = min / factor;
32616 // 根据平均值推算最逼近刻度值
32617 var similarityIndex = 0;
32618 for (var index = 0; index < SNAP_COUNT_ARRAY.length; index++) {
32619 var item = SNAP_COUNT_ARRAY[index];
32620 if (calInterval <= item) {
32621 similarityIndex = index;
32622 break;
32623 }
32624 }
32625 var similarityInterval = min < 0 && max > 0 && tickCount === 2 ? SNAP_COUNT_ARRAY[similarityIndex] : getInterval(similarityIndex, tickCount, calMin, calMax);
32626 // 小数点位数还原到数据的位数, 因为similarityIndex有可能是小数,所以需要保留similarityIndex自己的小数位数
32627 var fixedLength = getFixedLength(similarityInterval) + getFixedLength(factor);
32628 return toFixed(similarityInterval * factor, fixedLength);
32629 }
32630 function getInterval(startIndex, tickCount, min, max) {
32631 var verify = false;
32632 var interval = SNAP_COUNT_ARRAY[startIndex];
32633 // 刻度值校验,如果不满足,循环下去
32634 for (var i = startIndex; i < SNAP_COUNT_ARRAY.length; i++) {
32635 if (intervalIsVerify({
32636 interval: SNAP_COUNT_ARRAY[i],
32637 tickCount: tickCount,
32638 max: max,
32639 min: min
32640 })) {
32641 // 有符合条件的interval
32642 interval = SNAP_COUNT_ARRAY[i];
32643 verify = true;
32644 break;
32645 }
32646 }
32647 // 如果不满足, 依次缩小10倍,再计算
32648 if (!verify) {
32649 return 10 * getInterval(0, tickCount, min / 10, max / 10);
32650 }
32651 return interval;
32652 }
32653 // 刻度是否满足展示需求
32654 function intervalIsVerify(_a) {
32655 var interval = _a.interval,
32656 tickCount = _a.tickCount,
32657 max = _a.max,
32658 min = _a.min;
32659 var minTick = Math.floor(min / interval) * interval;
32660 if (minTick + (tickCount - 1) * interval >= max) {
32661 return true;
32662 }
32663 return false;
32664 }
32665 // 计算小数点应该保留的位数
32666 function getFixedLength(num) {
32667 var str = num.toString();
32668 var index = str.indexOf('.');
32669 var indexOfExp = str.indexOf('e-');
32670 var length = indexOfExp >= 0 ? parseInt(str.substr(indexOfExp + 2), 10) : str.substr(index + 1).length;
32671 if (length > 20) {
32672 // 最多保留20位小数
32673 length = 20;
32674 }
32675 return length;
32676 }
32677 // @antv/util fixedbase不支持科学计数法的判断,需要提mr
32678 function toFixed(v, length) {
32679 return parseFloat(v.toFixed(length));
32680 }
32681
32682 registerClass('cat', Category);
32683 registerClass('category', Category);
32684 registerClass('identity', Identity);
32685 registerClass('linear', Linear);
32686 registerClass('log', Log);
32687 registerClass('pow', Pow);
32688 registerClass('time', Time);
32689 registerClass('timeCat', TimeCat);
32690 registerClass('quantize', Quantize);
32691 registerClass('quantile', Quantile);
32692 // 覆盖0.3.x的 cat 方法
32693 registerTickMethod('cat', CatTick);
32694 registerTickMethod('time-cat', CatTick);
32695 // 覆盖linear 度量的tick算法
32696 registerTickMethod('wilkinson-extended', LinearTick);
32697 var ScaleController = /** @class */function () {
32698 function ScaleController(data) {
32699 this.data = data;
32700 this.options = {};
32701 this.scales = {};
32702 }
32703 ScaleController.prototype._getType = function (option) {
32704 var type = option.type,
32705 values = option.values,
32706 field = option.field;
32707 if (type) {
32708 return type;
32709 }
32710 if (isNumber(field) || isNil(values[0]) && field) {
32711 return 'identity';
32712 }
32713 if (typeof values[0] === 'number') {
32714 return 'linear';
32715 }
32716 return 'cat';
32717 };
32718 ScaleController.prototype._getOption = function (option) {
32719 var values = option.values,
32720 field = option.field,
32721 justifyContent = option.justifyContent;
32722 var type = this._getType(option);
32723 option.type = type;
32724 // identity
32725 if (type === 'identity') {
32726 option.field = field.toString();
32727 option.values = [field];
32728 return option;
32729 }
32730 // linear 类型
32731 if (type === 'linear') {
32732 // 设置默认nice
32733 if (typeof option.nice !== 'boolean') {
32734 option.nice = true;
32735 }
32736 // 重置最大最小
32737 var _a = getRange(values),
32738 min = _a.min,
32739 max = _a.max;
32740 if (isNil(option.min)) {
32741 option.min = min;
32742 }
32743 if (isNil(option.max)) {
32744 option.max = max;
32745 }
32746 option.values = values.sort(function (a, b) {
32747 return a - b;
32748 });
32749 return option;
32750 }
32751 // 分类类型和 timeCat 类型,调整 range
32752 if (type === 'cat' || type === 'timeCat') {
32753 if (option.range) {
32754 return option;
32755 }
32756 var count = values.length;
32757 var range = [0, 1];
32758 // 如果只有一项,显示在中间
32759 if (count === 1) {
32760 range = [0.5, 1];
32761 } else if (justifyContent) {
32762 // 居中
32763 var offset = 1 / count * 0.5;
32764 range = [offset, 1 - offset];
32765 } else {
32766 // 最后留 1 / count
32767 var offset = 1 / count;
32768 range = [0, 1 - offset];
32769 }
32770 option.range = range;
32771 }
32772 return option;
32773 };
32774 ScaleController.prototype.createScale = function (option) {
32775 var type = option.type;
32776 if (isFunction(type)) {
32777 return new type(option);
32778 }
32779 var ScaleClass = getClass(type);
32780 return new ScaleClass(option);
32781 };
32782 // 更新或创建scale
32783 ScaleController.prototype.setScale = function (field, option) {
32784 var _a = this,
32785 options = _a.options,
32786 scales = _a.scales;
32787 options[field] = mix({}, options[field], option);
32788 // 如果scale有更新,scale 也需要重新创建
32789 if (scales[field]) {
32790 scales[field].change(options[field]);
32791 // delete scales[field];
32792 }
32793 };
32794 ScaleController.prototype.create = function (options) {
32795 this.update(options);
32796 };
32797 ScaleController.prototype.update = function (options) {
32798 var _this = this;
32799 if (!options) return;
32800 each(options, function (option, field) {
32801 _this.setScale(field, option);
32802 });
32803 };
32804 ScaleController.prototype.changeData = function (data) {
32805 this.data = data;
32806 this.scales = {};
32807 };
32808 ScaleController.prototype.getData = function () {
32809 return this.data;
32810 };
32811 ScaleController.prototype.getScale = function (field) {
32812 var _a = this,
32813 scales = _a.scales,
32814 options = _a.options,
32815 data = _a.data;
32816 var scale = scales[field];
32817 if (scale) {
32818 // for adjust=dodge, 需要更新 range
32819 var option_1 = this._getOption(__assign(__assign({}, options[field]), {
32820 values: scale.values
32821 }));
32822 if (option_1.range) {
32823 scale.range = option_1.range;
32824 }
32825 return scale;
32826 }
32827 var option = options[field];
32828 if (!option) {
32829 return null;
32830 }
32831 var values = option.values ? option.values : data ? valuesOfKey(data, field) : [];
32832 var scaleOption = this._getOption(__assign(__assign({}, option), {
32833 field: field,
32834 values: values
32835 }));
32836 var newScale = this.createScale(scaleOption);
32837 scales[field] = newScale;
32838 return newScale;
32839 };
32840 ScaleController.prototype.getScales = function () {
32841 var _this = this;
32842 var _a = this,
32843 options = _a.options,
32844 scales = _a.scales;
32845 each(options, function (option, field) {
32846 _this.getScale(field);
32847 });
32848 return scales;
32849 };
32850 ScaleController.prototype.getOptions = function () {
32851 var scales = this.scales;
32852 var options = {};
32853 each(scales, function (scale, field) {
32854 options[field] = __assign({}, scale.__cfg__);
32855 });
32856 return options;
32857 };
32858 ScaleController.prototype.adjustStartZero = function (scale) {
32859 var options = this.options;
32860 var field = scale.field,
32861 min = scale.min,
32862 max = scale.max;
32863 var option = options[field];
32864 // 如果有定义,则不处理
32865 if (option && option.min) {
32866 return;
32867 }
32868 if (min > 0) {
32869 scale.change({
32870 min: 0
32871 });
32872 } else if (max < 0) {
32873 scale.change({
32874 max: 0
32875 });
32876 }
32877 };
32878 // 饼图下的scale调整
32879 ScaleController.prototype.adjustPieScale = function (scale) {
32880 var options = this.options;
32881 var field = scale.field;
32882 var option = options[field];
32883 if (option && !isNil(option.nice)) {
32884 return null;
32885 }
32886 scale.change({
32887 nice: false
32888 });
32889 };
32890 //堆叠下的scale调整
32891 ScaleController.prototype._updateStackRange = function (scale, flattenArray) {
32892 var options = this.options;
32893 var field = scale.field;
32894 var option = options[field];
32895 var dataMin = Infinity;
32896 var dataMax = -Infinity;
32897 for (var i = 0, len = flattenArray.length; i < len; i++) {
32898 var obj = flattenArray[i];
32899 var tmpMin = Math.min.apply(null, obj[field]);
32900 var tmpMax = Math.max.apply(null, obj[field]);
32901 if (tmpMin < dataMin) {
32902 dataMin = tmpMin;
32903 }
32904 if (tmpMax > dataMax) {
32905 dataMax = tmpMax;
32906 }
32907 }
32908 // 如果有定义,则优先级更高
32909 var min = (option === null || option === void 0 ? void 0 : option.min) || dataMin;
32910 var max = (option === null || option === void 0 ? void 0 : option.max) || dataMax;
32911 if (min !== scale.min || max !== scale.max) {
32912 scale.change({
32913 min: min,
32914 max: max
32915 });
32916 }
32917 };
32918 // 获取scale 在 0点对位置的值
32919 ScaleController.prototype.getZeroValue = function (scale) {
32920 var min = scale.min,
32921 max = scale.max;
32922 var value;
32923 if (min >= 0) {
32924 value = min;
32925 } else if (max <= 0) {
32926 value = max;
32927 } else {
32928 value = 0;
32929 }
32930 return scale.scale(value);
32931 };
32932 return ScaleController;
32933 }();
32934
32935 var axis = {
32936 labelOffset: '15px',
32937 line: {
32938 stroke: '#E8E8E8',
32939 lineWidth: '1px'
32940 },
32941 symbol: {
32942 fill: '#E8E8E8',
32943 radius: '10px'
32944 },
32945 tickLine: {
32946 stroke: '#E8E8E8'
32947 },
32948 label: {
32949 fill: '#808080',
32950 fontSize: '20px'
32951 },
32952 grid: {
32953 stroke: '#E8E8E8',
32954 lineWidth: '1px',
32955 lineDash: ['4px']
32956 }
32957 };
32958 var guide = {
32959 line: {
32960 style: {
32961 stroke: '#a3a3a3',
32962 lineWidth: 1
32963 },
32964 offsetX: 0,
32965 offsetY: 0
32966 },
32967 text: {
32968 style: {
32969 fill: '#787878',
32970 // textAlign: 'center',
32971 textBaseline: 'middle'
32972 },
32973 offsetX: 0,
32974 offsetY: 0
32975 },
32976 rect: {
32977 style: {
32978 fill: '#fafafa'
32979 }
32980 },
32981 arc: {
32982 style: {
32983 stroke: '#a3a3a3'
32984 }
32985 },
32986 html: {
32987 offsetX: 0,
32988 offsetY: 0,
32989 alignX: 'center',
32990 alignY: 'middle'
32991 },
32992 tag: {
32993 offsetX: 0,
32994 offsetY: 0,
32995 side: 4,
32996 background: {
32997 padding: 5,
32998 radius: 2,
32999 fill: '#1890FF'
33000 },
33001 textStyle: {
33002 fontSize: 12,
33003 fill: '#fff',
33004 textAlign: 'center',
33005 textBaseline: 'middle'
33006 }
33007 },
33008 point: {
33009 offsetX: 0,
33010 offsetY: 0,
33011 style: {
33012 fill: '#fff',
33013 r: 3,
33014 lineWidth: 2,
33015 stroke: '#1890ff'
33016 }
33017 },
33018 polyline: {
33019 style: {
33020 lineWidth: '4px',
33021 lineJoin: 'round',
33022 lineCap: 'round'
33023 },
33024 offsetX: 0,
33025 offsetY: 0
33026 }
33027 };
33028 var chart = {
33029 padding: ['30px', '30px', '30px', '30px']
33030 };
33031 var Theme = {
33032 chart: chart,
33033 colors: ['#1890FF', '#2FC25B', '#FACC14', '#223273', '#8543E0', '#13C2C2', '#3436C7', '#F04864'],
33034 shapes: {
33035 line: ['line', 'dash', 'smooth'],
33036 point: ['circle', 'hollowCircle', 'rect'],
33037 area: ['area', 'smooth'],
33038 interval: ['rect', 'pyramid', 'funnel']
33039 },
33040 sizes: ['4px', '6px', '8px', '10px', '12px'],
33041 shape: {
33042 line: {
33043 default: {
33044 lineWidth: '4px',
33045 lineJoin: 'round',
33046 lineCap: 'round'
33047 },
33048 smooth: {
33049 smooth: true
33050 },
33051 'step-start': {
33052 step: 'start'
33053 },
33054 'step-middle': {
33055 step: 'middle'
33056 },
33057 'step-end': {
33058 step: 'end'
33059 },
33060 dash: {
33061 lineDash: ['8px', '8px']
33062 }
33063 },
33064 point: {
33065 default: {
33066 size: '6px'
33067 },
33068 hollowCircle: {
33069 lineWidth: '2px'
33070 }
33071 },
33072 area: {
33073 default: {
33074 fillOpacity: 0.1
33075 }
33076 },
33077 interval: {
33078 default: {}
33079 }
33080 },
33081 axis: axis,
33082 guide: guide
33083 };
33084
33085 // 统计图表
33086 var Chart = /** @class */function (_super) {
33087 __extends(Chart, _super);
33088 function Chart(props, context) {
33089 var _this = _super.call(this, props) || this;
33090 // 坐标系
33091 _this.componentsPosition = [];
33092 var theme = context.theme,
33093 px2hd = context.px2hd;
33094 // hack 处理,设置默认的主题样式
33095 // 目前没想到其他更合适的方式,只能先这样处理
33096 context.theme = deepMix(px2hd(Theme), theme);
33097 var data = props.data;
33098 _this.scale = new ScaleController(data);
33099 _this.coord = new coordController();
33100 _this.coordRef = createRef();
33101 // state
33102 _this.state = {
33103 filters: {}
33104 };
33105 return _this;
33106 }
33107 Chart.prototype.getStyle = function (props) {
33108 var _a = this,
33109 context = _a.context,
33110 layout = _a.layout;
33111 var theme = context.theme,
33112 px2hd = context.px2hd;
33113 var left = layout.left,
33114 top = layout.top,
33115 width = layout.width,
33116 height = layout.height;
33117 var customStyle = props.style;
33118 return px2hd(__assign(__assign({
33119 left: left,
33120 top: top,
33121 width: width,
33122 height: height
33123 }, theme.chart), customStyle));
33124 };
33125 Chart.prototype.willMount = function () {
33126 var _a = this,
33127 props = _a.props,
33128 coord = _a.coord,
33129 scale = _a.scale;
33130 var scaleOptions = props.scale,
33131 coordOption = props.coord;
33132 this.resetCoordLayout();
33133 // 初始化 scale
33134 scale.create(scaleOptions);
33135 // 初始化 coord
33136 coord.create(coordOption);
33137 };
33138 // props 更新
33139 Chart.prototype.willReceiveProps = function (nextProps, context) {
33140 var _a = this,
33141 scale = _a.scale,
33142 coord = _a.coord,
33143 lastProps = _a.props;
33144 var nextStyle = nextProps.style,
33145 nextData = nextProps.data,
33146 nextScale = nextProps.scale;
33147 var lastStyle = lastProps.style,
33148 lastData = lastProps.data,
33149 lastScale = lastProps.scale;
33150 // style 更新
33151 if (!equal(nextStyle, lastStyle) || context !== this.context) {
33152 var style = this.getStyle(nextProps);
33153 coord.updateLayout(style);
33154 }
33155 if (nextData !== lastData) {
33156 scale.changeData(nextData);
33157 }
33158 // scale
33159 if (!equal(nextScale, lastScale)) {
33160 scale.update(nextScale);
33161 }
33162 };
33163 Chart.prototype.willUpdate = function () {
33164 this.coord.create(this.props.coord);
33165 };
33166 Chart.prototype.on = function (eventName, listener) {
33167 var roolEl = this.coordRef.current;
33168 if (!roolEl || !roolEl.gesture) return;
33169 var gesture = roolEl.gesture;
33170 gesture.on(eventName, listener);
33171 };
33172 Chart.prototype.off = function (eventName, listener) {
33173 var roolEl = this.coordRef.current;
33174 if (!roolEl || !roolEl.gesture) return;
33175 var gesture = roolEl.gesture;
33176 gesture.off(eventName, listener);
33177 };
33178 // 给需要显示的组件留空
33179 Chart.prototype.layoutCoord = function (layout) {
33180 this.coord.useLayout(layout);
33181 };
33182 Chart.prototype.resetCoordLayout = function () {
33183 var _a = this,
33184 coord = _a.coord,
33185 props = _a.props;
33186 var style = this.getStyle(props);
33187 coord.updateLayout(style);
33188 };
33189 Chart.prototype.updateCoordLayout = function (layout) {
33190 var _this = this;
33191 if (isArray(layout)) {
33192 layout.forEach(function (item) {
33193 _this.layoutCoord(item);
33194 });
33195 return;
33196 }
33197 this.layoutCoord(layout);
33198 };
33199 Chart.prototype.updateCoordFor = function (component, layout) {
33200 var _this = this;
33201 if (!layout) return;
33202 var componentsPosition = this.componentsPosition;
33203 var componentPosition = {
33204 component: component,
33205 layout: layout
33206 };
33207 var existIndex = findIndex(componentsPosition, function (item) {
33208 return item.component === component;
33209 });
33210 // 说明是已经存在的组件
33211 if (existIndex > -1) {
33212 componentsPosition.splice(existIndex, 1, componentPosition);
33213 // 先重置,然后整体重新算一次
33214 this.resetCoordLayout();
33215 // 再整体计算前,需要去掉已经销毁的组件
33216 this.removeComponentsPositionCache();
33217 componentsPosition.forEach(function (componentPosition) {
33218 var layout = componentPosition.layout;
33219 _this.updateCoordLayout(layout);
33220 });
33221 return;
33222 }
33223 // 是新组件,直接添加
33224 componentsPosition.push(componentPosition);
33225 this.updateCoordLayout(layout);
33226 };
33227 Chart.prototype.removeComponentsPositionCache = function () {
33228 var _a;
33229 if (!((_a = this.componentsPosition) === null || _a === void 0 ? void 0 : _a.length)) return;
33230 for (var i = this.componentsPosition.length; i > -1; i--) {
33231 var item = this.componentsPosition[i];
33232 if (item && item.component && item.component.destroyed) {
33233 this.componentsPosition.splice(i, 1);
33234 }
33235 }
33236 };
33237 Chart.prototype.getGeometrys = function () {
33238 // @ts-ignore
33239 var children = this.children.children;
33240 var geometrys = [];
33241 Children.toArray(children).forEach(function (element) {
33242 if (!element) return false;
33243 var component = element.component;
33244 // @ts-ignore
33245 if (component && component.isGeometry) {
33246 geometrys.push(component);
33247 }
33248 });
33249 return geometrys;
33250 };
33251 /**
33252 * calculate dataset's position on canvas
33253 * @param {Object} record the dataset
33254 * @return {Object} return the position
33255 */
33256 Chart.prototype.getPosition = function (record) {
33257 var coord = this.getCoord();
33258 var xScale = this.getXScales()[0];
33259 var xField = xScale.field;
33260 var yScales = this.getYScales();
33261 // default first
33262 var yScale = yScales[0];
33263 var yField = yScale.field;
33264 for (var i = 0, len = yScales.length; i < len; i++) {
33265 var scale = yScales[i];
33266 var field = scale.field;
33267 if (record[field]) {
33268 yScale = scale;
33269 yField = field;
33270 break;
33271 }
33272 }
33273 var x = xScale.scale(record[xField]);
33274 var y = yScale.scale(record[yField]);
33275 return coord.convertPoint({
33276 x: x,
33277 y: y
33278 });
33279 };
33280 Chart.prototype.getSnapRecords = function (point, inCoordRange) {
33281 var geometrys = this.getGeometrys();
33282 if (!geometrys.length) return;
33283 // @ts-ignore
33284 return geometrys[0].getSnapRecords(point, inCoordRange);
33285 };
33286 Chart.prototype.getRecords = function (data, field) {
33287 var geometrys = this.getGeometrys();
33288 if (!geometrys.length) return;
33289 // @ts-ignore
33290 return geometrys[0].getRecords(data, field);
33291 };
33292 Chart.prototype.getLegendItems = function (point) {
33293 var geometrys = this.getGeometrys();
33294 if (!geometrys.length) return;
33295 // @ts-ignore
33296 return geometrys[0].getLegendItems(point);
33297 };
33298 Chart.prototype.setScale = function (field, option) {
33299 this.scale.setScale(field, option);
33300 };
33301 Chart.prototype.getScale = function (field) {
33302 return this.scale.getScale(field);
33303 };
33304 Chart.prototype.getScales = function () {
33305 return this.scale.getScales();
33306 };
33307 Chart.prototype.getXScales = function () {
33308 var geometrys = this.getGeometrys();
33309 return geometrys.map(function (component) {
33310 // @ts-ignore
33311 return component.getXScale();
33312 });
33313 };
33314 Chart.prototype.getYScales = function () {
33315 var geometrys = this.getGeometrys();
33316 return geometrys.map(function (component) {
33317 // @ts-ignore
33318 return component.getYScale();
33319 });
33320 };
33321 Chart.prototype.getLayout = function () {
33322 return this.coord.layout;
33323 };
33324 Chart.prototype.getCoord = function () {
33325 return this.coord.coord;
33326 };
33327 Chart.prototype.filter = function (field, condition) {
33328 var _a;
33329 var filters = this.state.filters;
33330 this.setState({
33331 filters: __assign(__assign({}, filters), (_a = {}, _a[field] = condition, _a))
33332 });
33333 };
33334 Chart.prototype._getRenderData = function () {
33335 var _a = this,
33336 props = _a.props,
33337 state = _a.state;
33338 var data = props.data;
33339 var filters = state.filters;
33340 if (!filters || !Object.keys(filters).length) {
33341 return data;
33342 }
33343 var filteredData = data;
33344 each(filters, function (condition, field) {
33345 if (!condition) return;
33346 filteredData = filteredData.filter(function (record) {
33347 return condition(record[field], record);
33348 });
33349 });
33350 return filteredData;
33351 };
33352 Chart.prototype.render = function () {
33353 var _this = this;
33354 var _a = this,
33355 props = _a.props,
33356 scale = _a.scale,
33357 chartLayout = _a.layout;
33358 var children = props.children,
33359 originData = props.data;
33360 if (!originData) return null;
33361 var data = this._getRenderData();
33362 var layout = this.getLayout();
33363 var coord = this.getCoord();
33364 var scaleOptions = scale.getOptions();
33365 var width = chartLayout.width,
33366 height = chartLayout.height;
33367 return jsx("group", {
33368 ref: this.coordRef,
33369 style: {
33370 width: width,
33371 height: height,
33372 fill: 'transparent'
33373 }
33374 }, Children.map(children, function (child) {
33375 return Children.cloneElement(child, {
33376 data: data,
33377 chart: _this,
33378 layout: layout,
33379 coord: coord,
33380 // 传 scaleOptions 是为了让 child 感知到 props 的的变化,合理的做法的应该是传递 scale,但是现在无法感知到 scale 的变化, 所以暂时只能先这么处理,scaleOptions 子组件目前是使用不到的。
33381 scaleOptions: scaleOptions
33382 });
33383 }));
33384 };
33385 return Chart;
33386 }(Component);
33387
33388 function isEqual$1(origin1, origin2, fields) {
33389 if (origin1 === origin2) {
33390 return true;
33391 }
33392 for (var i = 0, len = fields.length; i < len; i++) {
33393 var field = fields[i];
33394 if (origin1[field] !== origin2[field]) {
33395 return false;
33396 }
33397 }
33398 return true;
33399 }
33400 var Selection = /** @class */function (_super) {
33401 __extends(Selection, _super);
33402 function Selection(props, context) {
33403 var _this = _super.call(this, props, context) || this;
33404 var selection = props.selection;
33405 if (!selection) return _this;
33406 var defaultSelected = selection.defaultSelected;
33407 _this.state.selected = defaultSelected;
33408 return _this;
33409 }
33410 Selection.prototype.didMount = function () {
33411 var _this = this;
33412 var _a = this,
33413 props = _a.props,
33414 state = _a.state;
33415 var selection = props.selection,
33416 chart = props.chart;
33417 if (!selection) return;
33418 // 默认为 click
33419 var _b = selection.triggerOn,
33420 triggerOn = _b === void 0 ? 'click' : _b,
33421 onChange = selection.onChange;
33422 chart.on(triggerOn, function (ev) {
33423 var points = ev.points,
33424 x = ev.canvasX,
33425 y = ev.canvasY;
33426 var point = triggerOn === 'click' ? {
33427 x: x,
33428 y: y
33429 } : points[0];
33430 var records = _this.getSnapRecords(point);
33431 var _a = selection.type,
33432 type = _a === void 0 ? 'single' : _a,
33433 _b = selection.cancelable,
33434 cancelable = _b === void 0 ? true : _b;
33435 if (!records || !records.length) {
33436 if (cancelable) {
33437 onChange && onChange({
33438 selected: null
33439 });
33440 _this.setState({
33441 selected: null
33442 });
33443 }
33444 return;
33445 }
33446 var selected = state.selected;
33447 var origins = records.map(function (record) {
33448 return record.origin;
33449 });
33450 if (!selected || !selected.length) {
33451 onChange && onChange({
33452 selected: origins
33453 });
33454 _this.setState({
33455 selected: origins
33456 });
33457 }
33458 if (type === 'single') {
33459 if (!cancelable) {
33460 onChange && onChange({
33461 selected: origins
33462 });
33463 _this.setState({
33464 selected: origins
33465 });
33466 return;
33467 }
33468 var newSelected_1 = [];
33469 records.forEach(function (record) {
33470 if (!_this.isSelected(record)) {
33471 newSelected_1.push(record.origin);
33472 }
33473 });
33474 onChange && onChange({
33475 selected: newSelected_1
33476 });
33477 _this.setState({
33478 selected: newSelected_1
33479 });
33480 return;
33481 }
33482 // 多选
33483 var scales = chart.getScales();
33484 var fields = Object.keys(scales);
33485 var selectedMap = {};
33486 selected.forEach(function (item) {
33487 var key = fields.map(function (field) {
33488 return item[field];
33489 }).join('-');
33490 selectedMap[key] = item;
33491 });
33492 records.forEach(function (record) {
33493 var origin = record.origin;
33494 var key = fields.map(function (field) {
33495 return origin[field];
33496 }).join('-');
33497 selectedMap[key] = selectedMap[key] ? null : origin;
33498 });
33499 var newSelected = Object.keys(selectedMap).map(function (key) {
33500 return selectedMap[key];
33501 }).filter(Boolean);
33502 onChange && onChange({
33503 selected: newSelected
33504 });
33505 _this.setState({
33506 selected: newSelected
33507 });
33508 });
33509 };
33510 Selection.prototype.willReceiveProps = function (nextProps) {
33511 var nextSelection = nextProps.selection;
33512 var lastSelection = this.props.selection;
33513 if (!nextSelection || !lastSelection) {
33514 return;
33515 }
33516 var nextDefaultSelected = nextSelection.defaultSelected;
33517 var lastDefaultSelected = lastSelection.defaultSelected;
33518 if (!equal(nextDefaultSelected, lastDefaultSelected)) {
33519 this.state.selected = nextDefaultSelected;
33520 }
33521 };
33522 Selection.prototype.getSnapRecords = function (_point) {
33523 return null;
33524 };
33525 Selection.prototype.isSelected = function (record) {
33526 var _a = this,
33527 state = _a.state,
33528 props = _a.props;
33529 var selected = state.selected;
33530 if (!selected || !selected.length) {
33531 return false;
33532 }
33533 var chart = props.chart;
33534 var scales = chart.getScales();
33535 var fields = Object.keys(scales);
33536 for (var i = 0, len = selected.length; i < len; i++) {
33537 var item = selected[i];
33538 if (isEqual$1(record.origin, item, fields)) {
33539 return true;
33540 }
33541 }
33542 return false;
33543 };
33544 Selection.prototype.getSelectionStyle = function (record) {
33545 var _a = this,
33546 state = _a.state,
33547 props = _a.props;
33548 var selected = state.selected;
33549 if (!selected || !selected.length) {
33550 return null;
33551 }
33552 var selection = props.selection;
33553 var selectedStyle = selection.selectedStyle,
33554 unSelectedStyle = selection.unSelectedStyle;
33555 var isSelected = this.isSelected(record);
33556 if (isSelected) {
33557 return isFunction(selectedStyle) ? selectedStyle(record) : selectedStyle;
33558 }
33559 return isFunction(unSelectedStyle) ? unSelectedStyle(record) : unSelectedStyle;
33560 };
33561 return Selection;
33562 }(Component);
33563
33564 var DEFAULT_Y = 0; // 默认的 y 的值
33565 // 偏移之后,间距
33566 var MARGIN_RATIO = 1 / 2;
33567 var DODGE_RATIO = 1 / 2;
33568 // 散点分开之后,距离边界的距离
33569 var GAP = 0.05;
33570
33571 var Adjust = /** @class */function () {
33572 function Adjust(cfg) {
33573 var xField = cfg.xField,
33574 yField = cfg.yField,
33575 _a = cfg.adjustNames,
33576 adjustNames = _a === void 0 ? ['x', 'y'] : _a,
33577 dimValuesMap = cfg.dimValuesMap;
33578 this.adjustNames = adjustNames;
33579 this.xField = xField;
33580 this.yField = yField;
33581 this.dimValuesMap = dimValuesMap;
33582 }
33583 /**
33584 * 查看维度是否是 adjust 字段
33585 * @param dim
33586 */
33587 Adjust.prototype.isAdjust = function (dim) {
33588 return this.adjustNames.indexOf(dim) >= 0;
33589 };
33590 Adjust.prototype.getAdjustRange = function (dim, dimValue, values) {
33591 var yField = this.yField;
33592 var index = values.indexOf(dimValue);
33593 var length = values.length;
33594 var pre;
33595 var next;
33596 // 没有 y 字段,但是需要根据 y 调整
33597 if (!yField && this.isAdjust('y')) {
33598 pre = 0;
33599 next = 1;
33600 } else if (length > 1) {
33601 // 如果以其开头,则取之,否则取他前面一个
33602 pre = values[index === 0 ? 0 : index - 1];
33603 // 如果以其结尾,则取之,否则取他后面一个
33604 next = values[index === length - 1 ? length - 1 : index + 1];
33605 if (index !== 0) {
33606 pre += (dimValue - pre) / 2;
33607 } else {
33608 pre -= (next - dimValue) / 2;
33609 }
33610 if (index !== length - 1) {
33611 next -= (next - dimValue) / 2;
33612 } else {
33613 next += (dimValue - values[length - 2]) / 2;
33614 }
33615 } else {
33616 pre = dimValue === 0 ? 0 : dimValue - 0.5;
33617 next = dimValue === 0 ? 1 : dimValue + 0.5;
33618 }
33619 return {
33620 pre: pre,
33621 next: next
33622 };
33623 };
33624 Adjust.prototype.adjustData = function (groupedDataArray, mergedData) {
33625 var _this = this;
33626 // 所有调整维度的值数组
33627 var dimValuesMap = this.getDimValues(mergedData);
33628 // 按照每一个分组来进行调整
33629 each(groupedDataArray, function (dataArray, index) {
33630 // 遍历所有数据集合
33631 // 每个分组中,分别按照不同的 dim 进行调整
33632 each(dimValuesMap, function (values, dim) {
33633 // 根据不同的度量分别调整位置
33634 _this.adjustDim(dim, values, dataArray, index);
33635 });
33636 });
33637 };
33638 /**
33639 * 对数据进行分组adjustData
33640 * @param data 数据
33641 * @param dim 分组的字段
33642 * @return 分组结果
33643 */
33644 Adjust.prototype.groupData = function (data, dim) {
33645 // 补齐数据空数据为默认值
33646 each(data, function (record) {
33647 if (record[dim] === undefined) {
33648 record[dim] = DEFAULT_Y;
33649 }
33650 });
33651 // 按照 dim 维度分组
33652 return groupBy(data, dim);
33653 };
33654 /** @override */
33655 Adjust.prototype.adjustDim = function (_dim, _values, _data, _index) {};
33656 /**
33657 * 获取可调整度量对应的值
33658 * @param mergedData 数据
33659 * @return 值的映射
33660 */
33661 Adjust.prototype.getDimValues = function (mergedData) {
33662 var _a = this,
33663 xField = _a.xField,
33664 yField = _a.yField;
33665 var dimValuesMap = mix({}, this.dimValuesMap);
33666 // 所有的维度
33667 var dims = [];
33668 if (xField && this.isAdjust('x')) {
33669 dims.push(xField);
33670 }
33671 if (yField && this.isAdjust('y')) {
33672 dims.push(yField);
33673 }
33674 dims.forEach(function (dim) {
33675 if (dimValuesMap && dimValuesMap[dim]) {
33676 return;
33677 }
33678 // 在每个维度上,所有的值
33679 dimValuesMap[dim] = valuesOfKey(mergedData, dim).sort(function (v1, v2) {
33680 return v1 - v2;
33681 }).filter(function (v) {
33682 return !isNaN(v);
33683 });
33684 });
33685 // 只有一维的情况下,同时调整 y,赋予默认值
33686 if (!yField && this.isAdjust('y')) {
33687 var dim = 'y';
33688 dimValuesMap[dim] = [DEFAULT_Y, 1]; // 默认分布在 y 轴的 0 与 1 之间
33689 }
33690 return dimValuesMap;
33691 };
33692 return Adjust;
33693 }();
33694
33695 var Dodge = /** @class */function (_super) {
33696 __extends(Dodge, _super);
33697 function Dodge(cfg) {
33698 var _this = _super.call(this, cfg) || this;
33699 _this.cacheMap = {};
33700 _this.adjustDataArray = [];
33701 _this.mergeData = [];
33702 var _a = cfg.marginRatio,
33703 marginRatio = _a === void 0 ? MARGIN_RATIO : _a,
33704 _b = cfg.dodgeRatio,
33705 dodgeRatio = _b === void 0 ? DODGE_RATIO : _b,
33706 dodgeBy = cfg.dodgeBy,
33707 intervalPadding = cfg.intervalPadding,
33708 dodgePadding = cfg.dodgePadding,
33709 xDimensionLength = cfg.xDimensionLength,
33710 groupNum = cfg.groupNum,
33711 defaultSize = cfg.defaultSize,
33712 maxColumnWidth = cfg.maxColumnWidth,
33713 minColumnWidth = cfg.minColumnWidth,
33714 columnWidthRatio = cfg.columnWidthRatio,
33715 customOffset = cfg.customOffset;
33716 _this.marginRatio = marginRatio;
33717 _this.dodgeRatio = dodgeRatio;
33718 _this.dodgeBy = dodgeBy;
33719 _this.intervalPadding = intervalPadding;
33720 _this.dodgePadding = dodgePadding;
33721 _this.xDimensionLegenth = xDimensionLength;
33722 _this.groupNum = groupNum;
33723 _this.defaultSize = defaultSize;
33724 _this.maxColumnWidth = maxColumnWidth;
33725 _this.minColumnWidth = minColumnWidth;
33726 _this.columnWidthRatio = columnWidthRatio;
33727 _this.customOffset = customOffset;
33728 return _this;
33729 }
33730 Dodge.prototype.process = function (groupDataArray) {
33731 var groupedDataArray = clone(groupDataArray);
33732 // 将数据数组展开一层
33733 var mergeData = flatten(groupedDataArray);
33734 var dodgeBy = this.dodgeBy;
33735 // 如果指定了分组 dim 的字段
33736 var adjustDataArray = dodgeBy ? group(mergeData, dodgeBy) : groupedDataArray;
33737 this.cacheMap = {};
33738 this.adjustDataArray = adjustDataArray;
33739 this.mergeData = mergeData;
33740 this.adjustData(adjustDataArray, mergeData);
33741 this.adjustDataArray = [];
33742 this.mergeData = [];
33743 return groupedDataArray;
33744 };
33745 Dodge.prototype.adjustDim = function (dim, values, data, frameIndex) {
33746 var _this = this;
33747 var customOffset = this.customOffset;
33748 var map = this.getDistribution(dim);
33749 var groupData = this.groupData(data, dim); // 根据值分组
33750 each(groupData, function (group, key) {
33751 var range;
33752 // xField 中只有一个值,不需要做 dodge
33753 if (values.length === 1) {
33754 range = {
33755 pre: values[0] - 1,
33756 next: values[0] + 1
33757 };
33758 } else {
33759 // 如果有多个,则需要获取调整的范围
33760 range = _this.getAdjustRange(dim, parseFloat(key), values);
33761 }
33762 each(group, function (d) {
33763 var value = d[dim];
33764 var valueArr = map[value];
33765 var valIndex = valueArr.indexOf(frameIndex);
33766 if (!isNil(customOffset)) {
33767 var pre = range.pre,
33768 next = range.next;
33769 d[dim] = isFunction(customOffset) ? customOffset(d, range) : (pre + next) / 2 + customOffset;
33770 } else {
33771 d[dim] = _this.getDodgeOffset(range, valIndex, valueArr.length);
33772 }
33773 });
33774 });
33775 return [];
33776 };
33777 Dodge.prototype.getDodgeOffset = function (range, idx, len) {
33778 var _a = this,
33779 dodgeRatio = _a.dodgeRatio,
33780 marginRatio = _a.marginRatio,
33781 intervalPadding = _a.intervalPadding,
33782 dodgePadding = _a.dodgePadding;
33783 var pre = range.pre,
33784 next = range.next;
33785 var tickLength = next - pre;
33786 var position;
33787 // 分多种输入情况
33788 if (!isNil(intervalPadding) && isNil(dodgePadding) && intervalPadding >= 0) {
33789 // 仅配置intervalPadding
33790 var offset = this.getIntervalOnlyOffset(len, idx);
33791 position = pre + offset;
33792 } else if (!isNil(dodgePadding) && isNil(intervalPadding) && dodgePadding >= 0) {
33793 // 仅配置dodgePadding
33794 var offset = this.getDodgeOnlyOffset(len, idx);
33795 position = pre + offset;
33796 } else if (!isNil(intervalPadding) && !isNil(dodgePadding) && intervalPadding >= 0 && dodgePadding >= 0) {
33797 // 同时配置intervalPadding和dodgePadding
33798 var offset = this.getIntervalAndDodgeOffset(len, idx);
33799 position = pre + offset;
33800 } else {
33801 // 默认情况
33802 var width = tickLength * dodgeRatio / len;
33803 var margin = marginRatio * width;
33804 var offset = 1 / 2 * (tickLength - len * width - (len - 1) * margin) + ((idx + 1) * width + idx * margin) - 1 / 2 * width - 1 / 2 * tickLength;
33805 position = (pre + next) / 2 + offset;
33806 }
33807 return position;
33808 };
33809 Dodge.prototype.getIntervalOnlyOffset = function (len, idx) {
33810 var _a = this,
33811 defaultSize = _a.defaultSize,
33812 intervalPadding = _a.intervalPadding,
33813 xDimensionLegenth = _a.xDimensionLegenth,
33814 groupNum = _a.groupNum,
33815 dodgeRatio = _a.dodgeRatio,
33816 maxColumnWidth = _a.maxColumnWidth,
33817 minColumnWidth = _a.minColumnWidth,
33818 columnWidthRatio = _a.columnWidthRatio;
33819 var normalizedIntervalPadding = intervalPadding / xDimensionLegenth;
33820 var normalizedDodgePadding = (1 - (groupNum - 1) * normalizedIntervalPadding) / groupNum * dodgeRatio / (len - 1);
33821 var geomWidth = ((1 - normalizedIntervalPadding * (groupNum - 1)) / groupNum - normalizedDodgePadding * (len - 1)) / len;
33822 // 根据columnWidthRatio/defaultSize/maxColumnWidth/minColumnWidth调整宽度
33823 geomWidth = !isNil(columnWidthRatio) ? 1 / groupNum / len * columnWidthRatio : geomWidth;
33824 if (!isNil(maxColumnWidth)) {
33825 var normalizedMaxWidht = maxColumnWidth / xDimensionLegenth;
33826 geomWidth = Math.min(geomWidth, normalizedMaxWidht);
33827 }
33828 if (!isNil(minColumnWidth)) {
33829 var normalizedMinWidht = minColumnWidth / xDimensionLegenth;
33830 geomWidth = Math.max(geomWidth, normalizedMinWidht);
33831 }
33832 geomWidth = defaultSize ? defaultSize / xDimensionLegenth : geomWidth;
33833 // 调整组内间隔
33834 normalizedDodgePadding = ((1 - (groupNum - 1) * normalizedIntervalPadding) / groupNum - len * geomWidth) / (len - 1);
33835 var offset = ((1 / 2 + idx) * geomWidth + idx * normalizedDodgePadding + 1 / 2 * normalizedIntervalPadding) * groupNum - normalizedIntervalPadding / 2;
33836 return offset;
33837 };
33838 Dodge.prototype.getDodgeOnlyOffset = function (len, idx) {
33839 var _a = this,
33840 defaultSize = _a.defaultSize,
33841 dodgePadding = _a.dodgePadding,
33842 xDimensionLegenth = _a.xDimensionLegenth,
33843 groupNum = _a.groupNum,
33844 marginRatio = _a.marginRatio,
33845 maxColumnWidth = _a.maxColumnWidth,
33846 minColumnWidth = _a.minColumnWidth,
33847 columnWidthRatio = _a.columnWidthRatio;
33848 var normalizedDodgePadding = dodgePadding / xDimensionLegenth;
33849 var normalizedIntervalPadding = 1 * marginRatio / (groupNum - 1);
33850 var geomWidth = ((1 - normalizedIntervalPadding * (groupNum - 1)) / groupNum - normalizedDodgePadding * (len - 1)) / len;
33851 // 根据columnWidthRatio/defaultSize/maxColumnWidth/minColumnWidth调整宽度
33852 geomWidth = columnWidthRatio ? 1 / groupNum / len * columnWidthRatio : geomWidth;
33853 if (!isNil(maxColumnWidth)) {
33854 var normalizedMaxWidht = maxColumnWidth / xDimensionLegenth;
33855 geomWidth = Math.min(geomWidth, normalizedMaxWidht);
33856 }
33857 if (!isNil(minColumnWidth)) {
33858 var normalizedMinWidht = minColumnWidth / xDimensionLegenth;
33859 geomWidth = Math.max(geomWidth, normalizedMinWidht);
33860 }
33861 geomWidth = defaultSize ? defaultSize / xDimensionLegenth : geomWidth;
33862 // 调整组间距
33863 normalizedIntervalPadding = (1 - (geomWidth * len + normalizedDodgePadding * (len - 1)) * groupNum) / (groupNum - 1);
33864 var offset = ((1 / 2 + idx) * geomWidth + idx * normalizedDodgePadding + 1 / 2 * normalizedIntervalPadding) * groupNum - normalizedIntervalPadding / 2;
33865 return offset;
33866 };
33867 Dodge.prototype.getIntervalAndDodgeOffset = function (len, idx) {
33868 var _a = this,
33869 intervalPadding = _a.intervalPadding,
33870 dodgePadding = _a.dodgePadding,
33871 xDimensionLegenth = _a.xDimensionLegenth,
33872 groupNum = _a.groupNum;
33873 var normalizedIntervalPadding = intervalPadding / xDimensionLegenth;
33874 var normalizedDodgePadding = dodgePadding / xDimensionLegenth;
33875 var geomWidth = ((1 - normalizedIntervalPadding * (groupNum - 1)) / groupNum - normalizedDodgePadding * (len - 1)) / len;
33876 var offset = ((1 / 2 + idx) * geomWidth + idx * normalizedDodgePadding + 1 / 2 * normalizedIntervalPadding) * groupNum - normalizedIntervalPadding / 2;
33877 return offset;
33878 };
33879 Dodge.prototype.getDistribution = function (dim) {
33880 var groupedDataArray = this.adjustDataArray;
33881 var cacheMap = this.cacheMap;
33882 var map = cacheMap[dim];
33883 if (!map) {
33884 map = {};
33885 each(groupedDataArray, function (data, index) {
33886 var values = valuesOfKey(data, dim);
33887 if (!values.length) {
33888 values.push(0);
33889 }
33890 each(values, function (val) {
33891 if (!map[val]) {
33892 map[val] = [];
33893 }
33894 map[val].push(index);
33895 });
33896 });
33897 cacheMap[dim] = map;
33898 }
33899 return map;
33900 };
33901 return Dodge;
33902 }(Adjust);
33903
33904 function randomNumber(min, max) {
33905 return (max - min) * Math.random() + min;
33906 }
33907 var Jitter = /** @class */function (_super) {
33908 __extends(Jitter, _super);
33909 function Jitter() {
33910 return _super !== null && _super.apply(this, arguments) || this;
33911 }
33912 Jitter.prototype.process = function (groupDataArray) {
33913 var groupedDataArray = clone(groupDataArray);
33914 // 之前分组之后的数据,然后有合并回去(和分组前可以理解成是一样的)
33915 var mergeData = flatten(groupedDataArray);
33916 // 返回值
33917 this.adjustData(groupedDataArray, mergeData);
33918 return groupedDataArray;
33919 };
33920 /**
33921 * 当前数据分组(index)中,按照维度 dim 进行 jitter 调整
33922 * @param dim
33923 * @param values
33924 * @param dataArray
33925 */
33926 Jitter.prototype.adjustDim = function (dim, values, dataArray) {
33927 var _this = this;
33928 // 在每一个分组中,将数据再按照 dim 分组,用于散列
33929 var groupDataArray = this.groupData(dataArray, dim);
33930 return each(groupDataArray, function (data, dimValue) {
33931 return _this.adjustGroup(data, dim, parseFloat(dimValue), values);
33932 });
33933 };
33934 // 随机出来的字段值
33935 Jitter.prototype.getAdjustOffset = function (range) {
33936 var pre = range.pre,
33937 next = range.next;
33938 // 随机的范围
33939 var margin = (next - pre) * GAP;
33940 return randomNumber(pre + margin, next - margin);
33941 };
33942 // adjust group data
33943 Jitter.prototype.adjustGroup = function (group, dim, dimValue, values) {
33944 var _this = this;
33945 // 调整范围
33946 var range = this.getAdjustRange(dim, dimValue, values);
33947 each(group, function (data) {
33948 data[dim] = _this.getAdjustOffset(range); // 获取调整的位置
33949 });
33950 return group;
33951 };
33952 return Jitter;
33953 }(Adjust);
33954
33955 var Stack = /** @class */function (_super) {
33956 __extends(Stack, _super);
33957 function Stack(cfg) {
33958 var _this = _super.call(this, cfg) || this;
33959 var _a = cfg.adjustNames,
33960 adjustNames = _a === void 0 ? ['y'] : _a,
33961 _b = cfg.height,
33962 height = _b === void 0 ? NaN : _b,
33963 _c = cfg.size,
33964 size = _c === void 0 ? 10 : _c,
33965 _d = cfg.reverseOrder,
33966 reverseOrder = _d === void 0 ? false : _d;
33967 _this.adjustNames = adjustNames;
33968 _this.height = height;
33969 _this.size = size;
33970 _this.reverseOrder = reverseOrder;
33971 return _this;
33972 }
33973 /**
33974 * 方法入参是经过数据分组、数据数字化之后的二维数组
33975 * @param groupDataArray 分组之后的数据
33976 */
33977 Stack.prototype.process = function (groupDataArray) {
33978 var _a = this,
33979 yField = _a.yField,
33980 reverseOrder = _a.reverseOrder;
33981 // 如果有指定 y 字段,那么按照 y 字段来 stack
33982 // 否则,按照高度均分
33983 var d = yField ? this.processStack(groupDataArray) : this.processOneDimStack(groupDataArray);
33984 return reverseOrder ? this.reverse(d) : d;
33985 };
33986 Stack.prototype.reverse = function (groupedDataArray) {
33987 return groupedDataArray.slice(0).reverse();
33988 };
33989 Stack.prototype.processStack = function (groupDataArray) {
33990 var _a = this,
33991 xField = _a.xField,
33992 yField = _a.yField,
33993 reverseOrder = _a.reverseOrder;
33994 // 层叠顺序翻转
33995 var groupedDataArray = reverseOrder ? this.reverse(groupDataArray) : groupDataArray;
33996 // 用来缓存,正数和负数的堆叠问题
33997 var positive = new default_1();
33998 var negative = new default_1();
33999 return groupedDataArray.map(function (dataArray) {
34000 return dataArray.map(function (data) {
34001 var _a;
34002 var x = get(data, xField, 0);
34003 var y = get(data, [yField]);
34004 var xKey = x.toString();
34005 // todo 是否应该取 _origin?因为 y 可能取到的值不正确,比如先 symmetric,再 stack!
34006 y = isArray(y) ? y[1] : y;
34007 if (!isNil(y)) {
34008 var cache = y >= 0 ? positive : negative;
34009 if (!cache.has(xKey)) {
34010 cache.set(xKey, 0);
34011 }
34012 var xValue = cache.get(xKey);
34013 var newXValue = y + xValue;
34014 // 存起来
34015 cache.set(xKey, newXValue);
34016 return __assign(__assign({}, data), (_a = {}, _a[yField] = [xValue, newXValue], _a));
34017 }
34018 // 没有修改,则直接返回
34019 return data;
34020 });
34021 });
34022 };
34023 Stack.prototype.processOneDimStack = function (groupDataArray) {
34024 var _this = this;
34025 var _a = this,
34026 xField = _a.xField,
34027 height = _a.height,
34028 reverseOrder = _a.reverseOrder;
34029 var yField = 'y';
34030 // 如果层叠的顺序翻转
34031 var groupedDataArray = reverseOrder ? this.reverse(groupDataArray) : groupDataArray;
34032 // 缓存累加数据
34033 var cache = new default_1();
34034 return groupedDataArray.map(function (dataArray) {
34035 return dataArray.map(function (data) {
34036 var _a;
34037 var size = _this.size;
34038 var xValue = data[xField];
34039 // todo 没有看到这个 stack 计算原理
34040 var stackHeight = size * 2 / height;
34041 if (!cache.has(xValue)) {
34042 cache.set(xValue, stackHeight / 2); // 初始值大小
34043 }
34044 var stackValue = cache.get(xValue);
34045 // 增加一层 stackHeight
34046 cache.set(xValue, stackValue + stackHeight);
34047 return __assign(__assign({}, data), (_a = {}, _a[yField] = stackValue, _a));
34048 });
34049 });
34050 };
34051 return Stack;
34052 }(Adjust);
34053
34054 var Symmetric = /** @class */function (_super) {
34055 __extends(Symmetric, _super);
34056 function Symmetric() {
34057 return _super !== null && _super.apply(this, arguments) || this;
34058 }
34059 Symmetric.prototype.process = function (groupDataArray) {
34060 var mergeData = flatten(groupDataArray);
34061 var _a = this,
34062 xField = _a.xField,
34063 yField = _a.yField;
34064 // 每个 x 值对应的 最大值
34065 var cache = this.getXValuesMaxMap(mergeData);
34066 // 所有数据的最大的值
34067 var max = Math.max.apply(Math, Object.keys(cache).map(function (key) {
34068 return cache[key];
34069 }));
34070 return map(groupDataArray, function (dataArray) {
34071 return map(dataArray, function (data) {
34072 var _a, _b;
34073 var yValue = data[yField];
34074 var xValue = data[xField];
34075 // 数组处理逻辑
34076 if (isArray(yValue)) {
34077 var off_1 = (max - cache[xValue]) / 2;
34078 return __assign(__assign({}, data), (_a = {}, _a[yField] = map(yValue, function (y) {
34079 return off_1 + y;
34080 }), _a));
34081 }
34082 // 非数组处理逻辑
34083 var offset = (max - yValue) / 2;
34084 return __assign(__assign({}, data), (_b = {}, _b[yField] = [offset, yValue + offset], _b));
34085 });
34086 });
34087 };
34088 // 获取每个 x 对应的最大的值
34089 Symmetric.prototype.getXValuesMaxMap = function (mergeData) {
34090 var _this = this;
34091 var _a = this,
34092 xField = _a.xField,
34093 yField = _a.yField;
34094 // 根据 xField 的值进行分组
34095 var groupDataArray = groupBy(mergeData, function (data) {
34096 return data[xField];
34097 });
34098 // 获取每个 xField 值中的最大值
34099 return mapValues(groupDataArray, function (dataArray) {
34100 return _this.getDimMaxValue(dataArray, yField);
34101 });
34102 };
34103 Symmetric.prototype.getDimMaxValue = function (mergeData, dim) {
34104 // 所有的 value 值
34105 var dimValues = map(mergeData, function (data) {
34106 return get(data, dim, []);
34107 });
34108 // 将数组打平(dim value 有可能是数组,比如 stack 之后的)
34109 var flattenValues = flatten(dimValues);
34110 // 求出数组的最大值
34111 return Math.max.apply(Math, flattenValues);
34112 };
34113 return Symmetric;
34114 }(Adjust);
34115
34116 function toTimeStamp$1(value) {
34117 if (isString(value)) {
34118 if (value.indexOf('T') > 0) {
34119 value = new Date(value).getTime();
34120 } else {
34121 // new Date('2010/01/10') 和 new Date('2010-01-10') 的差别在于:
34122 // 如果仅有年月日时,前者是带有时区的: Fri Jan 10 2020 02:40:13 GMT+0800 (中国标准时间)
34123 // 后者会格式化成 Sun Jan 10 2010 08:00:00 GMT+0800 (中国标准时间)
34124 value = new Date(value.replace(/-/gi, '/')).getTime();
34125 }
34126 }
34127 if (isDate(value)) {
34128 value = value.getTime();
34129 }
34130 return value;
34131 }
34132
34133 var Base$1 = /** @class */function () {
34134 function Base(options) {
34135 mix(this, options);
34136 var _a = this,
34137 scale = _a.scale,
34138 field = _a.field,
34139 data = _a.data;
34140 if (!scale && data) {
34141 var values = valuesOfKey(data, field);
34142 this.scale = this.createScale({
34143 values: values,
34144 field: field
34145 });
34146 }
34147 }
34148 Base.prototype.createScale = function (_scaleConfig) {
34149 return null;
34150 };
34151 // 数据映射方法
34152 Base.prototype._mapping = function (value) {
34153 return value;
34154 };
34155 Base.prototype.update = function (options) {
34156 mix(this, options);
34157 };
34158 Base.prototype.setRange = function (range) {
34159 this.range = range;
34160 };
34161 // 归一化,参数是原始数据,返回是归一化的数据
34162 Base.prototype.normalize = function (value) {
34163 var scale = this.scale;
34164 if (isArray(value)) {
34165 return value.map(function (v) {
34166 return scale.scale(v);
34167 });
34168 }
34169 return scale.scale(value);
34170 };
34171 // convert 参数是归一化的数据,返回定义域的值
34172 Base.prototype.convert = function (value) {
34173 return value;
34174 };
34175 // 等于 normalize + convert, 参数是原始数据,返回是定义域的值
34176 Base.prototype.mapping = function (value, child) {
34177 if (child === void 0) {
34178 child = null;
34179 }
34180 var rst = isFunction(this.callback) ? this.callback(value, child) : null;
34181 if (!isNil(rst)) {
34182 return rst;
34183 }
34184 return this._mapping(value);
34185 };
34186 return Base;
34187 }();
34188
34189 var _typeof_1 = createCommonjsModule(function (module) {
34190 function _typeof(o) {
34191 "@babel/helpers - typeof";
34192
34193 return module.exports = _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
34194 return typeof o;
34195 } : function (o) {
34196 return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
34197 }, module.exports.__esModule = true, module.exports["default"] = module.exports, _typeof(o);
34198 }
34199 module.exports = _typeof, module.exports.__esModule = true, module.exports["default"] = module.exports;
34200 });
34201
34202 function define$1 (constructor, factory, prototype) {
34203 constructor.prototype = factory.prototype = prototype;
34204 prototype.constructor = constructor;
34205 }
34206 function extend$1(parent, definition) {
34207 var prototype = Object.create(parent.prototype);
34208 for (var key in definition) prototype[key] = definition[key];
34209 return prototype;
34210 }
34211
34212 function Color$1() {}
34213 var _darker = 0.7;
34214 var _brighter = 1 / _darker;
34215 var reI$1 = "\\s*([+-]?\\d+)\\s*",
34216 reN$1 = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*",
34217 reP$1 = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*",
34218 reHex$1 = /^#([0-9a-f]{3,8})$/,
34219 reRgbInteger$1 = new RegExp("^rgb\\(" + [reI$1, reI$1, reI$1] + "\\)$"),
34220 reRgbPercent$1 = new RegExp("^rgb\\(" + [reP$1, reP$1, reP$1] + "\\)$"),
34221 reRgbaInteger$1 = new RegExp("^rgba\\(" + [reI$1, reI$1, reI$1, reN$1] + "\\)$"),
34222 reRgbaPercent$1 = new RegExp("^rgba\\(" + [reP$1, reP$1, reP$1, reN$1] + "\\)$"),
34223 reHslPercent$1 = new RegExp("^hsl\\(" + [reN$1, reP$1, reP$1] + "\\)$"),
34224 reHslaPercent$1 = new RegExp("^hsla\\(" + [reN$1, reP$1, reP$1, reN$1] + "\\)$");
34225 var named$1 = {
34226 aliceblue: 0xf0f8ff,
34227 antiquewhite: 0xfaebd7,
34228 aqua: 0x00ffff,
34229 aquamarine: 0x7fffd4,
34230 azure: 0xf0ffff,
34231 beige: 0xf5f5dc,
34232 bisque: 0xffe4c4,
34233 black: 0x000000,
34234 blanchedalmond: 0xffebcd,
34235 blue: 0x0000ff,
34236 blueviolet: 0x8a2be2,
34237 brown: 0xa52a2a,
34238 burlywood: 0xdeb887,
34239 cadetblue: 0x5f9ea0,
34240 chartreuse: 0x7fff00,
34241 chocolate: 0xd2691e,
34242 coral: 0xff7f50,
34243 cornflowerblue: 0x6495ed,
34244 cornsilk: 0xfff8dc,
34245 crimson: 0xdc143c,
34246 cyan: 0x00ffff,
34247 darkblue: 0x00008b,
34248 darkcyan: 0x008b8b,
34249 darkgoldenrod: 0xb8860b,
34250 darkgray: 0xa9a9a9,
34251 darkgreen: 0x006400,
34252 darkgrey: 0xa9a9a9,
34253 darkkhaki: 0xbdb76b,
34254 darkmagenta: 0x8b008b,
34255 darkolivegreen: 0x556b2f,
34256 darkorange: 0xff8c00,
34257 darkorchid: 0x9932cc,
34258 darkred: 0x8b0000,
34259 darksalmon: 0xe9967a,
34260 darkseagreen: 0x8fbc8f,
34261 darkslateblue: 0x483d8b,
34262 darkslategray: 0x2f4f4f,
34263 darkslategrey: 0x2f4f4f,
34264 darkturquoise: 0x00ced1,
34265 darkviolet: 0x9400d3,
34266 deeppink: 0xff1493,
34267 deepskyblue: 0x00bfff,
34268 dimgray: 0x696969,
34269 dimgrey: 0x696969,
34270 dodgerblue: 0x1e90ff,
34271 firebrick: 0xb22222,
34272 floralwhite: 0xfffaf0,
34273 forestgreen: 0x228b22,
34274 fuchsia: 0xff00ff,
34275 gainsboro: 0xdcdcdc,
34276 ghostwhite: 0xf8f8ff,
34277 gold: 0xffd700,
34278 goldenrod: 0xdaa520,
34279 gray: 0x808080,
34280 green: 0x008000,
34281 greenyellow: 0xadff2f,
34282 grey: 0x808080,
34283 honeydew: 0xf0fff0,
34284 hotpink: 0xff69b4,
34285 indianred: 0xcd5c5c,
34286 indigo: 0x4b0082,
34287 ivory: 0xfffff0,
34288 khaki: 0xf0e68c,
34289 lavender: 0xe6e6fa,
34290 lavenderblush: 0xfff0f5,
34291 lawngreen: 0x7cfc00,
34292 lemonchiffon: 0xfffacd,
34293 lightblue: 0xadd8e6,
34294 lightcoral: 0xf08080,
34295 lightcyan: 0xe0ffff,
34296 lightgoldenrodyellow: 0xfafad2,
34297 lightgray: 0xd3d3d3,
34298 lightgreen: 0x90ee90,
34299 lightgrey: 0xd3d3d3,
34300 lightpink: 0xffb6c1,
34301 lightsalmon: 0xffa07a,
34302 lightseagreen: 0x20b2aa,
34303 lightskyblue: 0x87cefa,
34304 lightslategray: 0x778899,
34305 lightslategrey: 0x778899,
34306 lightsteelblue: 0xb0c4de,
34307 lightyellow: 0xffffe0,
34308 lime: 0x00ff00,
34309 limegreen: 0x32cd32,
34310 linen: 0xfaf0e6,
34311 magenta: 0xff00ff,
34312 maroon: 0x800000,
34313 mediumaquamarine: 0x66cdaa,
34314 mediumblue: 0x0000cd,
34315 mediumorchid: 0xba55d3,
34316 mediumpurple: 0x9370db,
34317 mediumseagreen: 0x3cb371,
34318 mediumslateblue: 0x7b68ee,
34319 mediumspringgreen: 0x00fa9a,
34320 mediumturquoise: 0x48d1cc,
34321 mediumvioletred: 0xc71585,
34322 midnightblue: 0x191970,
34323 mintcream: 0xf5fffa,
34324 mistyrose: 0xffe4e1,
34325 moccasin: 0xffe4b5,
34326 navajowhite: 0xffdead,
34327 navy: 0x000080,
34328 oldlace: 0xfdf5e6,
34329 olive: 0x808000,
34330 olivedrab: 0x6b8e23,
34331 orange: 0xffa500,
34332 orangered: 0xff4500,
34333 orchid: 0xda70d6,
34334 palegoldenrod: 0xeee8aa,
34335 palegreen: 0x98fb98,
34336 paleturquoise: 0xafeeee,
34337 palevioletred: 0xdb7093,
34338 papayawhip: 0xffefd5,
34339 peachpuff: 0xffdab9,
34340 peru: 0xcd853f,
34341 pink: 0xffc0cb,
34342 plum: 0xdda0dd,
34343 powderblue: 0xb0e0e6,
34344 purple: 0x800080,
34345 rebeccapurple: 0x663399,
34346 red: 0xff0000,
34347 rosybrown: 0xbc8f8f,
34348 royalblue: 0x4169e1,
34349 saddlebrown: 0x8b4513,
34350 salmon: 0xfa8072,
34351 sandybrown: 0xf4a460,
34352 seagreen: 0x2e8b57,
34353 seashell: 0xfff5ee,
34354 sienna: 0xa0522d,
34355 silver: 0xc0c0c0,
34356 skyblue: 0x87ceeb,
34357 slateblue: 0x6a5acd,
34358 slategray: 0x708090,
34359 slategrey: 0x708090,
34360 snow: 0xfffafa,
34361 springgreen: 0x00ff7f,
34362 steelblue: 0x4682b4,
34363 tan: 0xd2b48c,
34364 teal: 0x008080,
34365 thistle: 0xd8bfd8,
34366 tomato: 0xff6347,
34367 turquoise: 0x40e0d0,
34368 violet: 0xee82ee,
34369 wheat: 0xf5deb3,
34370 white: 0xffffff,
34371 whitesmoke: 0xf5f5f5,
34372 yellow: 0xffff00,
34373 yellowgreen: 0x9acd32
34374 };
34375 define$1(Color$1, color$1, {
34376 copy: function copy(channels) {
34377 return Object.assign(new this.constructor(), this, channels);
34378 },
34379 displayable: function displayable() {
34380 return this.rgb().displayable();
34381 },
34382 hex: color_formatHex$1,
34383 // Deprecated! Use color.formatHex.
34384 formatHex: color_formatHex$1,
34385 formatHsl: color_formatHsl$1,
34386 formatRgb: color_formatRgb$1,
34387 toString: color_formatRgb$1
34388 });
34389 function color_formatHex$1() {
34390 return this.rgb().formatHex();
34391 }
34392 function color_formatHsl$1() {
34393 return hslConvert$1(this).formatHsl();
34394 }
34395 function color_formatRgb$1() {
34396 return this.rgb().formatRgb();
34397 }
34398 function color$1(format) {
34399 var m, l;
34400 format = (format + "").trim().toLowerCase();
34401 return (m = reHex$1.exec(format)) ? (l = m[1].length, m = parseInt(m[1], 16), l === 6 ? rgbn$1(m) // #ff0000
34402 : l === 3 ? new Rgb$1(m >> 8 & 0xf | m >> 4 & 0xf0, m >> 4 & 0xf | m & 0xf0, (m & 0xf) << 4 | m & 0xf, 1) // #f00
34403 : l === 8 ? rgba$1(m >> 24 & 0xff, m >> 16 & 0xff, m >> 8 & 0xff, (m & 0xff) / 0xff) // #ff000000
34404 : l === 4 ? rgba$1(m >> 12 & 0xf | m >> 8 & 0xf0, m >> 8 & 0xf | m >> 4 & 0xf0, m >> 4 & 0xf | m & 0xf0, ((m & 0xf) << 4 | m & 0xf) / 0xff) // #f000
34405 : null // invalid hex
34406 ) : (m = reRgbInteger$1.exec(format)) ? new Rgb$1(m[1], m[2], m[3], 1) // rgb(255, 0, 0)
34407 : (m = reRgbPercent$1.exec(format)) ? new Rgb$1(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%)
34408 : (m = reRgbaInteger$1.exec(format)) ? rgba$1(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1)
34409 : (m = reRgbaPercent$1.exec(format)) ? rgba$1(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1)
34410 : (m = reHslPercent$1.exec(format)) ? hsla$1(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%)
34411 : (m = reHslaPercent$1.exec(format)) ? hsla$1(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1)
34412 : named$1.hasOwnProperty(format) ? rgbn$1(named$1[format]) // eslint-disable-line no-prototype-builtins
34413 : format === "transparent" ? new Rgb$1(NaN, NaN, NaN, 0) : null;
34414 }
34415 function rgbn$1(n) {
34416 return new Rgb$1(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1);
34417 }
34418 function rgba$1(r, g, b, a) {
34419 if (a <= 0) r = g = b = NaN;
34420 return new Rgb$1(r, g, b, a);
34421 }
34422 function rgbConvert$1(o) {
34423 if (!(o instanceof Color$1)) o = color$1(o);
34424 if (!o) return new Rgb$1();
34425 o = o.rgb();
34426 return new Rgb$1(o.r, o.g, o.b, o.opacity);
34427 }
34428 function rgb$1(r, g, b, opacity) {
34429 return arguments.length === 1 ? rgbConvert$1(r) : new Rgb$1(r, g, b, opacity == null ? 1 : opacity);
34430 }
34431 function Rgb$1(r, g, b, opacity) {
34432 this.r = +r;
34433 this.g = +g;
34434 this.b = +b;
34435 this.opacity = +opacity;
34436 }
34437 define$1(Rgb$1, rgb$1, extend$1(Color$1, {
34438 brighter: function brighter(k) {
34439 k = k == null ? _brighter : Math.pow(_brighter, k);
34440 return new Rgb$1(this.r * k, this.g * k, this.b * k, this.opacity);
34441 },
34442 darker: function darker(k) {
34443 k = k == null ? _darker : Math.pow(_darker, k);
34444 return new Rgb$1(this.r * k, this.g * k, this.b * k, this.opacity);
34445 },
34446 rgb: function rgb() {
34447 return this;
34448 },
34449 displayable: function displayable() {
34450 return -0.5 <= this.r && this.r < 255.5 && -0.5 <= this.g && this.g < 255.5 && -0.5 <= this.b && this.b < 255.5 && 0 <= this.opacity && this.opacity <= 1;
34451 },
34452 hex: rgb_formatHex$1,
34453 // Deprecated! Use color.formatHex.
34454 formatHex: rgb_formatHex$1,
34455 formatRgb: rgb_formatRgb$1,
34456 toString: rgb_formatRgb$1
34457 }));
34458 function rgb_formatHex$1() {
34459 return "#" + hex$1(this.r) + hex$1(this.g) + hex$1(this.b);
34460 }
34461 function rgb_formatRgb$1() {
34462 var a = this.opacity;
34463 a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a));
34464 return (a === 1 ? "rgb(" : "rgba(") + Math.max(0, Math.min(255, Math.round(this.r) || 0)) + ", " + Math.max(0, Math.min(255, Math.round(this.g) || 0)) + ", " + Math.max(0, Math.min(255, Math.round(this.b) || 0)) + (a === 1 ? ")" : ", " + a + ")");
34465 }
34466 function hex$1(value) {
34467 value = Math.max(0, Math.min(255, Math.round(value) || 0));
34468 return (value < 16 ? "0" : "") + value.toString(16);
34469 }
34470 function hsla$1(h, s, l, a) {
34471 if (a <= 0) h = s = l = NaN;else if (l <= 0 || l >= 1) h = s = NaN;else if (s <= 0) h = NaN;
34472 return new Hsl$1(h, s, l, a);
34473 }
34474 function hslConvert$1(o) {
34475 if (o instanceof Hsl$1) return new Hsl$1(o.h, o.s, o.l, o.opacity);
34476 if (!(o instanceof Color$1)) o = color$1(o);
34477 if (!o) return new Hsl$1();
34478 if (o instanceof Hsl$1) return o;
34479 o = o.rgb();
34480 var r = o.r / 255,
34481 g = o.g / 255,
34482 b = o.b / 255,
34483 min = Math.min(r, g, b),
34484 max = Math.max(r, g, b),
34485 h = NaN,
34486 s = max - min,
34487 l = (max + min) / 2;
34488 if (s) {
34489 if (r === max) h = (g - b) / s + (g < b) * 6;else if (g === max) h = (b - r) / s + 2;else h = (r - g) / s + 4;
34490 s /= l < 0.5 ? max + min : 2 - max - min;
34491 h *= 60;
34492 } else {
34493 s = l > 0 && l < 1 ? 0 : h;
34494 }
34495 return new Hsl$1(h, s, l, o.opacity);
34496 }
34497 function hsl$1(h, s, l, opacity) {
34498 return arguments.length === 1 ? hslConvert$1(h) : new Hsl$1(h, s, l, opacity == null ? 1 : opacity);
34499 }
34500 function Hsl$1(h, s, l, opacity) {
34501 this.h = +h;
34502 this.s = +s;
34503 this.l = +l;
34504 this.opacity = +opacity;
34505 }
34506 define$1(Hsl$1, hsl$1, extend$1(Color$1, {
34507 brighter: function brighter(k) {
34508 k = k == null ? _brighter : Math.pow(_brighter, k);
34509 return new Hsl$1(this.h, this.s, this.l * k, this.opacity);
34510 },
34511 darker: function darker(k) {
34512 k = k == null ? _darker : Math.pow(_darker, k);
34513 return new Hsl$1(this.h, this.s, this.l * k, this.opacity);
34514 },
34515 rgb: function rgb() {
34516 var h = this.h % 360 + (this.h < 0) * 360,
34517 s = isNaN(h) || isNaN(this.s) ? 0 : this.s,
34518 l = this.l,
34519 m2 = l + (l < 0.5 ? l : 1 - l) * s,
34520 m1 = 2 * l - m2;
34521 return new Rgb$1(hsl2rgb$1(h >= 240 ? h - 240 : h + 120, m1, m2), hsl2rgb$1(h, m1, m2), hsl2rgb$1(h < 120 ? h + 240 : h - 120, m1, m2), this.opacity);
34522 },
34523 displayable: function displayable() {
34524 return (0 <= this.s && this.s <= 1 || isNaN(this.s)) && 0 <= this.l && this.l <= 1 && 0 <= this.opacity && this.opacity <= 1;
34525 },
34526 formatHsl: function formatHsl() {
34527 var a = this.opacity;
34528 a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a));
34529 return (a === 1 ? "hsl(" : "hsla(") + (this.h || 0) + ", " + (this.s || 0) * 100 + "%, " + (this.l || 0) * 100 + "%" + (a === 1 ? ")" : ", " + a + ")");
34530 }
34531 }));
34532
34533 /* From FvD 13.37, CSS Color Module Level 3 */
34534 function hsl2rgb$1(h, m1, m2) {
34535 return (h < 60 ? m1 + (m2 - m1) * h / 60 : h < 180 ? m2 : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60 : m1) * 255;
34536 }
34537
34538 var constant = (function (x) {
34539 return function () {
34540 return x;
34541 };
34542 });
34543
34544 function linear$1(a, d) {
34545 return function (t) {
34546 return a + t * d;
34547 };
34548 }
34549 function exponential(a, b, y) {
34550 return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function (t) {
34551 return Math.pow(a + t * b, y);
34552 };
34553 }
34554 function gamma(y) {
34555 return (y = +y) === 1 ? nogamma : function (a, b) {
34556 return b - a ? exponential(a, b, y) : constant(isNaN(a) ? b : a);
34557 };
34558 }
34559 function nogamma(a, b) {
34560 var d = b - a;
34561 return d ? linear$1(a, d) : constant(isNaN(a) ? b : a);
34562 }
34563
34564 var interpolateRgb = (function rgbGamma(y) {
34565 var color = gamma(y);
34566 function rgb(start, end) {
34567 var r = color((start = rgb$1(start)).r, (end = rgb$1(end)).r),
34568 g = color(start.g, end.g),
34569 b = color(start.b, end.b),
34570 opacity = nogamma(start.opacity, end.opacity);
34571 return function (t) {
34572 start.r = r(t);
34573 start.g = g(t);
34574 start.b = b(t);
34575 start.opacity = opacity(t);
34576 return start + '';
34577 };
34578 }
34579 rgb.gamma = rgbGamma;
34580 return rgb;
34581 })(1);
34582
34583 function interpolateNumber (a, b) {
34584 return a = +a, b = +b, function (t) {
34585 return a * (1 - t) + b * t;
34586 };
34587 }
34588
34589 // 只处理 number 和 color
34590 var interpolate$1 = function interpolate(a, b) {
34591 if (isNumber(b)) {
34592 return interpolateNumber(a, b);
34593 }
34594 return interpolateRgb(a, b);
34595 };
34596 var Linear$1 = /** @class */function (_super) {
34597 __extends(Linear$1, _super);
34598 function Linear$1(options) {
34599 var _this = _super.call(this, options) || this;
34600 _this._updateInterpolate();
34601 return _this;
34602 }
34603 Linear$1.prototype.createScale = function (scaleConfig) {
34604 return new Linear(scaleConfig);
34605 };
34606 Linear$1.prototype._updateInterpolate = function () {
34607 var _a = this.range,
34608 min = _a[0],
34609 max = _a[1];
34610 this.interpolate = interpolate$1(min, max);
34611 };
34612 Linear$1.prototype.update = function (options) {
34613 _super.prototype.update.call(this, options);
34614 this._updateInterpolate();
34615 };
34616 Linear$1.prototype._mapping = function (value) {
34617 var _a = this,
34618 scale = _a.scale,
34619 interpolate = _a.interpolate;
34620 if (isArray(value)) {
34621 return value.map(function (v) {
34622 return interpolate(scale.scale(v));
34623 });
34624 }
34625 return interpolate(scale.scale(value));
34626 };
34627 Linear$1.prototype.normalize = function (value) {
34628 var scale = this.scale;
34629 if (isArray(value)) {
34630 return value.map(function (v) {
34631 return scale.scale(v);
34632 });
34633 }
34634 return scale.scale(value);
34635 };
34636 Linear$1.prototype.convert = function (value) {
34637 var range = this.range;
34638 var min = range[0],
34639 max = range[1];
34640 if (isArray(value)) {
34641 return value.map(function (v) {
34642 return min + (max - min) * v;
34643 });
34644 }
34645 return min + (max - min) * value;
34646 };
34647 return Linear$1;
34648 }(Base$1);
34649
34650 var Category$1 = /** @class */function (_super) {
34651 __extends(Category$1, _super);
34652 function Category$1() {
34653 return _super !== null && _super.apply(this, arguments) || this;
34654 }
34655 Category$1.prototype.createScale = function (scaleConfig) {
34656 return new Category(scaleConfig);
34657 };
34658 Category$1.prototype._mapping = function (value) {
34659 var _a = this,
34660 scale = _a.scale,
34661 range = _a.range;
34662 if (scale.type === 'cat') {
34663 var index_1 = scale.translate(value);
34664 return range[index_1 % range.length];
34665 }
34666 var normalizeValue = scale.scale(value);
34667 var index = Math.round(normalizeValue * (range.length - 1));
34668 return range[index];
34669 };
34670 return Category$1;
34671 }(Base$1);
34672
34673 var Identity$1 = /** @class */function (_super) {
34674 __extends(Identity$1, _super);
34675 function Identity$1() {
34676 return _super !== null && _super.apply(this, arguments) || this;
34677 }
34678 Identity$1.prototype.createScale = function (scaleConfig) {
34679 return new Identity(scaleConfig);
34680 };
34681 Identity$1.prototype._mapping = function () {
34682 var _a = this,
34683 field = _a.field,
34684 range = _a.range;
34685 return field || range && range[0];
34686 };
34687 return Identity$1;
34688 }(Base$1);
34689
34690 var Attrs = /*#__PURE__*/Object.freeze({
34691 __proto__: null,
34692 Attr: Base$1,
34693 Linear: Linear$1,
34694 Category: Category$1,
34695 Identity: Identity$1
34696 });
34697
34698 var Identity$2 = Identity$1,
34699 Linear$2 = Linear$1,
34700 Category$2 = Category$1;
34701 // 需要映射的属性名
34702 var ATTRS = ['x', 'y', 'color', 'size', 'shape'];
34703 // 分组处理的属性
34704 var GROUP_ATTRS = ['color', 'size', 'shape'];
34705 function cloneScale(scale, scaleConfig) {
34706 // @ts-ignore
34707 return new scale.constructor(__assign(__assign({}, scale.__cfg__), scaleConfig));
34708 }
34709 var AttrController = /** @class */function () {
34710 function AttrController(scaleController, attrsRange) {
34711 this.scaleController = scaleController;
34712 this.attrsRange = attrsRange;
34713 this.options = {};
34714 this.attrs = {};
34715 }
34716 AttrController.prototype.parseOption = function (option, attrName) {
34717 if (!option) {
34718 return {
34719 type: 'identity'
34720 };
34721 }
34722 if (isString(option)) {
34723 return {
34724 field: option,
34725 type: 'category'
34726 };
34727 }
34728 if (isNumber(option)) {
34729 if (attrName === 'size') {
34730 return {
34731 type: 'identity',
34732 field: option
34733 };
34734 }
34735 }
34736 if (isArray(option)) {
34737 return {
34738 field: option[0],
34739 range: option[1]
34740 };
34741 }
34742 return option;
34743 };
34744 AttrController.prototype.getAttrOptions = function (props, justifyContentCenter) {
34745 var _this = this;
34746 if (!props.x || !props.y) {
34747 throw new Error('x, y are required !');
34748 }
34749 var options = {};
34750 var ranges = this.attrsRange;
34751 ATTRS.forEach(function (attrName) {
34752 if (!props[attrName]) return;
34753 var option = _this.parseOption(props[attrName], attrName);
34754 if (!option.range) {
34755 option.range = ranges[attrName];
34756 }
34757 options[attrName] = option;
34758 });
34759 // @ts-ignore
34760 var x = options.x,
34761 y = options.y;
34762 x.justifyContent = justifyContentCenter;
34763 // x, y 都是固定Linear 映射
34764 x.type = Linear$2;
34765 y.type = Linear$2;
34766 return options;
34767 };
34768 AttrController.prototype.getDefaultAttrValues = function () {
34769 var _a = this.attrsRange,
34770 color = _a.color,
34771 shape = _a.shape;
34772 return {
34773 color: color[0],
34774 shape: shape && shape[0]
34775 };
34776 };
34777 AttrController.prototype.getGroupScales = function () {
34778 var attrs = this.attrs;
34779 var scales = [];
34780 each(GROUP_ATTRS, function (attrName) {
34781 var attr = attrs[attrName];
34782 if (!attr) {
34783 return;
34784 }
34785 var scale = attr.scale;
34786 if (scale && scale.isCategory && scales.indexOf(scale) === -1) {
34787 scales.push(scale);
34788 }
34789 });
34790 return scales;
34791 };
34792 AttrController.prototype.createAttr = function (option) {
34793 var type = option.type,
34794 field = option.field,
34795 scaleConfig = option.scale;
34796 if (isNil(field) || type === Identity$2) {
34797 return new Identity$2(option);
34798 }
34799 var scale = this.scaleController.getScale(field);
34800 var attrOption = __assign(__assign({}, option), {
34801 data: this.scaleController.getData(),
34802 // scaleConfig 只在属性映射中生效
34803 scale: scaleConfig ? cloneScale(scale, scaleConfig) : scale
34804 });
34805 // identity
34806 if (scale && scale.type === 'identity') {
34807 return new Identity$2(attrOption);
34808 }
34809 // Attr的默认类型和scale类型保持一致
34810 var AttrConstructor = scale.isLinear ? Linear$2 : Category$2;
34811 // custom Attr Constructor
34812 if (isFunction(type)) {
34813 AttrConstructor = type;
34814 }
34815 if (isString(type) && Attrs[upperFirst(type)]) {
34816 AttrConstructor = Attrs[upperFirst(type)];
34817 }
34818 return new AttrConstructor(attrOption);
34819 };
34820 AttrController.prototype.create = function (options) {
34821 this.update(options);
34822 };
34823 AttrController.prototype.update = function (nextOptions) {
34824 var _a = this,
34825 scaleController = _a.scaleController,
34826 lastOptions = _a.options,
34827 lastAttrs = _a.attrs;
34828 var nextAttrs = {};
34829 each(nextOptions, function (nextOption, attrName) {
34830 var lastOption = lastOptions[attrName];
34831 if (equal(nextOption, lastOption)) {
34832 nextAttrs[attrName] = lastAttrs[attrName];
34833 }
34834 var field = nextOption.field,
34835 justifyContent = nextOption.justifyContent;
34836 if (field) {
34837 scaleController.setScale(field, {
34838 justifyContent: justifyContent
34839 });
34840 }
34841 });
34842 this.options = nextOptions;
34843 this.attrs = nextAttrs;
34844 };
34845 AttrController.prototype.getAttr = function (attrName) {
34846 var _a = this,
34847 attrs = _a.attrs,
34848 options = _a.options;
34849 var attr = attrs[attrName];
34850 if (attr) {
34851 return attr;
34852 }
34853 var option = options[attrName];
34854 if (!option) {
34855 return null;
34856 }
34857 var newAttr = this.createAttr(option);
34858 attrs[attrName] = newAttr;
34859 return newAttr;
34860 };
34861 AttrController.prototype.getAttrs = function () {
34862 var _this = this;
34863 var _a = this,
34864 options = _a.options,
34865 attrs = _a.attrs;
34866 each(options, function (option, attrName) {
34867 _this.getAttr(attrName);
34868 });
34869 return attrs;
34870 };
34871 AttrController.prototype.isGroupAttr = function (attrName) {
34872 return GROUP_ATTRS.indexOf(attrName) !== -1;
34873 };
34874 AttrController.prototype.getAttrsByLinear = function () {
34875 var attrs = this.attrs;
34876 var attrNames = Object.keys(attrs);
34877 var linearAttrs = [];
34878 var nonlinearAttrs = [];
34879 attrNames.forEach(function (attrName) {
34880 if (attrName === 'x' || attrName === 'y') {
34881 linearAttrs.push(attrName);
34882 return;
34883 }
34884 var scale = attrs[attrName].scale;
34885 if (scale && scale.type === 'linear') {
34886 linearAttrs.push(attrName);
34887 } else {
34888 nonlinearAttrs.push(attrName);
34889 }
34890 });
34891 return {
34892 linearAttrs: linearAttrs,
34893 nonlinearAttrs: nonlinearAttrs
34894 };
34895 };
34896 return AttrController;
34897 }();
34898
34899 var AdjustMap = {
34900 Stack: Stack,
34901 Dodge: Dodge,
34902 Jitter: Jitter,
34903 Symmetric: Symmetric
34904 };
34905 // 保留原始数据的字段
34906 var FIELD_ORIGIN = 'origin';
34907 var Geometry = /** @class */function (_super) {
34908 __extends(Geometry, _super);
34909 function Geometry(props, context) {
34910 var _this = _super.call(this, props, context) || this;
34911 _this.isGeometry = true;
34912 // x 轴居中
34913 _this.justifyContent = false;
34914 // y 轴是否从0开始
34915 _this.startOnZero = false;
34916 // 是否连接空值
34917 _this.connectNulls = false;
34918 // 是否需要排序
34919 _this.sortable = false;
34920 mix(_this, _this.getDefaultCfg());
34921 var chart = props.chart;
34922 var attrsRange = _this._getThemeAttrsRange();
34923 _this.attrController = new AttrController(chart.scale, attrsRange);
34924 var attrController = _this.attrController;
34925 var attrOptions = _this.getAttrOptions(props);
34926 attrController.create(attrOptions);
34927 return _this;
34928 }
34929 Geometry.prototype.getDefaultCfg = function () {
34930 return {};
34931 };
34932 Geometry.prototype.getAttrOptions = function (props) {
34933 var coord = props.coord;
34934 var _a = this,
34935 attrController = _a.attrController,
34936 justifyContent = _a.justifyContent;
34937 var justifyContentCenter = !coord.isCyclic() || justifyContent;
34938 var args = {};
34939 ATTRS.forEach(function (d) {
34940 return args[d] = props[d];
34941 });
34942 var attrOptions = attrController.getAttrOptions(this.context.px2hd(args), justifyContentCenter);
34943 return attrOptions;
34944 };
34945 Geometry.prototype.willReceiveProps = function (nextProps) {
34946 var _a = this,
34947 lastProps = _a.props,
34948 attrController = _a.attrController;
34949 var nextData = nextProps.data,
34950 nextAdjust = nextProps.adjust,
34951 selection = nextProps.selection;
34952 var lastData = lastProps.data,
34953 lastAdjust = lastProps.adjust,
34954 lastSelection = lastProps.selection;
34955 var lastAttrOptions = this.getAttrOptions(lastProps);
34956 attrController.attrsRange = this._getThemeAttrsRange();
34957 var nextAttrOptions = this.getAttrOptions(nextProps);
34958 if (!equal(nextAttrOptions, lastAttrOptions)) {
34959 attrController.update(nextAttrOptions);
34960 this.dataRecords = null;
34961 }
34962 // 重新处理数据
34963 if (nextData !== lastData) {
34964 this.dataRecords = null;
34965 }
34966 // 重新处理数据
34967 if (nextAdjust !== lastAdjust) {
34968 this.dataRecords = null;
34969 }
34970 // selection 发生变化
34971 if (!equal(selection, lastSelection)) {
34972 _super.prototype.willReceiveProps.call(this, nextProps);
34973 }
34974 };
34975 Geometry.prototype.willMount = function () {
34976 this._createAttrs();
34977 if (!this.dataRecords) {
34978 this._processData();
34979 }
34980 };
34981 Geometry.prototype.willUpdate = function () {
34982 this._createAttrs();
34983 if (!this.dataRecords) {
34984 this._processData();
34985 } else {
34986 this._readjustData(this.dataRecords);
34987 }
34988 };
34989 Geometry.prototype.didMount = function () {
34990 this._initEvent();
34991 _super.prototype.didMount.call(this);
34992 // 更新 attrController
34993 this.attrController.attrsRange = this._getThemeAttrsRange();
34994 };
34995 Geometry.prototype._initEvent = function () {
34996 var _this = this;
34997 var props = this.props;
34998 var chart = props.chart;
34999 ['onPressStart', 'onPress', 'onPressEnd', 'onPan', 'onPanStart', 'onPanEnd'].forEach(function (eventName) {
35000 if (props[eventName]) {
35001 chart.on(eventName.substr(2).toLowerCase(), function (ev) {
35002 ev.geometry = _this;
35003 props[eventName](ev);
35004 });
35005 }
35006 });
35007 };
35008 Geometry.prototype._createAttrs = function () {
35009 var attrController = this.attrController;
35010 attrController.attrs = {};
35011 this.attrs = attrController.getAttrs();
35012 };
35013 Geometry.prototype._getThemeAttrsRange = function () {
35014 var _a = this,
35015 context = _a.context,
35016 props = _a.props,
35017 geomType = _a.geomType;
35018 var coord = props.coord;
35019 var theme = context.theme;
35020 var colors = theme.colors,
35021 sizes = theme.sizes,
35022 shapes = theme.shapes;
35023 return {
35024 x: coord.x,
35025 y: coord.y,
35026 color: colors,
35027 size: sizes,
35028 shape: shapes[geomType]
35029 };
35030 };
35031 Geometry.prototype._createAdjust = function () {
35032 var _a = this,
35033 attrs = _a.attrs,
35034 props = _a.props;
35035 var adjust = props.adjust;
35036 if (!adjust) {
35037 return null;
35038 }
35039 var adjustCfg = typeof adjust === 'string' ? {
35040 type: adjust
35041 } : adjust;
35042 var adjustType = upperFirst(adjustCfg.type);
35043 var AdjustConstructor = AdjustMap[adjustType];
35044 if (!AdjustConstructor) {
35045 throw new Error('not support such adjust : ' + adjust);
35046 }
35047 if (adjustType === 'Dodge') {
35048 // @ts-ignore
35049 adjustCfg.adjustNames = ['x'];
35050 }
35051 var x = attrs.x,
35052 y = attrs.y;
35053 // @ts-ignore
35054 adjustCfg.xField = x.field;
35055 // @ts-ignore
35056 adjustCfg.yField = y.field;
35057 var adjustInstance = new AdjustConstructor(adjustCfg);
35058 this.adjust = {
35059 type: adjustCfg.type,
35060 adjust: adjustInstance
35061 };
35062 return this.adjust;
35063 };
35064 Geometry.prototype._adjustScales = function () {
35065 var _a = this,
35066 attrs = _a.attrs,
35067 props = _a.props,
35068 defaultStartOnZero = _a.startOnZero;
35069 var chart = props.chart,
35070 _b = props.startOnZero,
35071 startOnZero = _b === void 0 ? defaultStartOnZero : _b,
35072 coord = props.coord,
35073 adjust = props.adjust;
35074 var isPolar = coord.isPolar,
35075 transposed = coord.transposed;
35076 var y = attrs.y;
35077 // 如果从 0 开始,只调整 y 轴 scale
35078 if (startOnZero) {
35079 chart.scale.adjustStartZero(y.scale);
35080 }
35081 // 饼图的scale调整,关闭nice
35082 if (isPolar && transposed && (adjust === 'stack' || (adjust === null || adjust === void 0 ? void 0 : adjust.type) === 'stack')) {
35083 chart.scale.adjustPieScale(y.scale);
35084 }
35085 if (adjust === 'stack' || (adjust === null || adjust === void 0 ? void 0 : adjust.type) === 'stack') {
35086 chart.scale._updateStackRange(y.scale, flatten(this.dataArray));
35087 }
35088 };
35089 Geometry.prototype._groupData = function (data) {
35090 var attrController = this.attrController;
35091 var groupScales = attrController.getGroupScales();
35092 if (!groupScales.length) {
35093 return [{
35094 children: data
35095 }];
35096 }
35097 var names = [];
35098 groupScales.forEach(function (scale) {
35099 var field = scale.field;
35100 names.push(field);
35101 });
35102 var groups = groupToMap(data, names);
35103 var records = [];
35104 for (var key in groups) {
35105 records.push({
35106 key: key.replace(/^_/, ''),
35107 children: groups[key]
35108 });
35109 }
35110 return records;
35111 };
35112 Geometry.prototype._saveOrigin = function (originData) {
35113 var _a;
35114 var len = originData.length;
35115 var data = new Array(len);
35116 for (var i = 0; i < len; i++) {
35117 var record = originData[i];
35118 data[i] = __assign(__assign({}, record), (_a = {}, _a[FIELD_ORIGIN] = record, _a));
35119 }
35120 return data;
35121 };
35122 Geometry.prototype._numberic = function (data) {
35123 var attrs = this.attrs;
35124 var scales = [attrs.x.scale, attrs.y.scale];
35125 for (var j = 0, len = data.length; j < len; j++) {
35126 var obj = data[j];
35127 var count = scales.length;
35128 for (var i = 0; i < count; i++) {
35129 var scale = scales[i];
35130 if (scale.isCategory) {
35131 var field = scale.field;
35132 var value = scale.translate(obj.origin[field]);
35133 obj[field] = value;
35134 }
35135 }
35136 }
35137 };
35138 Geometry.prototype._adjustData = function (records) {
35139 var adjust = this.adjust;
35140 // groupedArray 是二维数组
35141 var groupedArray = records.map(function (record) {
35142 return record.children;
35143 });
35144 if (!adjust) {
35145 return groupedArray;
35146 }
35147 var attrs = this.attrs;
35148 var scales = [attrs.x.scale, attrs.y.scale];
35149 for (var i = 0, len = groupedArray.length; i < len; i++) {
35150 var records_1 = groupedArray[i];
35151 for (var j = 0, len_1 = records_1.length; j < len_1; j++) {
35152 var record = records_1[j];
35153 var count = scales.length;
35154 for (var i_1 = 0; i_1 < count; i_1++) {
35155 var scale = scales[i_1];
35156 var field = scale.field;
35157 record[field] = record.origin[field];
35158 }
35159 }
35160 }
35161 if (adjust.type === 'dodge') {
35162 for (var i = 0, len = groupedArray.length; i < len; i++) {
35163 // 如果是dodge, 需要处理数字再处理
35164 this._numberic(groupedArray[i]);
35165 }
35166 }
35167 var adjustData = adjust.adjust.process(groupedArray);
35168 // process 返回的是新数组,所以要修改 records
35169 records.forEach(function (record, index) {
35170 record.children = adjustData[index];
35171 });
35172 return adjustData;
35173 };
35174 Geometry.prototype._processData = function () {
35175 var props = this.props;
35176 var originData = props.data;
35177 var data = this._saveOrigin(originData);
35178 // 根据分类度量进行数据分组
35179 var records = this._groupData(data);
35180 this._createAdjust();
35181 // 根据adjust分组
35182 var dataArray = this._adjustData(records);
35183 this.dataArray = dataArray;
35184 // scale适配调整,主要是调整 y 轴是否从 0 开始 以及 饼图
35185 this._adjustScales();
35186 // 数据排序(非必须)
35187 if (this.sortable) {
35188 this._sortData(records);
35189 }
35190 this.dataRecords = records;
35191 };
35192 Geometry.prototype._readjustData = function (records) {
35193 var adjust = this.adjust;
35194 if (!adjust) return;
35195 // 根据adjust分组
35196 var dataArray = this._adjustData(records);
35197 this.dataArray = dataArray;
35198 };
35199 Geometry.prototype._sortData = function (records) {
35200 var xScale = this.getXScale();
35201 var field = xScale.field,
35202 type = xScale.type;
35203 if (type !== 'identity' && xScale.values.length > 1) {
35204 each(records, function (_a) {
35205 var children = _a.children;
35206 children.sort(function (record1, record2) {
35207 if (type === 'timeCat') {
35208 return toTimeStamp$1(record1[FIELD_ORIGIN][field]) - toTimeStamp$1(record2[FIELD_ORIGIN][field]);
35209 }
35210 var normalized1 = xScale.translate(record1[FIELD_ORIGIN][field]);
35211 var normalized2 = xScale.translate(record2[FIELD_ORIGIN][field]);
35212 if (isNaN(normalized1)) {
35213 return 1;
35214 }
35215 if (isNaN(normalized2)) {
35216 return -1;
35217 }
35218 return normalized1 - normalized2;
35219 });
35220 });
35221 }
35222 };
35223 Geometry.prototype.getY0Value = function () {
35224 var _a = this,
35225 attrs = _a.attrs,
35226 props = _a.props;
35227 var chart = props.chart;
35228 var field = attrs.y.field;
35229 var scale = chart.getScale(field);
35230 return chart.scale.getZeroValue(scale);
35231 };
35232 // 根据各属性映射的值域来获取真正的绘图属性
35233 Geometry.prototype._getShapeStyle = function (shape, origin) {
35234 var _a = this,
35235 context = _a.context,
35236 props = _a.props,
35237 geomType = _a.geomType;
35238 var theme = context.theme;
35239 var shapeTheme = theme.shape[geomType] || {};
35240 var defaultShapeStyle = shapeTheme.default;
35241 var shapeThemeStyle = shapeTheme[shape];
35242 var style = props.style;
35243 var shapeStyle = __assign(__assign({}, defaultShapeStyle), shapeThemeStyle);
35244 if (!style || !isObject(style)) {
35245 return shapeStyle;
35246 }
35247 // @ts-ignore
35248 var field = style.field,
35249 styles = __rest(style, ["field"]);
35250 var value = field ? origin[field] : origin;
35251 each(styles, function (attr, key) {
35252 if (isFunction(attr)) {
35253 var attrValue = attr(value);
35254 if (!attrValue) {
35255 return;
35256 }
35257 shapeStyle[key] = attrValue;
35258 return;
35259 }
35260 shapeStyle[key] = attr;
35261 });
35262 return shapeStyle;
35263 };
35264 /**
35265 * 数据映射到视图属性核心逻辑
35266 * x、y 每个元素走 normalize 然后 convertPoint
35267 * color、size、shape
35268 * 如果是Linear,则每个元素 走 mapping
35269 * 如果是Category/Identity 则第一个元素走 mapping
35270 */
35271 Geometry.prototype._mapping = function (records) {
35272 var _a = this,
35273 attrs = _a.attrs,
35274 props = _a.props,
35275 attrController = _a.attrController;
35276 var coord = props.coord;
35277 var _b = attrController.getAttrsByLinear(),
35278 linearAttrs = _b.linearAttrs,
35279 nonlinearAttrs = _b.nonlinearAttrs;
35280 var defaultAttrValues = attrController.getDefaultAttrValues();
35281 var mappedRecords = [];
35282 for (var i = 0, len = records.length; i < len; i++) {
35283 var record = records[i];
35284 var children = record.children;
35285 var attrValues = __assign({}, defaultAttrValues);
35286 var firstChild = children[0];
35287 if (children.length === 0) {
35288 mappedRecords.push(__assign({}, record));
35289 continue;
35290 }
35291 // 非线性映射
35292 for (var k = 0, len_2 = nonlinearAttrs.length; k < len_2; k++) {
35293 var attrName = nonlinearAttrs[k];
35294 var attr = attrs[attrName];
35295 // 非线性映射只用映射第一项就可以了
35296 attrValues[attrName] = attr.mapping(firstChild[attr.field], firstChild.origin);
35297 }
35298 // 线性属性映射
35299 var mappedChildren = [];
35300 for (var j = 0, childrenLen = children.length; j < childrenLen; j++) {
35301 var child = children[j];
35302 var normalized = {};
35303 for (var k = 0; k < linearAttrs.length; k++) {
35304 var attrName = linearAttrs[k];
35305 var attr = attrs[attrName];
35306 var value = child[attr.field];
35307 // 分类属性的线性映射
35308 if (attrController.isGroupAttr(attrName)) {
35309 attrValues[attrName] = attr.mapping(value, child);
35310 } else {
35311 normalized[attrName] = attr.normalize(value);
35312 }
35313 }
35314 var _c = coord.convertPoint({
35315 x: normalized.x,
35316 y: normalized.y
35317 }),
35318 x = _c.x,
35319 y = _c.y;
35320 // 获取 shape 的 style
35321 var origin_1 = child.origin;
35322 var shapeName = attrValues.shape;
35323 var shape = this._getShapeStyle(shapeName, origin_1);
35324 var selected = this.isSelected(child);
35325 mappedChildren.push(__assign(__assign(__assign({}, child), attrValues), {
35326 normalized: normalized,
35327 x: x,
35328 y: y,
35329 shapeName: shapeName,
35330 shape: shape,
35331 selected: selected
35332 }));
35333 }
35334 mappedRecords.push(__assign(__assign({}, record), {
35335 children: mappedChildren
35336 }));
35337 }
35338 return mappedRecords;
35339 };
35340 // 数据映射
35341 Geometry.prototype.mapping = function () {
35342 var dataRecords = this.dataRecords;
35343 // 数据映射
35344 this.records = this._mapping(dataRecords);
35345 return this.records;
35346 };
35347 Geometry.prototype.getClip = function () {
35348 var _a = this.props,
35349 coord = _a.coord,
35350 viewClip = _a.viewClip;
35351 var contentWidth = coord.width,
35352 contentHeight = coord.height,
35353 left = coord.left,
35354 top = coord.top;
35355 if (viewClip) {
35356 return {
35357 type: 'rect',
35358 style: {
35359 x: left,
35360 y: top,
35361 width: contentWidth,
35362 height: contentHeight
35363 }
35364 };
35365 }
35366 return null;
35367 };
35368 Geometry.prototype.getAttr = function (attrName) {
35369 return this.attrController.getAttr(attrName);
35370 };
35371 Geometry.prototype.getXScale = function () {
35372 return this.getAttr('x').scale;
35373 };
35374 Geometry.prototype.getYScale = function () {
35375 return this.getAttr('y').scale;
35376 };
35377 Geometry.prototype._getXSnap = function (invertPointX) {
35378 var xScale = this.getXScale();
35379 if (xScale.isCategory) {
35380 return xScale.invert(invertPointX);
35381 }
35382 // linear 类型
35383 var invertValue = xScale.invert(invertPointX);
35384 var values = xScale.values;
35385 var len = values.length;
35386 // 如果只有1个点直接返回第1个点
35387 if (len === 1) {
35388 return values[0];
35389 }
35390 // 第1个点和第2个点之间
35391 if ((values[0] + values[1]) / 2 > invertValue) {
35392 return values[0];
35393 }
35394 // 最后2个点
35395 if ((values[len - 2] + values[len - 1]) / 2 <= invertValue) {
35396 return values[len - 1];
35397 }
35398 for (var i = 1; i < len; i++) {
35399 // 中间的点
35400 if ((values[i - 1] + values[i]) / 2 <= invertValue && (values[i + 1] + values[i]) / 2 > invertValue) {
35401 return values[i];
35402 }
35403 }
35404 return null;
35405 };
35406 Geometry.prototype._getYSnapRecords = function (invertPointY, records) {
35407 var yScale = this.getYScale();
35408 var yField = yScale.field;
35409 var yValue = yScale.invert(invertPointY);
35410 // category
35411 if (yScale.isCategory) {
35412 return records.filter(function (record) {
35413 return record[FIELD_ORIGIN][yField] === yValue;
35414 });
35415 }
35416 // linear
35417 return records.filter(function (record) {
35418 var rangeY = record[yField];
35419 if (rangeY[0] <= yValue && rangeY[1] >= yValue) {
35420 return true;
35421 }
35422 return false;
35423 });
35424 };
35425 Geometry.prototype._getXSnapRecords = function (invertPointX, records) {
35426 var xScale = this.getXScale();
35427 var xField = xScale.field;
35428 var xValue = xScale.invert(invertPointX);
35429 // category
35430 if (xScale.isCategory) {
35431 return records.filter(function (record) {
35432 return record[FIELD_ORIGIN][xField] === xValue;
35433 });
35434 }
35435 // linear
35436 return records.filter(function (record) {
35437 var rangeX = record[xField];
35438 if (rangeX[0] <= xValue && rangeX[1] >= xValue) {
35439 return true;
35440 }
35441 return false;
35442 });
35443 };
35444 // 把 records 拍平
35445 Geometry.prototype.flatRecords = function () {
35446 var records = this.records;
35447 return records.reduce(function (prevRecords, record) {
35448 return prevRecords.concat(record.children);
35449 }, []);
35450 };
35451 Geometry.prototype.getSnapRecords = function (point, inCoordRange) {
35452 var props = this.props;
35453 var coord = props.coord,
35454 adjust = props.adjust;
35455 var invertPoint = coord.invertPoint(point);
35456 var xScale = this.getXScale();
35457 var yScale = this.getYScale();
35458 // 如果不在coord坐标范围内,直接返回空
35459 // if (invertPoint.x < 0 || invertPoint.y < 0) {
35460 // return [];
35461 // }
35462 // 是否调整 point,默认为不调整
35463 if (inCoordRange) {
35464 var xRange = xScale.range;
35465 var yRange = yScale.range;
35466 // 如果 inCoordRange=true,当 point 不在 coord 坐标范围内时,调整到 range 内
35467 invertPoint.x = Math.min(Math.max(invertPoint.x, xRange[0]), xRange[1]);
35468 invertPoint.y = Math.min(Math.max(invertPoint.y, yRange[0]), yRange[1]);
35469 }
35470 var records = this.flatRecords();
35471 var xValue = xScale.invert(invertPoint.x);
35472 var yValue = yScale.invert(invertPoint.y);
35473 var coordPoint = coord.convertPoint(invertPoint);
35474 var coordRecord = {
35475 // 坐标点
35476 x: coordPoint.x,
35477 y: coordPoint.y,
35478 xValue: xValue,
35479 yValue: yValue,
35480 xText: xScale.getText(xValue),
35481 yText: yScale.getText(yValue)
35482 };
35483 // 处理饼图
35484 if (adjust === 'stack' && coord.isPolar) {
35485 if (coord.transposed) {
35486 // 弧度在半径范围内
35487 if (invertPoint.x >= 0 && invertPoint.x <= 1) {
35488 var snapRecords = this._getYSnapRecords(invertPoint.y, records);
35489 return snapRecords;
35490 }
35491 } else {
35492 if (invertPoint.y >= 0 && invertPoint.y <= 1) {
35493 var snapRecords = this._getXSnapRecords(invertPoint.x, records);
35494 return snapRecords;
35495 }
35496 }
35497 }
35498 var rst = [];
35499 var value = this._getXSnap(invertPoint.x);
35500 if (isNull(value)) {
35501 return rst;
35502 }
35503 var xField = xScale.field;
35504 var yField = yScale.field;
35505 for (var i = 0, len = records.length; i < len; i++) {
35506 var record = __assign(__assign({}, records[i]), {
35507 xField: xField,
35508 yField: yField,
35509 coord: coordRecord
35510 });
35511 var originValue = record[FIELD_ORIGIN][xField];
35512 if (xScale.type === 'timeCat' && toTimeStamp$1(originValue) === value) {
35513 rst.push(record);
35514 } else if (originValue === value) {
35515 rst.push(record);
35516 }
35517 }
35518 return rst;
35519 };
35520 Geometry.prototype.getRecords = function (data, field) {
35521 if (field === void 0) {
35522 field = 'xfield';
35523 }
35524 var records = this.flatRecords();
35525 var xScale = this.getXScale();
35526 var yScale = this.getYScale();
35527 var xField = xScale.field;
35528 var yField = yScale.field;
35529 var value = data[xField];
35530 var rst = [];
35531 for (var i = 0, len = records.length; i < len; i++) {
35532 var record = __assign(__assign({}, records[i]), {
35533 xField: xField,
35534 yField: yField
35535 });
35536 var originValue = record[FIELD_ORIGIN][field === 'xfield' ? xField : yField];
35537 if (originValue === value) {
35538 rst.push(record);
35539 }
35540 }
35541 return rst;
35542 };
35543 Geometry.prototype.getLegendItems = function () {
35544 var _a = this,
35545 attrController = _a.attrController,
35546 records = _a.records;
35547 var colorAttr = attrController.getAttr('color');
35548 if (!colorAttr) return null;
35549 var scale = colorAttr.scale;
35550 var isCategory = scale.isCategory,
35551 field = scale.field;
35552 if (!isCategory) return null;
35553 var flatRecords = records ? this.flatRecords() : [];
35554 var ticks = scale.getTicks();
35555 var items = ticks.map(function (tick) {
35556 var text = tick.text,
35557 tickValue = tick.tickValue;
35558 var record = find(flatRecords, function (item) {
35559 if (!item) return false;
35560 var origin = item.origin;
35561 return origin[field] === tickValue;
35562 });
35563 // @ts-ignore
35564 var color = record ? record.color : colorAttr.mapping(tickValue);
35565 return {
35566 field: scale.field,
35567 color: color,
35568 name: text,
35569 tickValue: tickValue
35570 };
35571 });
35572 return items;
35573 };
35574 return Geometry;
35575 }(Selection);
35576
35577 var withLine = (function (View) {
35578 return /** @class */function (_super) {
35579 __extends(Line, _super);
35580 function Line() {
35581 return _super !== null && _super.apply(this, arguments) || this;
35582 }
35583 Line.prototype.getDefaultCfg = function () {
35584 return {
35585 geomType: 'line',
35586 sortable: true
35587 };
35588 };
35589 Line.prototype.splitPoints = function (points) {
35590 var topPoints = [];
35591 var bottomPoints = [];
35592 for (var i = 0, len = points.length; i < len; i++) {
35593 var point = points[i];
35594 var x = point.x,
35595 y = point.y;
35596 topPoints.push(__assign(__assign({}, point), {
35597 x: x,
35598 y: y[1]
35599 }));
35600 bottomPoints.push(__assign(__assign({}, point), {
35601 x: x,
35602 y: y[0]
35603 }));
35604 }
35605 return [topPoints, bottomPoints];
35606 };
35607 Line.prototype.splitNulls = function (points, connectNulls) {
35608 if (connectNulls) {
35609 var tmpPoints_1 = [];
35610 for (var i = 0, len = points.length; i < len; i++) {
35611 var point = points[i];
35612 var x = point.x,
35613 y = point.y;
35614 // 过滤 x 为 NaN 的点
35615 if (isNaN(x)) {
35616 continue;
35617 }
35618 if (isArray(y)) {
35619 if (isNaN(y[0])) {
35620 continue;
35621 }
35622 tmpPoints_1.push(point);
35623 continue;
35624 }
35625 if (isNaN(y)) {
35626 continue;
35627 }
35628 tmpPoints_1.push(point);
35629 }
35630 if (tmpPoints_1.length) {
35631 return [tmpPoints_1];
35632 }
35633 return [];
35634 }
35635 var result = [];
35636 var tmpPoints = [];
35637 for (var i = 0, len = points.length; i < len; i++) {
35638 var point = points[i];
35639 var x = point.x,
35640 y = point.y;
35641 // 过滤 x 为 NaN 的点
35642 if (isNaN(x)) {
35643 continue;
35644 }
35645 if (isArray(y)) {
35646 if (isNaN(y[0])) {
35647 if (tmpPoints.length) {
35648 result.push(tmpPoints);
35649 tmpPoints = [];
35650 }
35651 continue;
35652 }
35653 tmpPoints.push(point);
35654 continue;
35655 }
35656 if (isNaN(y)) {
35657 if (tmpPoints.length) {
35658 result.push(tmpPoints);
35659 tmpPoints = [];
35660 }
35661 continue;
35662 }
35663 tmpPoints.push(point);
35664 }
35665 if (tmpPoints.length) {
35666 result.push(tmpPoints);
35667 }
35668 return result;
35669 };
35670 Line.prototype.mapping = function () {
35671 var _this = this;
35672 var records = _super.prototype.mapping.call(this);
35673 var _a = this,
35674 props = _a.props,
35675 defaultConnectNulls = _a.connectNulls,
35676 context = _a.context;
35677 var coord = props.coord,
35678 _b = props.connectNulls,
35679 connectNulls = _b === void 0 ? defaultConnectNulls : _b,
35680 sizeZoom = props.sizeZoom;
35681 return records.map(function (record) {
35682 var _a;
35683 var children = record.children;
35684 // children 有可能为空
35685 var _b = children[0] || {},
35686 size = _b.size,
35687 color = _b.color,
35688 shape = _b.shape,
35689 y = _b.y,
35690 origin = _b.origin;
35691 // 极坐标时,需加入起点,从而闭合所绘图形
35692 var points = coord.isPolar ? __spreadArray(__spreadArray([], children, true), [children[0]], false) : children;
35693 var sizeZoomRatio = (_a = isFunction(sizeZoom) ? sizeZoom(origin) : sizeZoom) !== null && _a !== void 0 ? _a : 1;
35694 var splitPoints = _this.splitNulls(points, connectNulls);
35695 var newChildren = splitPoints.map(function (points) {
35696 var _a = isArray(y) ? _this.splitPoints(points) : [points, undefined],
35697 topPoints = _a[0],
35698 bottomPoints = _a[1];
35699 return {
35700 size: context.px2hd(size || shape.lineWidth) * sizeZoomRatio,
35701 color: color,
35702 shape: shape,
35703 points: [].concat(topPoints),
35704 topPoints: topPoints,
35705 bottomPoints: bottomPoints
35706 };
35707 });
35708 return __assign(__assign({}, record), {
35709 children: newChildren
35710 });
35711 });
35712 };
35713 Line.prototype.concatPoints = function (topPoints, bottomPoints) {
35714 if (!bottomPoints || !bottomPoints.length) {
35715 return topPoints;
35716 }
35717 var adjust = this.adjust;
35718 // 堆叠产生的 bottomPoints 不绘制
35719 if (adjust && adjust.type === 'stack') {
35720 return topPoints;
35721 }
35722 // 说明是 y 轴对应字段为数组, 这种情况下首尾默认相连,如果想画 2 根线,在数据里对数组分拆
35723 var points = topPoints.concat(bottomPoints.reverse());
35724 points.push(topPoints[0]);
35725 return points;
35726 };
35727 Line.prototype.render = function () {
35728 var props = this.props;
35729 var coord = props.coord;
35730 var records = this.mapping();
35731 var clip = this.getClip();
35732 for (var i = 0, len = records.length; i < len; i++) {
35733 var record = records[i];
35734 var children = record.children;
35735 for (var j = 0, len_1 = children.length; j < len_1; j++) {
35736 var child = children[j];
35737 var points = child.points,
35738 bottomPoints = child.bottomPoints;
35739 child.points = this.concatPoints(points, bottomPoints);
35740 }
35741 }
35742 return jsx(View, __assign({}, props, {
35743 coord: coord,
35744 records: records,
35745 clip: clip
35746 }));
35747 };
35748 return Line;
35749 }(Geometry);
35750 });
35751
35752 function concatPoints(children) {
35753 var result = [];
35754 for (var i = 0; i < children.length; i++) {
35755 var child = children[i];
35756 result = result.concat(child.points);
35757 }
35758 return result;
35759 }
35760 var LineView = (function (props) {
35761 var records = props.records,
35762 coord = props.coord,
35763 animation = props.animation,
35764 EndView = props.endView,
35765 clip = props.clip;
35766 var _a = coord,
35767 left = _a.left,
35768 top = _a.top,
35769 width = _a.width,
35770 height = _a.height,
35771 center = _a.center,
35772 startAngle = _a.startAngle,
35773 endAngle = _a.endAngle,
35774 radius = _a.radius;
35775 var appear = coord.isPolar ? {
35776 easing: 'quadraticOut',
35777 duration: 450,
35778 clip: {
35779 type: 'sector',
35780 property: ['endAngle'],
35781 style: {
35782 cx: center.x,
35783 cy: center.y,
35784 startAngle: "".concat(startAngle, "rad"),
35785 r: radius
35786 },
35787 start: {
35788 endAngle: "".concat(startAngle, "rad")
35789 },
35790 end: {
35791 endAngle: "".concat(endAngle, "rad")
35792 }
35793 }
35794 } : {
35795 easing: 'quadraticOut',
35796 duration: 450,
35797 clip: {
35798 type: 'rect',
35799 property: ['width'],
35800 style: {
35801 x: left,
35802 y: top,
35803 height: height
35804 },
35805 start: {
35806 width: 0
35807 },
35808 end: {
35809 width: width
35810 }
35811 }
35812 };
35813 return jsx("group", {
35814 style: {
35815 clip: clip
35816 }
35817 }, records.map(function (record) {
35818 var _a;
35819 var key = record.key,
35820 children = record.children;
35821 var points = concatPoints(children);
35822 var ref = createRef();
35823 return jsx("group", {
35824 key: key
35825 }, children.map(function (child) {
35826 var points = child.points,
35827 color = child.color,
35828 size = child.size,
35829 shape = child.shape;
35830 var fliterPoints = points.filter(function (point) {
35831 return !isNaN(point.x) && !isNaN(point.y);
35832 });
35833 if (fliterPoints.length === 0) return;
35834 return jsx("polyline", {
35835 key: key,
35836 ref: ref,
35837 style: __assign(__assign({
35838 points: fliterPoints.map(function (point) {
35839 return [point.x, point.y];
35840 }),
35841 stroke: color
35842 }, shape), {
35843 lineWidth: size || shape.lineWidth
35844 }),
35845 animation: deepMix({
35846 update: {
35847 easing: 'linear',
35848 duration: 450,
35849 property: ['points']
35850 },
35851 appear: appear
35852 }, animation)
35853 });
35854 }), EndView ? jsx("group", {
35855 style: {
35856 offset: ref
35857 },
35858 animation: deepMix({
35859 appear: {
35860 easing: 'quadraticOut',
35861 duration: 450,
35862 property: ['offsetDistance'],
35863 start: {
35864 offsetDistance: 0
35865 },
35866 end: {
35867 offsetDistance: 1
35868 }
35869 }
35870 }, animation)
35871 }, jsx(EndView, {
35872 origin: (_a = points[0]) === null || _a === void 0 ? void 0 : _a.origin
35873 })) : null);
35874 }));
35875 });
35876
35877 var index = withLine(LineView);
35878
35879 var withArea = (function (View) {
35880 return /** @class */function (_super) {
35881 __extends(Area, _super);
35882 function Area() {
35883 return _super !== null && _super.apply(this, arguments) || this;
35884 }
35885 Area.prototype.getDefaultCfg = function () {
35886 return {
35887 geomType: 'area',
35888 // 面积图默认设为从0开始
35889 startOnZero: true,
35890 // 点需要排序
35891 sortable: true
35892 };
35893 };
35894 Area.prototype.getBaseY = function () {
35895 // 坐标轴 y0
35896 var y0 = this.getY0Value();
35897 var _a = this,
35898 props = _a.props,
35899 defaultStartOnZero = _a.startOnZero;
35900 var coord = props.coord,
35901 _b = props.startOnZero,
35902 startOnZero = _b === void 0 ? defaultStartOnZero : _b;
35903 if (startOnZero) {
35904 // 零点映射到绝对坐标
35905 var originCoord = coord.convertPoint({
35906 x: 0,
35907 y: y0
35908 });
35909 return originCoord.y;
35910 }
35911 return coord.y[0];
35912 };
35913 Area.prototype.mapping = function () {
35914 var records = _super.prototype.mapping.call(this);
35915 var baseY = this.getBaseY();
35916 for (var i = 0, len = records.length; i < len; i++) {
35917 var record = records[i];
35918 var children = record.children;
35919 for (var j = 0, len_1 = children.length; j < len_1; j++) {
35920 var child = children[j];
35921 var points = child.points,
35922 bottomPoints = child.bottomPoints;
35923 if (bottomPoints && bottomPoints.length) {
35924 bottomPoints.reverse();
35925 child.points = points.concat(bottomPoints);
35926 } else {
35927 points.unshift({
35928 x: points[0].x,
35929 y: baseY
35930 });
35931 points.unshift({
35932 x: points[points.length - 1].x,
35933 y: baseY
35934 });
35935 }
35936 }
35937 }
35938 return records;
35939 };
35940 Area.prototype.render = function () {
35941 var props = this.props;
35942 var coord = props.coord;
35943 var records = this.mapping();
35944 var clip = this.getClip();
35945 var baseY = this.getBaseY();
35946 return jsx(View, __assign({}, props, {
35947 baseY: baseY,
35948 coord: coord,
35949 records: records,
35950 clip: clip
35951 }));
35952 };
35953 return Area;
35954 }(withLine(View));
35955 });
35956
35957 var AreaView = (function (props) {
35958 var coord = props.coord,
35959 records = props.records,
35960 baseY = props.baseY,
35961 shape = props.shape,
35962 animation = props.animation;
35963 var isSmooth = shape === 'smooth';
35964 var _a = coord,
35965 left = _a.left,
35966 top = _a.top,
35967 width = _a.width,
35968 height = _a.height,
35969 center = _a.center,
35970 startAngle = _a.startAngle,
35971 endAngle = _a.endAngle,
35972 radius = _a.radius;
35973 var appear = coord.isPolar ? {
35974 easing: 'quadraticOut',
35975 duration: 450,
35976 clip: {
35977 type: 'sector',
35978 property: ['endAngle'],
35979 style: {
35980 cx: center.x,
35981 cy: center.y,
35982 startAngle: "".concat(startAngle, "rad"),
35983 r: radius
35984 },
35985 start: {
35986 endAngle: "".concat(startAngle, "rad")
35987 },
35988 end: {
35989 endAngle: "".concat(endAngle, "rad")
35990 }
35991 }
35992 } : {
35993 easing: 'quadraticOut',
35994 duration: 450,
35995 clip: {
35996 type: 'rect',
35997 property: ['width'],
35998 style: {
35999 x: left,
36000 y: top,
36001 height: height
36002 },
36003 start: {
36004 width: 0
36005 },
36006 end: {
36007 width: width
36008 }
36009 }
36010 };
36011 return jsx("group", null, records.map(function (record) {
36012 var key = record.key,
36013 children = record.children;
36014 return jsx("group", {
36015 key: key
36016 }, children.map(function (child) {
36017 var points = child.points,
36018 topPoints = child.topPoints,
36019 bottomPoints = child.bottomPoints,
36020 color = child.color,
36021 shape = child.shape;
36022 if (isSmooth) {
36023 var generatePath = function generatePath() {
36024 var d = [];
36025 var constaint = [[0, 0], [1, 1]];
36026 var topSps = catmullRom2bezier(topPoints, false, constaint);
36027 d.push(['M', topPoints[0].x, topPoints[0].y]);
36028 for (var i = 0, n = topSps.length; i < n; i++) {
36029 var sp = topSps[i];
36030 d.push(['C', sp[1], sp[2], sp[3], sp[4], sp[5], sp[6]]);
36031 }
36032 if (bottomPoints && bottomPoints.length) {
36033 var bottomSps = catmullRom2bezier(bottomPoints, false, constaint);
36034 d.push(['L', bottomPoints[0].x, bottomPoints[0].y]);
36035 for (var i = 0, n = bottomSps.length; i < n; i++) {
36036 var sp = bottomSps[i];
36037 d.push(['C', sp[1], sp[2], sp[3], sp[4], sp[5], sp[6]]);
36038 }
36039 } else {
36040 d.push(['L', topPoints[topPoints.length - 1].x, baseY]);
36041 d.push(['L', topPoints[0].x, baseY]);
36042 }
36043 return d;
36044 };
36045 return jsx("path", {
36046 style: __assign({
36047 path: generatePath(),
36048 lineWidth: '2px',
36049 fill: color
36050 }, shape)
36051 });
36052 }
36053 return jsx("polygon", {
36054 style: __assign({
36055 points: points.map(function (point) {
36056 return [point.x, point.y];
36057 }),
36058 lineWidth: '2px',
36059 fill: color
36060 }, shape),
36061 animation: deepMix({
36062 appear: appear,
36063 update: {
36064 easing: 'linear',
36065 duration: 450,
36066 property: ['points']
36067 }
36068 }, animation)
36069 });
36070 }));
36071 }));
36072 });
36073
36074 var index$1 = withArea(AreaView);
36075
36076 /**
36077 * 计算两个坐标的中点坐标
36078 * @param start 起始点{x:number, y:number}
36079 * @param end 结束点{x:number, y:number}
36080 * @returns 中点坐标{x:number, y:number}
36081 */
36082 function getMiddlePoint(start, end) {
36083 var x = (end.x - start.x) / 2 + start.x;
36084 var y = (end.y - start.y) / 2 + start.y;
36085 return {
36086 x: x,
36087 y: y
36088 };
36089 }
36090
36091 var DEFAULT_LABEL_CFG = {
36092 textBaseline: 'middle',
36093 fill: '#808080'
36094 };
36095 function LabelView(props) {
36096 var _a;
36097 var record = props.record,
36098 offsetX = props.offsetX,
36099 offsetY = props.offsetY,
36100 points = props.points,
36101 label = props.label,
36102 guide = props.guide;
36103 var origin = record.origin,
36104 color = record.color;
36105 var labelAttrs, guideAttrs;
36106 if (isFunction(label)) {
36107 var point = points.length === 4 // 如果是金字塔图,顶部只有 3 个点
36108 ? getMiddlePoint(points[1], points[2]) : getMiddlePoint(points[0], points[1]);
36109 labelAttrs = mix({
36110 x: point.x + offsetX,
36111 y: point.y + offsetY
36112 }, DEFAULT_LABEL_CFG, label(origin, color));
36113 }
36114 if (isFunction(guide)) {
36115 var point = getMiddlePoint(points.length === 4 ? getMiddlePoint(points[0], points[1]) : points[0], getMiddlePoint(points[2], (_a = points[3]) !== null && _a !== void 0 ? _a : points[1]));
36116 guideAttrs = mix({
36117 x: point.x,
36118 y: point.y,
36119 textBaseline: 'middle',
36120 textAlign: 'center'
36121 }, DEFAULT_LABEL_CFG, guide(origin, color));
36122 }
36123 return jsx("group", null, labelAttrs && jsx("text", {
36124 attrs: labelAttrs
36125 }), guideAttrs && jsx("text", {
36126 attrs: guideAttrs
36127 }));
36128 }
36129
36130 var LabelViews = /*#__PURE__*/Object.freeze({
36131 __proto__: null,
36132 pyramid: LabelView,
36133 funnel: LabelView
36134 });
36135
36136 var withInterval = (function (Views) {
36137 return /** @class */function (_super) {
36138 __extends(Interval, _super);
36139 function Interval() {
36140 return _super !== null && _super.apply(this, arguments) || this;
36141 }
36142 Interval.prototype.getDefaultCfg = function () {
36143 return {
36144 geomType: 'interval',
36145 justifyContent: true,
36146 startOnZero: true
36147 };
36148 };
36149 Interval.prototype.getDefaultSize = function () {
36150 var _a = this,
36151 attrs = _a.attrs,
36152 props = _a.props,
36153 adjust = _a.adjust,
36154 records = _a.records;
36155 var coord = props.coord,
36156 sizeRatio = props.sizeRatio;
36157 var x = attrs.x;
36158 var scale = x.scale;
36159 var values = scale.values;
36160 if (sizeRatio) {
36161 return 1 / values.length * sizeRatio;
36162 }
36163 var defaultWithRatio = {
36164 column: 1 / 2,
36165 rose: 0.999999,
36166 multiplePie: 3 / 4 // 多饼图
36167 };
36168 var count = values.length;
36169 var ratio;
36170 if (coord.isPolar) {
36171 if (coord.transposed && count > 1) {
36172 ratio = defaultWithRatio.multiplePie;
36173 } else {
36174 ratio = defaultWithRatio.rose;
36175 }
36176 } else {
36177 ratio = defaultWithRatio.column;
36178 }
36179 var size = 1 / values.length * ratio;
36180 // 分组时size要除以类别个数
36181 if (adjust && adjust.type === 'dodge') {
36182 return size / records.length;
36183 }
36184 return size;
36185 };
36186 Interval.prototype.mapping = function () {
36187 var _a;
36188 var records = _super.prototype.mapping.call(this);
36189 var props = this.props;
36190 var coord = props.coord,
36191 sizeZoom = props.sizeZoom;
36192 var y0 = this.getY0Value();
36193 var defaultSize = this.getDefaultSize();
36194 for (var i = 0, len = records.length; i < len; i++) {
36195 var record = records[i];
36196 var children = record.children;
36197 for (var j = 0, len_1 = children.length; j < len_1; j++) {
36198 var child = children[j];
36199 var normalized = child.normalized,
36200 mappedSize = child.size,
36201 origin_1 = child.origin;
36202 // 没有指定size,则根据数据来计算默认size
36203 if (isNil(mappedSize)) {
36204 var x = normalized.x,
36205 y = normalized.y,
36206 _b = normalized.size,
36207 size = _b === void 0 ? defaultSize : _b;
36208 var zoomRatio = (_a = isFunction(sizeZoom) ? sizeZoom(origin_1) : sizeZoom) !== null && _a !== void 0 ? _a : 1;
36209 mix(child, coord.convertRect({
36210 x: x,
36211 y: y,
36212 y0: y0,
36213 size: size * zoomRatio
36214 }));
36215 } else {
36216 var x = child.x,
36217 y = child.y;
36218 var rect = {
36219 size: mappedSize,
36220 x: x,
36221 y: y,
36222 y0: y0
36223 };
36224 mix(child, coord.transformToRect(rect));
36225 }
36226 mix(child.shape, this.getSelectionStyle(child));
36227 }
36228 }
36229 return records;
36230 };
36231 // 获取Y轴坐标零点的画布位置
36232 Interval.prototype.getPointY0 = function () {
36233 var props = this.props;
36234 var coord = props.coord;
36235 var y0 = this.getY0Value();
36236 var y0Point = coord.convertPoint({
36237 y: y0,
36238 x: 0
36239 });
36240 return y0Point === null || y0Point === void 0 ? void 0 : y0Point.y;
36241 };
36242 Interval.prototype.render = function () {
36243 var _a = this,
36244 props = _a.props,
36245 state = _a.state;
36246 var coord = props.coord,
36247 _b = props.shape,
36248 shape = _b === void 0 ? 'rect' : _b,
36249 animation = props.animation,
36250 showLabel = props.showLabel,
36251 customLabelCfg = props.labelCfg;
36252 var View = isFunction(Views) ? Views : Views[shape];
36253 var LabelView = LabelViews[shape];
36254 var labelCfg = deepMix({
36255 label: null,
36256 offsetX: 0,
36257 offsetY: 0
36258 }, customLabelCfg);
36259 if (!View) return null;
36260 var selected = state.selected;
36261 var records = this.mapping();
36262 var pointY0 = this.getPointY0();
36263 var clip = this.getClip();
36264 return jsx(View, {
36265 coord: coord,
36266 records: records,
36267 selected: selected,
36268 shape: shape,
36269 animation: animation,
36270 showLabel: showLabel,
36271 labelCfg: labelCfg,
36272 LabelView: LabelView,
36273 y0: pointY0,
36274 clip: clip
36275 });
36276 };
36277 return Interval;
36278 }(Geometry);
36279 });
36280
36281 var Rect$2 = (function (props) {
36282 var records = props.records,
36283 animation = props.animation,
36284 y0 = props.y0,
36285 clip = props.clip,
36286 onClick = props.onClick;
36287 return jsx("group", {
36288 attrs: {
36289 clip: clip
36290 }
36291 }, records.map(function (record) {
36292 var key = record.key,
36293 children = record.children;
36294 return jsx("group", {
36295 key: key
36296 }, children.map(function (item) {
36297 var key = item.key,
36298 xMin = item.xMin,
36299 xMax = item.xMax,
36300 yMin = item.yMin,
36301 yMax = item.yMax,
36302 color = item.color,
36303 shape = item.shape;
36304 if (isNaN(xMin) || isNaN(xMax) || isNaN(yMin) || isNaN(yMax)) {
36305 return null;
36306 }
36307 return jsx("rect", {
36308 key: key,
36309 attrs: __assign({
36310 x: xMin,
36311 y: yMin,
36312 width: xMax - xMin,
36313 height: yMax - yMin,
36314 fill: color
36315 }, shape),
36316 onClick: onClick,
36317 animation: deepMix({
36318 appear: {
36319 easing: 'linear',
36320 duration: 450,
36321 property: ['y', 'height'],
36322 start: {
36323 y: y0,
36324 height: 0
36325 }
36326 },
36327 update: {
36328 easing: 'linear',
36329 duration: 450,
36330 property: ['x', 'y', 'width', 'height']
36331 }
36332 }, animation)
36333 });
36334 }));
36335 }));
36336 });
36337
36338 var Polar$1 = (function (props) {
36339 var coord = props.coord,
36340 records = props.records,
36341 animation = props.animation,
36342 onClick = props.onClick;
36343 var center = coord.center,
36344 startAngle = coord.startAngle,
36345 endAngle = coord.endAngle,
36346 radius = coord.radius;
36347 return jsx("group", {
36348 animation: {
36349 appear: __assign({
36350 easing: 'quadraticOut',
36351 duration: 450,
36352 clip: {
36353 type: 'sector',
36354 property: ['endAngle'],
36355 style: {
36356 cx: center.x,
36357 cy: center.y,
36358 startAngle: "".concat(startAngle, "rad"),
36359 r: radius
36360 },
36361 start: {
36362 endAngle: "".concat(startAngle, "rad")
36363 },
36364 end: {
36365 endAngle: "".concat(endAngle, "rad")
36366 }
36367 }
36368 }, animation && animation.appear)
36369 }
36370 }, records.map(function (record) {
36371 var key = record.key,
36372 children = record.children;
36373 return jsx("group", {
36374 key: key
36375 }, children.map(function (item) {
36376 var key = item.key,
36377 xMin = item.xMin,
36378 xMax = item.xMax,
36379 yMin = item.yMin,
36380 yMax = item.yMax,
36381 color = item.color,
36382 shape = item.shape;
36383 return jsx("sector", {
36384 key: key,
36385 attrs: __assign({
36386 cx: center.x,
36387 cy: center.y,
36388 fill: color,
36389 lineWidth: 1,
36390 startAngle: "".concat(xMin, "rad"),
36391 endAngle: "".concat(xMax, "rad"),
36392 r0: yMin,
36393 r: yMax
36394 }, shape),
36395 onClick: onClick,
36396 animation: deepMix({
36397 update: {
36398 easing: 'linear',
36399 duration: 450,
36400 property: ['x', 'y', 'startAngle', 'endAngle', 'r0', 'r']
36401 }
36402 }, animation)
36403 });
36404 }));
36405 }));
36406 });
36407
36408 var intervalView = (function (props) {
36409 var coord = props.coord;
36410 var coordType = coord.type;
36411 // 直角坐标系
36412 if (coordType === 'rect') {
36413 return jsx(Rect$2, __assign({}, props));
36414 }
36415 // 极坐标系
36416 return jsx(Polar$1, __assign({}, props));
36417 });
36418
36419 function convertToPoints(_a) {
36420 var xMin = _a.xMin,
36421 xMax = _a.xMax,
36422 yMin = _a.yMin,
36423 yMax = _a.yMax;
36424 return [{
36425 x: xMin,
36426 y: yMin
36427 }, {
36428 x: xMax,
36429 y: yMin
36430 }, {
36431 x: xMax,
36432 y: yMax
36433 }, {
36434 x: xMin,
36435 y: yMax
36436 } // bl
36437 ];
36438 }
36439
36440 // 金字塔图和漏斗图的View
36441 var polygonView = (function (props) {
36442 var records = props.records,
36443 shape = props.shape,
36444 showLabel = props.showLabel,
36445 labelCfg = props.labelCfg,
36446 LabelView = props.LabelView;
36447 // 是否倒置
36448 var overturn = false;
36449 return jsx("group", null, records.map(function (record, index) {
36450 var key = record.key,
36451 children = record.children;
36452 var isLastRecord = index === records.length - 1;
36453 var nextRecord = isLastRecord ? record : records[index + 1];
36454 var nextChildren = nextRecord.children;
36455 var nextFirstPoint = convertToPoints(nextChildren[0]);
36456 var nextLastPoints = convertToPoints(nextChildren[nextChildren.length - 1]);
36457 if (!overturn) {
36458 overturn = nextChildren[0].yMax > children[0].yMax;
36459 }
36460 if (overturn) {
36461 nextFirstPoint.reverse();
36462 nextLastPoints.reverse();
36463 }
36464 var polygonPoints = children.map(function (child, childIndex) {
36465 var points = convertToPoints(child);
36466 if (overturn) {
36467 points.reverse();
36468 }
36469 if (isLastRecord) {
36470 if (shape === 'pyramid') {
36471 points = [getMiddlePoint(points[0], points[1]), points[2], points[3]];
36472 }
36473 } else {
36474 if (childIndex === 0) {
36475 points[0] = nextFirstPoint[3];
36476 }
36477 if (childIndex === children.length - 1) {
36478 points[1] = nextLastPoints[2];
36479 }
36480 }
36481 return __assign(__assign({}, child), {
36482 points: points
36483 });
36484 });
36485 return jsx("group", {
36486 key: key
36487 }, polygonPoints.map(function (child) {
36488 var points = child.points,
36489 color = child.color,
36490 shape = child.shape;
36491 return jsx("group", null, jsx("polygon", {
36492 attrs: __assign({
36493 points: points.map(function (d) {
36494 return [d.x, d.y];
36495 }),
36496 fill: color
36497 }, shape)
36498 }), showLabel && LabelView ? jsx(LabelView, __assign({
36499 record: child,
36500 points: points
36501 }, labelCfg)) : null);
36502 }));
36503 }));
36504 });
36505
36506 // 柱图/条图
36507
36508 var Views = /*#__PURE__*/Object.freeze({
36509 __proto__: null,
36510 rect: intervalView,
36511 pyramid: polygonView,
36512 funnel: polygonView
36513 });
36514
36515 var index$2 = withInterval(Views);
36516
36517 var withPoint = (function (View) {
36518 return /** @class */function (_super) {
36519 __extends(Point, _super);
36520 function Point() {
36521 return _super !== null && _super.apply(this, arguments) || this;
36522 }
36523 Point.prototype.getDefaultCfg = function () {
36524 return {
36525 geomType: 'point'
36526 };
36527 };
36528 Point.prototype.render = function () {
36529 var props = this.props;
36530 var coord = props.coord;
36531 var records = this.mapping();
36532 var clip = this.getClip();
36533 return jsx(View, __assign({}, props, {
36534 coord: coord,
36535 records: records,
36536 clip: clip
36537 }));
36538 };
36539 return Point;
36540 }(Geometry);
36541 });
36542
36543 var PointView = (function (props) {
36544 var records = props.records,
36545 animation = props.animation,
36546 clip = props.clip;
36547 return jsx("group", {
36548 attrs: {
36549 clip: clip
36550 }
36551 }, records.map(function (record) {
36552 var key = record.key,
36553 children = record.children;
36554 return jsx("group", {
36555 key: key
36556 }, children.map(function (item) {
36557 var x = item.x,
36558 y = item.y,
36559 size = item.size,
36560 color = item.color,
36561 shapeName = item.shapeName,
36562 shape = item.shape;
36563 if (isNaN(x) || isNaN(y)) {
36564 return null;
36565 }
36566 if (shapeName === 'rect') {
36567 var rectSize = isNil(size) ? shape.size : size;
36568 return jsx("rect", {
36569 key: key,
36570 attrs: __assign(__assign({
36571 x: x - rectSize,
36572 y: y - rectSize,
36573 fill: color,
36574 stroke: color
36575 }, shape), {
36576 width: rectSize * 2,
36577 height: rectSize * 2
36578 }),
36579 animation: deepMix({
36580 appear: {
36581 easing: 'linear',
36582 duration: 450
36583 },
36584 update: {
36585 easing: 'linear',
36586 duration: 450,
36587 property: ['x', 'y', 'width', 'height', 'fill']
36588 }
36589 }, animation)
36590 });
36591 }
36592 return jsx("circle", {
36593 key: key,
36594 style: __assign(__assign({
36595 cx: x,
36596 cy: y,
36597 fill: shapeName === 'circle' ? color : null,
36598 stroke: shapeName === 'hollowCircle' ? color : null
36599 }, shape), {
36600 r: isNil(size) ? shape.size : size
36601 }),
36602 animation: deepMix({
36603 appear: {
36604 easing: 'linear',
36605 duration: 450
36606 },
36607 update: {
36608 easing: 'linear',
36609 duration: 450,
36610 property: ['cx', 'cy', 'r', 'fill']
36611 }
36612 }, animation)
36613 });
36614 }));
36615 }));
36616 });
36617
36618 var index$3 = withPoint(PointView);
36619
36620 var withAxis = (function (View) {
36621 return /** @class */function (_super) {
36622 __extends(Axis, _super);
36623 function Axis(props) {
36624 var _this = _super.call(this, props) || this;
36625 _this.axisStyle = {};
36626 var chart = props.chart,
36627 field = props.field;
36628 var scaleOption = _this.getScaleOption(props);
36629 chart.setScale(field, scaleOption);
36630 return _this;
36631 }
36632 Axis.prototype.willReceiveProps = function (nextProps) {
36633 var lastProps = this.props;
36634 var chart = nextProps.chart,
36635 field = nextProps.field;
36636 var nextScaleOption = this.getScaleOption(nextProps);
36637 var lastScaleOption = this.getScaleOption(lastProps);
36638 if (!equal(nextScaleOption, lastScaleOption)) {
36639 chart.setScale(field, nextScaleOption);
36640 }
36641 };
36642 Axis.prototype.willMount = function () {
36643 this.updateCoord();
36644 };
36645 Axis.prototype.willUpdate = function () {
36646 this.updateCoord();
36647 };
36648 Axis.prototype.getScaleOption = function (props) {
36649 var type = props.type,
36650 tickCount = props.tickCount,
36651 range = props.range,
36652 mask = props.mask,
36653 formatter = props.formatter,
36654 ticks = props.ticks,
36655 min = props.min,
36656 max = props.max,
36657 nice = props.nice;
36658 return {
36659 type: type,
36660 tickCount: tickCount,
36661 range: range,
36662 mask: mask,
36663 formatter: formatter,
36664 min: min,
36665 max: max,
36666 nice: nice,
36667 ticks: ticks
36668 };
36669 };
36670 Axis.prototype._getDimType = function () {
36671 var props = this.props;
36672 var field = props.field,
36673 chart = props.chart;
36674 var xScales = chart.getXScales();
36675 var scales = xScales.filter(function (scale) {
36676 return scale.field === field;
36677 });
36678 return scales.length > 0 ? 'x' : 'y';
36679 };
36680 // 获取ticks最大的宽高
36681 Axis.prototype.getMaxBBox = function (ticks, style) {
36682 var context = this.context;
36683 var measureText = context.measureText;
36684 var label = style.label,
36685 labelOffset = style.labelOffset;
36686 var width = 0;
36687 var height = 0;
36688 ticks.forEach(function (tick) {
36689 if (!label) return;
36690 var _a = tick.labelStyle,
36691 labelStyle = _a === void 0 ? {} : _a,
36692 text = tick.text;
36693 var bbox = measureText(labelStyle.text || text, __assign(__assign({}, label), labelStyle));
36694 width = Math.max(width, bbox.width);
36695 height = Math.max(height, bbox.height);
36696 });
36697 if (!width && !height) {
36698 return {
36699 width: width,
36700 height: height
36701 };
36702 }
36703 var bbox = {
36704 width: width + labelOffset,
36705 height: height + labelOffset
36706 };
36707 return bbox;
36708 };
36709 Axis.prototype._getPosition = function () {
36710 var props = this.props;
36711 var position = props.position,
36712 coord = props.coord;
36713 if (position) {
36714 return position;
36715 }
36716 var dimType = this._getDimType();
36717 if (coord.transposed) {
36718 return dimType === 'x' ? 'left' : 'bottom';
36719 }
36720 return dimType === 'x' ? 'bottom' : 'left';
36721 };
36722 Axis.prototype.getTicks = function () {
36723 var props = this.props;
36724 var field = props.field,
36725 chart = props.chart;
36726 var scale = chart.getScale(field);
36727 var ticks = scale.getTicks();
36728 // 设置tick的样式
36729 ticks = this._setTicksStyle(ticks);
36730 ticks = this._generateGridPoints(ticks);
36731 return ticks;
36732 };
36733 /**
36734 * 生成极坐标下网格线的交叉点
36735 * @param ticks
36736 * @returns
36737 */
36738 Axis.prototype._generateGridPoints = function (ticks) {
36739 var props = this.props;
36740 var chart = props.chart,
36741 coord = props.coord;
36742 if (!coord.isPolar) {
36743 return ticks;
36744 }
36745 var dimType = this._getDimType();
36746 // 只需要在 y 的时候生成
36747 if (dimType !== 'y') {
36748 return ticks;
36749 }
36750 var xScale = chart.getXScales()[0];
36751 var xTicks = xScale.getTicks();
36752 ticks.forEach(function (tick) {
36753 var gridPoints = xTicks.map(function (xTick) {
36754 return coord.convertPoint({
36755 x: xTick.value,
36756 y: tick.value
36757 });
36758 });
36759 // 添加第 1 个点,形成环状
36760 gridPoints.push(gridPoints[0]);
36761 tick.gridPoints = gridPoints;
36762 });
36763 return ticks;
36764 };
36765 Axis.prototype._setTicksStyle = function (ticks) {
36766 var _this = this;
36767 var _a = this,
36768 props = _a.props,
36769 context = _a.context;
36770 var theme = context.theme,
36771 px2hd = context.px2hd;
36772 var _b = props.style,
36773 style = _b === void 0 ? {} : _b;
36774 var themeAxis = theme.axis;
36775 each(themeAxis, function (value, key) {
36776 // 关闭tick的样式
36777 if (style[key] === null) {
36778 return;
36779 }
36780 var styleValue = isFunction(style[key]) ? undefined : style[key];
36781 if (isString(value) || isNumber(value)) {
36782 _this.axisStyle[key] = px2hd(styleValue) || value;
36783 } else if (isArray(styleValue)) {
36784 _this.axisStyle[key] = styleValue.map(function (d) {
36785 return px2hd(deepMix(clone(value), d));
36786 });
36787 } else {
36788 _this.axisStyle[key] = px2hd(deepMix(clone(value), styleValue));
36789 }
36790 });
36791 return ticks.map(function (tick, index) {
36792 var label = style.label,
36793 grid = style.grid;
36794 var defaultLabelStyle = themeAxis.label,
36795 defaultGridStyle = themeAxis.grid;
36796 if (isFunction(label)) {
36797 tick.labelStyle = px2hd(mix({}, defaultLabelStyle, label(tick.text, index, ticks)));
36798 }
36799 if (isFunction(grid)) {
36800 tick.gridStyle = px2hd(mix({}, defaultGridStyle, grid(tick.text, index, ticks.length)));
36801 }
36802 return tick;
36803 });
36804 };
36805 Axis.prototype.convertTicks = function (ticks) {
36806 var props = this.props;
36807 var coord = props.coord;
36808 var dimType = this._getDimType();
36809 var otherDim = dimType === 'x' ? 'y' : 'x';
36810 return ticks.map(function (tick) {
36811 var _a, _b;
36812 var start = coord.convertPoint((_a = {}, _a[dimType] = tick.value, _a[otherDim] = 0, _a));
36813 var end = coord.convertPoint((_b = {}, _b[dimType] = tick.value, _b[otherDim] = 1, _b));
36814 return __assign(__assign({}, tick), {
36815 points: [start, end]
36816 });
36817 });
36818 };
36819 Axis.prototype.measureLayout = function () {
36820 var _a = this,
36821 props = _a.props,
36822 context = _a.context;
36823 var visible = props.visible,
36824 coord = props.coord,
36825 style = props.style;
36826 if (visible === false) {
36827 return null;
36828 }
36829 var _b = style || {},
36830 customWidth = _b.width,
36831 customHeight = _b.height;
36832 var ticks = this.getTicks();
36833 var bbox = this.getMaxBBox(ticks, this.axisStyle);
36834 var isPolar = coord.isPolar;
36835 var dimType = this._getDimType();
36836 // const { width, height } = bbox;
36837 var width = isNil(customWidth) ? bbox.width : context.px2hd(customWidth);
36838 var height = isNil(customHeight) ? bbox.height : context.px2hd(customHeight);
36839 if (isPolar) {
36840 // 机坐标系的 y 不占位置
36841 if (dimType === 'y') {
36842 return null;
36843 }
36844 // 4 个方向都需要留空
36845 return ['top', 'right', 'bottom', 'left'].map(function (position) {
36846 return {
36847 position: position,
36848 width: width,
36849 height: height
36850 };
36851 });
36852 }
36853 // 直角坐标系下
36854 var position = this._getPosition();
36855 return {
36856 position: position,
36857 width: width,
36858 height: height
36859 };
36860 };
36861 // 主要是计算coord的布局
36862 Axis.prototype.updateCoord = function () {
36863 var props = this.props;
36864 var chart = props.chart;
36865 var layout = this.measureLayout();
36866 chart.updateCoordFor(this, layout);
36867 };
36868 Axis.prototype.render = function () {
36869 var _a = this,
36870 props = _a.props,
36871 axisStyle = _a.axisStyle;
36872 var visible = props.visible,
36873 coord = props.coord;
36874 if (visible === false) {
36875 return null;
36876 }
36877 var ticks = this.getTicks();
36878 var position = this._getPosition();
36879 var dimType = this._getDimType();
36880 return jsx(View, __assign({}, props, {
36881 style: axisStyle,
36882 ticks: this.convertTicks(ticks),
36883 coord: coord,
36884 position: position,
36885 dimType: dimType
36886 }));
36887 };
36888 return Axis;
36889 }(Component);
36890 });
36891
36892 // 相对圆心偏移量的点
36893 function getOffsetPoint(center, point, offset) {
36894 var vectorX = point.x - center.x;
36895 var vectorY = point.y - center.y;
36896 var vectorLength = length$1([vectorX, vectorY]);
36897 var offsetLength = vectorLength + offset;
36898 var x = vectorX / vectorLength * offsetLength;
36899 var y = vectorY / vectorLength * offsetLength;
36900 return {
36901 x: center.x + x,
36902 y: center.y + y
36903 };
36904 }
36905 // 获取文本的对齐方式
36906 function getTextAlignInfo(center, point) {
36907 // 文本点向量
36908 var vector = [point.x - center.x, point.y - center.y];
36909 var align;
36910 var baseLine;
36911 // 水平对齐
36912 if (vector[0] > 0) {
36913 align = 'left';
36914 } else if (vector[0] < 0) {
36915 align = 'right';
36916 } else {
36917 align = 'center';
36918 }
36919 // 垂直对齐
36920 if (vector[1] > 0) {
36921 baseLine = 'top';
36922 } else if (vector[1] < 0) {
36923 baseLine = 'bottom';
36924 } else {
36925 baseLine = 'middle';
36926 }
36927 return {
36928 textAlign: align,
36929 textBaseline: baseLine
36930 };
36931 }
36932 var Line$1 = function Line(props) {
36933 var line = props.line,
36934 gridType = props.gridType,
36935 center = props.center,
36936 radius = props.radius,
36937 ticks = props.ticks;
36938 if (!line) return null;
36939 if (gridType !== 'line') {
36940 return jsx("arc", {
36941 attrs: __assign({
36942 cx: center.x,
36943 cy: center.y,
36944 r: radius,
36945 startAngle: 0,
36946 endAngle: 360
36947 }, line)
36948 });
36949 }
36950 var points = ticks.map(function (tick) {
36951 var points = tick.points;
36952 return points[points.length - 1];
36953 });
36954 // 头尾相连
36955 points.push(points[0]);
36956 return jsx("polyline", {
36957 attrs: __assign({
36958 points: points.map(function (d) {
36959 return [d.x, d.y];
36960 })
36961 }, line)
36962 });
36963 };
36964 var PolarX = (function (props) {
36965 var originTicks = props.ticks,
36966 coord = props.coord,
36967 style = props.style,
36968 gridType = props.grid;
36969 var center = coord.center;
36970 var grid = style.grid,
36971 tickLine = style.tickLine,
36972 line = style.line,
36973 labelOffset = style.labelOffset,
36974 label = style.label;
36975 var ticks = originTicks.filter(function (d) {
36976 return !isNaN(d.value);
36977 });
36978 var firstTicks = ticks[0];
36979 var points = firstTicks.points;
36980 var end = points[points.length - 1];
36981 var radius = length$1([end.x - center.x, end.y - center.y]);
36982 return jsx("group", null, grid ? ticks.map(function (tick) {
36983 var points = tick.points,
36984 gridStyle = tick.gridStyle;
36985 var end = points[points.length - 1];
36986 return jsx("line", {
36987 attrs: __assign(__assign({
36988 x1: center.x,
36989 y1: center.y,
36990 x2: end.x,
36991 y2: end.y
36992 }, grid), gridStyle)
36993 });
36994 }) : null, tickLine && tickLine.length ? ticks.map(function (tick) {
36995 var points = tick.points;
36996 var end = points[points.length - 1];
36997 var offsetPoint = getOffsetPoint(center, end, tickLine.length);
36998 return jsx("line", {
36999 attrs: __assign({
37000 x1: end.x,
37001 y1: end.y,
37002 x2: offsetPoint.x,
37003 y2: offsetPoint.y
37004 }, tickLine)
37005 });
37006 }) : null, jsx(Line$1, {
37007 line: line,
37008 gridType: gridType,
37009 center: center,
37010 radius: radius,
37011 ticks: ticks
37012 }), label ? ticks.map(function (tick) {
37013 var points = tick.points,
37014 text = tick.text,
37015 labelStyle = tick.labelStyle;
37016 var end = points[points.length - 1];
37017 var offsetPoint = getOffsetPoint(center, end, labelOffset);
37018 return jsx("text", {
37019 attrs: __assign(__assign(__assign({
37020 x: offsetPoint.x,
37021 y: offsetPoint.y,
37022 text: text
37023 }, getTextAlignInfo(center, end)), label), labelStyle)
37024 });
37025 }) : null);
37026 });
37027
37028 var PolarY = (function (props) {
37029 var originTicks = props.ticks,
37030 coord = props.coord,
37031 style = props.style,
37032 gridType = props.grid;
37033 var center = coord.center;
37034 var grid = style.grid,
37035 tickLine = style.tickLine,
37036 line = style.line,
37037 labelOffset = style.labelOffset,
37038 label = style.label;
37039 var ticks = originTicks.filter(function (d) {
37040 return !isNaN(d.value);
37041 });
37042 return jsx("group", null, grid ? ticks.map(function (tick) {
37043 var points = tick.points,
37044 gridStyle = tick.gridStyle,
37045 gridPoints = tick.gridPoints;
37046 var end = points[points.length - 1];
37047 if (gridType !== 'line') {
37048 return jsx("arc", {
37049 style: __assign(__assign({
37050 cx: center.x,
37051 cy: center.y,
37052 startAngle: 0,
37053 endAngle: 360,
37054 r: length$1([end.x - center.x, end.y - center.y])
37055 }, grid), gridStyle)
37056 });
37057 }
37058 return jsx("polyline", {
37059 attrs: __assign(__assign({
37060 points: gridPoints.map(function (d) {
37061 return [d.x, d.y];
37062 })
37063 }, grid), gridStyle)
37064 });
37065 }) : null, tickLine && tickLine.length ? ticks.map(function (tick) {
37066 var points = tick.points;
37067 var end = points[points.length - 1];
37068 return jsx("line", {
37069 attrs: __assign({
37070 x1: end.x,
37071 y1: end.y,
37072 x2: end.x - tickLine.length,
37073 y2: end.y
37074 }, tickLine)
37075 });
37076 }) : null, line ? jsx("line", {
37077 attrs: __assign({
37078 x1: ticks[0].points[0].x,
37079 y1: ticks[0].points[0].y,
37080 x2: ticks[ticks.length - 1].points[0].x,
37081 y2: ticks[ticks.length - 1].points[0].y
37082 }, line)
37083 }) : null, label ? ticks.map(function (tick) {
37084 var points = tick.points,
37085 text = tick.text,
37086 labelStyle = tick.labelStyle;
37087 var end = points[points.length - 1];
37088 return jsx("text", {
37089 attrs: __assign(__assign({
37090 x: end.x - labelOffset,
37091 y: end.y,
37092 text: text,
37093 textAlign: 'right',
37094 textBaseline: 'middle'
37095 }, label), labelStyle)
37096 });
37097 }) : null);
37098 });
37099
37100 var Top = (function (props, context) {
37101 var originTicks = props.ticks,
37102 coord = props.coord,
37103 style = props.style;
37104 var px2hd = context.px2hd;
37105 var left = coord.left,
37106 top = coord.top,
37107 right = coord.right;
37108 var grid = style.grid,
37109 tickLine = style.tickLine,
37110 line = style.line,
37111 labelOffset = style.labelOffset,
37112 label = style.label,
37113 symbol = style.symbol;
37114 var ticks = originTicks.filter(function (d) {
37115 return !isNaN(d.value);
37116 });
37117 var symbols = isArray(symbol) ? symbol : [symbol];
37118 var _a = tickLine || {},
37119 tickLineLength = _a.length,
37120 tickLineStyle = __rest(_a, ["length"]);
37121 return jsx("group", null, grid ? ticks.map(function (tick) {
37122 var points = tick.points,
37123 tickValue = tick.tickValue,
37124 gridStyle = tick.gridStyle;
37125 var start = points[0];
37126 var end = points[points.length - 1];
37127 return jsx("line", {
37128 key: "grid-".concat(tickValue),
37129 style: __assign(__assign({
37130 x1: start.x,
37131 y1: start.y,
37132 x2: end.x,
37133 y2: end.y
37134 }, grid), gridStyle)
37135 });
37136 }) : null, tickLine && tickLine.length ? ticks.map(function (tick) {
37137 var points = tick.points,
37138 tickValue = tick.tickValue;
37139 var end = points[points.length - 1];
37140 return jsx("line", {
37141 key: "tickLine-".concat(tickValue),
37142 style: __assign({
37143 x1: end.x,
37144 y1: end.y,
37145 x2: end.x,
37146 y2: end.y - px2hd(tickLineLength)
37147 }, tickLineStyle)
37148 });
37149 }) : null, symbols[0] ? jsx("marker", {
37150 style: __assign(__assign({
37151 x: right,
37152 y: top,
37153 transform: 'rotate(90deg)',
37154 transformOrigin: '50% 50%'
37155 }, symbols[0]), {
37156 symbol: symbols[0].type
37157 })
37158 }) : null, line ? jsx("line", {
37159 style: __assign({
37160 x1: left,
37161 y1: top,
37162 x2: right,
37163 y2: top
37164 }, line)
37165 }) : null, symbols[1] ? jsx("marker", {
37166 style: __assign(__assign({
37167 x: left,
37168 y: top,
37169 transform: 'rotate(-90deg)',
37170 transformOrigin: '50% 50%'
37171 }, symbols[0]), {
37172 symbol: symbols[1].type
37173 })
37174 }) : null, label ? ticks.map(function (tick, _index) {
37175 var tickValue = tick.tickValue,
37176 points = tick.points,
37177 text = tick.text,
37178 labelStyle = tick.labelStyle;
37179 var end = points[points.length - 1];
37180 return jsx("text", {
37181 key: "text-".concat(tickValue),
37182 style: __assign(__assign({
37183 x: end.x,
37184 y: end.y - labelOffset,
37185 textAlign: 'center',
37186 textBaseline: 'bottom',
37187 text: text
37188 }, label), labelStyle)
37189 });
37190 }) : null);
37191 });
37192
37193 var Bottom = (function (props, context) {
37194 var ticks = props.ticks,
37195 coord = props.coord,
37196 style = props.style,
37197 animation = props.animation;
37198 var px2hd = context.px2hd,
37199 measureText = context.measureText;
37200 var left = coord.left,
37201 right = coord.right,
37202 bottom = coord.bottom;
37203 var grid = style.grid,
37204 tickLine = style.tickLine,
37205 line = style.line,
37206 labelOffset = style.labelOffset,
37207 label = style.label,
37208 symbol = style.symbol;
37209 var filterTicks = ticks.filter(function (d) {
37210 return !isNaN(d.value);
37211 });
37212 var symbols = isArray(symbol) ? symbol : [symbol];
37213 var _a = tickLine || {},
37214 tickLineLength = _a.length,
37215 tickLineStyle = __rest(_a, ["length"]);
37216 return jsx("group", null, grid ? filterTicks.map(function (tick) {
37217 var points = tick.points,
37218 tickValue = tick.tickValue,
37219 gridStyle = tick.gridStyle;
37220 var start = points[0];
37221 var end = points[points.length - 1];
37222 return jsx("line", {
37223 key: "grid-".concat(tickValue),
37224 style: __assign(__assign({
37225 x1: start.x,
37226 y1: start.y,
37227 x2: end.x,
37228 y2: end.y
37229 }, grid), gridStyle)
37230 });
37231 }) : null, tickLineLength ? filterTicks.map(function (tick) {
37232 var points = tick.points,
37233 tickValue = tick.tickValue;
37234 var start = points[0];
37235 return jsx("line", {
37236 key: "tickLine-".concat(tickValue),
37237 style: __assign({
37238 x1: start.x,
37239 y1: start.y,
37240 x2: start.x,
37241 y2: start.y + px2hd(tickLineLength)
37242 }, tickLineStyle)
37243 });
37244 }) : null, symbols[0] ? jsx("marker", {
37245 style: __assign(__assign({
37246 x: right,
37247 y: bottom,
37248 transform: 'rotate(90deg)',
37249 transformOrigin: '50% 50%'
37250 }, symbols[0]), {
37251 symbol: symbols[0].type
37252 })
37253 }) : null, line ? jsx("line", {
37254 style: __assign({
37255 x1: left,
37256 y1: bottom,
37257 x2: right,
37258 y2: bottom
37259 }, line)
37260 }) : null, symbols[1] ? jsx("marker", {
37261 style: __assign(__assign({
37262 x: left,
37263 y: bottom,
37264 transform: 'rotate(-90deg)',
37265 transformOrigin: '50% 50%'
37266 }, symbols[0]), {
37267 symbol: symbols[1].type
37268 })
37269 }) : null, label ? filterTicks.map(function (tick, index) {
37270 var points = tick.points,
37271 text = tick.text,
37272 tickValue = tick.tickValue,
37273 labelStyle = tick.labelStyle;
37274 var _a = points[0],
37275 x = _a.x,
37276 y = _a.y;
37277 var _b = (labelStyle || label || {}).align,
37278 align = _b === void 0 ? 'center' : _b;
37279 var textAttrs = __assign(__assign({
37280 x: x,
37281 y: y + labelOffset,
37282 textBaseline: 'top',
37283 text: text
37284 }, label), labelStyle);
37285 if (align === 'between') {
37286 if (index === 0) {
37287 textAttrs.textAlign = 'start';
37288 } else if (index === ticks.length - 1) {
37289 textAttrs.textAlign = 'end';
37290 } else {
37291 textAttrs.textAlign = 'center';
37292 }
37293 } else if (align === 'auto') {
37294 textAttrs.textAlign = 'center';
37295 var width = measureText(text, textAttrs).width;
37296 var halfWidth = width / 2;
37297 if (x - halfWidth < left) {
37298 textAttrs.x = left + width / 2;
37299 } else if (x + halfWidth > right) {
37300 textAttrs.x = right - width / 2;
37301 }
37302 } else {
37303 textAttrs.textAlign = align;
37304 }
37305 return jsx("text", {
37306 key: "text-".concat(tickValue),
37307 style: textAttrs,
37308 animation: animation || {
37309 appear: {
37310 easing: 'linear',
37311 duration: 300,
37312 delay: 0,
37313 property: ['fillOpacity'],
37314 start: {
37315 fillOpacity: 0
37316 },
37317 end: {
37318 fillOpacity: 1
37319 }
37320 },
37321 update: {
37322 easing: 'linear',
37323 duration: 450,
37324 delay: 0,
37325 property: ['x', 'y']
37326 },
37327 leave: {
37328 easing: 'linear',
37329 duration: 450,
37330 delay: 0,
37331 property: ['fillOpacity'],
37332 start: {
37333 fillOpacity: 1
37334 },
37335 end: {
37336 fillOpacity: 0
37337 }
37338 }
37339 }
37340 });
37341 }) : null);
37342 });
37343
37344 var Right = (function (props, context) {
37345 var originTicks = props.ticks,
37346 coord = props.coord,
37347 style = props.style;
37348 var px2hd = context.px2hd;
37349 var top = coord.top,
37350 right = coord.right,
37351 bottom = coord.bottom;
37352 var grid = style.grid,
37353 tickLine = style.tickLine,
37354 line = style.line,
37355 labelOffset = style.labelOffset,
37356 label = style.label,
37357 symbol = style.symbol;
37358 var ticks = originTicks.filter(function (d) {
37359 return !isNaN(d.value);
37360 });
37361 var symbols = isArray(symbol) ? symbol : [symbol];
37362 var _a = tickLine || {},
37363 tickLineLength = _a.length,
37364 tickLineStyle = __rest(_a, ["length"]);
37365 return jsx("group", null, grid ? ticks.map(function (tick) {
37366 var points = tick.points,
37367 tickValue = tick.tickValue,
37368 gridStyle = tick.gridStyle;
37369 var start = points[0];
37370 var end = points[points.length - 1];
37371 return jsx("line", {
37372 key: "grid-".concat(tickValue),
37373 style: __assign(__assign({
37374 x1: start.x,
37375 y1: start.y,
37376 x2: end.x,
37377 y2: end.y
37378 }, grid), gridStyle)
37379 });
37380 }) : null, tickLineLength ? ticks.map(function (tick) {
37381 var points = tick.points,
37382 tickValue = tick.tickValue;
37383 var end = points[points.length - 1];
37384 return jsx("line", {
37385 key: "tickLine-".concat(tickValue),
37386 style: __assign({
37387 x1: end.x,
37388 y1: end.y,
37389 x2: end.x + px2hd(tickLineLength),
37390 y2: end.y
37391 }, tickLineStyle)
37392 });
37393 }) : null, symbols[0] ? jsx("marker", {
37394 style: __assign(__assign({
37395 x: right,
37396 y: top
37397 }, symbols[0]), {
37398 symbol: symbols[0].type
37399 })
37400 }) : null, line ? jsx("line", {
37401 style: __assign({
37402 x1: right,
37403 y1: top,
37404 x2: right,
37405 y2: bottom
37406 }, line)
37407 }) : null, symbols[1] ? jsx("marker", {
37408 style: __assign(__assign({
37409 x: right,
37410 y: bottom,
37411 transform: 'rotate(180deg)',
37412 transformOrigin: '50% 50%'
37413 }, symbols[1]), {
37414 symbol: symbols[1].type
37415 })
37416 }) : null, label ? ticks.map(function (tick, _index) {
37417 var tickValue = tick.tickValue,
37418 points = tick.points,
37419 text = tick.text,
37420 labelStyle = tick.labelStyle;
37421 var end = points[points.length - 1];
37422 return jsx("text", {
37423 key: "text-".concat(tickValue),
37424 style: __assign(__assign({
37425 x: end.x + labelOffset,
37426 y: end.y,
37427 textAlign: 'left',
37428 textBaseline: 'middle',
37429 text: text
37430 }, label), labelStyle)
37431 });
37432 }) : null);
37433 });
37434
37435 var Left = (function (props, context) {
37436 var originTicks = props.ticks,
37437 coord = props.coord,
37438 style = props.style,
37439 animation = props.animation;
37440 var px2hd = context.px2hd;
37441 var left = coord.left,
37442 top = coord.top,
37443 bottom = coord.bottom;
37444 var grid = style.grid,
37445 tickLine = style.tickLine,
37446 line = style.line,
37447 labelOffset = style.labelOffset,
37448 label = style.label,
37449 symbol = style.symbol;
37450 var ticks = originTicks.filter(function (d) {
37451 return !isNaN(d.value);
37452 });
37453 var symbols = isArray(symbol) ? symbol : [symbol];
37454 var _a = tickLine || {},
37455 tickLineLength = _a.length,
37456 tickLineStyle = __rest(_a, ["length"]);
37457 return jsx("group", null, grid ? ticks.map(function (tick) {
37458 var points = tick.points,
37459 tickValue = tick.tickValue,
37460 gridStyle = tick.gridStyle;
37461 var start = points[0];
37462 var end = points[points.length - 1];
37463 return jsx("line", {
37464 key: "grid-".concat(tickValue),
37465 style: __assign(__assign({
37466 x1: start.x,
37467 y1: start.y,
37468 x2: end.x,
37469 y2: end.y
37470 }, grid), gridStyle)
37471 });
37472 }) : null, tickLineLength ? ticks.map(function (tick) {
37473 var points = tick.points,
37474 tickValue = tick.tickValue;
37475 var start = points[0];
37476 return jsx("line", {
37477 key: "tickLine-".concat(tickValue),
37478 style: __assign({
37479 x1: start.x,
37480 y1: start.y,
37481 x2: start.x - px2hd(tickLineLength),
37482 y2: start.y
37483 }, tickLineStyle)
37484 });
37485 }) : null, symbols[0] ? jsx("marker", {
37486 style: __assign(__assign({
37487 x: left,
37488 y: top
37489 }, symbols[0]), {
37490 symbol: symbols[0].type
37491 })
37492 }) : null, line ? jsx("line", {
37493 style: __assign({
37494 x1: left,
37495 y1: top,
37496 x2: left,
37497 y2: bottom
37498 }, line)
37499 }) : null, symbols[1] ? jsx("marker", {
37500 style: __assign(__assign({
37501 x: left,
37502 y: bottom,
37503 transform: 'rotate(180deg)',
37504 transformOrigin: '50% 50%'
37505 }, symbols[1]), {
37506 symbol: symbols[1].type
37507 })
37508 }) : null, label ? ticks.map(function (tick, _index) {
37509 var tickValue = tick.tickValue,
37510 points = tick.points,
37511 text = tick.text,
37512 labelStyle = tick.labelStyle;
37513 var start = points[0];
37514 return jsx("text", {
37515 key: "text-".concat(tickValue),
37516 style: __assign(__assign({
37517 x: start.x - labelOffset,
37518 y: start.y,
37519 textAlign: 'right',
37520 textBaseline: 'middle',
37521 text: text
37522 }, label), labelStyle),
37523 animation: animation || {
37524 appear: {
37525 easing: 'linear',
37526 duration: 300,
37527 delay: 0,
37528 property: ['fillOpacity'],
37529 start: {
37530 fillOpacity: 0
37531 },
37532 end: {
37533 fillOpacity: 1
37534 }
37535 },
37536 update: {
37537 easing: 'linear',
37538 duration: 450,
37539 delay: 0,
37540 property: ['x', 'y']
37541 },
37542 leave: {
37543 easing: 'linear',
37544 duration: 450,
37545 delay: 0,
37546 property: ['fillOpacity'],
37547 start: {
37548 fillOpacity: 1
37549 },
37550 end: {
37551 fillOpacity: 0
37552 }
37553 }
37554 }
37555 });
37556 }) : null);
37557 });
37558
37559 function isPolar(props) {
37560 return props.coord.isPolar;
37561 }
37562 var AxisView = (function (props) {
37563 // 极坐标
37564 if (isPolar(props)) {
37565 var dimType = props.dimType;
37566 if (dimType === 'x') {
37567 return jsx(PolarX, __assign({}, props));
37568 }
37569 return jsx(PolarY, __assign({}, props));
37570 }
37571 var position = props.position;
37572 // 直角坐标
37573 if (position === 'right') {
37574 return jsx(Right, __assign({}, props));
37575 }
37576 if (position === 'left') {
37577 return jsx(Left, __assign({}, props));
37578 }
37579 if (position === 'top') {
37580 return jsx(Top, __assign({}, props));
37581 }
37582 return jsx(Bottom, __assign({}, props));
37583 });
37584
37585 var index$4 = withAxis(AxisView);
37586
37587 var withLegend = (function (View) {
37588 return /** @class */function (_super) {
37589 __extends(Legend, _super);
37590 function Legend(props) {
37591 var _this = _super.call(this, props) || this;
37592 _this._onclick = function (item) {
37593 var _a;
37594 var props = _this.props;
37595 var chart = props.chart,
37596 _b = props.clickable,
37597 clickable = _b === void 0 ? true : _b,
37598 onClick = props.onClick;
37599 if (!clickable) return;
37600 var clickItem = item.currentTarget;
37601 if (!clickItem) {
37602 return;
37603 }
37604 // @ts-ignore
37605 var dataItem = clickItem.config['data-item'];
37606 if (!dataItem) {
37607 return;
37608 }
37609 if (isFunction(onClick)) {
37610 onClick(dataItem);
37611 }
37612 var field = dataItem.field,
37613 tickValue = dataItem.tickValue;
37614 var prevFiltered = _this.state.filtered;
37615 var filtered = __assign(__assign({}, prevFiltered), (_a = {}, _a[tickValue] = !prevFiltered[tickValue], _a));
37616 _this.setState({
37617 filtered: filtered
37618 });
37619 chart.filter(field, function (value) {
37620 return !filtered[value];
37621 });
37622 };
37623 _this.state = {
37624 filtered: {},
37625 items: []
37626 };
37627 return _this;
37628 }
37629 Legend.prototype.getOriginItems = function () {
37630 var chart = this.props.chart;
37631 return chart.getLegendItems();
37632 };
37633 Legend.prototype.getItems = function () {
37634 var _a;
37635 var _b = this,
37636 props = _b.props,
37637 state = _b.state;
37638 var filtered = state.filtered;
37639 var renderItems = ((_a = props.items) === null || _a === void 0 ? void 0 : _a.length) ? props.items : this.getOriginItems();
37640 if (!renderItems) return null;
37641 return renderItems.map(function (item) {
37642 var tickValue = item.tickValue;
37643 return __assign(__assign({}, item), {
37644 filtered: filtered[tickValue]
37645 });
37646 });
37647 };
37648 Legend.prototype.setItems = function (items) {
37649 this.setState({
37650 items: items
37651 });
37652 };
37653 Legend.prototype.getMaxItemBox = function (node) {
37654 var maxItemWidth = 0;
37655 var maxItemHeight = 0;
37656 (node.children || []).forEach(function (child) {
37657 var layout = child.layout;
37658 var width = layout.width,
37659 height = layout.height;
37660 maxItemWidth = Math.max(maxItemWidth, width);
37661 maxItemHeight = Math.max(maxItemHeight, height);
37662 });
37663 return {
37664 width: maxItemWidth,
37665 height: maxItemHeight
37666 };
37667 };
37668 // 计算 legend 的位置
37669 Legend.prototype._init = function () {
37670 var _a = this,
37671 props = _a.props,
37672 context = _a.context;
37673 var
37674 // @ts-ignore
37675 parentLayout = props.layout,
37676 customWidth = props.width,
37677 customHeight = props.height,
37678 _b = props.position,
37679 position = _b === void 0 ? 'top' : _b;
37680 var items = this.getItems();
37681 if (!items || !items.length) return;
37682 var left = parentLayout.left,
37683 top = parentLayout.top,
37684 layoutWidth = parentLayout.width,
37685 layoutHeight = parentLayout.height;
37686 var width = context.px2hd(customWidth) || layoutWidth;
37687 var node = computeLayout$1(this, this.render());
37688 var _c = this.getMaxItemBox(node),
37689 itemMaxWidth = _c.width,
37690 itemMaxHeight = _c.height;
37691 // 每行最多的个数
37692 var lineMaxCount = Math.max(1, Math.floor(width / itemMaxWidth));
37693 var itemCount = items.length;
37694 // legend item 的行数
37695 var lineCount = Math.ceil(itemCount / lineMaxCount);
37696 var itemWidth = width / lineMaxCount;
37697 var autoHeight = itemMaxHeight * lineCount;
37698 var style = {
37699 left: left,
37700 top: top,
37701 width: width,
37702 // height 默认自适应
37703 height: undefined,
37704 flexDirection: 'row',
37705 flexWrap: 'wrap',
37706 alignItems: 'center',
37707 justifyContent: 'flex-start'
37708 };
37709 // 如果只有一行,2端对齐
37710 if (lineCount === 1) {
37711 style.justifyContent = 'space-between';
37712 }
37713 if (position === 'top') {
37714 style.height = customHeight ? customHeight : autoHeight;
37715 }
37716 if (position === 'left') {
37717 style.flexDirection = 'column';
37718 style.justifyContent = 'center';
37719 style.width = itemMaxWidth;
37720 style.height = customHeight ? customHeight : layoutHeight;
37721 }
37722 if (position === 'right') {
37723 style.flexDirection = 'column';
37724 style.alignItems = 'flex-start';
37725 style.justifyContent = 'center';
37726 style.width = itemMaxWidth;
37727 style.height = customHeight ? customHeight : layoutHeight;
37728 style.left = left + (width - itemMaxWidth);
37729 }
37730 if (position === 'bottom') {
37731 style.top = top + (layoutHeight - autoHeight);
37732 style.height = customHeight ? customHeight : autoHeight;
37733 }
37734 this.itemWidth = itemWidth;
37735 this.legendStyle = style;
37736 };
37737 Legend.prototype.updateCoord = function () {
37738 var _a = this,
37739 context = _a.context,
37740 props = _a.props,
37741 legendStyle = _a.legendStyle;
37742 var _b = props.position,
37743 position = _b === void 0 ? 'top' : _b,
37744 _c = props.margin,
37745 margin = _c === void 0 ? '30px' : _c,
37746 chart = props.chart;
37747 var width = legendStyle.width,
37748 height = legendStyle.height;
37749 var marginNumber = context.px2hd(margin);
37750 chart.updateCoordFor(this, {
37751 position: position,
37752 width: width + marginNumber,
37753 height: height + marginNumber
37754 });
37755 };
37756 Legend.prototype.willMount = function () {
37757 var items = this.getItems();
37758 if (!items || !items.length) return;
37759 this._init();
37760 this.updateCoord();
37761 };
37762 Legend.prototype.didMount = function () {
37763 // this._initEvent();
37764 };
37765 Legend.prototype.willUpdate = function () {
37766 var items = this.getItems();
37767 if (!items || !items.length) return;
37768 this._init();
37769 this.updateCoord();
37770 };
37771 Legend.prototype.render = function () {
37772 var _a = this,
37773 props = _a.props,
37774 itemWidth = _a.itemWidth,
37775 legendStyle = _a.legendStyle;
37776 var items = this.getItems();
37777 if (!items || !items.length) {
37778 return null;
37779 }
37780 return jsx(View, __assign({}, props, {
37781 items: items,
37782 itemWidth: itemWidth,
37783 style: __assign(__assign({}, legendStyle), props.style),
37784 onClick: this._onclick
37785 }));
37786 };
37787 return Legend;
37788 }(Component);
37789 });
37790
37791 var Marker$1 = function Marker(_a) {
37792 var type = _a.type,
37793 color = _a.color;
37794 if (type === 'square') {
37795 return jsx("rect", {
37796 style: {
37797 width: '12px',
37798 height: '12px',
37799 marginRight: '10px'
37800 },
37801 attrs: {
37802 fill: color
37803 }
37804 });
37805 }
37806 if (type === 'line') {
37807 return jsx("line", {
37808 style: {
37809 width: '19px',
37810 marginRight: '10px'
37811 },
37812 attrs: {
37813 stroke: color,
37814 lineCap: 'round',
37815 lineWidth: '4px'
37816 }
37817 });
37818 }
37819 return jsx("circle", {
37820 style: {
37821 width: '12px',
37822 height: '12px',
37823 marginRight: '10px',
37824 fill: color
37825 }
37826 });
37827 };
37828 var LegendView = (function (props) {
37829 var items = props.items,
37830 itemWidth = props.itemWidth,
37831 itemFormatter = props.itemFormatter,
37832 style = props.style,
37833 _a = props.marker,
37834 marker = _a === void 0 ? 'circle' : _a,
37835 // 图例标记默认为 circle
37836 itemStyle = props.itemStyle,
37837 nameStyle = props.nameStyle,
37838 valueStyle = props.valueStyle,
37839 valuePrefix = props.valuePrefix,
37840 onClick = props.onClick;
37841 var formatValue = function formatValue(value, valuePrefix) {
37842 if (valuePrefix === void 0) {
37843 valuePrefix = ': ';
37844 }
37845 return "".concat(valuePrefix).concat(value);
37846 };
37847 return jsx("group", {
37848 style: __assign({
37849 display: 'flex'
37850 }, style)
37851 }, items.map(function (item) {
37852 var color = item.color,
37853 name = item.name,
37854 value = item.value,
37855 filtered = item.filtered,
37856 tickValue = item.tickValue;
37857 var valueText = isFunction(itemFormatter) ? itemFormatter(value, tickValue) : value;
37858 return jsx("group", {
37859 className: "legend-item",
37860 style: __assign({
37861 width: itemWidth,
37862 display: 'flex',
37863 flexDirection: 'row',
37864 alignItems: 'center',
37865 justifyContent: 'flex-start',
37866 //TODO: padding改为’12px‘ 就和原来一致了
37867 padding: ['6px', '6px', '6px', 0]
37868 }, itemStyle),
37869 "data-item": item,
37870 onClick: onClick
37871 }, Marker$1({
37872 color: filtered ? '#bfbfbf' : color,
37873 type: marker
37874 }), jsx("text", {
37875 attrs: __assign({
37876 fill: filtered ? '#bfbfbf' : '#808080',
37877 text: name
37878 }, nameStyle)
37879 }), valueText ? jsx("text", {
37880 attrs: __assign({
37881 fill: '#808080',
37882 text: formatValue(valueText, valuePrefix)
37883 }, valueStyle)
37884 }) : null);
37885 }));
37886 });
37887
37888 var index$5 = withLegend(LegendView);
37889
37890 function withGuide (View) {
37891 return /** @class */function (_super) {
37892 __extends(Guide, _super);
37893 function Guide(props) {
37894 return _super.call(this, props) || this;
37895 }
37896 Guide.prototype.getGuideBBox = function () {
37897 var node = computeLayout$1(this, this.render());
37898 var layout = node.layout;
37899 if (!layout) return;
37900 return layout;
37901 };
37902 // 解析record里的模板字符串,如min、max、50%...
37903 Guide.prototype.parseReplaceStr = function (value, scale) {
37904 var replaceMap = {
37905 min: 0,
37906 max: 1,
37907 median: 0.5
37908 };
37909 // 传入的是 min、max、median 的
37910 if (!isNil(replaceMap[value])) {
37911 return replaceMap[value];
37912 }
37913 // 传入的是 xx%
37914 if (isString(value) && value.indexOf('%') != -1 && !isNaN(Number(value.slice(0, -1)))) {
37915 var rateValue = Number(value.slice(0, -1));
37916 var percent = rateValue / 100;
37917 return percent;
37918 }
37919 return scale.scale(value);
37920 };
37921 Guide.prototype.parsePoint = function (record) {
37922 var props = this.props;
37923 var chart = props.chart,
37924 coord = props.coord;
37925 var xScale = chart.getXScales()[0];
37926 // 只取第一个yScale
37927 var yScale = chart.getYScales()[0];
37928 // 解析 record 为归一化后的坐标
37929 var x = this.parseReplaceStr(record[xScale.field], xScale);
37930 var y = this.parseReplaceStr(record[yScale.field], yScale);
37931 return coord.convertPoint({
37932 x: x,
37933 y: y
37934 });
37935 };
37936 Guide.prototype.convertPoints = function (records) {
37937 var _this = this;
37938 return records.map(function (record) {
37939 return _this.parsePoint(record);
37940 });
37941 };
37942 Guide.prototype.getGuideTheme = function () {
37943 var context = this.context;
37944 var theme = context.theme;
37945 return theme.guide;
37946 };
37947 Guide.prototype.render = function () {
37948 var _a = this,
37949 props = _a.props,
37950 context = _a.context;
37951 var coord = props.coord,
37952 _b = props.records,
37953 records = _b === void 0 ? [] : _b,
37954 animation = props.animation,
37955 chart = props.chart,
37956 style = props.style,
37957 _onClick = props.onClick,
37958 _c = props.visible,
37959 visible = _c === void 0 ? true : _c;
37960 if (!visible) return;
37961 var width = context.width,
37962 height = context.height;
37963 var points = this.convertPoints(records);
37964 var theme = this.getGuideTheme();
37965 return jsx("group", {
37966 onClick: function onClick(ev) {
37967 _onClick && _onClick(ev);
37968 }
37969 }, jsx(View, __assign({
37970 points: points,
37971 theme: theme,
37972 coord: coord
37973 }, props, {
37974 canvasWidth: width,
37975 canvasHeight: height,
37976 style: isFunction(style) ? style(points, chart) : style,
37977 animation: isFunction(animation) ? animation(points, chart) : animation
37978 })));
37979 };
37980 return Guide;
37981 }(Component);
37982 }
37983
37984 var TextGuideView = (function (props, context) {
37985 var _a = props.theme,
37986 theme = _a === void 0 ? {} : _a;
37987 var _b = deepMix(__assign({}, theme.text), props),
37988 points = _b.points,
37989 style = _b.style,
37990 offsetX = _b.offsetX,
37991 offsetY = _b.offsetY,
37992 content = _b.content,
37993 animation = _b.animation;
37994 var _c = points[0] || {},
37995 x = _c.x,
37996 y = _c.y;
37997 if (isNaN(x) || isNaN(y)) return null;
37998 var offsetXNum = context.px2hd(offsetX);
37999 var offsetYNum = context.px2hd(offsetY);
38000 var posX = x + (offsetXNum || 0);
38001 var posY = y + (offsetYNum || 0);
38002 return jsx("text", {
38003 attrs: __assign({
38004 text: "".concat(content),
38005 x: posX,
38006 y: posY
38007 }, style),
38008 animation: deepMix({
38009 update: {
38010 easing: 'linear',
38011 duration: 450,
38012 property: ['x', 'y']
38013 }
38014 }, animation)
38015 });
38016 });
38017
38018 var PointGuideView = (function (props, context) {
38019 var theme = props.theme;
38020 var _a = deepMix(__assign({}, theme.point), props),
38021 points = _a.points,
38022 style = _a.style,
38023 offsetX = _a.offsetX,
38024 offsetY = _a.offsetY,
38025 animation = _a.animation;
38026 var _b = points[0] || {},
38027 x = _b.x,
38028 y = _b.y;
38029 if (isNaN(x) || isNaN(y)) return null;
38030 var offsetXNum = context.px2hd(offsetX);
38031 var offsetYNum = context.px2hd(offsetY);
38032 var posX = x + (offsetXNum || 0);
38033 var posY = y + (offsetYNum || 0);
38034 return jsx("group", null, jsx("circle", {
38035 style: __assign({
38036 cx: posX,
38037 cy: posY
38038 }, style),
38039 animation: animation
38040 }));
38041 });
38042
38043 var LineGuideView = (function (props, context) {
38044 var _a = props.theme,
38045 theme = _a === void 0 ? {} : _a;
38046 var _b = deepMix(__assign({}, theme.line), props),
38047 points = _b.points,
38048 style = _b.style,
38049 offsetX = _b.offsetX,
38050 offsetY = _b.offsetY,
38051 animation = _b.animation;
38052 var checkNaN = points.some(function (d) {
38053 return isNaN(d.x) || isNaN(d.y);
38054 });
38055 if (checkNaN) return;
38056 var _c = points[0] || {},
38057 x1 = _c.x,
38058 y1 = _c.y;
38059 var _d = points[1] || {},
38060 x2 = _d.x,
38061 y2 = _d.y;
38062 var offsetXNum = context.px2hd(offsetX);
38063 var offsetYNum = context.px2hd(offsetY);
38064 var posX1 = x1 + (isArray(offsetXNum) ? offsetXNum[0] || 0 : offsetXNum || 0);
38065 var posY1 = y1 + (isArray(offsetYNum) ? offsetYNum[0] || 0 : offsetYNum || 0);
38066 var posX2 = x2 + (isArray(offsetXNum) ? offsetXNum[1] || 0 : offsetXNum || 0);
38067 var posY2 = y2 + (isArray(offsetYNum) ? offsetYNum[1] || 0 : offsetYNum || 0);
38068 return jsx("group", null, jsx("line", {
38069 style: __assign({
38070 x1: posX1,
38071 y1: posY1,
38072 x2: posX2,
38073 y2: posY2
38074 }, style),
38075 animation: animation
38076 }));
38077 });
38078
38079 var ArcGuideView = (function (props) {
38080 var _a = props.theme,
38081 theme = _a === void 0 ? {} : _a;
38082 var _b = deepMix(__assign({}, theme.line), props),
38083 coord = _b.coord,
38084 points = _b.points,
38085 style = _b.style,
38086 animation = _b.animation;
38087 var checkNaN = points.some(function (d) {
38088 return isNaN(d.x) || isNaN(d.y);
38089 });
38090 if (checkNaN) return null;
38091 var start = points[0] || {};
38092 var end = points[1] || {};
38093 var coordCenter = coord.center;
38094 var radius = Math.sqrt((start.x - coordCenter.x) * (start.x - coordCenter.x) + (start.y - coordCenter.y) * (start.y - coordCenter.y));
38095 var startAngle = Math.atan2(start.y - coordCenter.y, start.x - coordCenter.x);
38096 var endAngle = Math.atan2(end.y - coordCenter.y, end.x - coordCenter.x);
38097 return jsx("group", null, jsx("arc", {
38098 style: __assign({
38099 cx: coordCenter.x,
38100 cy: coordCenter.y,
38101 r: radius,
38102 startAngle: "".concat(startAngle, "rad"),
38103 endAngle: "".concat(endAngle, "rad")
38104 }, style),
38105 animation: animation
38106 }));
38107 });
38108
38109 var RectGuideView = (function (props, context) {
38110 var _a = props.theme,
38111 theme = _a === void 0 ? {} : _a;
38112 var _b = deepMix(__assign({}, theme.rect), props),
38113 points = _b.points,
38114 style = _b.style,
38115 animation = _b.animation,
38116 offsetX = _b.offsetX,
38117 offsetY = _b.offsetY;
38118 var checkNaN = points.some(function (d) {
38119 return isNaN(d.x) || isNaN(d.y);
38120 });
38121 if (checkNaN) return null;
38122 var start = points[0] || {};
38123 var end = points[1] || {};
38124 var offsetXNum = context.px2hd(offsetX);
38125 var offsetYNum = context.px2hd(offsetY);
38126 var posX = Math.min(start.x, end.x) + (offsetXNum || 0);
38127 var posY = Math.min(start.y, end.y) + (offsetYNum || 0);
38128 return jsx("group", null, jsx("rect", {
38129 style: __assign({
38130 x: posX,
38131 y: posY,
38132 width: Math.abs(end.x - start.x),
38133 height: Math.abs(start.y - end.y)
38134 }, style),
38135 animation: animation
38136 }));
38137 });
38138
38139 var defaultProps = {
38140 offsetX: 0,
38141 offsetY: 0,
38142 points: [],
38143 src: ''
38144 };
38145 var ImageGuideView = (function (props, context) {
38146 var cfg = deepMix({}, defaultProps, props);
38147 var points = cfg.points,
38148 style = cfg.style,
38149 attrs = cfg.attrs,
38150 offsetX = cfg.offsetX,
38151 offsetY = cfg.offsetY,
38152 src = cfg.src,
38153 animation = cfg.animation;
38154 var _a = points[0] || {},
38155 x = _a.x,
38156 y = _a.y;
38157 if (isNaN(x) || isNaN(y)) return null;
38158 var _b = __assign(__assign({}, attrs), style),
38159 _c = _b.height,
38160 height = _c === void 0 ? 0 : _c,
38161 _d = _b.width,
38162 width = _d === void 0 ? 0 : _d;
38163 var heightNum = isNumber(height) ? context.px2hd(height + 'px') : context.px2hd(height);
38164 var widthNum = isNumber(width) ? context.px2hd(width + 'px') : context.px2hd(width);
38165 var offsetXNum = context.px2hd(offsetX);
38166 var offsetYNum = context.px2hd(offsetY);
38167 var posX = x + (offsetXNum || 0) - widthNum / 2;
38168 var posY = y + (offsetYNum || 0) - heightNum / 2;
38169 return jsx("group", null, jsx("image", {
38170 style: __assign(__assign(__assign({}, attrs), style), {
38171 height: heightNum,
38172 width: widthNum,
38173 x: posX,
38174 y: posY,
38175 src: src
38176 }),
38177 animation: deepMix({
38178 update: {
38179 easing: 'linear',
38180 duration: 450,
38181 property: ['x', 'y']
38182 }
38183 }, animation)
38184 }));
38185 });
38186
38187 var defaultProps$1 = {
38188 offsetX: 0,
38189 offsetY: 0,
38190 points: [],
38191 direct: 'tl',
38192 side: '8px',
38193 autoAdjust: true
38194 };
38195 var defaultStyle = {
38196 container: {
38197 fill: '#1677FF',
38198 radius: '4px',
38199 padding: ['4px', '8px']
38200 },
38201 text: {
38202 fontSize: '22px',
38203 fill: '#fff'
38204 },
38205 arrow: {
38206 fill: '#1677FF'
38207 }
38208 };
38209 var Label = function Label(_a) {
38210 var content = _a.content,
38211 background = _a.background,
38212 textStyle = _a.textStyle,
38213 _b = _a.animation,
38214 animation = _b === void 0 ? {} : _b;
38215 return jsx("rect", {
38216 style: __assign({
38217 display: 'flex',
38218 fill: defaultStyle.container.fill,
38219 padding: defaultStyle.container.padding,
38220 radius: defaultStyle.container.radius
38221 }, background),
38222 animation: animation
38223 }, jsx("text", {
38224 style: __assign({
38225 text: content,
38226 fontSize: defaultStyle.text.fontSize,
38227 fill: defaultStyle.text.fill
38228 }, textStyle),
38229 animation: animation
38230 }));
38231 };
38232 var Tag = /** @class */function (_super) {
38233 __extends(Tag, _super);
38234 function Tag() {
38235 return _super !== null && _super.apply(this, arguments) || this;
38236 }
38237 Tag.prototype.render = function () {
38238 var _a = this,
38239 props = _a.props,
38240 context = _a.context;
38241 var px2hd = context.px2hd;
38242 var cfg = __assign(__assign({}, defaultProps$1), props);
38243 var _b = px2hd(cfg),
38244 points = _b.points,
38245 content = _b.content,
38246 offsetX = _b.offsetX,
38247 offsetY = _b.offsetY,
38248 direct = _b.direct,
38249 side = _b.side,
38250 autoAdjust = _b.autoAdjust,
38251 canvasWidth = _b.canvasWidth,
38252 canvasHeight = _b.canvasHeight,
38253 background = _b.background,
38254 textStyle = _b.textStyle,
38255 animation = _b.animation;
38256 var _c = points[0] || {},
38257 x = _c.x,
38258 y = _c.y;
38259 if (isNaN(x) || isNaN(y)) return null;
38260 var offsetXNum = context.px2hd(offsetX);
38261 var offsetYNum = context.px2hd(offsetY);
38262 var posX = x + (offsetXNum || 0);
38263 var posY = y + (offsetYNum || 0);
38264 var layout = computeLayout$1(this, jsx(Label, {
38265 content: content,
38266 background: background,
38267 textStyle: textStyle
38268 })).layout;
38269 var guideWidth = layout.width,
38270 guideHeight = layout.height;
38271 var _getDirect = function _getDirect(point) {
38272 var newDirect = direct;
38273 var x = point.x,
38274 y = point.y;
38275 var vertical = newDirect[0];
38276 var horizontal = newDirect[1];
38277 // adjust for vertical direction
38278 if (vertical === 't' && y - side - guideHeight < 0) {
38279 vertical = 'b';
38280 } else if (vertical === 'b' && y + side + guideHeight > canvasHeight) {
38281 vertical = 't';
38282 }
38283 // adjust for horizontal direction
38284 var diff = vertical === 'c' ? side : 0;
38285 if (horizontal === 'l' && x - diff - guideWidth < 0) {
38286 horizontal = 'r';
38287 } else if (horizontal === 'r' && x + diff + guideWidth > canvasWidth) {
38288 horizontal = 'l';
38289 } else if (horizontal === 'c') {
38290 if (guideWidth / 2 + x + diff > canvasWidth) {
38291 horizontal = 'l';
38292 } else if (x - guideWidth / 2 - diff < 0) {
38293 horizontal = 'r';
38294 }
38295 }
38296 newDirect = vertical + horizontal;
38297 return newDirect;
38298 };
38299 var _getArrowPoints = function _getArrowPoints(direct) {
38300 var arrowPoints = [];
38301 if (direct === 'tl') {
38302 arrowPoints = [{
38303 x: guideWidth,
38304 y: guideHeight - 1
38305 }, {
38306 x: guideWidth,
38307 y: guideHeight + side
38308 }, {
38309 x: guideWidth - side,
38310 y: guideHeight - 1
38311 }];
38312 posX -= guideWidth || 0;
38313 posY = posY - (guideHeight || 0) - side;
38314 } else if (direct === 'cl') {
38315 arrowPoints = [{
38316 x: guideWidth,
38317 y: guideHeight / 2 - side
38318 }, {
38319 x: guideWidth,
38320 y: guideHeight / 2 + side
38321 }, {
38322 x: guideWidth + side,
38323 y: guideHeight / 2
38324 }];
38325 posX = posX - (guideWidth || 0) - side;
38326 posY -= guideHeight / 2 || 0;
38327 } else if (direct === 'bl') {
38328 arrowPoints = [{
38329 x: guideWidth,
38330 y: -side
38331 }, {
38332 x: guideWidth,
38333 y: 1
38334 }, {
38335 x: guideWidth - side,
38336 y: 1
38337 }];
38338 posX = posX - (guideWidth || 0);
38339 posY += side;
38340 } else if (direct === 'bc') {
38341 arrowPoints = [{
38342 x: guideWidth / 2,
38343 y: -side
38344 }, {
38345 x: guideWidth / 2 - side,
38346 y: 1
38347 }, {
38348 x: guideWidth / 2 + side,
38349 y: 1
38350 }];
38351 posX = posX - (guideWidth / 2 || 0);
38352 posY = posY + side;
38353 } else if (direct === 'br') {
38354 arrowPoints = [{
38355 x: 0,
38356 y: -side
38357 }, {
38358 x: 0,
38359 y: 1
38360 }, {
38361 x: +side,
38362 y: 1
38363 }];
38364 posY += side;
38365 } else if (direct === 'cr') {
38366 arrowPoints = [{
38367 x: -side,
38368 y: guideHeight / 2
38369 }, {
38370 x: 0,
38371 y: guideHeight / 2 - side
38372 }, {
38373 x: 0,
38374 y: guideHeight / 2 + side
38375 }];
38376 posX += side;
38377 posY -= guideHeight / 2 || 0;
38378 } else if (direct === 'tr') {
38379 arrowPoints = [{
38380 x: 0,
38381 y: guideHeight + side
38382 }, {
38383 x: 0,
38384 y: guideHeight - 1
38385 }, {
38386 x: side,
38387 y: guideHeight - 1
38388 }];
38389 posY = posY - (guideHeight || 0) - side;
38390 } else if (direct === 'tc') {
38391 arrowPoints = [{
38392 x: guideWidth / 2,
38393 y: guideHeight + side
38394 }, {
38395 x: guideWidth / 2 - side,
38396 y: guideHeight - 1
38397 }, {
38398 x: guideWidth / 2 + side,
38399 y: guideHeight - 1
38400 }];
38401 posX -= guideWidth / 2 || 0;
38402 posY = posY - guideHeight - side;
38403 }
38404 return arrowPoints;
38405 };
38406 var dr = autoAdjust ? _getDirect(points[0]) : direct;
38407 var arrowPoints = _getArrowPoints(dr);
38408 return jsx("group", {
38409 style: {
38410 x: posX,
38411 y: posY
38412 }
38413 }, jsx(Label, {
38414 content: content,
38415 background: background,
38416 textStyle: textStyle,
38417 animation: animation
38418 }), jsx("polygon", {
38419 style: {
38420 points: arrowPoints.map(function (d) {
38421 return [d.x, d.y];
38422 }),
38423 fill: (background === null || background === void 0 ? void 0 : background.fill) || defaultStyle.arrow.fill
38424 },
38425 animation: animation
38426 }));
38427 };
38428 return Tag;
38429 }(Component);
38430
38431 var eps = 0.0001;
38432 /**
38433 * Provides some control methods like:
38434 * - play
38435 * - pause
38436 * - stop
38437 * - goToAndStop
38438 * - goToAndPlay
38439 * @see https://github.com/airbnb/lottie-web/blob/master/player/js/animation/AnimationItem.js
38440 */
38441 var LottieAnimation = /** @class */ (function () {
38442 function LottieAnimation(width, height, elements, context) {
38443 var _this = this;
38444 this.width = width;
38445 this.height = height;
38446 this.elements = elements;
38447 this.context = context;
38448 this.keyframeAnimationMap = new WeakMap();
38449 this.displayObjectElementMap = new WeakMap();
38450 this.animations = [];
38451 this.isPaused = false;
38452 this.direction = 1;
38453 this.displayObjects = elements.map(function (element) {
38454 return _this.buildHierachy(element);
38455 });
38456 // TODO: preload images
38457 // TODO: preload fonts
38458 }
38459 LottieAnimation.prototype.generateTransform = function (tx, ty, scaleX, scaleY, rotation) {
38460 var transformStr = '';
38461 if (tx !== 0 || ty !== 0) {
38462 transformStr += "translate(".concat(tx, ", ").concat(ty, ")");
38463 }
38464 if (scaleX !== 1 || scaleY !== 1) {
38465 transformStr += " scale(".concat(scaleX === 0 ? eps : scaleX, ", ").concat(scaleY === 0 ? eps : scaleY, ")");
38466 }
38467 if (rotation !== 0) {
38468 transformStr += " rotate(".concat(rotation, "deg)");
38469 }
38470 return transformStr;
38471 };
38472 LottieAnimation.prototype.buildHierachy = function (element) {
38473 var _this = this;
38474 var type = element.type, name = element.name, _a = element.anchorX, anchorX = _a === void 0 ? 0 : _a, _b = element.anchorY, anchorY = _b === void 0 ? 0 : _b, _c = element.rotation, rotation = _c === void 0 ? 0 : _c, _d = element.scaleX, scaleX = _d === void 0 ? 1 : _d, _e = element.scaleY, scaleY = _e === void 0 ? 1 : _e, _f = element.x, x = _f === void 0 ? 0 : _f, _g = element.y, y = _g === void 0 ? 0 : _g,
38475 // skew = 0,
38476 // skewAxis = 0,
38477 children = element.children, shape = element.shape, style = element.style, keyframeAnimation = element.keyframeAnimation;
38478 var displayObject;
38479 var transform = this.generateTransform(x - anchorX, y - anchorY, scaleX, scaleY, rotation);
38480 // const transformMat = mat4.fromRotationTranslationScaleOrigin(
38481 // mat4.create(),
38482 // quat.fromEuler(quat.create(), 0, 0, rotation),
38483 // [x - anchorX, y - anchorY, 0],
38484 // [scaleX, scaleY, 1],
38485 // [anchorX, anchorY, 0],
38486 // );
38487 // TODO: repeater @see https://lottiefiles.github.io/lottie-docs/shapes/#repeater
38488 // @see https://lottiefiles.github.io/lottie-docs/shapes/#shape
38489 // TODO: polystar, convert to Bezier @see https://lottiefiles.github.io/lottie-docs/rendering/#polystar
38490 if (type === Shape.GROUP) {
38491 displayObject = new Group({
38492 style: {
38493 transformOrigin: "".concat(anchorX, "px ").concat(anchorY, "px"),
38494 transform: transform,
38495 },
38496 });
38497 }
38498 else if (type === Shape.ELLIPSE) {
38499 var cx = shape.cx, cy = shape.cy, rx = shape.rx, ry = shape.ry;
38500 // const center = vec3.fromValues(cx, cy, 0);
38501 // vec3.transformMat4(center, center, transformMat);
38502 displayObject = new Ellipse({
38503 style: {
38504 // cx: center[0],
38505 // cy: center[1],
38506 cx: cx,
38507 cy: cy,
38508 rx: rx,
38509 ry: ry,
38510 // reset transform-origin based on anchor & center
38511 transformOrigin: "".concat(anchorX - cx + rx, "px ").concat(anchorY - cy + ry, "px"),
38512 transform: transform,
38513 },
38514 });
38515 }
38516 else if (type === Shape.PATH) {
38517 var d = this.generatePathFromShape(shape);
38518 displayObject = new Path({
38519 style: {
38520 d: d, // use Path Array which can be skipped when parsing
38521 transformOrigin: "".concat(anchorX, "px ").concat(anchorY, "px"),
38522 transform: transform,
38523 },
38524 });
38525 }
38526 else if (type === Shape.RECT) {
38527 // @see https://lottiefiles.github.io/lottie-docs/shapes/#rectangle
38528 var cx = shape.x, cy = shape.y, width = shape.width, height = shape.height, r = shape.r;
38529 displayObject = new Rect({
38530 style: {
38531 x: cx,
38532 y: cy,
38533 width: width,
38534 height: height,
38535 anchor: [0.5, 0.5], // position means the center of the rectangle
38536 radius: r,
38537 transformOrigin: "".concat(anchorX - cx + width / 2, "px ").concat(anchorY - cy + height / 2, "px"),
38538 transform: transform,
38539 },
38540 });
38541 }
38542 else if (type === Shape.IMAGE) {
38543 var width = shape.width, height = shape.height, src = shape.src;
38544 displayObject = new Image({
38545 style: {
38546 x: 0,
38547 y: 0,
38548 width: width,
38549 height: height,
38550 src: src,
38551 transformOrigin: "".concat(anchorX, "px ").concat(anchorY, "px"),
38552 transform: transform,
38553 },
38554 });
38555 }
38556 if (name) {
38557 displayObject.name = name;
38558 }
38559 // TODO: match name `mn`, used in expressions
38560 if (style) {
38561 // { fill, fillOpacity, fillRule, opacity, lineDash, lineDashOffset }
38562 displayObject.attr(style);
38563 }
38564 if (keyframeAnimation) {
38565 this.keyframeAnimationMap.set(displayObject, keyframeAnimation);
38566 }
38567 if (children) {
38568 var childNodes = children.map(function (child) { return _this.buildHierachy(child); });
38569 displayObject.append.apply(displayObject, __spreadArray([], __read(childNodes), false));
38570 }
38571 this.displayObjectElementMap.set(displayObject, element);
38572 return displayObject;
38573 };
38574 LottieAnimation.prototype.getAnimations = function () {
38575 return this.animations;
38576 };
38577 /**
38578 * Returns the animation duration in seconds or frames.
38579 * @see https://github.com/airbnb/lottie-web#getdurationinframes
38580 */
38581 LottieAnimation.prototype.getDuration = function (inFrames) {
38582 if (inFrames === void 0) { inFrames = false; }
38583 return (((inFrames ? this.fps() : 1) *
38584 (this.context.endFrame - this.context.startFrame) *
38585 this.context.frameTime) /
38586 1000);
38587 };
38588 /**
38589 * Returns the animation frame rate (frames / second).
38590 */
38591 LottieAnimation.prototype.fps = function () {
38592 return this.context.fps;
38593 };
38594 LottieAnimation.prototype.isSameKeyframeOptions = function (options1, options2) {
38595 return (options1.delay === options2.delay &&
38596 options1.duration === options2.duration &&
38597 options1.easing === options2.easing);
38598 };
38599 LottieAnimation.prototype.isSameKeyframes = function (keyframe1, keyframe2) {
38600 // const { offset: o1, easing: e1, ...rest1 } = keyframe1;
38601 // const { offset: o2, easing: e2, ...rest2 } = keyframe2;
38602 // const isAllApplyToTransform =
38603 // Object.keys(rest1).every((key) =>
38604 // ['x', 'y', 'scaleX', 'scaleY', 'rotation'].includes(key),
38605 // ) &&
38606 // Object.keys(rest2).every((key) =>
38607 // ['x', 'y', 'scaleX', 'scaleY', 'rotation'].includes(key),
38608 // );
38609 return (keyframe1.offset === keyframe2.offset &&
38610 keyframe1.easing === keyframe2.easing
38611 // (keyframe1.easing === keyframe2.easing || isAllApplyToTransform)
38612 );
38613 };
38614 LottieAnimation.prototype.generatePathFromShape = function (shape) {
38615 // @see https://lottiefiles.github.io/lottie-docs/shapes/#path
38616 var close = shape.close, v = shape.v, i = shape.in, out = shape.out;
38617 var d = [];
38618 d.push(['M', v[0][0], v[0][1]]);
38619 for (var n = 1; n < v.length; n++) {
38620 // @see https://lottiefiles.github.io/lottie-docs/concepts/#bezier
38621 // The nth bezier segment is defined as:
38622 // v[n], v[n]+o[n], v[n+1]+i[n+1], v[n+1]
38623 d.push([
38624 'C',
38625 out[n - 1][0],
38626 out[n - 1][1],
38627 i[n][0],
38628 i[n][1],
38629 v[n][0],
38630 v[n][1],
38631 ]);
38632 }
38633 if (close) {
38634 d.push([
38635 'C',
38636 out[v.length - 1][0],
38637 out[v.length - 1][1],
38638 i[0][0],
38639 i[0][1],
38640 v[0][0],
38641 v[0][1],
38642 ]);
38643 d.push(['Z']);
38644 }
38645 return d;
38646 };
38647 /**
38648 * render Lottie Group to canvas or a mounted display object
38649 */
38650 LottieAnimation.prototype.render = function (canvasOrDisplayObject) {
38651 var _this = this;
38652 var wrapper = new Group();
38653 wrapper.append.apply(wrapper, __spreadArray([], __read(this.displayObjects), false));
38654 if (isCanvas(canvasOrDisplayObject)) {
38655 canvasOrDisplayObject.appendChild(wrapper);
38656 }
38657 else if (isDisplayObject(canvasOrDisplayObject)) {
38658 if (!canvasOrDisplayObject.isConnected) {
38659 throw new Error('[g-lottie-player]: Cannot render Lottie to an unmounted DisplayObject.');
38660 }
38661 else {
38662 canvasOrDisplayObject.appendChild(wrapper);
38663 }
38664 }
38665 else {
38666 throw new Error('[g-lottie-player]: We should render Lottie to a mounted DisplayObject or Canvas.');
38667 }
38668 this.displayObjects.forEach(function (parent) {
38669 parent.forEach(function (child) {
38670 var _a;
38671 var keyframeAnimation = _this.keyframeAnimationMap.get(child);
38672 // console.log('keyframeAnimation', keyframeAnimation);
38673 var element = _this.displayObjectElementMap.get(child);
38674 if (element && element.clipPath) {
38675 var _b = element.clipPath, shape = _b.shape, keyframeAnimation_1 = _b.keyframeAnimation;
38676 var clipPath = new Path();
38677 // use clipPath as target's siblings
38678 child.parentElement.appendChild(clipPath);
38679 child.style.clipPath = clipPath;
38680 if (shape) {
38681 clipPath.style.d = _this.generatePathFromShape(shape);
38682 }
38683 // TODO: only support one clipPath now
38684 if (keyframeAnimation_1 && keyframeAnimation_1.length) {
38685 var _c = keyframeAnimation_1[0], delay = _c.delay, duration = _c.duration, easing = _c.easing, keyframes = _c.keyframes;
38686 // animate clipPath with its `d` property
38687 var clipPathAnimation = clipPath.animate(keyframes.map(function (_a) {
38688 var offset = _a.offset, shape = _a.shape, easing = _a.easing;
38689 return {
38690 offset: offset,
38691 d: path2String(_this.generatePathFromShape(shape)),
38692 easing: easing,
38693 };
38694 }), {
38695 delay: delay,
38696 duration: duration,
38697 easing: easing,
38698 iterations: _this.context.iterations,
38699 });
38700 _this.animations.push(clipPathAnimation);
38701 }
38702 }
38703 // account for animation only apply to visibility, e.g. spring
38704 var visibilityStartOffset = element.visibilityStartOffset, visibilityEndOffset = element.visibilityEndOffset, visibilityFrame = element.visibilityFrame;
38705 if (visibilityFrame &&
38706 (!keyframeAnimation || !keyframeAnimation.length)) {
38707 keyframeAnimation = [
38708 {
38709 duration: _this.context.frameTime * visibilityFrame,
38710 keyframes: [
38711 { offset: 0, style: { opacity: 1 } },
38712 { offset: 1, style: { opacity: 1 } },
38713 ],
38714 },
38715 ];
38716 }
38717 if (keyframeAnimation && keyframeAnimation.length) {
38718 var keyframesOptions_1 = [];
38719 keyframeAnimation.map(function (_a) {
38720 var _b = _a.delay, delay = _b === void 0 ? 0 : _b, duration = _a.duration, easing = _a.easing, keyframes = _a.keyframes;
38721 var formattedKeyframes = keyframes.map(function (keyframe) {
38722 return definedProps(keyframe);
38723 });
38724 var options = definedProps({
38725 delay: delay,
38726 duration: duration,
38727 easing: easing,
38728 iterations: _this.context.iterations,
38729 fill: _this.context.fill,
38730 });
38731 keyframesOptions_1.push([formattedKeyframes, options]);
38732 });
38733 var mergedKeyframesOptions = [keyframesOptions_1[0]];
38734 var _loop_1 = function (i) {
38735 var _d = __read(keyframesOptions_1[i], 2), currentKeyframes = _d[0], currentOptions = _d[1];
38736 // can merge options?
38737 var existedKeyframeOptions = mergedKeyframesOptions.find(function (_a) {
38738 var _b = __read(_a, 2), keyframes = _b[0], options = _b[1];
38739 return keyframes.length === currentKeyframes.length &&
38740 _this.isSameKeyframeOptions(currentOptions, options);
38741 });
38742 if (existedKeyframeOptions) {
38743 currentKeyframes.forEach(function (currentKeyframe) {
38744 var existedKeyframe = existedKeyframeOptions[0].find(function (keyframe) { return _this.isSameKeyframes(currentKeyframe, keyframe); });
38745 if (existedKeyframe) {
38746 currentKeyframe.offset;
38747 // eslint-disable-next-line @typescript-eslint/no-unused-vars
38748 currentKeyframe.easing;
38749 var rest = __rest(currentKeyframe, ["offset", "easing"]);
38750 // merge interpolated properties
38751 Object.assign(existedKeyframe, rest);
38752 }
38753 else {
38754 // append if cannot be merged
38755 existedKeyframeOptions[0].push(currentKeyframe);
38756 }
38757 });
38758 }
38759 else {
38760 // cannot be merged since options are different
38761 mergedKeyframesOptions.push(keyframesOptions_1[i]);
38762 }
38763 };
38764 // merge [{ offset: 0, cx: 1 }, { offset: 0, cy: 1 }] into { offset: 0, cx: 1, cy: 1 }
38765 for (var i = 1; i < keyframesOptions_1.length; i++) {
38766 _loop_1(i);
38767 }
38768 // restore animations for later use
38769 (_a = _this.animations).push.apply(_a, __spreadArray([], __read(mergedKeyframesOptions
38770 .map(function (_a) {
38771 var _b = __read(_a, 2), merged = _b[0], options = _b[1];
38772 // format interpolated properties, e.g. scaleX -> transform
38773 var formatted = _this.formatKeyframes(merged, child);
38774 if (formatted.length) {
38775 // console.log(child, formatted);
38776 var animation_1 = child.animate(formatted, options);
38777 if (!isNil(visibilityStartOffset) &&
38778 !isNil(visibilityEndOffset)) {
38779 child.style.visibility = 'hidden';
38780 animation_1.onframe = function () {
38781 var progress = animation_1.effect.getComputedTiming().progress;
38782 if (progress >= visibilityStartOffset &&
38783 progress < visibilityEndOffset) {
38784 child.style.visibility = 'visible';
38785 }
38786 else {
38787 child.style.visibility = 'hidden';
38788 }
38789 };
38790 }
38791 if (!_this.context.autoplay) {
38792 animation_1.pause();
38793 }
38794 return animation_1;
38795 }
38796 })
38797 .filter(function (animation) { return !!animation; })), false));
38798 }
38799 });
38800 });
38801 return wrapper;
38802 };
38803 LottieAnimation.prototype.formatKeyframes = function (keyframes, object) {
38804 keyframes.forEach(function (keyframe) {
38805 // if ('offsetPath' in keyframe) {
38806 // if (!object.style.offsetPath) {
38807 // const [ox, oy] = object.getOrigin();
38808 // (keyframe.offsetPath as AbsoluteArray).forEach((segment) => {
38809 // if (segment[0] === 'M') {
38810 // segment[1] -= ox;
38811 // segment[2] -= oy;
38812 // } else if (segment[0] === 'C') {
38813 // segment[1] -= ox;
38814 // segment[2] -= oy;
38815 // segment[3] -= ox;
38816 // segment[4] -= oy;
38817 // segment[5] -= ox;
38818 // segment[6] -= oy;
38819 // }
38820 // });
38821 // const offsetPath = new Path({
38822 // style: {
38823 // d: keyframe.offsetPath,
38824 // },
38825 // });
38826 // object.style.offsetPath = offsetPath;
38827 // console.log(offsetPath);
38828 // }
38829 // delete keyframe.offsetPath;
38830 // // offsetPath should override x/y
38831 // delete keyframe.x;
38832 // delete keyframe.y;
38833 // }
38834 // should keep transform during initialization
38835 // if (!object.style.offsetPath) {
38836 // keyframe.transform = object.style.transform || '';
38837 // }
38838 keyframe.transform = object.style.transform || '';
38839 // TODO: transforms with different easing functions will conflict
38840 if ('scaleX' in keyframe) {
38841 keyframe.transform =
38842 (keyframe.transform || '') +
38843 " scaleX(".concat(keyframe.scaleX === 0 ? eps : keyframe.scaleX, ")");
38844 delete keyframe.scaleX;
38845 }
38846 if ('scaleY' in keyframe) {
38847 keyframe.transform =
38848 (keyframe.transform || '') +
38849 " scaleY(".concat(keyframe.scaleY === 0 ? eps : keyframe.scaleY, ")");
38850 delete keyframe.scaleY;
38851 }
38852 if ('rotation' in keyframe) {
38853 keyframe.transform =
38854 (keyframe.transform || '') + " rotate(".concat(keyframe.rotation, "deg)");
38855 delete keyframe.rotation;
38856 }
38857 // TODO: skew & skewAxis
38858 // if ('skew' in keyframe) {
38859 // keyframe.transform = (keyframe.transform || '') + ` skew(${keyframe.skew}deg)`;
38860 // delete keyframe.skew;
38861 // }
38862 if ('x' in keyframe) {
38863 keyframe.transform =
38864 (keyframe.transform || '') + " translateX(".concat(keyframe.x, "px)");
38865 delete keyframe.x;
38866 }
38867 if ('y' in keyframe) {
38868 keyframe.transform =
38869 (keyframe.transform || '') + " translateY(".concat(keyframe.y, "px)");
38870 delete keyframe.y;
38871 }
38872 // { style: { opacity: 1 } }
38873 if ('style' in keyframe) {
38874 Object.keys(keyframe.style).forEach(function (name) {
38875 keyframe[name] = keyframe.style[name];
38876 });
38877 delete keyframe.style;
38878 }
38879 });
38880 // ignore empty interpolable attributes
38881 keyframes = keyframes.filter(function (keyframe) {
38882 // TODO: support negative offset
38883 keyframe.ignore; keyframe.easing; var offset = keyframe.offset, rest = __rest(keyframe, ["ignore", "easing", "offset"]);
38884 return offset >= 0 && Object.keys(rest).length > 0;
38885 // return Object.keys(rest).length > 0;
38886 });
38887 if (keyframes.length) {
38888 // padding offset = 1
38889 if (keyframes[keyframes.length - 1].offset !== 1) {
38890 keyframes.push(__assign(__assign({}, keyframes[keyframes.length - 1]), { offset: 1 }));
38891 }
38892 }
38893 // sort by offset
38894 keyframes.sort(function (a, b) { return a.offset - b.offset; });
38895 // remove empty attributes
38896 keyframes.forEach(function (keyframe) {
38897 Object.keys(keyframe).forEach(function (name) {
38898 if (keyframe[name] === '') {
38899 delete keyframe[name];
38900 }
38901 });
38902 });
38903 return keyframes;
38904 };
38905 /**
38906 * Destroy all internal displayobjects.
38907 */
38908 LottieAnimation.prototype.destroy = function () {
38909 this.displayObjects.forEach(function (object) {
38910 object.destroy();
38911 });
38912 };
38913 /**
38914 * Return the size of this animation.
38915 * @param outputSize - If provided, the size will be copied into here as width, height.
38916 */
38917 LottieAnimation.prototype.size = function (outputSize) {
38918 return { width: this.width, height: this.height };
38919 };
38920 /**
38921 * Bodymovin version
38922 */
38923 LottieAnimation.prototype.version = function () {
38924 return this.context.version;
38925 };
38926 LottieAnimation.prototype.play = function () {
38927 this.isPaused = false;
38928 this.animations.forEach(function (animation) {
38929 animation.play();
38930 });
38931 };
38932 /**
38933 * Can contain 2 numeric values that will be used as first and last frame of the animation.
38934 * @see https://github.com/airbnb/lottie-web#playsegmentssegments-forceflag
38935 */
38936 LottieAnimation.prototype.playSegments = function (segments) {
38937 var _this = this;
38938 var _a = __read(segments, 2), firstFrame = _a[0], lastFrame = _a[1];
38939 this.isPaused = false;
38940 this.animations.forEach(function (animation) {
38941 animation.currentTime = (firstFrame / _this.fps()) * 1000;
38942 var originOnFrame = animation.onframe;
38943 animation.onframe = function (e) {
38944 if (originOnFrame) {
38945 // @ts-ignore
38946 originOnFrame(e);
38947 }
38948 if (animation.currentTime >= (lastFrame / _this.fps()) * 1000) {
38949 animation.finish();
38950 if (originOnFrame) {
38951 animation.onframe = originOnFrame;
38952 }
38953 else {
38954 animation.onframe = null;
38955 }
38956 }
38957 };
38958 animation.play();
38959 });
38960 };
38961 LottieAnimation.prototype.pause = function () {
38962 this.isPaused = true;
38963 this.animations.forEach(function (animation) {
38964 animation.pause();
38965 });
38966 };
38967 /**
38968 *
38969 */
38970 LottieAnimation.prototype.togglePause = function () {
38971 if (this.isPaused) {
38972 this.play();
38973 }
38974 else {
38975 this.pause();
38976 }
38977 };
38978 /**
38979 * Goto and stop at a specific time(in seconds) or frame.
38980 * Split goToAndStop/Play into goTo & stop/play
38981 * @see https://github.com/airbnb/lottie-web
38982 */
38983 LottieAnimation.prototype.goTo = function (value, isFrame) {
38984 var _this = this;
38985 if (isFrame === void 0) { isFrame = false; }
38986 if (isFrame) {
38987 this.animations.forEach(function (animation) {
38988 animation.currentTime = (value / _this.fps()) * 1000;
38989 });
38990 }
38991 else {
38992 this.animations.forEach(function (animation) {
38993 animation.currentTime = value * 1000;
38994 });
38995 }
38996 };
38997 /**
38998 * @see https://github.com/airbnb/lottie-web#stop
38999 */
39000 LottieAnimation.prototype.stop = function () {
39001 this.animations.forEach(function (animation) {
39002 animation.finish();
39003 });
39004 };
39005 /**
39006 * 1 is normal speed.
39007 * @see https://github.com/airbnb/lottie-web#setspeedspeed
39008 */
39009 LottieAnimation.prototype.setSpeed = function (speed) {
39010 var _this = this;
39011 this.animations.forEach(function (animation) {
39012 animation.playbackRate = speed * _this.direction;
39013 });
39014 };
39015 /**
39016 * 1 is forward, -1 is reverse.
39017 * @see https://github.com/airbnb/lottie-web#setdirectiondirection
39018 */
39019 LottieAnimation.prototype.setDirection = function (direction) {
39020 this.direction = direction;
39021 this.animations.forEach(function (animation) {
39022 animation.playbackRate *= direction;
39023 });
39024 };
39025 return LottieAnimation;
39026 }());
39027
39028 /**
39029 * borrow from https://github.com/airbnb/lottie-web/blob/master/player/js/utils/DataManager.js#L40-L493
39030 */
39031 function completeLayers(layers, comps) {
39032 var layerData;
39033 var i;
39034 var len = layers.length;
39035 var j;
39036 var jLen;
39037 var k;
39038 var kLen;
39039 for (i = 0; i < len; i += 1) {
39040 layerData = layers[i];
39041 if ('ks' in layerData && !layerData.completed) {
39042 layerData.completed = true;
39043 if (layerData.tt) {
39044 layers[i - 1].td = layerData.tt;
39045 }
39046 if (layerData.hasMask) {
39047 var maskProps = layerData.masksProperties;
39048 jLen = maskProps.length;
39049 for (j = 0; j < jLen; j += 1) {
39050 if (maskProps[j].pt.k.i) {
39051 convertPathsToAbsoluteValues(maskProps[j].pt.k);
39052 }
39053 else {
39054 kLen = maskProps[j].pt.k.length;
39055 for (k = 0; k < kLen; k += 1) {
39056 if (maskProps[j].pt.k[k].s) {
39057 convertPathsToAbsoluteValues(maskProps[j].pt.k[k].s[0]);
39058 }
39059 if (maskProps[j].pt.k[k].e) {
39060 convertPathsToAbsoluteValues(maskProps[j].pt.k[k].e[0]);
39061 }
39062 }
39063 }
39064 }
39065 }
39066 if (layerData.ty === 0) {
39067 layerData.layers = findCompLayers(layerData.refId, comps);
39068 completeLayers(layerData.layers, comps);
39069 }
39070 else if (layerData.ty === 4) {
39071 completeShapes(layerData.shapes);
39072 }
39073 else if (layerData.ty === 5) {
39074 completeText(layerData);
39075 }
39076 }
39077 }
39078 }
39079 function completeChars(chars, assets) {
39080 if (chars) {
39081 var i = 0;
39082 var len = chars.length;
39083 for (i = 0; i < len; i += 1) {
39084 if (chars[i].t === 1) {
39085 // var compData = findComp(chars[i].data.refId, assets);
39086 chars[i].data.layers = findCompLayers(chars[i].data.refId, assets);
39087 // chars[i].data.ip = 0;
39088 // chars[i].data.op = 99999;
39089 // chars[i].data.st = 0;
39090 // chars[i].data.sr = 1;
39091 // chars[i].w = compData.w;
39092 // chars[i].data.ks = {
39093 // a: { k: [0, 0, 0], a: 0 },
39094 // p: { k: [0, -compData.h, 0], a: 0 },
39095 // r: { k: 0, a: 0 },
39096 // s: { k: [100, 100], a: 0 },
39097 // o: { k: 100, a: 0 },
39098 // };
39099 completeLayers(chars[i].data.layers, assets);
39100 }
39101 }
39102 }
39103 }
39104 function findComp(id, comps) {
39105 var i = 0;
39106 var len = comps.length;
39107 while (i < len) {
39108 if (comps[i].id === id) {
39109 return comps[i];
39110 }
39111 i += 1;
39112 }
39113 return null;
39114 }
39115 function findCompLayers(id, comps) {
39116 var comp = findComp(id, comps);
39117 if (comp) {
39118 if (!comp.layers.__used) {
39119 comp.layers.__used = true;
39120 return comp.layers;
39121 }
39122 return JSON.parse(JSON.stringify(comp.layers));
39123 }
39124 return null;
39125 }
39126 function completeShapes(arr) {
39127 var i;
39128 var len = arr.length;
39129 var j;
39130 var jLen;
39131 for (i = len - 1; i >= 0; i -= 1) {
39132 if (arr[i].ty === 'sh') {
39133 if (arr[i].ks.k.i) {
39134 convertPathsToAbsoluteValues(arr[i].ks.k);
39135 }
39136 else {
39137 jLen = arr[i].ks.k.length;
39138 for (j = 0; j < jLen; j += 1) {
39139 if (arr[i].ks.k[j].s) {
39140 convertPathsToAbsoluteValues(arr[i].ks.k[j].s[0]);
39141 }
39142 if (arr[i].ks.k[j].e) {
39143 convertPathsToAbsoluteValues(arr[i].ks.k[j].e[0]);
39144 }
39145 }
39146 }
39147 }
39148 else if (arr[i].ty === 'gr') {
39149 completeShapes(arr[i].it);
39150 }
39151 }
39152 }
39153 function convertPathsToAbsoluteValues(path) {
39154 var i;
39155 var len = path.i.length;
39156 for (i = 0; i < len; i += 1) {
39157 path.i[i][0] += path.v[i][0];
39158 path.i[i][1] += path.v[i][1];
39159 path.o[i][0] += path.v[i][0];
39160 path.o[i][1] += path.v[i][1];
39161 }
39162 }
39163 function checkVersion(minimum, animVersionString) {
39164 var animVersion = animVersionString ? animVersionString.split('.') : [100, 100, 100];
39165 if (minimum[0] > animVersion[0]) {
39166 return true;
39167 }
39168 if (animVersion[0] > minimum[0]) {
39169 return false;
39170 }
39171 if (minimum[1] > animVersion[1]) {
39172 return true;
39173 }
39174 if (animVersion[1] > minimum[1]) {
39175 return false;
39176 }
39177 if (minimum[2] > animVersion[2]) {
39178 return true;
39179 }
39180 if (animVersion[2] > minimum[2]) {
39181 return false;
39182 }
39183 return null;
39184 }
39185 var checkText = (function () {
39186 var minimumVersion = [4, 4, 14];
39187 function updateTextLayer(textLayer) {
39188 var documentData = textLayer.t.d;
39189 textLayer.t.d = {
39190 k: [
39191 {
39192 s: documentData,
39193 t: 0,
39194 },
39195 ],
39196 };
39197 }
39198 function iterateLayers(layers) {
39199 var i;
39200 var len = layers.length;
39201 for (i = 0; i < len; i += 1) {
39202 if (layers[i].ty === 5) {
39203 updateTextLayer(layers[i]);
39204 }
39205 }
39206 }
39207 return function (animationData) {
39208 if (checkVersion(minimumVersion, animationData.v)) {
39209 iterateLayers(animationData.layers);
39210 if (animationData.assets) {
39211 var i = void 0;
39212 var len = animationData.assets.length;
39213 for (i = 0; i < len; i += 1) {
39214 if (animationData.assets[i].layers) {
39215 iterateLayers(animationData.assets[i].layers);
39216 }
39217 }
39218 }
39219 }
39220 };
39221 })();
39222 var checkChars = (function () {
39223 var minimumVersion = [4, 7, 99];
39224 return function (animationData) {
39225 if (animationData.chars && !checkVersion(minimumVersion, animationData.v)) {
39226 var i = void 0;
39227 var len = animationData.chars.length;
39228 for (i = 0; i < len; i += 1) {
39229 var charData = animationData.chars[i];
39230 if (charData.data && charData.data.shapes) {
39231 completeShapes(charData.data.shapes);
39232 charData.data.ip = 0;
39233 charData.data.op = 99999;
39234 charData.data.st = 0;
39235 charData.data.sr = 1;
39236 charData.data.ks = {
39237 p: { k: [0, 0], a: 0 },
39238 s: { k: [100, 100], a: 0 },
39239 a: { k: [0, 0], a: 0 },
39240 r: { k: 0, a: 0 },
39241 o: { k: 100, a: 0 },
39242 };
39243 if (!animationData.chars[i].t) {
39244 charData.data.shapes.push({
39245 ty: 'no',
39246 });
39247 charData.data.shapes[0].it.push({
39248 p: { k: [0, 0], a: 0 },
39249 s: { k: [100, 100], a: 0 },
39250 a: { k: [0, 0], a: 0 },
39251 r: { k: 0, a: 0 },
39252 o: { k: 100, a: 0 },
39253 sk: { k: 0, a: 0 },
39254 sa: { k: 0, a: 0 },
39255 ty: 'tr',
39256 });
39257 }
39258 }
39259 }
39260 }
39261 };
39262 })();
39263 var checkPathProperties = (function () {
39264 var minimumVersion = [5, 7, 15];
39265 function updateTextLayer(textLayer) {
39266 var pathData = textLayer.t.p;
39267 if (typeof pathData.a === 'number') {
39268 pathData.a = {
39269 a: 0,
39270 k: pathData.a,
39271 };
39272 }
39273 if (typeof pathData.p === 'number') {
39274 pathData.p = {
39275 a: 0,
39276 k: pathData.p,
39277 };
39278 }
39279 if (typeof pathData.r === 'number') {
39280 pathData.r = {
39281 a: 0,
39282 k: pathData.r,
39283 };
39284 }
39285 }
39286 function iterateLayers(layers) {
39287 var i;
39288 var len = layers.length;
39289 for (i = 0; i < len; i += 1) {
39290 if (layers[i].ty === 5) {
39291 updateTextLayer(layers[i]);
39292 }
39293 }
39294 }
39295 return function (animationData) {
39296 if (checkVersion(minimumVersion, animationData.v)) {
39297 iterateLayers(animationData.layers);
39298 if (animationData.assets) {
39299 var i = void 0;
39300 var len = animationData.assets.length;
39301 for (i = 0; i < len; i += 1) {
39302 if (animationData.assets[i].layers) {
39303 iterateLayers(animationData.assets[i].layers);
39304 }
39305 }
39306 }
39307 }
39308 };
39309 })();
39310 var checkColors = (function () {
39311 var minimumVersion = [4, 1, 9];
39312 function iterateShapes(shapes) {
39313 var i;
39314 var len = shapes.length;
39315 var j;
39316 var jLen;
39317 for (i = 0; i < len; i += 1) {
39318 if (shapes[i].ty === 'gr') {
39319 iterateShapes(shapes[i].it);
39320 }
39321 else if (shapes[i].ty === 'fl' || shapes[i].ty === 'st') {
39322 if (shapes[i].c.k && shapes[i].c.k[0].i) {
39323 jLen = shapes[i].c.k.length;
39324 for (j = 0; j < jLen; j += 1) {
39325 if (shapes[i].c.k[j].s) {
39326 shapes[i].c.k[j].s[0] /= 255;
39327 shapes[i].c.k[j].s[1] /= 255;
39328 shapes[i].c.k[j].s[2] /= 255;
39329 shapes[i].c.k[j].s[3] /= 255;
39330 }
39331 if (shapes[i].c.k[j].e) {
39332 shapes[i].c.k[j].e[0] /= 255;
39333 shapes[i].c.k[j].e[1] /= 255;
39334 shapes[i].c.k[j].e[2] /= 255;
39335 shapes[i].c.k[j].e[3] /= 255;
39336 }
39337 }
39338 }
39339 else {
39340 shapes[i].c.k[0] /= 255;
39341 shapes[i].c.k[1] /= 255;
39342 shapes[i].c.k[2] /= 255;
39343 shapes[i].c.k[3] /= 255;
39344 }
39345 }
39346 }
39347 }
39348 function iterateLayers(layers) {
39349 var i;
39350 var len = layers.length;
39351 for (i = 0; i < len; i += 1) {
39352 if (layers[i].ty === 4) {
39353 iterateShapes(layers[i].shapes);
39354 }
39355 }
39356 }
39357 return function (animationData) {
39358 if (checkVersion(minimumVersion, animationData.v)) {
39359 iterateLayers(animationData.layers);
39360 if (animationData.assets) {
39361 var i = void 0;
39362 var len = animationData.assets.length;
39363 for (i = 0; i < len; i += 1) {
39364 if (animationData.assets[i].layers) {
39365 iterateLayers(animationData.assets[i].layers);
39366 }
39367 }
39368 }
39369 }
39370 };
39371 })();
39372 var checkShapes = (function () {
39373 var minimumVersion = [4, 4, 18];
39374 function completeClosingShapes(arr) {
39375 var i;
39376 var len = arr.length;
39377 var j;
39378 var jLen;
39379 for (i = len - 1; i >= 0; i -= 1) {
39380 if (arr[i].ty === 'sh') {
39381 if (arr[i].ks.k.i) {
39382 arr[i].ks.k.c = arr[i].closed;
39383 }
39384 else {
39385 jLen = arr[i].ks.k.length;
39386 for (j = 0; j < jLen; j += 1) {
39387 if (arr[i].ks.k[j].s) {
39388 arr[i].ks.k[j].s[0].c = arr[i].closed;
39389 }
39390 if (arr[i].ks.k[j].e) {
39391 arr[i].ks.k[j].e[0].c = arr[i].closed;
39392 }
39393 }
39394 }
39395 }
39396 else if (arr[i].ty === 'gr') {
39397 completeClosingShapes(arr[i].it);
39398 }
39399 }
39400 }
39401 function iterateLayers(layers) {
39402 var layerData;
39403 var i;
39404 var len = layers.length;
39405 var j;
39406 var jLen;
39407 var k;
39408 var kLen;
39409 for (i = 0; i < len; i += 1) {
39410 layerData = layers[i];
39411 if (layerData.hasMask) {
39412 var maskProps = layerData.masksProperties;
39413 jLen = maskProps.length;
39414 for (j = 0; j < jLen; j += 1) {
39415 if (maskProps[j].pt.k.i) {
39416 maskProps[j].pt.k.c = maskProps[j].cl;
39417 }
39418 else {
39419 kLen = maskProps[j].pt.k.length;
39420 for (k = 0; k < kLen; k += 1) {
39421 if (maskProps[j].pt.k[k].s) {
39422 maskProps[j].pt.k[k].s[0].c = maskProps[j].cl;
39423 }
39424 if (maskProps[j].pt.k[k].e) {
39425 maskProps[j].pt.k[k].e[0].c = maskProps[j].cl;
39426 }
39427 }
39428 }
39429 }
39430 }
39431 if (layerData.ty === 4) {
39432 completeClosingShapes(layerData.shapes);
39433 }
39434 }
39435 }
39436 return function (animationData) {
39437 if (checkVersion(minimumVersion, animationData.v)) {
39438 iterateLayers(animationData.layers);
39439 if (animationData.assets) {
39440 var i = void 0;
39441 var len = animationData.assets.length;
39442 for (i = 0; i < len; i += 1) {
39443 if (animationData.assets[i].layers) {
39444 iterateLayers(animationData.assets[i].layers);
39445 }
39446 }
39447 }
39448 }
39449 };
39450 })();
39451 function completeData(animationData) {
39452 if (animationData.__complete) {
39453 return;
39454 }
39455 checkColors(animationData);
39456 checkText(animationData);
39457 checkChars(animationData);
39458 checkPathProperties(animationData);
39459 checkShapes(animationData);
39460 completeLayers(animationData.layers, animationData.assets);
39461 completeChars(animationData.chars, animationData.assets);
39462 animationData.__complete = true;
39463 }
39464 function completeText(data) {
39465 if (data.t.a.length === 0 && !('m' in data.t.p)) ;
39466 }
39467
39468 /**
39469 * https://lottiefiles.github.io/lottie-docs/constants/
39470 */
39471 var BlendMode;
39472 (function (BlendMode) {
39473 BlendMode[BlendMode["Normal"] = 0] = "Normal";
39474 BlendMode[BlendMode["Multiply"] = 1] = "Multiply";
39475 BlendMode[BlendMode["Screen"] = 2] = "Screen";
39476 BlendMode[BlendMode["Overlay"] = 3] = "Overlay";
39477 BlendMode[BlendMode["Darken"] = 4] = "Darken";
39478 BlendMode[BlendMode["Lighten"] = 5] = "Lighten";
39479 BlendMode[BlendMode["ColorDodge"] = 6] = "ColorDodge";
39480 BlendMode[BlendMode["ColorBurn"] = 7] = "ColorBurn";
39481 BlendMode[BlendMode["HardLight"] = 8] = "HardLight";
39482 BlendMode[BlendMode["SoftLight"] = 9] = "SoftLight";
39483 BlendMode[BlendMode["Difference"] = 10] = "Difference";
39484 BlendMode[BlendMode["Exclusion"] = 11] = "Exclusion";
39485 BlendMode[BlendMode["Hue"] = 12] = "Hue";
39486 BlendMode[BlendMode["Saturation"] = 13] = "Saturation";
39487 BlendMode[BlendMode["Color"] = 14] = "Color";
39488 BlendMode[BlendMode["Luminosity"] = 15] = "Luminosity";
39489 BlendMode[BlendMode["Add"] = 16] = "Add";
39490 BlendMode[BlendMode["HardMix"] = 17] = "HardMix";
39491 })(BlendMode || (BlendMode = {}));
39492 /**
39493 * @see https://lottiefiles.github.io/lottie-docs/constants/#mattemode
39494 */
39495 var MatteMode;
39496 (function (MatteMode) {
39497 MatteMode[MatteMode["Normal"] = 0] = "Normal";
39498 MatteMode[MatteMode["Alpha"] = 1] = "Alpha";
39499 MatteMode[MatteMode["InvertedAlpha"] = 2] = "InvertedAlpha";
39500 MatteMode[MatteMode["Luma"] = 3] = "Luma";
39501 MatteMode[MatteMode["InvertedLuma"] = 4] = "InvertedLuma";
39502 })(MatteMode || (MatteMode = {}));
39503 var Layer3DMode;
39504 (function (Layer3DMode) {
39505 Layer3DMode[Layer3DMode["Off"] = 0] = "Off";
39506 Layer3DMode[Layer3DMode["On"] = 1] = "On";
39507 })(Layer3DMode || (Layer3DMode = {}));
39508 var AutoOrientMode;
39509 (function (AutoOrientMode) {
39510 AutoOrientMode[AutoOrientMode["Off"] = 0] = "Off";
39511 AutoOrientMode[AutoOrientMode["On"] = 1] = "On";
39512 })(AutoOrientMode || (AutoOrientMode = {}));
39513 var EffectValueType;
39514 (function (EffectValueType) {
39515 EffectValueType[EffectValueType["Number"] = 0] = "Number";
39516 EffectValueType[EffectValueType["Color"] = 2] = "Color";
39517 EffectValueType[EffectValueType["MultiDimensional"] = 3] = "MultiDimensional";
39518 EffectValueType[EffectValueType["Boolean"] = 7] = "Boolean";
39519 })(EffectValueType || (EffectValueType = {}));
39520 var EffectType;
39521 (function (EffectType) {
39522 EffectType[EffectType["Transform"] = 5] = "Transform";
39523 EffectType[EffectType["DropShadow"] = 25] = "DropShadow";
39524 })(EffectType || (EffectType = {}));
39525 var MaskMode;
39526 (function (MaskMode) {
39527 MaskMode["No"] = "n";
39528 MaskMode["Add"] = "a";
39529 MaskMode["Subtract"] = "s";
39530 MaskMode["Intersect"] = "i";
39531 MaskMode["Lighten"] = "l";
39532 MaskMode["Darken"] = "d";
39533 MaskMode["Difference"] = "f";
39534 })(MaskMode || (MaskMode = {}));
39535 var LayerType;
39536 (function (LayerType) {
39537 LayerType[LayerType["precomp"] = 0] = "precomp";
39538 LayerType[LayerType["solid"] = 1] = "solid";
39539 LayerType[LayerType["image"] = 2] = "image";
39540 LayerType[LayerType["null"] = 3] = "null";
39541 LayerType[LayerType["shape"] = 4] = "shape";
39542 LayerType[LayerType["text"] = 5] = "text";
39543 LayerType[LayerType["audio"] = 6] = "audio";
39544 LayerType[LayerType["pholderVideo"] = 7] = "pholderVideo";
39545 LayerType[LayerType["imageSeq"] = 8] = "imageSeq";
39546 LayerType[LayerType["video"] = 9] = "video";
39547 LayerType[LayerType["pholderStill"] = 10] = "pholderStill";
39548 LayerType[LayerType["guide"] = 11] = "guide";
39549 LayerType[LayerType["adjustment"] = 12] = "adjustment";
39550 LayerType[LayerType["camera"] = 13] = "camera";
39551 LayerType[LayerType["light"] = 14] = "light";
39552 LayerType[LayerType["data"] = 15] = "data";
39553 })(LayerType || (LayerType = {}));
39554 var TextJustify;
39555 (function (TextJustify) {
39556 TextJustify[TextJustify["Left"] = 0] = "Left";
39557 TextJustify[TextJustify["Right"] = 1] = "Right";
39558 TextJustify[TextJustify["Center"] = 2] = "Center";
39559 })(TextJustify || (TextJustify = {}));
39560 var VerticalJustify;
39561 (function (VerticalJustify) {
39562 VerticalJustify[VerticalJustify["Top"] = 0] = "Top";
39563 VerticalJustify[VerticalJustify["Center"] = 1] = "Center";
39564 VerticalJustify[VerticalJustify["Bottom"] = 2] = "Bottom";
39565 })(VerticalJustify || (VerticalJustify = {}));
39566 var RangeSelectorDomain;
39567 (function (RangeSelectorDomain) {
39568 RangeSelectorDomain[RangeSelectorDomain["Characters"] = 1] = "Characters";
39569 RangeSelectorDomain[RangeSelectorDomain["CharactersExcludingSpaces"] = 2] = "CharactersExcludingSpaces";
39570 RangeSelectorDomain[RangeSelectorDomain["Words"] = 3] = "Words";
39571 RangeSelectorDomain[RangeSelectorDomain["Lines"] = 4] = "Lines";
39572 })(RangeSelectorDomain || (RangeSelectorDomain = {}));
39573 var RangeSelectorShape;
39574 (function (RangeSelectorShape) {
39575 RangeSelectorShape[RangeSelectorShape["Square"] = 1] = "Square";
39576 RangeSelectorShape[RangeSelectorShape["RampUp"] = 2] = "RampUp";
39577 RangeSelectorShape[RangeSelectorShape["RampDown"] = 3] = "RampDown";
39578 RangeSelectorShape[RangeSelectorShape["Triangle"] = 4] = "Triangle";
39579 RangeSelectorShape[RangeSelectorShape["Round"] = 5] = "Round";
39580 RangeSelectorShape[RangeSelectorShape["Smooth"] = 6] = "Smooth";
39581 })(RangeSelectorShape || (RangeSelectorShape = {}));
39582 var RangeSelectorUnits;
39583 (function (RangeSelectorUnits) {
39584 RangeSelectorUnits[RangeSelectorUnits["Percentage"] = 1] = "Percentage";
39585 RangeSelectorUnits[RangeSelectorUnits["Index"] = 2] = "Index";
39586 })(RangeSelectorUnits || (RangeSelectorUnits = {}));
39587 var RangeSelectorMode;
39588 (function (RangeSelectorMode) {
39589 RangeSelectorMode[RangeSelectorMode["Add"] = 1] = "Add";
39590 RangeSelectorMode[RangeSelectorMode["Subtract"] = 2] = "Subtract";
39591 RangeSelectorMode[RangeSelectorMode["Intersect"] = 3] = "Intersect";
39592 RangeSelectorMode[RangeSelectorMode["Min"] = 4] = "Min";
39593 RangeSelectorMode[RangeSelectorMode["Max"] = 5] = "Max";
39594 RangeSelectorMode[RangeSelectorMode["Difference"] = 6] = "Difference";
39595 })(RangeSelectorMode || (RangeSelectorMode = {}));
39596 /**
39597 * @see https://lottiefiles.github.io/lottie-docs/shapes/#shape-types
39598 */
39599 var ShapeType;
39600 (function (ShapeType) {
39601 ShapeType["Rectangle"] = "rc";
39602 ShapeType["Ellipse"] = "el";
39603 ShapeType["PolyStar"] = "sr";
39604 ShapeType["Path"] = "sh";
39605 ShapeType["Fill"] = "fl";
39606 ShapeType["Stroke"] = "st";
39607 ShapeType["GradientFill"] = "gf";
39608 ShapeType["GradientStroke"] = "gs";
39609 ShapeType["NoStyle"] = "no";
39610 ShapeType["Group"] = "gr";
39611 ShapeType["Transform"] = "tr";
39612 ShapeType["Repeater"] = "rp";
39613 ShapeType["Trim"] = "tm";
39614 ShapeType["RoundedCorners"] = "rd";
39615 ShapeType["PuckerOrBloat"] = "pb";
39616 ShapeType["Merge"] = "mm";
39617 ShapeType["Twist"] = "tw";
39618 ShapeType["OffsetPath"] = "op";
39619 ShapeType["ZigZag"] = "zz";
39620 })(ShapeType || (ShapeType = {}));
39621 /**
39622 * @see https://lottiefiles.github.io/lottie-docs/constants/#fillrule
39623 */
39624 var FillRule;
39625 (function (FillRule) {
39626 FillRule[FillRule["NonZero"] = 1] = "NonZero";
39627 FillRule[FillRule["EvenOdd"] = 2] = "EvenOdd";
39628 })(FillRule || (FillRule = {}));
39629 /**
39630 * @see https://lottiefiles.github.io/lottie-docs/constants/#linejoin
39631 */
39632 var LineJoin;
39633 (function (LineJoin) {
39634 LineJoin[LineJoin["Miter"] = 1] = "Miter";
39635 LineJoin[LineJoin["Round"] = 2] = "Round";
39636 LineJoin[LineJoin["Bevel"] = 3] = "Bevel";
39637 })(LineJoin || (LineJoin = {}));
39638 /**
39639 * @see https://lottiefiles.github.io/lottie-docs/constants/#linecap
39640 */
39641 var LineCap;
39642 (function (LineCap) {
39643 LineCap[LineCap["Butt"] = 1] = "Butt";
39644 LineCap[LineCap["Round"] = 2] = "Round";
39645 LineCap[LineCap["Square"] = 3] = "Square";
39646 })(LineCap || (LineCap = {}));
39647 /**
39648 * @see https://lottiefiles.github.io/lottie-docs/constants/#gradienttype
39649 */
39650 var GradientType$1;
39651 (function (GradientType) {
39652 GradientType[GradientType["Linear"] = 1] = "Linear";
39653 GradientType[GradientType["Radial"] = 2] = "Radial";
39654 })(GradientType$1 || (GradientType$1 = {}));
39655 var FontPathOrigin;
39656 (function (FontPathOrigin) {
39657 FontPathOrigin[FontPathOrigin["CssUrl"] = 1] = "CssUrl";
39658 FontPathOrigin[FontPathOrigin["ScriptUrl"] = 2] = "ScriptUrl";
39659 FontPathOrigin[FontPathOrigin["FontUrl"] = 3] = "FontUrl";
39660 })(FontPathOrigin || (FontPathOrigin = {}));
39661
39662 var ParseContext = /** @class */ (function () {
39663 function ParseContext() {
39664 this.frameTime = 1000 / 30;
39665 this.startFrame = 0;
39666 this.autoplay = false;
39667 this.fill = 'auto';
39668 this.iterations = 0;
39669 this.assetsMap = new Map();
39670 }
39671 return ParseContext;
39672 }());
39673 function isNumberArray(val) {
39674 return Array.isArray(val) && typeof val[0] === 'number';
39675 }
39676 function isMultiDimensionalValue(val) {
39677 return isNumberArray(val === null || val === void 0 ? void 0 : val.k);
39678 }
39679 function isMultiDimensionalKeyframedValue(val) {
39680 var k = val === null || val === void 0 ? void 0 : val.k;
39681 return Array.isArray(k) && k[0].t !== undefined && isNumberArray(k[0].s);
39682 }
39683 function isValue(val) {
39684 // TODO is [100] sort of value?
39685 return typeof (val === null || val === void 0 ? void 0 : val.k) === 'number';
39686 }
39687 function isKeyframedValue(val) {
39688 var k = val === null || val === void 0 ? void 0 : val.k;
39689 return Array.isArray(k) && k[0].t !== undefined && typeof k[0].s === 'number';
39690 }
39691 function toColorString(val) {
39692 var opacity = getMultiDimensionValue(val, 3);
39693 return "rgba(".concat([
39694 Math.round(getMultiDimensionValue(val, 0) * 255),
39695 Math.round(getMultiDimensionValue(val, 1) * 255),
39696 Math.round(getMultiDimensionValue(val, 2) * 255),
39697 !isNil(opacity) ? opacity : 1,
39698 ].join(','), ")");
39699 }
39700 function getMultiDimensionValue(val, dimIndex) {
39701 return val != null
39702 ? typeof val === 'number'
39703 ? val
39704 : val[dimIndex || 0]
39705 : NaN;
39706 }
39707 /**
39708 * @see https://lottiefiles.github.io/lottie-docs/concepts/#easing-handles
39709 */
39710 function getMultiDimensionEasingBezierString(kf, nextKf, dimIndex) {
39711 var _a, _b, _c, _d;
39712 var bezierEasing = [];
39713 bezierEasing.push((((_a = kf.o) === null || _a === void 0 ? void 0 : _a.x) &&
39714 (getMultiDimensionValue(kf.o.x, dimIndex) ||
39715 getMultiDimensionValue(kf.o.x, 0))) ||
39716 0, (((_b = kf.o) === null || _b === void 0 ? void 0 : _b.y) &&
39717 (getMultiDimensionValue(kf.o.y, dimIndex) ||
39718 getMultiDimensionValue(kf.o.y, 0))) ||
39719 0, (((_c = kf.i) === null || _c === void 0 ? void 0 : _c.x) &&
39720 (getMultiDimensionValue(kf.i.x, dimIndex) ||
39721 getMultiDimensionValue(kf.i.x, 0))) ||
39722 1, (((_d = kf.i) === null || _d === void 0 ? void 0 : _d.y) &&
39723 (getMultiDimensionValue(kf.i.y, dimIndex) ||
39724 getMultiDimensionValue(kf.i.y, 0))) ||
39725 1);
39726 // linear by default
39727 if (!(bezierEasing[0] === 0 &&
39728 bezierEasing[1] === 0 &&
39729 bezierEasing[2] === 1 &&
39730 bezierEasing[3] === 1)) {
39731 return "cubic-bezier(".concat(bezierEasing.join(','), ")");
39732 }
39733 return;
39734 }
39735 /**
39736 * @see https://lottiefiles.github.io/lottie-docs/concepts/#keyframe
39737 */
39738 function parseKeyframe(kfs, bezierEasingDimIndex, context, setVal) {
39739 var kfsLen = kfs.length;
39740 // const offset = context.layerStartTime;
39741 var duration = context.endFrame - context.startFrame;
39742 var out = {
39743 duration: 0,
39744 delay: 0,
39745 keyframes: [],
39746 };
39747 var prevKf;
39748 for (var i = 0; i < kfsLen; i++) {
39749 var kf = kfs[i];
39750 var nextKf = kfs[i + 1];
39751 // If h is present and it's 1, you don't need i and o,
39752 // as the property will keep the same value until the next keyframe.
39753 var isDiscrete = kf.h === 1;
39754 var offset = (kf.t + context.layerOffsetTime - context.startFrame) / duration;
39755 var outKeyframe = {
39756 offset: offset,
39757 };
39758 if (!isDiscrete) {
39759 outKeyframe.easing = getMultiDimensionEasingBezierString(kf, nextKf, bezierEasingDimIndex);
39760 }
39761 // Use end state of later frame if start state not exits.
39762 // @see https://lottiefiles.github.io/lottie-docs/concepts/#old-lottie-keyframes
39763 var startVal = kf.s || (prevKf === null || prevKf === void 0 ? void 0 : prevKf.e);
39764 if (startVal) {
39765 setVal(outKeyframe, startVal);
39766 }
39767 if (outKeyframe.offset > 0 && i === 0) {
39768 // Set initial
39769 var initialKeyframe = {
39770 offset: 0,
39771 };
39772 if (startVal) {
39773 setVal(initialKeyframe, startVal);
39774 }
39775 out.keyframes.push(initialKeyframe);
39776 }
39777 out.keyframes.push(outKeyframe);
39778 if (isDiscrete && nextKf) {
39779 // Use two keyframe to simulate the discrete animation.
39780 var extraKeyframe = {
39781 offset: Math.max((nextKf.t + context.layerOffsetTime - context.startFrame) / duration, 0),
39782 };
39783 setVal(extraKeyframe, startVal);
39784 out.keyframes.push(extraKeyframe);
39785 }
39786 prevKf = kf;
39787 }
39788 if (kfsLen) {
39789 out.duration = context.frameTime * duration;
39790 }
39791 return out;
39792 }
39793 function parseOffsetKeyframe(kfs, targetPropName, propNames, keyframeAnimations, context, convertVal) {
39794 var _loop_1 = function (dimIndex) {
39795 var propName = propNames[dimIndex];
39796 var keyframeAnim = parseKeyframe(kfs, dimIndex, context, function (outKeyframe, startVal) {
39797 var val = getMultiDimensionValue(startVal, dimIndex);
39798 if (convertVal) {
39799 val = convertVal(val);
39800 }
39801 (targetPropName
39802 ? (outKeyframe[targetPropName] = {})
39803 : outKeyframe)[propName] = val;
39804 });
39805 // moving position around a curved path
39806 var needOffsetPath = kfs.some(function (kf) { return kf.ti && kf.to; });
39807 if (needOffsetPath) {
39808 var offsetPath_1 = [];
39809 kfs.forEach(function (kf, i) {
39810 keyframeAnim.keyframes[i].offsetPath = offsetPath_1;
39811 // convert to & ti(Tangent for values (eg: moving position around a curved path)) to offsetPath & offsetDistance
39812 // @see https://lottiefiles.github.io/lottie-docs/concepts/#animated-position
39813 if (kf.ti && kf.to) {
39814 if (i === 0) {
39815 offsetPath_1.push(['M', kf.s[0], kf.s[1]]);
39816 }
39817 keyframeAnim.keyframes[i].segmentLength = getTotalLength(offsetPath_1);
39818 // @see https://lottiefiles.github.io/lottie-docs/concepts/#bezier
39819 // The nth bezier segment is defined as:
39820 // v[n], v[n]+o[n], v[n+1]+i[n+1], v[n+1]
39821 offsetPath_1.push([
39822 'C',
39823 kf.s[0] + kf.to[0],
39824 kf.s[1] + kf.to[1],
39825 kf.s[0] + kf.ti[0],
39826 kf.s[1] + kf.ti[1],
39827 kf.e[0],
39828 kf.e[1],
39829 ]);
39830 }
39831 });
39832 // calculate offsetDistance: segmentLength / totalLength
39833 var totalLength_1 = getTotalLength(offsetPath_1);
39834 keyframeAnim.keyframes.forEach(function (kf) {
39835 kf.offsetDistance = isNil(kf.segmentLength)
39836 ? 1
39837 : kf.segmentLength / totalLength_1;
39838 delete kf.segmentLength;
39839 });
39840 }
39841 if (keyframeAnim.keyframes.length) {
39842 keyframeAnimations.push(keyframeAnim);
39843 }
39844 };
39845 for (var dimIndex = 0; dimIndex < propNames.length; dimIndex++) {
39846 _loop_1(dimIndex);
39847 }
39848 }
39849 function parseColorOffsetKeyframe(kfs, targetPropName, propName, keyframeAnimations, context) {
39850 var keyframeAnim = parseKeyframe(kfs, 0, context, function (outKeyframe, startVal) {
39851 (targetPropName
39852 ? (outKeyframe[targetPropName] = {})
39853 : outKeyframe)[propName] = toColorString(startVal);
39854 });
39855 if (keyframeAnim.keyframes.length) {
39856 keyframeAnimations.push(keyframeAnim);
39857 }
39858 }
39859 function parseValue(lottieVal, attrs, targetPropName, propNames, animations, context, convertVal) {
39860 if (targetPropName) {
39861 attrs[targetPropName] = attrs[targetPropName] || {};
39862 }
39863 var target = targetPropName ? attrs[targetPropName] : attrs;
39864 if (isValue(lottieVal)) {
39865 var val = lottieVal.k;
39866 target[propNames[0]] = convertVal ? convertVal(val) : val;
39867 }
39868 else if (isKeyframedValue(lottieVal)) {
39869 parseOffsetKeyframe(lottieVal.k, targetPropName, propNames, animations, context, convertVal);
39870 }
39871 else if (isMultiDimensionalValue(lottieVal)) {
39872 for (var i = 0; i < propNames.length; i++) {
39873 var val = getMultiDimensionValue(lottieVal.k, i);
39874 target[propNames[i]] = convertVal ? convertVal(val) : val;
39875 }
39876 }
39877 else if (isMultiDimensionalKeyframedValue(lottieVal)) {
39878 // TODO Merge dimensions
39879 parseOffsetKeyframe(lottieVal.k, targetPropName, propNames, animations, context, convertVal);
39880 }
39881 }
39882 /**
39883 * @see https://lottiefiles.github.io/lottie-docs/concepts/#transform
39884 */
39885 function parseTransforms(ks, attrs, animations, context, targetProp, transformProps) {
39886 if (targetProp === void 0) { targetProp = ''; }
39887 if (transformProps === void 0) { transformProps = {
39888 x: 'x',
39889 y: 'y',
39890 rotation: 'rotation',
39891 scaleX: 'scaleX',
39892 scaleY: 'scaleY',
39893 anchorX: 'anchorX',
39894 anchorY: 'anchorY',
39895 skew: 'skew',
39896 skewAxis: 'skewAxis',
39897 }; }
39898 // @see https://lottiefiles.github.io/lottie-docs/concepts/#split-vector
39899 if (ks.p.s) {
39900 parseValue(ks.p.x, attrs, targetProp, [transformProps.x], animations, context);
39901 parseValue(ks.p.y, attrs, targetProp, [transformProps.y], animations, context);
39902 }
39903 else {
39904 parseValue(ks.p, attrs, targetProp, [transformProps.x, transformProps.y], animations, context);
39905 }
39906 parseValue(ks.s, attrs, targetProp, [transformProps.scaleX, transformProps.scaleY], animations, context, function (val) { return val / 100; });
39907 parseValue(ks.r, attrs, targetProp, [transformProps.rotation], animations, context);
39908 parseValue(ks.a, attrs, targetProp, [transformProps.anchorX, transformProps.anchorY], animations, context);
39909 parseValue(ks.sk, attrs, targetProp, [transformProps.skew], animations, context);
39910 parseValue(ks.sa, attrs, targetProp, [transformProps.skewAxis], animations, context);
39911 }
39912 function isGradientFillOrStroke(fl) {
39913 return fl.g && fl.s && fl.e;
39914 }
39915 function convertColorStops(arr, count) {
39916 var colorStops = [];
39917 for (var i = 0; i < count * 4;) {
39918 var offset = arr[i++];
39919 var r = Math.round(arr[i++] * 255);
39920 var g = Math.round(arr[i++] * 255);
39921 var b = Math.round(arr[i++] * 255);
39922 colorStops.push({
39923 offset: offset,
39924 color: "rgb(".concat(r, ", ").concat(g, ", ").concat(b, ")"),
39925 });
39926 }
39927 return colorStops;
39928 }
39929 function joinColorStops(colorStops) {
39930 return "".concat(colorStops
39931 .map(function (_a) {
39932 var offset = _a.offset, color = _a.color;
39933 return "".concat(color, " ").concat(offset * 100, "%");
39934 })
39935 .join(', '));
39936 }
39937 /**
39938 * TODO:
39939 * * Transition
39940 * * Highlight length & angle in Radial Gradient
39941 *
39942 * @see https://lottiefiles.github.io/lottie-docs/concepts/#gradients
39943 * @see https://lottiefiles.github.io/lottie-docs/shapes/#gradients
39944 */
39945 function parseGradient$2(shape) {
39946 var colorArr = shape.g.k.k;
39947 var colorStops = convertColorStops(colorArr, shape.g.p);
39948 // @see https://lottiefiles.github.io/lottie-docs/constants/#gradienttype
39949 if (shape.t === GradientType$1.Linear) {
39950 var angle = rad2deg(Math.atan2(shape.e.k[1] - shape.s.k[1], shape.e.k[0] - shape.s.k[0]));
39951 // @see https://g-next.antv.vision/zh/docs/api/css/css-properties-values-api#linear-gradient
39952 return "linear-gradient(".concat(angle, "deg, ").concat(joinColorStops(colorStops), ")");
39953 }
39954 else if (shape.t === GradientType$1.Radial) {
39955 // TODO: highlight length & angle (h & a)
39956 // Highlight Length, as a percentage between s and e
39957 // Highlight Angle, relative to the direction from s to e
39958 var size = distanceSquareRoot(shape.e.k, shape.s.k);
39959 // @see https://g-next.antv.vision/zh/docs/api/css/css-properties-values-api#radial-gradient
39960 return "radial-gradient(circle ".concat(size, "px at ").concat(shape.s.k[0], "px ").concat(shape.s.k[1], "px, ").concat(joinColorStops(colorStops), ")");
39961 }
39962 else {
39963 // Invalid gradient
39964 return '#000';
39965 }
39966 }
39967 function parseFill(fl, attrs, animations, context) {
39968 attrs.style = attrs.style || {};
39969 // Color
39970 if (isGradientFillOrStroke(fl)) {
39971 attrs.style.fill = parseGradient$2(fl);
39972 }
39973 else {
39974 if (isMultiDimensionalValue(fl.c)) {
39975 attrs.style.fill = toColorString(fl.c.k);
39976 }
39977 else if (isMultiDimensionalKeyframedValue(fl.c)) {
39978 parseColorOffsetKeyframe(fl.c.k, 'style', 'fill', animations, context);
39979 }
39980 }
39981 // FillRule @see https://lottiefiles.github.io/lottie-docs/constants/#fillrule
39982 attrs.style.fillRule =
39983 fl.r === FillRule.EvenOdd ? 'evenodd' : 'nonzero';
39984 // Opacity
39985 parseValue(fl.o, attrs, 'style', ['fillOpacity'], animations, context, function (opacity) { return opacity / 100; });
39986 }
39987 function parseStroke(st, attrs, animations, context) {
39988 attrs.style = attrs.style || {};
39989 // Color
39990 if (isGradientFillOrStroke(st)) {
39991 attrs.style.stroke = parseGradient$2(st);
39992 }
39993 else {
39994 if (isMultiDimensionalValue(st.c)) {
39995 attrs.style.stroke = toColorString(st.c.k);
39996 }
39997 else if (isMultiDimensionalKeyframedValue(st.c)) {
39998 parseColorOffsetKeyframe(st.c.k, 'style', 'stroke', animations, context);
39999 }
40000 }
40001 // Opacity
40002 parseValue(st.o, attrs, 'style', ['strokeOpacity'], animations, context, function (opacity) { return opacity / 100; });
40003 // Line width
40004 parseValue(st.w, attrs, 'style', ['lineWidth'], animations, context);
40005 switch (st.lj) {
40006 case LineJoin.Bevel:
40007 attrs.style.lineJoin = 'bevel';
40008 break;
40009 case LineJoin.Round:
40010 attrs.style.lineJoin = 'round';
40011 break;
40012 case LineJoin.Miter:
40013 attrs.style.lineJoin = 'miter';
40014 break;
40015 }
40016 switch (st.lc) {
40017 case LineCap.Butt:
40018 attrs.style.lineCap = 'butt';
40019 break;
40020 case LineCap.Round:
40021 attrs.style.lineCap = 'round';
40022 break;
40023 case LineCap.Square:
40024 attrs.style.lineCap = 'square';
40025 break;
40026 }
40027 // Line dash
40028 var dashArray = [];
40029 var dashOffset = 0;
40030 if (st.d) {
40031 st.d.forEach(function (item) {
40032 if (item.n !== 'o') {
40033 dashArray.push(item.v.k);
40034 }
40035 else {
40036 dashOffset = item.v.k;
40037 }
40038 });
40039 attrs.style.lineDash = dashArray;
40040 attrs.style.lineDashOffset = dashOffset;
40041 }
40042 }
40043 function isBezier(k) {
40044 return k && k.i && k.o && k.v;
40045 }
40046 /**
40047 * @see https://lottiefiles.github.io/lottie-docs/shapes/#path
40048 */
40049 function parseShapePaths(shape, animations, context) {
40050 var attrs = {
40051 type: Shape.PATH,
40052 // Should have no fill and stroke by default
40053 style: {
40054 fill: 'none',
40055 stroke: 'none',
40056 },
40057 };
40058 // @see https://lottiefiles.github.io/lottie-docs/concepts/#bezier
40059 if (isBezier(shape.ks.k)) {
40060 attrs.shape = {
40061 in: shape.ks.k.i,
40062 out: shape.ks.k.o,
40063 v: shape.ks.k.v,
40064 close: shape.ks.k.c,
40065 };
40066 }
40067 else if (Array.isArray(shape.ks.k)) {
40068 var keyframeAnim = parseKeyframe(shape.ks.k, 0, context, function (outKeyframe, startVal) {
40069 outKeyframe.shape = {
40070 in: startVal[0].i,
40071 out: startVal[0].o,
40072 v: startVal[0].v,
40073 close: startVal[0].c,
40074 };
40075 });
40076 if (keyframeAnim.keyframes.length) {
40077 animations.push(keyframeAnim);
40078 }
40079 }
40080 return attrs;
40081 }
40082 /**
40083 * @see https://lottiefiles.github.io/lottie-docs/shapes/#rectangle
40084 */
40085 function parseShapeRect(shape, animations, context) {
40086 var attrs = {
40087 type: Shape.RECT,
40088 // Should have no fill and stroke by default
40089 style: {
40090 fill: 'none',
40091 stroke: 'none',
40092 },
40093 shape: {},
40094 };
40095 parseValue(shape.p, attrs, 'shape', ['x', 'y'], animations, context);
40096 parseValue(shape.s, attrs, 'shape', ['width', 'height'], animations, context);
40097 parseValue(shape.r, attrs, 'shape', ['r'], animations, context);
40098 return attrs;
40099 }
40100 /**
40101 * @see https://lottiefiles.github.io/lottie-docs/layers/#image-layer
40102 */
40103 function parseImageLayer(layer, context) {
40104 var attrs = {
40105 type: Shape.IMAGE,
40106 style: {},
40107 shape: {
40108 width: 0,
40109 height: 0,
40110 src: '',
40111 },
40112 };
40113 var asset = context.assetsMap.get(layer.refId);
40114 if (asset) {
40115 attrs.shape.width = asset.w;
40116 attrs.shape.height = asset.h;
40117 // TODO: url to fetch
40118 attrs.shape.src = asset.p;
40119 }
40120 return attrs;
40121 }
40122 /**
40123 * @see https://lottiefiles.github.io/lottie-docs/shapes/#ellipse
40124 */
40125 function parseShapeEllipse(shape, animations, context) {
40126 var attrs = {
40127 type: Shape.ELLIPSE,
40128 // Should have no fill and stroke by default
40129 style: {
40130 fill: 'none',
40131 stroke: 'none',
40132 },
40133 shape: {},
40134 };
40135 parseValue(shape.p, attrs, 'shape', ['cx', 'cy'], animations, context);
40136 parseValue(shape.s, attrs, 'shape', ['rx', 'ry'], animations, context, function (val) { return val / 2; });
40137 return attrs;
40138 }
40139 function parseShapeLayer(layer, context) {
40140 function tryCreateShape(shape, keyframeAnimations) {
40141 var ecEl;
40142 // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
40143 switch (shape.ty) {
40144 case ShapeType.Path:
40145 ecEl = parseShapePaths(shape, keyframeAnimations, context);
40146 break;
40147 case ShapeType.Ellipse:
40148 ecEl = parseShapeEllipse(shape, keyframeAnimations, context);
40149 break;
40150 case ShapeType.Rectangle:
40151 ecEl = parseShapeRect(shape, keyframeAnimations, context);
40152 break;
40153 case ShapeType.PolyStar:
40154 // TODO: parseShapePolyStar
40155 break;
40156 }
40157 return ecEl;
40158 }
40159 function parseModifiers(shapes, modifiers) {
40160 shapes.forEach(function (shape) {
40161 if (shape.hd) {
40162 return;
40163 }
40164 // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
40165 switch (shape.ty) {
40166 case ShapeType.Repeater:
40167 parseValue(shape.c, modifiers.attrs, 'shape', ['repeat'], modifiers.keyframeAnimations, context);
40168 parseTransforms(shape.tr, modifiers.attrs, modifiers.keyframeAnimations, context, 'shape', {
40169 x: 'repeatX',
40170 y: 'repeatY',
40171 rotation: 'repeatRot',
40172 scaleX: 'repeatScaleX',
40173 scaleY: 'repeatScaleY',
40174 anchorX: 'repeatAnchorX',
40175 anchorY: 'repeatAnchorY',
40176 skew: 'repeatSkew',
40177 skewAxis: 'repeatSkewAxis',
40178 });
40179 break;
40180 case ShapeType.Trim:
40181 parseValue(shape.s, modifiers.attrs, 'shape', ['trimStart'], modifiers.keyframeAnimations, context);
40182 parseValue(shape.e, modifiers.attrs, 'shape', ['trimEnd'], modifiers.keyframeAnimations, context);
40183 break;
40184 }
40185 });
40186 }
40187 function parseIterations(shapes, modifiers) {
40188 var ecEls = [];
40189 var attrs = {};
40190 var keyframeAnimations = [];
40191 // Order is reversed
40192 shapes = shapes.slice().reverse();
40193 // Modifiers first:
40194 parseModifiers(shapes, modifiers);
40195 shapes.forEach(function (shape) {
40196 if (shape.hd) {
40197 return;
40198 }
40199 var ecEl;
40200 switch (shape.ty) {
40201 case ShapeType.Group:
40202 ecEl = {
40203 type: Shape.GROUP,
40204 children: parseIterations(shape.it,
40205 // Modifiers will be applied to all childrens.
40206 modifiers),
40207 };
40208 break;
40209 // TODO Multiple fill and stroke
40210 case ShapeType.Fill:
40211 case ShapeType.GradientFill:
40212 parseFill(shape, attrs, keyframeAnimations, context);
40213 break;
40214 case ShapeType.Stroke:
40215 case ShapeType.GradientStroke:
40216 parseStroke(shape, attrs, keyframeAnimations, context);
40217 break;
40218 case ShapeType.Transform:
40219 parseTransforms(shape, attrs, keyframeAnimations, context);
40220 break;
40221 // TODO Multiple shapes.
40222 default:
40223 ecEl = tryCreateShape(shape, keyframeAnimations);
40224 }
40225 if (ecEl) {
40226 ecEl.name = shape.nm;
40227 ecEls.push(ecEl);
40228 }
40229 });
40230 ecEls.forEach(function (el, idx) {
40231 // Apply modifiers first
40232 el = __assign(__assign(__assign({}, el), definedProps(modifiers.attrs)), attrs);
40233 if (keyframeAnimations.length || modifiers.keyframeAnimations.length) {
40234 el.keyframeAnimation = __spreadArray(__spreadArray([], __read(modifiers.keyframeAnimations), false), __read(keyframeAnimations), false);
40235 }
40236 ecEls[idx] = el;
40237 });
40238 return ecEls;
40239 }
40240 return {
40241 type: Shape.GROUP,
40242 children: parseIterations(layer.shapes, {
40243 attrs: {},
40244 keyframeAnimations: [],
40245 }),
40246 };
40247 }
40248 function traverse(el, cb) {
40249 var _a;
40250 cb(el);
40251 if (el.type === Shape.GROUP) {
40252 (_a = el.children) === null || _a === void 0 ? void 0 : _a.forEach(function (child) {
40253 traverse(child, cb);
40254 });
40255 }
40256 }
40257 function addLayerOpacity(layer, layerGroup, context) {
40258 var _a, _b;
40259 var opacityAttrs = {};
40260 var opacityAnimations = [];
40261 if ((_a = layer.ks) === null || _a === void 0 ? void 0 : _a.o) {
40262 parseValue(layer.ks.o, opacityAttrs, 'style', ['opacity'], opacityAnimations, context, function (val) { return val / 100; });
40263 if (((_b = opacityAttrs.style) === null || _b === void 0 ? void 0 : _b.opacity) || opacityAnimations.length) {
40264 // apply opacity to group's children
40265 traverse(layerGroup, function (el) {
40266 if (el.type !== Shape.GROUP && el.style) {
40267 Object.assign(el.style, opacityAttrs.style);
40268 if (opacityAnimations.length) {
40269 el.keyframeAnimation = (el.keyframeAnimation || []).concat(opacityAnimations);
40270 }
40271 }
40272 });
40273 }
40274 }
40275 }
40276 function parseSolidShape(layer) {
40277 return {
40278 type: Shape.RECT,
40279 shape: {
40280 x: 0,
40281 y: 0,
40282 width: layer.sw,
40283 height: layer.sh,
40284 },
40285 style: {
40286 fill: layer.sc,
40287 },
40288 };
40289 }
40290 function parseLayers(layers, context, precompLayerTl) {
40291 var elements = [];
40292 // Order is reversed
40293 layers = layers.slice().reverse();
40294 var layerIndexMap = new Map();
40295 var offsetTime = (precompLayerTl === null || precompLayerTl === void 0 ? void 0 : precompLayerTl.st) || 0;
40296 layers === null || layers === void 0 ? void 0 : layers.forEach(function (layer) {
40297 // Layer time is offseted by the precomp layer.
40298 var _a, _b;
40299 // Use the ip, op, st of ref from.
40300 var layerIp = offsetTime + layer.ip;
40301 var layerOp = offsetTime + layer.op;
40302 var layerSt = offsetTime + layer.st;
40303 context.layerOffsetTime = offsetTime;
40304 var layerGroup;
40305 // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
40306 switch (layer.ty) {
40307 case LayerType.shape:
40308 // @see https://lottiefiles.github.io/lottie-docs/layers/#shape-layer
40309 layerGroup = parseShapeLayer(layer, context);
40310 break;
40311 case LayerType.null:
40312 // @see https://lottiefiles.github.io/lottie-docs/layers/#null-layer
40313 layerGroup = {
40314 type: Shape.GROUP,
40315 children: [],
40316 };
40317 break;
40318 case LayerType.solid:
40319 // @see https://lottiefiles.github.io/lottie-docs/layers/#solid-color-layer
40320 layerGroup = {
40321 type: Shape.GROUP,
40322 children: [],
40323 };
40324 // Anything you can do with solid layers, you can do better with a shape layer and a rectangle shape
40325 // since none of this layer's own properties can be animated.
40326 if (layer.sc) {
40327 layerGroup.children.push(parseSolidShape(layer));
40328 }
40329 break;
40330 case LayerType.precomp:
40331 // @see https://lottiefiles.github.io/lottie-docs/layers/#precomposition-layer
40332 layerGroup = {
40333 type: Shape.GROUP,
40334 children: parseLayers(((_a = context.assetsMap.get(layer.refId)) === null || _a === void 0 ? void 0 : _a.layers) || [], context, {
40335 st: layerSt,
40336 }),
40337 };
40338 break;
40339 case LayerType.text:
40340 // TODO: https://lottiefiles.github.io/lottie-docs/layers/#text-layer
40341 break;
40342 case LayerType.image:
40343 // TODO: https://lottiefiles.github.io/lottie-docs/layers/#image-layer
40344 layerGroup = layerGroup = {
40345 type: Shape.GROUP,
40346 children: [parseImageLayer(layer, context)],
40347 };
40348 break;
40349 }
40350 if (layerGroup) {
40351 var keyframeAnimations = [];
40352 var attrs = {
40353 name: layer.nm,
40354 };
40355 if (layer.ks) {
40356 parseTransforms(layer.ks, attrs, keyframeAnimations, context);
40357 }
40358 Object.assign(layerGroup, attrs);
40359 if (layer.ind != null) {
40360 layerIndexMap.set(layer.ind, layerGroup);
40361 }
40362 layerGroup.extra = {
40363 layerParent: layer.parent,
40364 };
40365 // Masks @see https://lottiefiles.github.io/lottie-docs/layers/#masks
40366 // @see https://lottie-animation-community.github.io/docs/specs/layers/common/#clipping-masks
40367 // TODO: not support alpha and other modes.
40368 // @see https://lottie-animation-community.github.io/docs/specs/properties/mask-mode-types/
40369 if (layer.hasMask && ((_b = layer.masksProperties) === null || _b === void 0 ? void 0 : _b.length)) {
40370 var maskKeyframeAnimations = [];
40371 // TODO: Only support one mask now.
40372 var attrs_1 = parseShapePaths({
40373 ks: layer.masksProperties[0].pt,
40374 }, maskKeyframeAnimations, context);
40375 layerGroup.clipPath = __assign({ type: Shape.PATH }, attrs_1);
40376 if (maskKeyframeAnimations.length) {
40377 layerGroup.clipPath.keyframeAnimation = maskKeyframeAnimations;
40378 }
40379 }
40380 addLayerOpacity(layer, layerGroup, context);
40381 // Update in and out animation.
40382 if (layerIp != null &&
40383 layerOp != null &&
40384 (layerIp > context.startFrame || layerOp < context.endFrame)) {
40385 var duration = context.endFrame - context.startFrame;
40386 var visibilityStartOffset = (layerIp - context.startFrame) / duration;
40387 var visibilityEndOffset = (layerOp - context.startFrame) / duration;
40388 layerGroup.visibilityStartOffset = visibilityStartOffset;
40389 layerGroup.visibilityEndOffset = visibilityEndOffset;
40390 layerGroup.visibilityFrame = duration;
40391 }
40392 if (keyframeAnimations.length) {
40393 layerGroup.keyframeAnimation = keyframeAnimations;
40394 }
40395 elements.push(layerGroup);
40396 }
40397 });
40398 // Build hierarchy
40399 return elements.filter(function (el) {
40400 var _a, _b;
40401 var parentLayer = layerIndexMap.get((_a = el.extra) === null || _a === void 0 ? void 0 : _a.layerParent);
40402 if (parentLayer) {
40403 (_b = parentLayer.children) === null || _b === void 0 ? void 0 : _b.push(el);
40404 return false;
40405 }
40406 return true;
40407 });
40408 }
40409 var DEFAULT_LOAD_ANIMATION_OPTIONS = {
40410 loop: true,
40411 autoplay: false,
40412 fill: 'both',
40413 };
40414 function parse(data, options) {
40415 var _a;
40416 completeData(data);
40417 var _b = __assign(__assign({}, DEFAULT_LOAD_ANIMATION_OPTIONS), options), loop = _b.loop, autoplay = _b.autoplay, fill = _b.fill;
40418 var context = new ParseContext();
40419 context.fps = data.fr || 30;
40420 context.frameTime = 1000 / context.fps;
40421 context.startFrame = data.ip;
40422 context.endFrame = data.op;
40423 context.version = data.v;
40424 context.autoplay = !!autoplay;
40425 context.fill = fill;
40426 context.iterations = isNumber(loop) ? loop : loop ? Infinity : 1;
40427 // @see https://lottiefiles.github.io/lottie-docs/assets/
40428 (_a = data.assets) === null || _a === void 0 ? void 0 : _a.forEach(function (asset) {
40429 context.assetsMap.set(asset.id, asset);
40430 });
40431 var elements = parseLayers(data.layers || [], context);
40432 return {
40433 width: data.w,
40434 height: data.h,
40435 elements: elements,
40436 context: context,
40437 };
40438 }
40439
40440 /**
40441 * @see https://github.com/airbnb/lottie-web/wiki/loadAnimation-options
40442 * @see https://github.com/airbnb/lottie-web#other-loading-options
40443 */
40444 function loadAnimation(data, options) {
40445 var _a = parse(data, options), width = _a.width, height = _a.height, elements = _a.elements, context = _a.context;
40446 return new LottieAnimation(width, height, elements, context);
40447 }
40448
40449 var Lottie = /** @class */function (_super) {
40450 __extends(Lottie, _super);
40451 function Lottie(props) {
40452 var _this = _super.call(this, props) || this;
40453 _this.addLottie = function () {
40454 var _a = _this,
40455 props = _a.props,
40456 context = _a.context;
40457 var data = props.data,
40458 options = props.options,
40459 play = props.play;
40460 var canvas = context.canvas;
40461 if (!data) return;
40462 // 文档流后挂载lottie
40463 canvas.ready.then(function () {
40464 _this.animation = _this.animation ? _this.animation : loadAnimation(data, options);
40465 _this.animation.render(_this.ref.current);
40466 _this.size = _this.animation.size();
40467 _this.updateSize();
40468 // 播放控制
40469 if (play) {
40470 var _a = play.speed,
40471 speed = _a === void 0 ? 1 : _a,
40472 _b = play.start,
40473 start = _b === void 0 ? 0 : _b,
40474 _c = play.end,
40475 end = _c === void 0 ? _this.animation.getDuration(true) : _c;
40476 _this.animation.setSpeed(speed);
40477 _this.animation.playSegments([start, end]);
40478 }
40479 });
40480 };
40481 _this.updateSize = function () {
40482 var _a = _this.size,
40483 currentWidth = _a.width,
40484 currentHeight = _a.height;
40485 var style = _this.props.style;
40486 if (!style) return;
40487 var _b = style.width,
40488 width = _b === void 0 ? currentWidth : _b,
40489 _c = style.height,
40490 height = _c === void 0 ? currentHeight : _c;
40491 _this.ref.current.scale(width / currentWidth, height / currentHeight);
40492 _this.size = {
40493 width: width,
40494 height: height
40495 };
40496 };
40497 _this.ref = createRef();
40498 return _this;
40499 }
40500 Lottie.prototype.didMount = function () {
40501 this.addLottie();
40502 };
40503 Lottie.prototype.willUpdate = function () {
40504 this.addLottie();
40505 };
40506 Lottie.prototype.render = function () {
40507 var _a = this.props,
40508 style = _a.style,
40509 animation = _a.animation;
40510 return jsx("group", {
40511 ref: this.ref,
40512 style: style,
40513 animation: animation
40514 });
40515 };
40516 return Lottie;
40517 }(Component);
40518
40519 var defaultProps$2 = {
40520 offsetX: 0,
40521 offsetY: 0,
40522 points: [],
40523 data: '',
40524 animation: null,
40525 options: {
40526 loop: true,
40527 autoplay: true
40528 }
40529 };
40530 var LottieGuideView = (function (props, context) {
40531 var cfg = deepMix({}, defaultProps$2, props);
40532 var points = cfg.points,
40533 style = cfg.style,
40534 offsetX = cfg.offsetX,
40535 offsetY = cfg.offsetY,
40536 lottieJson = cfg.lottieJson,
40537 animation = cfg.animation,
40538 options = cfg.options;
40539 var _a = points[0] || {},
40540 x = _a.x,
40541 y = _a.y;
40542 if (isNaN(x) || isNaN(y)) return null;
40543 var _b = style.height,
40544 height = _b === void 0 ? 0 : _b,
40545 _c = style.width,
40546 width = _c === void 0 ? 0 : _c;
40547 var offsetXNum = context.px2hd(offsetX);
40548 var offsetYNum = context.px2hd(offsetY);
40549 var posX = x + (offsetXNum || 0) - width / 2;
40550 var posY = y + (offsetYNum || 0) - height / 2;
40551 return jsx(Lottie, {
40552 data: lottieJson,
40553 options: options,
40554 style: {
40555 x: posX,
40556 y: posY,
40557 width: width,
40558 height: height
40559 },
40560 animation: deepMix({
40561 update: {
40562 easing: 'linear',
40563 duration: 450,
40564 property: ['x', 'y']
40565 }
40566 }, animation)
40567 });
40568 });
40569
40570 var PolylineGuideView = (function (props, context) {
40571 var _a = props.theme,
40572 theme = _a === void 0 ? {} : _a;
40573 var _b = deepMix(__assign({}, theme.polyline), props),
40574 points = _b.points,
40575 style = _b.style,
40576 offsetX = _b.offsetX,
40577 offsetY = _b.offsetY,
40578 animation = _b.animation;
40579 var checkNaN = points.some(function (d) {
40580 return isNaN(d.x) || isNaN(d.y);
40581 });
40582 if (checkNaN) return;
40583 var offsetXNum = context.px2hd(offsetX);
40584 var offsetYNum = context.px2hd(offsetY);
40585 return jsx("group", null, jsx("polyline", {
40586 style: __assign({
40587 points: points.map(function (point) {
40588 return [point.x + offsetXNum, point.y + offsetYNum];
40589 })
40590 }, style),
40591 animation: animation
40592 }));
40593 });
40594
40595 var DefaultGuideView = function DefaultGuideView() {
40596 return null;
40597 };
40598 var TextGuide = withGuide(TextGuideView);
40599 var PointGuide = withGuide(PointGuideView);
40600 var LineGuide = withGuide(LineGuideView);
40601 var ArcGuide = withGuide(ArcGuideView);
40602 var RectGuide = withGuide(RectGuideView);
40603 var ImageGuide = withGuide(ImageGuideView);
40604 var TagGuide = withGuide(Tag);
40605 var LottieGuide = withGuide(LottieGuideView);
40606 var PolylineGuide = withGuide(PolylineGuideView);
40607 var index$6 = withGuide(DefaultGuideView);
40608
40609 var withTooltip = (function (View) {
40610 return /** @class */function (_super) {
40611 __extends(Tooltip, _super);
40612 function Tooltip(props) {
40613 var _this = _super.call(this, props) || this;
40614 _this._triggerOn = function (ev) {
40615 var x = ev.x,
40616 y = ev.y;
40617 _this.show({
40618 x: x,
40619 y: y
40620 }, ev);
40621 };
40622 _this._triggerOff = function () {
40623 var _a = _this.props.alwaysShow,
40624 alwaysShow = _a === void 0 ? false : _a;
40625 if (!alwaysShow) {
40626 _this.hide();
40627 }
40628 };
40629 _this.state = {
40630 records: null
40631 };
40632 return _this;
40633 }
40634 Tooltip.prototype.updateCoord = function () {
40635 var _a = this,
40636 props = _a.props,
40637 context = _a.context;
40638 var _b = props.padding,
40639 padding = _b === void 0 ? '10px' : _b,
40640 chart = props.chart;
40641 chart.updateCoordFor(this, {
40642 position: 'top',
40643 width: 0,
40644 height: context.px2hd(padding)
40645 });
40646 };
40647 Tooltip.prototype.willMount = function () {
40648 this.updateCoord();
40649 };
40650 Tooltip.prototype.didMount = function () {
40651 this._initShow();
40652 this._initEvent();
40653 };
40654 Tooltip.prototype._initEvent = function () {
40655 var _a = this.props,
40656 chart = _a.chart,
40657 _b = _a.triggerOn,
40658 triggerOn = _b === void 0 ? 'press' : _b,
40659 _c = _a.triggerOff,
40660 triggerOff = _c === void 0 ? 'pressend' : _c;
40661 chart.on(triggerOn, this._triggerOn);
40662 chart.on(triggerOff, this._triggerOff);
40663 };
40664 Tooltip.prototype.willReceiveProps = function (nextProps) {
40665 var nextDefaultItem = nextProps.defaultItem,
40666 nextCoord = nextProps.coord;
40667 var _a = this.props,
40668 lastDefaultItem = _a.defaultItem,
40669 lastCoord = _a.coord;
40670 // 默认元素或坐标有变动,均需重新渲染
40671 if (!equal(nextDefaultItem, lastDefaultItem) || !equal(nextCoord, lastCoord)) {
40672 this._showByData(nextDefaultItem);
40673 }
40674 };
40675 Tooltip.prototype._initShow = function () {
40676 var props = this.props;
40677 var defaultItem = props.defaultItem;
40678 this._showByData(defaultItem);
40679 };
40680 Tooltip.prototype._showByData = function (dataItem) {
40681 var _this = this;
40682 if (!dataItem) return;
40683 var props = this.props;
40684 var chart = props.chart;
40685 // 因为 tooltip 有可能在 geometry 之前,所以需要等 geometry render 完后再执行
40686 setTimeout(function () {
40687 var snapRecords = chart.getRecords(dataItem, 'xfield');
40688 _this.showSnapRecords(snapRecords);
40689 }, 0);
40690 };
40691 Tooltip.prototype.show = function (point, _ev) {
40692 var props = this.props;
40693 var chart = props.chart;
40694 var snapRecords = chart.getSnapRecords(point, true); // 超出边界会自动调整
40695 if (!snapRecords || !snapRecords.length) return;
40696 this.showSnapRecords(snapRecords);
40697 };
40698 Tooltip.prototype.showSnapRecords = function (snapRecords) {
40699 var _a = this.props,
40700 chart = _a.chart,
40701 onChange = _a.onChange;
40702 var legendItems = chart.getLegendItems();
40703 var _b = snapRecords[0],
40704 xField = _b.xField,
40705 yField = _b.yField;
40706 var xScale = chart.getScale(xField);
40707 var yScale = chart.getScale(yField);
40708 var records = snapRecords.map(function (record) {
40709 var origin = record.origin,
40710 xField = record.xField,
40711 yField = record.yField;
40712 var value = isArray(origin[yField]) ? origin[yField].map(function (v) {
40713 return yScale.getText(v);
40714 }) : yScale.getText(origin[yField]);
40715 // 默认取 alias 的配置
40716 var name = yScale.alias;
40717 if (!name) {
40718 name = xScale.getText(origin[xField]);
40719 if (legendItems && legendItems.length) {
40720 var item = find(legendItems, function (item) {
40721 var field = item.field,
40722 tickValue = item.tickValue;
40723 return origin[field] === tickValue;
40724 });
40725 if (item && item.name) {
40726 name = item.name;
40727 }
40728 }
40729 }
40730 return __assign(__assign({}, record), {
40731 name: name,
40732 value: "".concat(value)
40733 });
40734 });
40735 if (!isArray(records) || !records.length) {
40736 return;
40737 }
40738 this.setState({
40739 records: records
40740 });
40741 if (isFunction(onChange)) {
40742 onChange(records);
40743 }
40744 };
40745 Tooltip.prototype.hide = function () {
40746 this.setState({
40747 records: null
40748 });
40749 };
40750 Tooltip.prototype.render = function () {
40751 var _a = this,
40752 props = _a.props,
40753 state = _a.state;
40754 var visible = props.visible;
40755 if (visible === false) {
40756 return null;
40757 }
40758 var records = state.records;
40759 return records && records.length && jsx(View, __assign({}, props, {
40760 records: records
40761 }));
40762 };
40763 return Tooltip;
40764 }(Component);
40765 });
40766
40767 // view 的默认配置
40768 var defaultStyle$1 = {
40769 showTitle: false,
40770 showCrosshairs: false,
40771 crosshairsType: 'y',
40772 crosshairsStyle: {
40773 stroke: 'rgba(0, 0, 0, 0.25)',
40774 lineWidth: '2px'
40775 },
40776 showTooltipMarker: false,
40777 markerBackgroundStyle: {
40778 fill: '#CCD6EC',
40779 opacity: 0.3,
40780 padding: '6px'
40781 },
40782 tooltipMarkerStyle: {
40783 fill: '#fff',
40784 lineWidth: '3px'
40785 },
40786 background: {
40787 radius: '4px',
40788 fill: 'rgba(0, 0, 0, 0.65)',
40789 padding: ['6px', '10px']
40790 },
40791 titleStyle: {
40792 fontSize: '24px',
40793 fill: '#fff',
40794 textAlign: 'start',
40795 textBaseline: 'top'
40796 },
40797 nameStyle: {
40798 fontSize: '24px',
40799 fill: 'rgba(255, 255, 255, 0.65)',
40800 textAlign: 'start',
40801 textBaseline: 'middle'
40802 },
40803 valueStyle: {
40804 fontSize: '24px',
40805 fill: '#fff',
40806 textAlign: 'start',
40807 textBaseline: 'middle'
40808 },
40809 joinString: ': ',
40810 showItemMarker: true,
40811 itemMarkerStyle: {
40812 width: '12px',
40813 radius: '6px',
40814 symbol: 'circle',
40815 lineWidth: '2px',
40816 stroke: '#fff'
40817 },
40818 layout: 'horizontal',
40819 snap: false,
40820 xTipTextStyle: {
40821 fontSize: '24px',
40822 fill: '#fff'
40823 },
40824 yTipTextStyle: {
40825 fontSize: '24px',
40826 fill: '#fff'
40827 },
40828 xTipBackground: {
40829 radius: '4px',
40830 fill: 'rgba(0, 0, 0, 0.65)',
40831 padding: ['6px', '10px'],
40832 marginLeft: '-50%',
40833 marginTop: '6px'
40834 },
40835 yTipBackground: {
40836 radius: '4px',
40837 fill: 'rgba(0, 0, 0, 0.65)',
40838 padding: ['6px', '10px'],
40839 marginLeft: '-100%',
40840 marginTop: '-50%'
40841 }
40842 };
40843 function directionEnabled(mode, dir) {
40844 if (mode === undefined) {
40845 return true;
40846 } else if (typeof mode === 'string') {
40847 return mode.indexOf(dir) !== -1;
40848 }
40849 return false;
40850 }
40851 var RenderItemMarker = function RenderItemMarker(props) {
40852 var records = props.records,
40853 coord = props.coord,
40854 context = props.context,
40855 markerBackgroundStyle = props.markerBackgroundStyle;
40856 var point = coord.convertPoint({
40857 x: 1,
40858 y: 1
40859 });
40860 var padding = context.px2hd(markerBackgroundStyle.padding || '6px');
40861 var xPoints = __spreadArray(__spreadArray([], records.map(function (record) {
40862 return record.xMin;
40863 }), true), records.map(function (record) {
40864 return record.xMax;
40865 }), true);
40866 var yPoints = __spreadArray(__spreadArray([], records.map(function (record) {
40867 return record.yMin;
40868 }), true), records.map(function (record) {
40869 return record.yMax;
40870 }), true);
40871 if (coord.transposed) {
40872 xPoints.push(point.x);
40873 } else {
40874 yPoints.push(point.y);
40875 }
40876 var xMin = Math.min.apply(null, xPoints);
40877 var xMax = Math.max.apply(null, xPoints);
40878 var yMin = Math.min.apply(null, yPoints);
40879 var yMax = Math.max.apply(null, yPoints);
40880 var x = coord.transposed ? xMin : xMin - padding;
40881 var y = coord.transposed ? yMin - padding : yMin;
40882 var width = coord.transposed ? xMax - xMin : xMax - xMin + 2 * padding;
40883 var height = coord.transposed ? yMax - yMin + 2 * padding : yMax - yMin;
40884 return jsx("rect", {
40885 style: __assign({
40886 x: x,
40887 y: y,
40888 width: width,
40889 height: height
40890 }, markerBackgroundStyle)
40891 });
40892 };
40893 var RenderCrosshairs = function RenderCrosshairs(props) {
40894 var records = props.records,
40895 coord = props.coord,
40896 chart = props.chart,
40897 crosshairsType = props.crosshairsType,
40898 crosshairsStyle = props.crosshairsStyle,
40899 xPositionType = props.xPositionType,
40900 yPositionType = props.yPositionType;
40901 var coordLeft = coord.left,
40902 coordTop = coord.top,
40903 coordRight = coord.right,
40904 coordBottom = coord.bottom,
40905 center = coord.center;
40906 var firstRecord = records[0];
40907 var x = firstRecord.x,
40908 y = firstRecord.y,
40909 origin = firstRecord.origin,
40910 xField = firstRecord.xField,
40911 coordData = firstRecord.coord;
40912 if (coord.isPolar) {
40913 // 极坐标下的辅助线
40914 var xScale = chart.getScale(xField);
40915 var ticks = xScale.getTicks();
40916 var tick = find(ticks, function (tick) {
40917 return origin[xField] === tick.tickValue;
40918 });
40919 var end = coord.convertPoint({
40920 x: tick.value,
40921 y: 1
40922 });
40923 return jsx("line", {
40924 style: __assign({
40925 x1: center.x,
40926 y1: center.y,
40927 x2: end.x,
40928 y2: end.y
40929 }, crosshairsStyle)
40930 });
40931 }
40932 return jsx("group", null, directionEnabled(crosshairsType, 'x') ? jsx("line", {
40933 style: __assign({
40934 x1: coordLeft,
40935 y1: yPositionType === 'coord' ? coordData.y : y,
40936 x2: coordRight,
40937 y2: yPositionType === 'coord' ? coordData.y : y
40938 }, crosshairsStyle)
40939 }) : null, directionEnabled(crosshairsType, 'y') ? jsx("line", {
40940 style: __assign({
40941 x1: xPositionType === 'coord' ? coordData.x : x,
40942 y1: coordTop,
40943 x2: xPositionType === 'coord' ? coordData.x : x,
40944 y2: coordBottom
40945 }, crosshairsStyle)
40946 }) : null);
40947 };
40948 var RenderXTip = function RenderXTip(props) {
40949 var records = props.records,
40950 coord = props.coord,
40951 xTip = props.xTip,
40952 xPositionType = props.xPositionType,
40953 xTipTextStyle = props.xTipTextStyle,
40954 xTipBackground = props.xTipBackground;
40955 var coordBottom = coord.bottom;
40956 var firstRecord = records[0];
40957 var x = firstRecord.x,
40958 coordData = firstRecord.coord;
40959 var xFirstText = firstRecord.name;
40960 return jsx("rect", {
40961 style: __assign({
40962 display: 'flex',
40963 left: xPositionType === 'coord' ? coordData.x : x,
40964 top: coordBottom
40965 }, xTipBackground)
40966 }, jsx("text", {
40967 style: __assign(__assign({}, xTipTextStyle), {
40968 text: xPositionType === 'coord' ? coordData.xText : isFunction(xTip) ? xTip(xFirstText, firstRecord) : xFirstText
40969 })
40970 }));
40971 };
40972 var RenderYTip = function RenderYTip(props) {
40973 var records = props.records,
40974 coord = props.coord,
40975 yTip = props.yTip,
40976 yPositionType = props.yPositionType,
40977 yTipTextStyle = props.yTipTextStyle,
40978 yTipBackground = props.yTipBackground;
40979 var coordLeft = coord.left;
40980 var firstRecord = records[0];
40981 var y = firstRecord.y,
40982 coordData = firstRecord.coord;
40983 var yFirstText = firstRecord.value;
40984 return jsx("rect", {
40985 style: __assign({
40986 display: 'flex',
40987 left: coordLeft,
40988 top: yPositionType === 'coord' ? coordData.y : y
40989 }, yTipBackground)
40990 }, jsx("text", {
40991 style: __assign(__assign({}, yTipTextStyle), {
40992 text: yPositionType === 'coord' ? coordData.yText : isFunction(yTip) ? yTip(yFirstText, firstRecord) : yFirstText
40993 })
40994 }));
40995 };
40996 // tooltip 内容框
40997 var RenderLabel = /** @class */function (_super) {
40998 __extends(RenderLabel, _super);
40999 function RenderLabel() {
41000 var _this = _super !== null && _super.apply(this, arguments) || this;
41001 _this.style = {};
41002 return _this;
41003 }
41004 RenderLabel.prototype.getMaxItemBox = function (node) {
41005 var maxItemWidth = 0;
41006 var maxItemHeight = 0;
41007 (node.children || []).forEach(function (child) {
41008 var layout = child.layout;
41009 var width = layout.width,
41010 height = layout.height;
41011 maxItemWidth = Math.max(maxItemWidth, width);
41012 maxItemHeight = Math.max(maxItemHeight, height);
41013 });
41014 return {
41015 width: maxItemWidth,
41016 height: maxItemHeight
41017 };
41018 };
41019 RenderLabel.prototype._getContainerLayout = function () {
41020 var _a = this.props,
41021 records = _a.records,
41022 coord = _a.coord;
41023 if (!records || !records.length) return;
41024 var width = coord.width;
41025 var node = computeLayout$1(this, this.render());
41026 var itemMaxWidth = this.getMaxItemBox(node === null || node === void 0 ? void 0 : node.children[0]).width;
41027 // 每行最多的个数
41028 var lineMaxCount = Math.max(1, Math.floor(width / itemMaxWidth));
41029 var itemCount = records.length;
41030 // 是否需要换行
41031 if (itemCount > lineMaxCount) {
41032 this.style = {
41033 width: width
41034 };
41035 }
41036 };
41037 RenderLabel.prototype.willMount = function () {
41038 this._getContainerLayout();
41039 };
41040 RenderLabel.prototype.render = function () {
41041 var _this = this;
41042 var _a = this.props,
41043 records = _a.records,
41044 background = _a.background,
41045 showItemMarker = _a.showItemMarker,
41046 itemMarkerStyle = _a.itemMarkerStyle,
41047 customText = _a.customText,
41048 nameStyle = _a.nameStyle,
41049 valueStyle = _a.valueStyle,
41050 joinString = _a.joinString,
41051 arrowWidth = _a.arrowWidth,
41052 x = _a.x,
41053 coord = _a.coord,
41054 itemWidth = _a.itemWidth;
41055 // 显示内容
41056 var labelView = function labelView(left, top) {
41057 return jsx("group", {
41058 style: {
41059 display: 'flex'
41060 }
41061 }, jsx("group", {
41062 style: __assign(__assign({
41063 display: 'flex',
41064 flexDirection: 'row',
41065 flexWrap: 'wrap',
41066 padding: [0, 0, 0, '6px'],
41067 left: left,
41068 top: top
41069 }, _this.style), background)
41070 }, records.map(function (record) {
41071 var name = record.name,
41072 value = record.value;
41073 return jsx("group", {
41074 style: {
41075 display: 'flex',
41076 flexDirection: 'row',
41077 alignItems: 'center',
41078 padding: [0, '6px', 0, 0],
41079 width: itemWidth
41080 }
41081 }, showItemMarker ? jsx("marker", {
41082 style: __assign(__assign({
41083 width: itemMarkerStyle.width,
41084 marginRight: '6px'
41085 }, itemMarkerStyle), {
41086 fill: record.color
41087 })
41088 }) : null, customText && isFunction(customText) ? customText(record) : jsx("group", {
41089 style: {
41090 display: 'flex',
41091 flexDirection: 'row'
41092 }
41093 }, jsx("text", {
41094 style: __assign(__assign({}, nameStyle), {
41095 text: value ? "".concat(name).concat(joinString) : name
41096 })
41097 }), jsx("text", {
41098 style: __assign(__assign({}, valueStyle), {
41099 text: value
41100 })
41101 })));
41102 })), jsx("group", null, jsx("polygon", {
41103 style: {
41104 points: [[x - arrowWidth, top], [x + arrowWidth, top], [x, top + arrowWidth]],
41105 fill: background.fill
41106 }
41107 })));
41108 };
41109 // 计算显示位置
41110 var layout = computeLayout$1(this, labelView(0, 0)).layout; // 获取内容区大小
41111 var coordLeft = coord.left,
41112 coordTop = coord.top,
41113 coordRight = coord.right;
41114 var width = layout.width,
41115 height = layout.height;
41116 var halfWidth = width / 2;
41117 // 让 tooltip 限制在 coord 的显示范围内
41118 var advanceLeft = x - halfWidth;
41119 var advanceTop = coordTop - height;
41120 var left = advanceLeft < coordLeft ? coordLeft : advanceLeft > coordRight - width ? coordRight - width : advanceLeft;
41121 var top = advanceTop < 0 ? 0 : advanceTop;
41122 return labelView(left, top);
41123 };
41124 return RenderLabel;
41125 }(Component);
41126 var TooltipView = /** @class */function (_super) {
41127 __extends(TooltipView, _super);
41128 function TooltipView() {
41129 return _super !== null && _super.apply(this, arguments) || this;
41130 }
41131 TooltipView.prototype.render = function () {
41132 var _a = this,
41133 props = _a.props,
41134 context = _a.context;
41135 var records = props.records,
41136 coord = props.coord;
41137 var firstRecord = records[0];
41138 var x = firstRecord.x,
41139 coordData = firstRecord.coord;
41140 var chart = props.chart,
41141 customBackground = props.background,
41142 _b = props.showTooltipMarker,
41143 showTooltipMarker = _b === void 0 ? defaultStyle$1.showTooltipMarker : _b,
41144 _c = props.markerBackgroundStyle,
41145 markerBackgroundStyle = _c === void 0 ? defaultStyle$1.markerBackgroundStyle : _c,
41146 _d = props.showItemMarker,
41147 showItemMarker = _d === void 0 ? defaultStyle$1.showItemMarker : _d,
41148 customItemMarkerStyle = props.itemMarkerStyle,
41149 nameStyle = props.nameStyle,
41150 valueStyle = props.valueStyle,
41151 _e = props.joinString,
41152 joinString = _e === void 0 ? defaultStyle$1.joinString : _e,
41153 _f = props.showCrosshairs,
41154 showCrosshairs = _f === void 0 ? defaultStyle$1.showCrosshairs : _f,
41155 crosshairsStyle = props.crosshairsStyle,
41156 _g = props.crosshairsType,
41157 crosshairsType = _g === void 0 ? defaultStyle$1.crosshairsType : _g,
41158 _h = props.snap,
41159 snap = _h === void 0 ? defaultStyle$1.snap : _h,
41160 _j = props.tooltipMarkerStyle,
41161 tooltipMarkerStyle = _j === void 0 ? defaultStyle$1.tooltipMarkerStyle : _j,
41162 showXTip = props.showXTip,
41163 xPositionType = props.xPositionType,
41164 showYTip = props.showYTip,
41165 yPositionType = props.yPositionType,
41166 xTip = props.xTip,
41167 yTip = props.yTip,
41168 _k = props.xTipTextStyle,
41169 xTipTextStyle = _k === void 0 ? defaultStyle$1.xTipTextStyle : _k,
41170 _l = props.yTipTextStyle,
41171 yTipTextStyle = _l === void 0 ? defaultStyle$1.yTipTextStyle : _l,
41172 _m = props.xTipBackground,
41173 xTipBackground = _m === void 0 ? defaultStyle$1.xTipBackground : _m,
41174 _o = props.yTipBackground,
41175 yTipBackground = _o === void 0 ? defaultStyle$1.yTipBackground : _o,
41176 _p = props.custom,
41177 custom = _p === void 0 ? false : _p,
41178 customText = props.customText,
41179 itemWidth = props.itemWidth;
41180 var itemMarkerStyle = __assign(__assign({}, customItemMarkerStyle), defaultStyle$1.itemMarkerStyle);
41181 var background = __assign(__assign({}, defaultStyle$1.background), customBackground);
41182 var arrowWidth = context.px2hd('6px');
41183 return jsx("group", null, showTooltipMarker ? jsx(RenderItemMarker, {
41184 coord: coord,
41185 context: context,
41186 records: records,
41187 markerBackgroundStyle: markerBackgroundStyle
41188 }) : null, showCrosshairs ? jsx(RenderCrosshairs, {
41189 chart: chart,
41190 coord: coord,
41191 records: records,
41192 xPositionType: xPositionType,
41193 yPositionType: yPositionType,
41194 crosshairsType: crosshairsType,
41195 crosshairsStyle: __assign(__assign({}, defaultStyle$1.crosshairsStyle), crosshairsStyle)
41196 }) : null, snap ? records.map(function (item) {
41197 var x = item.x,
41198 y = item.y,
41199 color = item.color,
41200 shape = item.shape;
41201 return jsx("circle", {
41202 style: __assign(__assign({
41203 cx: xPositionType === 'coord' ? coordData.x : x,
41204 cy: yPositionType === 'coord' ? coordData.y : y,
41205 r: '6px',
41206 stroke: color,
41207 fill: color
41208 }, shape), tooltipMarkerStyle)
41209 });
41210 }) : null, showXTip && jsx(RenderXTip, {
41211 records: records,
41212 coord: coord,
41213 xTip: xTip,
41214 xPositionType: xPositionType,
41215 xTipTextStyle: __assign(__assign({}, defaultStyle$1.xTipTextStyle), xTipTextStyle),
41216 xTipBackground: __assign(__assign({}, defaultStyle$1.xTipBackground), xTipBackground)
41217 }), showYTip && jsx(RenderYTip, {
41218 records: records,
41219 coord: coord,
41220 yTip: yTip,
41221 yPositionType: yPositionType,
41222 yTipTextStyle: __assign(__assign({}, defaultStyle$1.yTipTextStyle), yTipTextStyle),
41223 yTipBackground: __assign(__assign({}, defaultStyle$1.yTipBackground), yTipBackground)
41224 }), !custom && jsx(RenderLabel, {
41225 records: records,
41226 coord: coord,
41227 itemMarkerStyle: itemMarkerStyle,
41228 customText: customText,
41229 showItemMarker: showItemMarker,
41230 x: x,
41231 arrowWidth: arrowWidth,
41232 background: background,
41233 nameStyle: __assign(__assign({}, defaultStyle$1.nameStyle), nameStyle),
41234 valueStyle: __assign(__assign({}, defaultStyle$1.valueStyle), valueStyle),
41235 joinString: joinString,
41236 itemWidth: itemWidth
41237 }));
41238 };
41239 return TooltipView;
41240 }(Component);
41241
41242 var index$7 = withTooltip(TooltipView);
41243
41244 var toPrimitive_1 = createCommonjsModule(function (module) {
41245 var _typeof = _typeof_1["default"];
41246 function toPrimitive(t, r) {
41247 if ("object" != _typeof(t) || !t) return t;
41248 var e = t[Symbol.toPrimitive];
41249 if (void 0 !== e) {
41250 var i = e.call(t, r || "default");
41251 if ("object" != _typeof(i)) return i;
41252 throw new TypeError("@@toPrimitive must return a primitive value.");
41253 }
41254 return ("string" === r ? String : Number)(t);
41255 }
41256 module.exports = toPrimitive, module.exports.__esModule = true, module.exports["default"] = module.exports;
41257 });
41258
41259 var toPropertyKey_1 = createCommonjsModule(function (module) {
41260 var _typeof = _typeof_1["default"];
41261
41262 function toPropertyKey(t) {
41263 var i = toPrimitive_1(t, "string");
41264 return "symbol" == _typeof(i) ? i : i + "";
41265 }
41266 module.exports = toPropertyKey, module.exports.__esModule = true, module.exports["default"] = module.exports;
41267 });
41268
41269 var defineProperty = createCommonjsModule(function (module) {
41270 function _defineProperty(e, r, t) {
41271 return (r = toPropertyKey_1(r)) in e ? Object.defineProperty(e, r, {
41272 value: t,
41273 enumerable: !0,
41274 configurable: !0,
41275 writable: !0
41276 }) : e[r] = t, e;
41277 }
41278 module.exports = _defineProperty, module.exports.__esModule = true, module.exports["default"] = module.exports;
41279 });
41280
41281 var _defineProperty = /*@__PURE__*/getDefaultExportFromCjs(defineProperty);
41282
41283 function count(node) {
41284 var sum = 0,
41285 children = node.children,
41286 i = children && children.length;
41287 if (!i) sum = 1;else while (--i >= 0) sum += children[i].value;
41288 node.value = sum;
41289 }
41290 function node_count () {
41291 return this.eachAfter(count);
41292 }
41293
41294 var arrayLikeToArray = createCommonjsModule(function (module) {
41295 function _arrayLikeToArray(r, a) {
41296 (null == a || a > r.length) && (a = r.length);
41297 for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
41298 return n;
41299 }
41300 module.exports = _arrayLikeToArray, module.exports.__esModule = true, module.exports["default"] = module.exports;
41301 });
41302
41303 var unsupportedIterableToArray = createCommonjsModule(function (module) {
41304 function _unsupportedIterableToArray(r, a) {
41305 if (r) {
41306 if ("string" == typeof r) return arrayLikeToArray(r, a);
41307 var t = {}.toString.call(r).slice(8, -1);
41308 return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? arrayLikeToArray(r, a) : void 0;
41309 }
41310 }
41311 module.exports = _unsupportedIterableToArray, module.exports.__esModule = true, module.exports["default"] = module.exports;
41312 });
41313
41314 var createForOfIteratorHelper = createCommonjsModule(function (module) {
41315 function _createForOfIteratorHelper(r, e) {
41316 var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
41317 if (!t) {
41318 if (Array.isArray(r) || (t = unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) {
41319 t && (r = t);
41320 var _n = 0,
41321 F = function F() {};
41322 return {
41323 s: F,
41324 n: function n() {
41325 return _n >= r.length ? {
41326 done: !0
41327 } : {
41328 done: !1,
41329 value: r[_n++]
41330 };
41331 },
41332 e: function e(r) {
41333 throw r;
41334 },
41335 f: F
41336 };
41337 }
41338 throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
41339 }
41340 var o,
41341 a = !0,
41342 u = !1;
41343 return {
41344 s: function s() {
41345 t = t.call(r);
41346 },
41347 n: function n() {
41348 var r = t.next();
41349 return a = r.done, r;
41350 },
41351 e: function e(r) {
41352 u = !0, o = r;
41353 },
41354 f: function f() {
41355 try {
41356 a || null == t["return"] || t["return"]();
41357 } finally {
41358 if (u) throw o;
41359 }
41360 }
41361 };
41362 }
41363 module.exports = _createForOfIteratorHelper, module.exports.__esModule = true, module.exports["default"] = module.exports;
41364 });
41365
41366 var _createForOfIteratorHelper = /*@__PURE__*/getDefaultExportFromCjs(createForOfIteratorHelper);
41367
41368 function node_each (callback, that) {
41369 var index = -1;
41370 var _iterator = _createForOfIteratorHelper(this),
41371 _step;
41372 try {
41373 for (_iterator.s(); !(_step = _iterator.n()).done;) {
41374 var node = _step.value;
41375 callback.call(that, node, ++index, this);
41376 }
41377 } catch (err) {
41378 _iterator.e(err);
41379 } finally {
41380 _iterator.f();
41381 }
41382 return this;
41383 }
41384
41385 function node_eachBefore (callback, that) {
41386 var node = this,
41387 nodes = [node],
41388 children,
41389 i,
41390 index = -1;
41391 while (node = nodes.pop()) {
41392 callback.call(that, node, ++index, this);
41393 if (children = node.children) {
41394 for (i = children.length - 1; i >= 0; --i) {
41395 nodes.push(children[i]);
41396 }
41397 }
41398 }
41399 return this;
41400 }
41401
41402 function node_eachAfter (callback, that) {
41403 var node = this,
41404 nodes = [node],
41405 next = [],
41406 children,
41407 i,
41408 n,
41409 index = -1;
41410 while (node = nodes.pop()) {
41411 next.push(node);
41412 if (children = node.children) {
41413 for (i = 0, n = children.length; i < n; ++i) {
41414 nodes.push(children[i]);
41415 }
41416 }
41417 }
41418 while (node = next.pop()) {
41419 callback.call(that, node, ++index, this);
41420 }
41421 return this;
41422 }
41423
41424 function node_find (callback, that) {
41425 var index = -1;
41426 var _iterator = _createForOfIteratorHelper(this),
41427 _step;
41428 try {
41429 for (_iterator.s(); !(_step = _iterator.n()).done;) {
41430 var node = _step.value;
41431 if (callback.call(that, node, ++index, this)) {
41432 return node;
41433 }
41434 }
41435 } catch (err) {
41436 _iterator.e(err);
41437 } finally {
41438 _iterator.f();
41439 }
41440 }
41441
41442 function node_sum (value) {
41443 return this.eachAfter(function (node) {
41444 var sum = +value(node.data) || 0,
41445 children = node.children,
41446 i = children && children.length;
41447 while (--i >= 0) sum += children[i].value;
41448 node.value = sum;
41449 });
41450 }
41451
41452 function node_sort (compare) {
41453 return this.eachBefore(function (node) {
41454 if (node.children) {
41455 node.children.sort(compare);
41456 }
41457 });
41458 }
41459
41460 function node_path (end) {
41461 var start = this,
41462 ancestor = leastCommonAncestor(start, end),
41463 nodes = [start];
41464 while (start !== ancestor) {
41465 start = start.parent;
41466 nodes.push(start);
41467 }
41468 var k = nodes.length;
41469 while (end !== ancestor) {
41470 nodes.splice(k, 0, end);
41471 end = end.parent;
41472 }
41473 return nodes;
41474 }
41475 function leastCommonAncestor(a, b) {
41476 if (a === b) return a;
41477 var aNodes = a.ancestors(),
41478 bNodes = b.ancestors(),
41479 c = null;
41480 a = aNodes.pop();
41481 b = bNodes.pop();
41482 while (a === b) {
41483 c = a;
41484 a = aNodes.pop();
41485 b = bNodes.pop();
41486 }
41487 return c;
41488 }
41489
41490 function node_ancestors () {
41491 var node = this,
41492 nodes = [node];
41493 while (node = node.parent) {
41494 nodes.push(node);
41495 }
41496 return nodes;
41497 }
41498
41499 function node_descendants () {
41500 return Array.from(this);
41501 }
41502
41503 function node_leaves () {
41504 var leaves = [];
41505 this.eachBefore(function (node) {
41506 if (!node.children) {
41507 leaves.push(node);
41508 }
41509 });
41510 return leaves;
41511 }
41512
41513 function node_links () {
41514 var root = this,
41515 links = [];
41516 root.each(function (node) {
41517 if (node !== root) {
41518 // Don’t include the root’s parent, if any.
41519 links.push({
41520 source: node.parent,
41521 target: node
41522 });
41523 }
41524 });
41525 return links;
41526 }
41527
41528 var regeneratorRuntime$1 = createCommonjsModule(function (module) {
41529 var _typeof = _typeof_1["default"];
41530 function _regeneratorRuntime() {
41531 module.exports = _regeneratorRuntime = function _regeneratorRuntime() {
41532 return e;
41533 }, module.exports.__esModule = true, module.exports["default"] = module.exports;
41534 var t,
41535 e = {},
41536 r = Object.prototype,
41537 n = r.hasOwnProperty,
41538 o = Object.defineProperty || function (t, e, r) {
41539 t[e] = r.value;
41540 },
41541 i = "function" == typeof Symbol ? Symbol : {},
41542 a = i.iterator || "@@iterator",
41543 c = i.asyncIterator || "@@asyncIterator",
41544 u = i.toStringTag || "@@toStringTag";
41545 function define(t, e, r) {
41546 return Object.defineProperty(t, e, {
41547 value: r,
41548 enumerable: !0,
41549 configurable: !0,
41550 writable: !0
41551 }), t[e];
41552 }
41553 try {
41554 define({}, "");
41555 } catch (t) {
41556 define = function define(t, e, r) {
41557 return t[e] = r;
41558 };
41559 }
41560 function wrap(t, e, r, n) {
41561 var i = e && e.prototype instanceof Generator ? e : Generator,
41562 a = Object.create(i.prototype),
41563 c = new Context(n || []);
41564 return o(a, "_invoke", {
41565 value: makeInvokeMethod(t, r, c)
41566 }), a;
41567 }
41568 function tryCatch(t, e, r) {
41569 try {
41570 return {
41571 type: "normal",
41572 arg: t.call(e, r)
41573 };
41574 } catch (t) {
41575 return {
41576 type: "throw",
41577 arg: t
41578 };
41579 }
41580 }
41581 e.wrap = wrap;
41582 var h = "suspendedStart",
41583 l = "suspendedYield",
41584 f = "executing",
41585 s = "completed",
41586 y = {};
41587 function Generator() {}
41588 function GeneratorFunction() {}
41589 function GeneratorFunctionPrototype() {}
41590 var p = {};
41591 define(p, a, function () {
41592 return this;
41593 });
41594 var d = Object.getPrototypeOf,
41595 v = d && d(d(values([])));
41596 v && v !== r && n.call(v, a) && (p = v);
41597 var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p);
41598 function defineIteratorMethods(t) {
41599 ["next", "throw", "return"].forEach(function (e) {
41600 define(t, e, function (t) {
41601 return this._invoke(e, t);
41602 });
41603 });
41604 }
41605 function AsyncIterator(t, e) {
41606 function invoke(r, o, i, a) {
41607 var c = tryCatch(t[r], t, o);
41608 if ("throw" !== c.type) {
41609 var u = c.arg,
41610 h = u.value;
41611 return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) {
41612 invoke("next", t, i, a);
41613 }, function (t) {
41614 invoke("throw", t, i, a);
41615 }) : e.resolve(h).then(function (t) {
41616 u.value = t, i(u);
41617 }, function (t) {
41618 return invoke("throw", t, i, a);
41619 });
41620 }
41621 a(c.arg);
41622 }
41623 var r;
41624 o(this, "_invoke", {
41625 value: function value(t, n) {
41626 function callInvokeWithMethodAndArg() {
41627 return new e(function (e, r) {
41628 invoke(t, n, e, r);
41629 });
41630 }
41631 return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg();
41632 }
41633 });
41634 }
41635 function makeInvokeMethod(e, r, n) {
41636 var o = h;
41637 return function (i, a) {
41638 if (o === f) throw Error("Generator is already running");
41639 if (o === s) {
41640 if ("throw" === i) throw a;
41641 return {
41642 value: t,
41643 done: !0
41644 };
41645 }
41646 for (n.method = i, n.arg = a;;) {
41647 var c = n.delegate;
41648 if (c) {
41649 var u = maybeInvokeDelegate(c, n);
41650 if (u) {
41651 if (u === y) continue;
41652 return u;
41653 }
41654 }
41655 if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) {
41656 if (o === h) throw o = s, n.arg;
41657 n.dispatchException(n.arg);
41658 } else "return" === n.method && n.abrupt("return", n.arg);
41659 o = f;
41660 var p = tryCatch(e, r, n);
41661 if ("normal" === p.type) {
41662 if (o = n.done ? s : l, p.arg === y) continue;
41663 return {
41664 value: p.arg,
41665 done: n.done
41666 };
41667 }
41668 "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg);
41669 }
41670 };
41671 }
41672 function maybeInvokeDelegate(e, r) {
41673 var n = r.method,
41674 o = e.iterator[n];
41675 if (o === t) return r.delegate = null, "throw" === n && e.iterator["return"] && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y;
41676 var i = tryCatch(o, e.iterator, r.arg);
41677 if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y;
41678 var a = i.arg;
41679 return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y);
41680 }
41681 function pushTryEntry(t) {
41682 var e = {
41683 tryLoc: t[0]
41684 };
41685 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e);
41686 }
41687 function resetTryEntry(t) {
41688 var e = t.completion || {};
41689 e.type = "normal", delete e.arg, t.completion = e;
41690 }
41691 function Context(t) {
41692 this.tryEntries = [{
41693 tryLoc: "root"
41694 }], t.forEach(pushTryEntry, this), this.reset(!0);
41695 }
41696 function values(e) {
41697 if (e || "" === e) {
41698 var r = e[a];
41699 if (r) return r.call(e);
41700 if ("function" == typeof e.next) return e;
41701 if (!isNaN(e.length)) {
41702 var o = -1,
41703 i = function next() {
41704 for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next;
41705 return next.value = t, next.done = !0, next;
41706 };
41707 return i.next = i;
41708 }
41709 }
41710 throw new TypeError(_typeof(e) + " is not iterable");
41711 }
41712 return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", {
41713 value: GeneratorFunctionPrototype,
41714 configurable: !0
41715 }), o(GeneratorFunctionPrototype, "constructor", {
41716 value: GeneratorFunction,
41717 configurable: !0
41718 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) {
41719 var e = "function" == typeof t && t.constructor;
41720 return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name));
41721 }, e.mark = function (t) {
41722 return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t;
41723 }, e.awrap = function (t) {
41724 return {
41725 __await: t
41726 };
41727 }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () {
41728 return this;
41729 }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) {
41730 void 0 === i && (i = Promise);
41731 var a = new AsyncIterator(wrap(t, r, n, o), i);
41732 return e.isGeneratorFunction(r) ? a : a.next().then(function (t) {
41733 return t.done ? t.value : a.next();
41734 });
41735 }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () {
41736 return this;
41737 }), define(g, "toString", function () {
41738 return "[object Generator]";
41739 }), e.keys = function (t) {
41740 var e = Object(t),
41741 r = [];
41742 for (var n in e) r.push(n);
41743 return r.reverse(), function next() {
41744 for (; r.length;) {
41745 var t = r.pop();
41746 if (t in e) return next.value = t, next.done = !1, next;
41747 }
41748 return next.done = !0, next;
41749 };
41750 }, e.values = values, Context.prototype = {
41751 constructor: Context,
41752 reset: function reset(e) {
41753 if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t);
41754 },
41755 stop: function stop() {
41756 this.done = !0;
41757 var t = this.tryEntries[0].completion;
41758 if ("throw" === t.type) throw t.arg;
41759 return this.rval;
41760 },
41761 dispatchException: function dispatchException(e) {
41762 if (this.done) throw e;
41763 var r = this;
41764 function handle(n, o) {
41765 return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o;
41766 }
41767 for (var o = this.tryEntries.length - 1; o >= 0; --o) {
41768 var i = this.tryEntries[o],
41769 a = i.completion;
41770 if ("root" === i.tryLoc) return handle("end");
41771 if (i.tryLoc <= this.prev) {
41772 var c = n.call(i, "catchLoc"),
41773 u = n.call(i, "finallyLoc");
41774 if (c && u) {
41775 if (this.prev < i.catchLoc) return handle(i.catchLoc, !0);
41776 if (this.prev < i.finallyLoc) return handle(i.finallyLoc);
41777 } else if (c) {
41778 if (this.prev < i.catchLoc) return handle(i.catchLoc, !0);
41779 } else {
41780 if (!u) throw Error("try statement without catch or finally");
41781 if (this.prev < i.finallyLoc) return handle(i.finallyLoc);
41782 }
41783 }
41784 }
41785 },
41786 abrupt: function abrupt(t, e) {
41787 for (var r = this.tryEntries.length - 1; r >= 0; --r) {
41788 var o = this.tryEntries[r];
41789 if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) {
41790 var i = o;
41791 break;
41792 }
41793 }
41794 i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null);
41795 var a = i ? i.completion : {};
41796 return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a);
41797 },
41798 complete: function complete(t, e) {
41799 if ("throw" === t.type) throw t.arg;
41800 return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y;
41801 },
41802 finish: function finish(t) {
41803 for (var e = this.tryEntries.length - 1; e >= 0; --e) {
41804 var r = this.tryEntries[e];
41805 if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y;
41806 }
41807 },
41808 "catch": function _catch(t) {
41809 for (var e = this.tryEntries.length - 1; e >= 0; --e) {
41810 var r = this.tryEntries[e];
41811 if (r.tryLoc === t) {
41812 var n = r.completion;
41813 if ("throw" === n.type) {
41814 var o = n.arg;
41815 resetTryEntry(r);
41816 }
41817 return o;
41818 }
41819 }
41820 throw Error("illegal catch attempt");
41821 },
41822 delegateYield: function delegateYield(e, r, n) {
41823 return this.delegate = {
41824 iterator: values(e),
41825 resultName: r,
41826 nextLoc: n
41827 }, "next" === this.method && (this.arg = t), y;
41828 }
41829 }, e;
41830 }
41831 module.exports = _regeneratorRuntime, module.exports.__esModule = true, module.exports["default"] = module.exports;
41832 });
41833
41834 // TODO(Babel 8): Remove this file.
41835
41836 var runtime$1 = regeneratorRuntime$1();
41837 var regenerator = runtime$1;
41838
41839 // Copied from https://github.com/facebook/regenerator/blob/main/packages/runtime/runtime.js#L736=
41840 try {
41841 regeneratorRuntime = runtime$1;
41842 } catch (accidentalStrictMode) {
41843 if (typeof globalThis === "object") {
41844 globalThis.regeneratorRuntime = runtime$1;
41845 } else {
41846 Function("r", "regeneratorRuntime = r")(runtime$1);
41847 }
41848 }
41849
41850 var _marked = /*#__PURE__*/regenerator.mark(_callee);
41851 function _callee() {
41852 var node, current, next, children, i, n;
41853 return regenerator.wrap(function _callee$(_context) {
41854 while (1) switch (_context.prev = _context.next) {
41855 case 0:
41856 node = this, next = [node];
41857 case 1:
41858 current = next.reverse(), next = [];
41859 case 2:
41860 if (!(node = current.pop())) {
41861 _context.next = 8;
41862 break;
41863 }
41864 _context.next = 5;
41865 return node;
41866 case 5:
41867 if (children = node.children) {
41868 for (i = 0, n = children.length; i < n; ++i) {
41869 next.push(children[i]);
41870 }
41871 }
41872 _context.next = 2;
41873 break;
41874 case 8:
41875 if (next.length) {
41876 _context.next = 1;
41877 break;
41878 }
41879 case 9:
41880 case "end":
41881 return _context.stop();
41882 }
41883 }, _marked, this);
41884 }
41885
41886 function hierarchy(data, children) {
41887 if (data instanceof Map) {
41888 data = [undefined, data];
41889 if (children === undefined) children = mapChildren;
41890 } else if (children === undefined) {
41891 children = objectChildren;
41892 }
41893 var root = new Node$1(data),
41894 node,
41895 nodes = [root],
41896 child,
41897 childs,
41898 i,
41899 n;
41900 while (node = nodes.pop()) {
41901 if ((childs = children(node.data)) && (n = (childs = Array.from(childs)).length)) {
41902 node.children = childs;
41903 for (i = n - 1; i >= 0; --i) {
41904 nodes.push(child = childs[i] = new Node$1(childs[i]));
41905 child.parent = node;
41906 child.depth = node.depth + 1;
41907 }
41908 }
41909 }
41910 return root.eachBefore(computeHeight);
41911 }
41912 function node_copy() {
41913 return hierarchy(this).eachBefore(copyData);
41914 }
41915 function objectChildren(d) {
41916 return d.children;
41917 }
41918 function mapChildren(d) {
41919 return Array.isArray(d) ? d[1] : null;
41920 }
41921 function copyData(node) {
41922 if (node.data.value !== undefined) node.value = node.data.value;
41923 node.data = node.data.data;
41924 }
41925 function computeHeight(node) {
41926 var height = 0;
41927 do node.height = height; while ((node = node.parent) && node.height < ++height);
41928 }
41929 function Node$1(data) {
41930 this.data = data;
41931 this.depth = this.height = 0;
41932 this.parent = null;
41933 }
41934 Node$1.prototype = hierarchy.prototype = _defineProperty({
41935 constructor: Node$1,
41936 count: node_count,
41937 each: node_each,
41938 eachAfter: node_eachAfter,
41939 eachBefore: node_eachBefore,
41940 find: node_find,
41941 sum: node_sum,
41942 sort: node_sort,
41943 path: node_path,
41944 ancestors: node_ancestors,
41945 descendants: node_descendants,
41946 leaves: node_leaves,
41947 links: node_links,
41948 copy: node_copy
41949 }, Symbol.iterator, _callee);
41950
41951 function required(f) {
41952 if (typeof f !== "function") throw new Error();
41953 return f;
41954 }
41955
41956 function constantZero() {
41957 return 0;
41958 }
41959 function constant$1 (x) {
41960 return function () {
41961 return x;
41962 };
41963 }
41964
41965 function roundNode (node) {
41966 node.x0 = Math.round(node.x0);
41967 node.y0 = Math.round(node.y0);
41968 node.x1 = Math.round(node.x1);
41969 node.y1 = Math.round(node.y1);
41970 }
41971
41972 function treemapDice (parent, x0, y0, x1, y1) {
41973 var nodes = parent.children,
41974 node,
41975 i = -1,
41976 n = nodes.length,
41977 k = parent.value && (x1 - x0) / parent.value;
41978 while (++i < n) {
41979 node = nodes[i], node.y0 = y0, node.y1 = y1;
41980 node.x0 = x0, node.x1 = x0 += node.value * k;
41981 }
41982 }
41983
41984 function partition () {
41985 var dx = 1,
41986 dy = 1,
41987 padding = 0,
41988 round = false;
41989 function partition(root) {
41990 var n = root.height + 1;
41991 root.x0 = root.y0 = padding;
41992 root.x1 = dx;
41993 root.y1 = dy / n;
41994 root.eachBefore(positionNode(dy, n));
41995 if (round) root.eachBefore(roundNode);
41996 return root;
41997 }
41998 function positionNode(dy, n) {
41999 return function (node) {
42000 if (node.children) {
42001 treemapDice(node, node.x0, dy * (node.depth + 1) / n, node.x1, dy * (node.depth + 2) / n);
42002 }
42003 var x0 = node.x0,
42004 y0 = node.y0,
42005 x1 = node.x1 - padding,
42006 y1 = node.y1 - padding;
42007 if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
42008 if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
42009 node.x0 = x0;
42010 node.y0 = y0;
42011 node.x1 = x1;
42012 node.y1 = y1;
42013 };
42014 }
42015 partition.round = function (x) {
42016 return arguments.length ? (round = !!x, partition) : round;
42017 };
42018 partition.size = function (x) {
42019 return arguments.length ? (dx = +x[0], dy = +x[1], partition) : [dx, dy];
42020 };
42021 partition.padding = function (x) {
42022 return arguments.length ? (padding = +x, partition) : padding;
42023 };
42024 return partition;
42025 }
42026
42027 function treemapSlice (parent, x0, y0, x1, y1) {
42028 var nodes = parent.children,
42029 node,
42030 i = -1,
42031 n = nodes.length,
42032 k = parent.value && (y1 - y0) / parent.value;
42033 while (++i < n) {
42034 node = nodes[i], node.x0 = x0, node.x1 = x1;
42035 node.y0 = y0, node.y1 = y0 += node.value * k;
42036 }
42037 }
42038
42039 var phi = (1 + Math.sqrt(5)) / 2;
42040 function squarifyRatio(ratio, parent, x0, y0, x1, y1) {
42041 var rows = [],
42042 nodes = parent.children,
42043 row,
42044 nodeValue,
42045 i0 = 0,
42046 i1 = 0,
42047 n = nodes.length,
42048 dx,
42049 dy,
42050 value = parent.value,
42051 sumValue,
42052 minValue,
42053 maxValue,
42054 newRatio,
42055 minRatio,
42056 alpha,
42057 beta;
42058 while (i0 < n) {
42059 dx = x1 - x0, dy = y1 - y0;
42060
42061 // Find the next non-empty node.
42062 do sumValue = nodes[i1++].value; while (!sumValue && i1 < n);
42063 minValue = maxValue = sumValue;
42064 alpha = Math.max(dy / dx, dx / dy) / (value * ratio);
42065 beta = sumValue * sumValue * alpha;
42066 minRatio = Math.max(maxValue / beta, beta / minValue);
42067
42068 // Keep adding nodes while the aspect ratio maintains or improves.
42069 for (; i1 < n; ++i1) {
42070 sumValue += nodeValue = nodes[i1].value;
42071 if (nodeValue < minValue) minValue = nodeValue;
42072 if (nodeValue > maxValue) maxValue = nodeValue;
42073 beta = sumValue * sumValue * alpha;
42074 newRatio = Math.max(maxValue / beta, beta / minValue);
42075 if (newRatio > minRatio) {
42076 sumValue -= nodeValue;
42077 break;
42078 }
42079 minRatio = newRatio;
42080 }
42081
42082 // Position and record the row orientation.
42083 rows.push(row = {
42084 value: sumValue,
42085 dice: dx < dy,
42086 children: nodes.slice(i0, i1)
42087 });
42088 if (row.dice) treemapDice(row, x0, y0, x1, value ? y0 += dy * sumValue / value : y1);else treemapSlice(row, x0, y0, value ? x0 += dx * sumValue / value : x1, y1);
42089 value -= sumValue, i0 = i1;
42090 }
42091 return rows;
42092 }
42093 var squarify = (function custom(ratio) {
42094 function squarify(parent, x0, y0, x1, y1) {
42095 squarifyRatio(ratio, parent, x0, y0, x1, y1);
42096 }
42097 squarify.ratio = function (x) {
42098 return custom((x = +x) > 1 ? x : 1);
42099 };
42100 return squarify;
42101 })(phi);
42102
42103 function treemap () {
42104 var tile = squarify,
42105 round = false,
42106 dx = 1,
42107 dy = 1,
42108 paddingStack = [0],
42109 paddingInner = constantZero,
42110 paddingTop = constantZero,
42111 paddingRight = constantZero,
42112 paddingBottom = constantZero,
42113 paddingLeft = constantZero;
42114 function treemap(root) {
42115 root.x0 = root.y0 = 0;
42116 root.x1 = dx;
42117 root.y1 = dy;
42118 root.eachBefore(positionNode);
42119 paddingStack = [0];
42120 if (round) root.eachBefore(roundNode);
42121 return root;
42122 }
42123 function positionNode(node) {
42124 var p = paddingStack[node.depth],
42125 x0 = node.x0 + p,
42126 y0 = node.y0 + p,
42127 x1 = node.x1 - p,
42128 y1 = node.y1 - p;
42129 if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
42130 if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
42131 node.x0 = x0;
42132 node.y0 = y0;
42133 node.x1 = x1;
42134 node.y1 = y1;
42135 if (node.children) {
42136 p = paddingStack[node.depth + 1] = paddingInner(node) / 2;
42137 x0 += paddingLeft(node) - p;
42138 y0 += paddingTop(node) - p;
42139 x1 -= paddingRight(node) - p;
42140 y1 -= paddingBottom(node) - p;
42141 if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
42142 if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
42143 tile(node, x0, y0, x1, y1);
42144 }
42145 }
42146 treemap.round = function (x) {
42147 return arguments.length ? (round = !!x, treemap) : round;
42148 };
42149 treemap.size = function (x) {
42150 return arguments.length ? (dx = +x[0], dy = +x[1], treemap) : [dx, dy];
42151 };
42152 treemap.tile = function (x) {
42153 return arguments.length ? (tile = required(x), treemap) : tile;
42154 };
42155 treemap.padding = function (x) {
42156 return arguments.length ? treemap.paddingInner(x).paddingOuter(x) : treemap.paddingInner();
42157 };
42158 treemap.paddingInner = function (x) {
42159 return arguments.length ? (paddingInner = typeof x === "function" ? x : constant$1(+x), treemap) : paddingInner;
42160 };
42161 treemap.paddingOuter = function (x) {
42162 return arguments.length ? treemap.paddingTop(x).paddingRight(x).paddingBottom(x).paddingLeft(x) : treemap.paddingTop();
42163 };
42164 treemap.paddingTop = function (x) {
42165 return arguments.length ? (paddingTop = typeof x === "function" ? x : constant$1(+x), treemap) : paddingTop;
42166 };
42167 treemap.paddingRight = function (x) {
42168 return arguments.length ? (paddingRight = typeof x === "function" ? x : constant$1(+x), treemap) : paddingRight;
42169 };
42170 treemap.paddingBottom = function (x) {
42171 return arguments.length ? (paddingBottom = typeof x === "function" ? x : constant$1(+x), treemap) : paddingBottom;
42172 };
42173 treemap.paddingLeft = function (x) {
42174 return arguments.length ? (paddingLeft = typeof x === "function" ? x : constant$1(+x), treemap) : paddingLeft;
42175 };
42176 return treemap;
42177 }
42178
42179 function treemapBinary (parent, x0, y0, x1, y1) {
42180 var nodes = parent.children,
42181 i,
42182 n = nodes.length,
42183 sum,
42184 sums = new Array(n + 1);
42185 for (sums[0] = sum = i = 0; i < n; ++i) {
42186 sums[i + 1] = sum += nodes[i].value;
42187 }
42188 partition(0, n, parent.value, x0, y0, x1, y1);
42189 function partition(i, j, value, x0, y0, x1, y1) {
42190 if (i >= j - 1) {
42191 var node = nodes[i];
42192 node.x0 = x0, node.y0 = y0;
42193 node.x1 = x1, node.y1 = y1;
42194 return;
42195 }
42196 var valueOffset = sums[i],
42197 valueTarget = value / 2 + valueOffset,
42198 k = i + 1,
42199 hi = j - 1;
42200 while (k < hi) {
42201 var mid = k + hi >>> 1;
42202 if (sums[mid] < valueTarget) k = mid + 1;else hi = mid;
42203 }
42204 if (valueTarget - sums[k - 1] < sums[k] - valueTarget && i + 1 < k) --k;
42205 var valueLeft = sums[k] - valueOffset,
42206 valueRight = value - valueLeft;
42207 if (x1 - x0 > y1 - y0) {
42208 var xk = value ? (x0 * valueRight + x1 * valueLeft) / value : x1;
42209 partition(i, k, valueLeft, x0, y0, xk, y1);
42210 partition(k, j, valueRight, xk, y0, x1, y1);
42211 } else {
42212 var yk = value ? (y0 * valueRight + y1 * valueLeft) / value : y1;
42213 partition(i, k, valueLeft, x0, y0, x1, yk);
42214 partition(k, j, valueRight, x0, yk, x1, y1);
42215 }
42216 }
42217 }
42218
42219 var withTreemap = function withTreemap(View) {
42220 return /** @class */function (_super) {
42221 __extends(Treemap, _super);
42222 function Treemap(props, context) {
42223 var _this = _super.call(this, props, context) || this;
42224 var color = props.color,
42225 data = props.data,
42226 theme = props.theme,
42227 _a = props.selection,
42228 selection = _a === void 0 ? {} : _a;
42229 var px2hd = context.px2hd;
42230 context.theme = deepMix(px2hd(Theme), theme);
42231 _this.coord = new coordController();
42232 _this.color = new Category$1(__assign(__assign({
42233 range: context.theme.colors
42234 }, color), {
42235 data: data
42236 }));
42237 var _b = selection.defaultSelected,
42238 defaultSelected = _b === void 0 ? null : _b;
42239 _this.state.selected = defaultSelected;
42240 _this.coordRef = createRef();
42241 _this.records = [];
42242 return _this;
42243 }
42244 Treemap.prototype.isSelected = function (record) {
42245 var state = this.state;
42246 var selected = state.selected;
42247 if (!selected || !selected.length) {
42248 return false;
42249 }
42250 for (var i = 0, len = selected.length; i < len; i++) {
42251 var item = selected[i];
42252 if (equal(record, item)) {
42253 return true;
42254 }
42255 }
42256 return false;
42257 };
42258 Treemap.prototype.getSelectionStyle = function (record) {
42259 var _a = this,
42260 state = _a.state,
42261 props = _a.props;
42262 var selected = state.selected;
42263 if (!selected || !selected.length) {
42264 return null;
42265 }
42266 var selection = props.selection;
42267 var selectedStyle = selection.selectedStyle,
42268 unSelectedStyle = selection.unSelectedStyle;
42269 var isSelected = this.isSelected(record);
42270 if (isSelected) {
42271 return isFunction(selectedStyle) ? selectedStyle(record) : selectedStyle;
42272 }
42273 return isFunction(unSelectedStyle) ? unSelectedStyle(record) : unSelectedStyle;
42274 };
42275 Treemap.prototype.willMount = function () {
42276 var _a = this,
42277 props = _a.props,
42278 coord = _a.coord,
42279 layout = _a.layout;
42280 var coordOption = props.coord;
42281 coord.updateLayout(layout);
42282 coord.create(coordOption);
42283 };
42284 Treemap.prototype.willReceiveProps = function (nextProps) {
42285 var nextSelection = nextProps.selection;
42286 var lastSelection = this.props.selection;
42287 if (!nextSelection || !lastSelection) {
42288 return;
42289 }
42290 var nextDefaultSelected = nextSelection.defaultSelected;
42291 var lastDefaultSelected = lastSelection.defaultSelected;
42292 if (!equal(nextDefaultSelected, lastDefaultSelected)) {
42293 this.state.selected = nextDefaultSelected;
42294 }
42295 };
42296 Treemap.prototype.treemapLayout = function () {
42297 var _this = this;
42298 var _a = this,
42299 props = _a.props,
42300 coord = _a.coord,
42301 colorAttr = _a.color;
42302 var _b = coord.getCoord(),
42303 width = _b.width,
42304 height = _b.height;
42305 var data = props.data,
42306 value = props.value,
42307 _c = props.space,
42308 space = _c === void 0 ? 0 : _c;
42309 var root = hierarchy({
42310 children: data
42311 }).sum(function (d) {
42312 return d[value];
42313 }).sort(function (a, b) {
42314 return b[value] - a[value];
42315 });
42316 var treemapLayout = treemap()
42317 // 默认treemapSquarify
42318 .tile(treemapBinary).round(false).size([width, height])
42319 // .padding(1);
42320 .paddingInner(space);
42321 // .paddingOuter(options.paddingOuter)
42322 // .paddingTop(options.paddingTop)
42323 // .paddingRight(options.paddingRight)
42324 // .paddingBottom(options.paddingBottom)
42325 // .paddingLeft(options.paddingLeft);
42326 var nodes = treemapLayout(root);
42327 return nodes.children.map(function (item) {
42328 var data = item.data,
42329 x0 = item.x0,
42330 y0 = item.y0,
42331 x1 = item.x1,
42332 y1 = item.y1;
42333 var color = colorAttr.mapping(data[colorAttr.field]);
42334 var rect = {
42335 xMin: x0,
42336 xMax: x1,
42337 yMin: y0,
42338 yMax: y1
42339 };
42340 var style = _this.getSelectionStyle(data);
42341 return __assign(__assign({
42342 key: data.key,
42343 origin: data,
42344 color: color
42345 }, rect), {
42346 style: style
42347 });
42348 });
42349 };
42350 Treemap.prototype.select = function (ev, trigger) {
42351 var _this = this;
42352 var points = ev.points,
42353 x = ev.canvasX,
42354 y = ev.canvasY;
42355 var _a = this.props.selection,
42356 selection = _a === void 0 ? {} : _a;
42357 var triggerOn = selection.triggerOn,
42358 _b = selection.type,
42359 type = _b === void 0 ? 'single' : _b,
42360 _c = selection.cancelable,
42361 cancelable = _c === void 0 ? true : _c;
42362 if (!triggerOn || trigger !== triggerOn) return;
42363 var point = triggerOn === 'click' ? {
42364 x: x,
42365 y: y
42366 } : points[0];
42367 var selected = this.state.selected;
42368 var origin = [];
42369 each(this.records, function (record) {
42370 if (point.x >= record.xMin && point.x <= record.xMax && point.y >= record.yMin && point.y <= record.yMax) {
42371 origin.push(record === null || record === void 0 ? void 0 : record.origin);
42372 }
42373 });
42374 // 没选中元素
42375 if (!origin) {
42376 this.setState({
42377 selected: null
42378 });
42379 return;
42380 }
42381 if (!selected) {
42382 this.setState({
42383 selected: origin
42384 });
42385 return;
42386 }
42387 // 单选
42388 var newSelected = [];
42389 origin.forEach(function (record) {
42390 if (!_this.isSelected(record)) {
42391 newSelected.push(record);
42392 }
42393 });
42394 if (type === 'single') {
42395 this.setState({
42396 selected: cancelable ? newSelected : origin
42397 });
42398 return;
42399 }
42400 this.setState({
42401 selected: __spreadArray(__spreadArray([], newSelected, true), selected, true)
42402 });
42403 };
42404 Treemap.prototype.render = function () {
42405 var _this = this;
42406 var nodes = this.treemapLayout();
42407 this.records = nodes;
42408 var _a = this,
42409 props = _a.props,
42410 coord = _a.coord;
42411 var _b = coord.getCoord(),
42412 width = _b.width,
42413 height = _b.height;
42414 return jsx("group", {
42415 style: {
42416 width: width,
42417 height: height,
42418 fill: 'transparent'
42419 },
42420 onClick: function onClick(ev) {
42421 return _this.select(ev, 'click');
42422 },
42423 onPress: function onPress(ev) {
42424 return _this.select(ev, 'press');
42425 }
42426 }, jsx(View, __assign({
42427 nodes: nodes
42428 }, props, {
42429 coord: coord.getCoord()
42430 })));
42431 };
42432 return Treemap;
42433 }(Component);
42434 };
42435
42436 var TreemapView = (function (props // Coord 在 withTreemap 被转成 Coord 类型了,所以这里需要重新定义
42437 ) {
42438 var nodes = props.nodes,
42439 coord = props.coord,
42440 onClick = props.onClick,
42441 _a = props.label,
42442 label = _a === void 0 ? false : _a;
42443 if (coord.isPolar) {
42444 var center = coord.center;
42445 var x_1 = center.x,
42446 y_1 = center.y;
42447 return jsx("group", null, nodes.map(function (node) {
42448 var xMin = node.xMin,
42449 xMax = node.xMax,
42450 yMin = node.yMin,
42451 yMax = node.yMax,
42452 color = node.color,
42453 style = node.style;
42454 return jsx("sector", {
42455 style: __assign({
42456 cx: x_1,
42457 cy: y_1,
42458 lineWidth: '1px',
42459 stroke: '#fff',
42460 startAngle: xMin,
42461 endAngle: xMax,
42462 r0: yMin,
42463 r: yMax,
42464 fill: color
42465 }, style),
42466 onClick: onClick ? function () {
42467 return onClick(node);
42468 } : null
42469 });
42470 }));
42471 }
42472 return jsx("group", null, nodes.map(function (node) {
42473 var key = node.key,
42474 xMin = node.xMin,
42475 xMax = node.xMax,
42476 yMin = node.yMin,
42477 yMax = node.yMax,
42478 color = node.color,
42479 style = node.style;
42480 return jsx("group", null, jsx("rect", {
42481 key: key,
42482 style: __assign({
42483 x: xMin,
42484 y: yMin,
42485 width: xMax - xMin,
42486 height: yMax - yMin,
42487 fill: color,
42488 lineWidth: '4px',
42489 stroke: '#fff',
42490 radius: '8px'
42491 }, style),
42492 animation: {
42493 appear: {
42494 easing: 'linear',
42495 duration: 450,
42496 property: ['fillOpacity', 'strokeOpacity'],
42497 start: {
42498 fillOpacity: 0,
42499 strokeOpacity: 0
42500 }
42501 },
42502 update: {
42503 easing: 'linear',
42504 duration: 450,
42505 property: ['x', 'y', 'width', 'height', 'radius', 'lineWidth', 'fillOpacity', 'strokeOpacity']
42506 }
42507 },
42508 onClick: onClick ? function () {
42509 return onClick(node);
42510 } : null
42511 }), label && jsx("text", {
42512 style: __assign({
42513 x: (xMin + xMax) / 2,
42514 y: (yMin + yMax) / 2,
42515 text: node.origin.name,
42516 fill: 'white',
42517 textAlign: 'center',
42518 textBaseline: 'middle'
42519 }, label)
42520 }));
42521 }));
42522 });
42523
42524 var index$8 = withTreemap(TreemapView);
42525
42526 function rootParent(data) {
42527 var d = data;
42528 while (d.depth > 1) {
42529 d = d.parent;
42530 }
42531 return d;
42532 }
42533 var withSunburst = (function (View) {
42534 return /** @class */function (_super) {
42535 __extends(Sunburst, _super);
42536 function Sunburst(props, context) {
42537 var _this = _super.call(this, props, context) || this;
42538 var color = props.color,
42539 data = props.data;
42540 _this.coord = new coordController();
42541 _this.color = new Category$1(__assign(__assign({
42542 range: Theme.colors
42543 }, color), {
42544 data: data
42545 }));
42546 return _this;
42547 }
42548 Sunburst.prototype.willMount = function () {
42549 var _a = this,
42550 props = _a.props,
42551 coord = _a.coord,
42552 layout = _a.layout;
42553 var coordOption = props.coord;
42554 coord.updateLayout(layout);
42555 coord.create(coordOption);
42556 };
42557 Sunburst.prototype.didMount = function () {};
42558 Sunburst.prototype._mapping = function (children) {
42559 var _a = this,
42560 colorAttr = _a.color,
42561 coord = _a.coord;
42562 for (var i = 0, len = children.length; i < len; i++) {
42563 var node = children[i];
42564 var root = rootParent(node);
42565 var color = colorAttr.mapping(root.data[colorAttr.field]);
42566 node.color = color;
42567 var x0 = node.x0,
42568 x1 = node.x1,
42569 y0 = node.y0,
42570 y1 = node.y1;
42571 var rect = coord.getCoord().convertRect({
42572 x: [x0, x1],
42573 y: [y0, y1]
42574 });
42575 mix(node, rect);
42576 // 递归处理
42577 if (node.children && node.children.length) {
42578 this._mapping(node.children);
42579 }
42580 }
42581 };
42582 Sunburst.prototype.sunburst = function () {
42583 var props = this.props;
42584 var data = props.data,
42585 value = props.value,
42586 _a = props.sort,
42587 sort = _a === void 0 ? true : _a;
42588 var root = hierarchy({
42589 children: data
42590 }).sum(function (d) {
42591 return d[value];
42592 });
42593 // 内置按value大小顺序排序,支持传入sort函数
42594 if (sort === true || isFunction(sort)) {
42595 var sortFn = isFunction(sort) ? sort : function (a, b) {
42596 return b[value] - a[value];
42597 };
42598 root.sort(sortFn);
42599 }
42600 var nodes = partition()(root);
42601 var children = nodes.children;
42602 this._mapping(children);
42603 return nodes;
42604 };
42605 Sunburst.prototype.render = function () {
42606 var node = this.sunburst();
42607 var _a = this,
42608 coord = _a.coord,
42609 props = _a.props;
42610 return jsx(View, __assign({}, props, {
42611 coord: coord.getCoord(),
42612 node: node,
42613 triggerRef: this.triggerRef
42614 }));
42615 };
42616 return Sunburst;
42617 }(Component);
42618 });
42619
42620 var SunburstView = (function (props) {
42621 var coord = props.coord,
42622 node = props.node,
42623 onClick = props.onClick;
42624 var children = node.children;
42625 var _a = coord.center,
42626 x = _a.x,
42627 y = _a.y;
42628 var _renderNodes = function renderNodes(nodes) {
42629 return jsx("group", null, nodes.map(function (node) {
42630 var xMin = node.xMin,
42631 xMax = node.xMax,
42632 yMin = node.yMin,
42633 yMax = node.yMax,
42634 color = node.color,
42635 children = node.children;
42636 return jsx("group", {
42637 onClick: onClick
42638 }, jsx("sector", {
42639 attrs: {
42640 cx: x,
42641 cy: y,
42642 lineWidth: '1px',
42643 stroke: '#fff',
42644 startAngle: "".concat(xMin, " rad"),
42645 endAngle: "".concat(xMax, " rad"),
42646 r0: yMin,
42647 r: yMax,
42648 fill: color
42649 }
42650 }), children && children.length ? _renderNodes(children) : null);
42651 }));
42652 };
42653 return _renderNodes(children);
42654 });
42655
42656 var IcicleView = (function (props) {
42657 var node = props.node,
42658 onClick = props.onClick;
42659 var children = node.children;
42660 var _renderNodes = function renderNodes(nodes) {
42661 return jsx("group", null, nodes.map(function (node) {
42662 var xMin = node.xMin,
42663 xMax = node.xMax,
42664 yMin = node.yMin,
42665 yMax = node.yMax,
42666 color = node.color,
42667 children = node.children;
42668 return jsx("group", {
42669 onClick: onClick
42670 }, jsx("rect", {
42671 attrs: {
42672 x: xMin,
42673 y: yMin,
42674 width: xMax - xMin,
42675 height: yMax - yMin,
42676 lineWidth: '1px',
42677 stroke: '#fff',
42678 fill: color
42679 }
42680 }), children && children.length ? _renderNodes(children) : null);
42681 }));
42682 };
42683 return _renderNodes(children);
42684 });
42685
42686 var View = (function (props) {
42687 var coord = props.coord;
42688 if (coord.type === 'polar') {
42689 return jsx(SunburstView, __assign({}, props));
42690 }
42691 return jsx(IcicleView, __assign({}, props));
42692 });
42693
42694 var index$9 = withSunburst(View);
42695
42696 var DEFAULT_CONFIG = {
42697 anchorOffset: '10px',
42698 inflectionOffset: '30px',
42699 sidePadding: '15px',
42700 height: '64px',
42701 adjustOffset: '30',
42702 triggerOn: 'click',
42703 // activeShape: false, // 当有图形被选中的时候,是否激活图形
42704 // activeStyle: {
42705 // offset: '1px',
42706 // appendRadius: '8px',
42707 // fillOpacity: 0.5,
42708 // },
42709 label1OffsetY: '-4px',
42710 label2OffsetY: '4px'
42711 };
42712 function getEndPoint(center, angle, r) {
42713 return {
42714 x: center.x + r * Math.cos(angle),
42715 y: center.y + r * Math.sin(angle)
42716 };
42717 }
42718 // 计算中间角度
42719 function getMiddleAngle(startAngle, endAngle) {
42720 if (endAngle < startAngle) {
42721 endAngle += Math.PI * 2;
42722 }
42723 return (endAngle + startAngle) / 2;
42724 }
42725 function move(from, to, count, center) {
42726 var x = center.x;
42727 var sort = from.sort(function (a, b) {
42728 var aDistance = Math.abs(a.x - x);
42729 var bDistance = Math.abs(b.x - x);
42730 return bDistance - aDistance;
42731 });
42732 return [sort.slice(0, sort.length - count), sort.slice(sort.length - count).concat(to)];
42733 }
42734 // 第一象限
42735 function isFirstQuadrant(angle) {
42736 return angle >= -Math.PI / 2 && angle < 0;
42737 }
42738 // 第二象限
42739 function isSecondQuadrant(angle) {
42740 return angle >= 0 && angle < Math.PI / 2;
42741 }
42742 function isThirdQuadrant(angle) {
42743 return angle >= Math.PI / 2 && angle < Math.PI;
42744 }
42745 function isFourthQuadrant(angle) {
42746 return angle >= Math.PI && angle < Math.PI * 3 / 2;
42747 }
42748 var withPieLabel = (function (View) {
42749 return /** @class */function (_super) {
42750 __extends(PieLabel, _super);
42751 function PieLabel(props) {
42752 return _super.call(this, props) || this;
42753 }
42754 PieLabel.prototype.willMount = function () {};
42755 /**
42756 * 绑定事件
42757 */
42758 PieLabel.prototype.didMount = function () {};
42759 PieLabel.prototype.getLabels = function (props) {
42760 var chart = props.chart,
42761 coord = props.coord,
42762 anchorOffset = props.anchorOffset,
42763 inflectionOffset = props.inflectionOffset,
42764 label1 = props.label1,
42765 label2 = props.label2,
42766 itemHeight = props.height,
42767 sidePadding = props.sidePadding;
42768 var center = coord.center,
42769 radius = coord.radius,
42770 coordWidth = coord.width,
42771 coordHeight = coord.height,
42772 coordLeft = coord.left,
42773 coordRight = coord.right,
42774 coordTop = coord.top;
42775 var maxCountForOneSide = Math.floor(coordHeight / itemHeight);
42776 var maxCount = maxCountForOneSide * 2;
42777 var geometry = chart.getGeometrys()[0];
42778 var records = geometry.flatRecords()
42779 // 按角度大到小排序
42780 .sort(function (a, b) {
42781 var angle1 = a.xMax - a.xMin;
42782 var angle2 = b.xMax - b.xMin;
42783 return angle2 - angle1;
42784 })
42785 // 只取前 maxCount 个显示
42786 .slice(0, maxCount);
42787 // 存储左右 labels
42788 var halves = [[], [] // right
42789 ];
42790 records.forEach(function (record) {
42791 var xMin = record.xMin,
42792 xMax = record.xMax,
42793 color = record.color,
42794 origin = record.origin;
42795 // 锚点角度
42796 var anchorAngle = getMiddleAngle(xMin, xMax);
42797 // 锚点坐标
42798 var anchorPoint = getEndPoint(center, anchorAngle, radius + anchorOffset);
42799 // 拐点坐标
42800 var inflectionPoint = getEndPoint(center, anchorAngle, radius + inflectionOffset);
42801 // 锚点方向
42802 var side = anchorPoint.x < center.x ? 'left' : 'right';
42803 var label = {
42804 origin: origin,
42805 angle: anchorAngle,
42806 anchor: anchorPoint,
42807 inflection: inflectionPoint,
42808 side: side,
42809 x: inflectionPoint.x,
42810 y: inflectionPoint.y,
42811 r: radius + inflectionOffset,
42812 color: color,
42813 label1: isFunction(label1) ? label1(origin, record) : label1,
42814 label2: isFunction(label2) ? label2(origin, record) : label2
42815 };
42816 // 判断文本的方向
42817 if (side === 'left') {
42818 halves[0].push(label);
42819 } else {
42820 halves[1].push(label);
42821 }
42822 });
42823 // 判断是有一边超过了显示的最大
42824 if (halves[0].length > maxCountForOneSide) {
42825 halves = move(halves[0], halves[1], halves[0].length - maxCountForOneSide, center);
42826 } else if (halves[1].length > maxCountForOneSide) {
42827 var _a = move(halves[1], halves[0], halves[1].length - maxCountForOneSide, center),
42828 right = _a[0],
42829 left = _a[1];
42830 halves = [left, right];
42831 }
42832 // label 的最大宽度
42833 var labelWidth = coordWidth / 2 - radius - anchorOffset - inflectionOffset - 2 * sidePadding;
42834 var labels = [];
42835 halves.forEach(function (half, index) {
42836 var showSide = index === 0 ? 'left' : 'right';
42837 // 顺时针方向排序
42838 half.sort(function (a, b) {
42839 var aAngle = a.angle;
42840 var bAngle = b.angle;
42841 if (showSide === 'left') {
42842 // 是否在第一象限
42843 aAngle = isFirstQuadrant(aAngle) ? aAngle + Math.PI * 2 : aAngle;
42844 bAngle = isFirstQuadrant(bAngle) ? bAngle + Math.PI * 2 : bAngle;
42845 return bAngle - aAngle;
42846 } else {
42847 // 是否在第四象限
42848 aAngle = isFourthQuadrant(aAngle) ? aAngle - Math.PI * 2 : aAngle;
42849 bAngle = isFourthQuadrant(bAngle) ? bAngle - Math.PI * 2 : bAngle;
42850 return aAngle - bAngle;
42851 }
42852 });
42853 var pointsY = half.map(function (label) {
42854 return label.y;
42855 });
42856 var maxY = Math.max.apply(null, pointsY);
42857 var minY = Math.min.apply(null, pointsY);
42858 // 每个 label 占用的高度
42859 var labelCount = half.length;
42860 var labelHeight = coordHeight / labelCount;
42861 var halfLabelHeight = labelHeight / 2;
42862 // 线之间的间隔
42863 var lineInterval = 2;
42864 if (showSide === 'left') {
42865 half.forEach(function (label, index) {
42866 var anchor = label.anchor,
42867 inflection = label.inflection,
42868 angle = label.angle,
42869 x = label.x,
42870 y = label.y;
42871 var points = [anchor, inflection];
42872 var endX = coordLeft + sidePadding;
42873 var endY = coordTop + halfLabelHeight + labelHeight * index;
42874 // 文本开始点
42875 var labelStart = {
42876 x: endX + labelWidth + lineInterval * index,
42877 y: endY
42878 };
42879 // 文本结束点
42880 var labelEnd = {
42881 x: endX,
42882 y: endY
42883 };
42884 // 第四象限
42885 if (isFirstQuadrant(angle)) {
42886 var pointY = minY - lineInterval * (labelCount - index);
42887 points.push({
42888 x: x,
42889 y: pointY
42890 });
42891 points.push({
42892 x: labelStart.x,
42893 y: pointY
42894 });
42895 } else if (isThirdQuadrant(angle) || isFourthQuadrant(angle)) {
42896 points.push({
42897 x: labelStart.x,
42898 y: y
42899 });
42900 } else if (isSecondQuadrant(angle)) {
42901 var pointY = maxY + lineInterval * index;
42902 points.push({
42903 x: x,
42904 y: pointY
42905 });
42906 points.push({
42907 x: labelStart.x,
42908 y: pointY
42909 });
42910 }
42911 points.push(labelStart);
42912 points.push(labelEnd);
42913 label.points = points;
42914 label.side = showSide;
42915 labels.push(label);
42916 });
42917 } else {
42918 half.forEach(function (label, index) {
42919 var anchor = label.anchor,
42920 inflection = label.inflection,
42921 angle = label.angle,
42922 x = label.x,
42923 y = label.y;
42924 // 折线的点
42925 var points = [anchor, inflection];
42926 var endX = coordRight - sidePadding;
42927 var endY = coordTop + halfLabelHeight + labelHeight * index;
42928 // 文本开始点
42929 var labelStart = {
42930 x: endX - labelWidth - lineInterval * index,
42931 y: endY
42932 };
42933 // 文本结束点
42934 var labelEnd = {
42935 x: endX,
42936 y: endY
42937 };
42938 // 第四象限
42939 if (isFourthQuadrant(angle)) {
42940 var pointY = minY - lineInterval * (labelCount - index);
42941 points.push({
42942 x: x,
42943 y: pointY
42944 });
42945 points.push({
42946 x: labelStart.x,
42947 y: pointY
42948 });
42949 } else if (isFirstQuadrant(angle) || isSecondQuadrant(angle)) {
42950 points.push({
42951 x: labelStart.x,
42952 y: y
42953 });
42954 } else if (isThirdQuadrant(angle)) {
42955 var pointY = maxY + lineInterval * index;
42956 points.push({
42957 x: x,
42958 y: pointY
42959 });
42960 points.push({
42961 x: labelStart.x,
42962 y: pointY
42963 });
42964 }
42965 points.push(labelStart);
42966 points.push(labelEnd);
42967 label.points = points;
42968 label.side = showSide;
42969 labels.push(label);
42970 });
42971 }
42972 });
42973 return labels;
42974 };
42975 PieLabel.prototype.render = function () {
42976 var context = this.context;
42977 var props = context.px2hd(deepMix({}, DEFAULT_CONFIG, this.props));
42978 var labels = this.getLabels(props);
42979 return jsx(View, __assign({
42980 labels: labels
42981 }, props));
42982 };
42983 return PieLabel;
42984 }(Component);
42985 });
42986
42987 var PieLabelView = (function (props) {
42988 var lineStyle = props.lineStyle,
42989 anchorStyle = props.anchorStyle,
42990 labels = props.labels,
42991 label1OffsetY = props.label1OffsetY,
42992 label2OffsetY = props.label2OffsetY,
42993 triggerRef = props.triggerRef,
42994 onClick = props.onClick;
42995 return jsx("group", {
42996 ref: triggerRef
42997 }, labels.map(function (label) {
42998 var origin = label.origin,
42999 anchor = label.anchor,
43000 side = label.side,
43001 color = label.color,
43002 label1 = label.label1,
43003 label2 = label.label2,
43004 points = label.points;
43005 var end = points[points.length - 1];
43006 return jsx("group", {
43007 onClick: onClick ? function () {
43008 onClick(label);
43009 } : null
43010 }, jsx("circle", {
43011 attrs: __assign({
43012 r: '4px',
43013 cx: anchor.x,
43014 cy: anchor.y,
43015 fill: color
43016 }, anchorStyle)
43017 }), jsx("polyline", {
43018 attrs: __assign({
43019 points: points.map(function (d) {
43020 return [d.x, d.y];
43021 }),
43022 lineWidth: '2px',
43023 stroke: color
43024 }, lineStyle)
43025 }), jsx("text", {
43026 className: "click",
43027 attrs: __assign({
43028 x: end.x,
43029 y: end.y + label1OffsetY,
43030 fontSize: '24px',
43031 lineHeight: '24px',
43032 fill: color,
43033 textBaseline: 'bottom',
43034 textAlign: side === 'left' ? 'left' : 'right'
43035 }, label1),
43036 data: origin
43037 }), jsx("text", {
43038 className: "click",
43039 attrs: __assign({
43040 x: end.x,
43041 y: end.y + label2OffsetY,
43042 fontSize: '24px',
43043 lineHeight: '24px',
43044 fill: '#808080',
43045 textBaseline: 'top',
43046 textAlign: side === 'left' ? 'left' : 'right'
43047 }, label2),
43048 data: origin
43049 }));
43050 }));
43051 });
43052
43053 var index$a = withPieLabel(PieLabelView);
43054
43055 var getPoint$1 = function getPoint(cener, angle, r) {
43056 var x = cener.x + Math.cos(angle) * r;
43057 var y = cener.y + Math.sin(angle) * r;
43058 return {
43059 x: x,
43060 y: y
43061 };
43062 };
43063 var getTicks = function getTicks(start, end, tickCount, center, r, tickOffset, tickLength) {
43064 var ticks = [];
43065 var diff = end - start;
43066 for (var i = 0; i <= tickCount; i++) {
43067 var tickValue = start + diff * i / tickCount;
43068 var startPoint = getPoint$1(center, tickValue, r + tickOffset - tickLength);
43069 var endPoint = getPoint$1(center, tickValue, r + tickOffset);
43070 ticks.push({
43071 tickValue: tickValue,
43072 start: startPoint,
43073 end: endPoint
43074 });
43075 }
43076 return ticks;
43077 };
43078 var withGauge = function withGauge(View) {
43079 return /** @class */function (_super) {
43080 __extends(Gauge, _super);
43081 function Gauge() {
43082 return _super !== null && _super.apply(this, arguments) || this;
43083 }
43084 Gauge.prototype.render = function () {
43085 var _a = this,
43086 props = _a.props,
43087 context = _a.context;
43088 var startAngle = props.startAngle,
43089 endAngle = props.endAngle,
43090 tickCount = props.tickCount,
43091 center = props.center,
43092 r = props.r,
43093 tickOffset = props.tickOffset,
43094 tickLength = props.tickLength;
43095 var ticks = getTicks(startAngle, endAngle, tickCount, center, context.px2hd(r), context.px2hd(tickOffset), context.px2hd(tickLength));
43096 return jsx(View, __assign({}, props, {
43097 ticks: ticks
43098 }));
43099 };
43100 return Gauge;
43101 }(Component);
43102 };
43103
43104 var GaugeView = (function (props) {
43105 var center = props.center,
43106 startAngle = props.startAngle,
43107 endAngle = props.endAngle,
43108 r = props.r,
43109 percent = props.percent,
43110 ticks = props.ticks;
43111 var x = center.x,
43112 y = center.y;
43113 var diff = endAngle - startAngle;
43114 return jsx("group", null, jsx("arc", {
43115 attrs: {
43116 cx: x,
43117 cy: y,
43118 r: r,
43119 startAngle: "".concat(startAngle, " rad"),
43120 endAngle: "".concat(endAngle, " rad"),
43121 lineWidth: '20px',
43122 lineCap: 'round',
43123 stroke: '#e7e7e7'
43124 }
43125 }), jsx("arc", {
43126 attrs: {
43127 cx: x,
43128 cy: y,
43129 r: r,
43130 startAngle: "".concat(startAngle, " rad"),
43131 endAngle: "".concat(startAngle, " rad"),
43132 lineWidth: '40px',
43133 lineCap: 'round',
43134 stroke: '#0075ff'
43135 },
43136 animation: {
43137 appear: {
43138 easing: 'linear',
43139 duration: 500,
43140 property: ['endAngle'],
43141 start: {
43142 endAngle: "".concat(startAngle, " rad")
43143 },
43144 end: {
43145 endAngle: "".concat(startAngle + diff * percent, " rad")
43146 }
43147 }
43148 }
43149 }), ticks.map(function (tick) {
43150 var start = tick.start,
43151 end = tick.end;
43152 return jsx("line", {
43153 attrs: {
43154 x1: start.x,
43155 y1: start.y,
43156 x2: end.x,
43157 y2: end.y,
43158 lineWidth: '6px',
43159 lineCap: 'round',
43160 stroke: '#e7e7e7'
43161 }
43162 });
43163 }));
43164 });
43165
43166 var index$b = withGauge(GaugeView);
43167
43168 // 判断新老values是否相等,这里只要判断前后是否相等即可
43169 function isValuesEqual(values, newValues) {
43170 if (values.length !== newValues.length) {
43171 return false;
43172 }
43173 var lastIndex = values.length - 1;
43174 return values[0] === newValues[0] && values[lastIndex] === newValues[lastIndex];
43175 }
43176 function updateCategoryRange(scale, originScale, range) {
43177 var currentValues = scale.values,
43178 currentTicks = scale.ticks,
43179 tickMethod = scale.tickMethod,
43180 tickCount = scale.tickCount;
43181 var originValues = originScale.values;
43182 var start = range[0],
43183 end = range[1];
43184 var len = originValues.length;
43185 var valueStart = start * len;
43186 var valueEnd = end * len;
43187 // 保持滑动时个数的稳定
43188 var diff = valueEnd - valueStart;
43189 var precision = parseFloat(diff.toFixed(3)); // js 计算精度问题
43190 var count = Math.round(precision);
43191 var sliceSatrt = Math.min(Math.round(valueStart), len - count);
43192 // 从原始数据里截取需要显示的数据
43193 var newValues = originValues.slice(sliceSatrt, sliceSatrt + count);
43194 // 根据当前数据的比例,和定义的tickCount计算应该需要多少个ticks
43195 var newTickCount = Math.round(tickCount * originValues.length / newValues.length);
43196 // 计算新的ticks
43197 var catTicks = getTickMethod(tickMethod);
43198 var newTicks = catTicks({
43199 tickCount: newTickCount,
43200 values: originValues
43201 });
43202 // 如果新数组和当前显示的数组相同,则不更新
43203 if (isValuesEqual(currentValues, newValues) && isValuesEqual(currentTicks, newTicks)) {
43204 return;
43205 }
43206 scale.change({
43207 values: newValues,
43208 ticks: newTicks
43209 });
43210 return scale;
43211 }
43212 function updateLinearRange(scale, originScale, range) {
43213 var min = originScale.min,
43214 max = originScale.max;
43215 var start = range[0],
43216 end = range[1];
43217 var newMin = min + (max - min) * start;
43218 var newMax = min + (max - min) * end;
43219 scale.change({
43220 min: newMin,
43221 max: newMax,
43222 nice: false
43223 });
43224 }
43225 function updateScale(scale, values) {
43226 var isLinear = scale.isLinear;
43227 if (isLinear) {
43228 var _a = getRange(values),
43229 min = _a.min,
43230 max = _a.max;
43231 return scale.change({
43232 min: min,
43233 max: max,
43234 nice: true
43235 });
43236 }
43237 }
43238 function updateRange(scale, originScale, range) {
43239 var isCategory = scale.isCategory,
43240 isLinear = scale.isLinear;
43241 if (isCategory) {
43242 return updateCategoryRange(scale, originScale, range);
43243 }
43244 if (isLinear) {
43245 return updateLinearRange(scale, originScale, range);
43246 }
43247 }
43248 function updateFollow(scales, mainScale, data) {
43249 var mainField = mainScale.field,
43250 mainType = mainScale.type,
43251 mainValues = mainScale.values;
43252 // 转成 map 提高查询性能
43253 var mainValuesMap = {};
43254 mainValues.forEach(function (item) {
43255 mainValuesMap[item] = true;
43256 });
43257 return scales.map(function (scale) {
43258 var followField = scale.field;
43259 var values = [];
43260 data.forEach(function (item) {
43261 var value = mainType === 'timeCat' ? toTimeStamp$1(item[mainField]) : item[mainField];
43262 if (mainValuesMap[value]) {
43263 var followItemValue = item[followField];
43264 if (isArray(followItemValue)) {
43265 values.push.apply(values, followItemValue);
43266 } else {
43267 values.push(followItemValue);
43268 }
43269 }
43270 });
43271 return updateScale(scale, values);
43272 });
43273 }
43274
43275 function quadraticOut(k) {
43276 return k * (2 - k);
43277 }
43278
43279 function lerp$1(min, max, fraction) {
43280 return (max - min) * fraction + min;
43281 }
43282 function isNumberEqualRange(aRange, bRange) {
43283 if (!bRange) return false;
43284 for (var i = 0, len = aRange.length; i < len; i++) {
43285 if (!isNumberEqual(aRange[i], bRange[i])) return false;
43286 }
43287 return true;
43288 }
43289 function isEqualRange(aRange, bRange) {
43290 if (!bRange) return false;
43291 if (isArray(aRange)) {
43292 return isNumberEqualRange(aRange, bRange);
43293 }
43294 // object
43295 for (var i in aRange) {
43296 if (!isNumberEqualRange(aRange[i], bRange[i])) return false;
43297 }
43298 return true;
43299 }
43300 function cloneScale$1(scale, scaleConfig) {
43301 // @ts-ignore
43302 return new scale.constructor(__assign(__assign({}, scale.__cfg__), scaleConfig));
43303 }
43304 var withZoom = (function (View) {
43305 return /** @class */function (_super) {
43306 __extends(Zoom, _super);
43307 function Zoom(props) {
43308 var _this = this;
43309 var defaultProps = {
43310 onPanStart: function onPanStart() {},
43311 onPinchStart: function onPinchStart() {},
43312 onPan: function onPan() {},
43313 onPinch: function onPinch() {},
43314 onInit: function onInit() {},
43315 onPanEnd: function onPanEnd() {},
43316 onPinchEnd: function onPinchEnd() {},
43317 minCount: 10
43318 };
43319 _this = _super.call(this, __assign(__assign({}, defaultProps), props)) || this;
43320 _this.scale = {};
43321 _this.originScale = {};
43322 //swipe end x y
43323 _this.swipeEnd = {
43324 startX: 0,
43325 startY: 0,
43326 endX: 0,
43327 endY: 0
43328 };
43329 _this.onPanStart = function () {
43330 var scale = _this.scale;
43331 var onPanStart = _this.props.onPanStart;
43332 _this.onStart();
43333 onPanStart === null || onPanStart === void 0 ? void 0 : onPanStart({
43334 scale: scale
43335 });
43336 };
43337 _this.onPan = function (ev) {
43338 var onPan = _this.props.onPan;
43339 var dims = _this.dims;
43340 var range = {};
43341 each(dims, function (dim) {
43342 if (dim === 'x') {
43343 range['x'] = _this._doXPan(ev);
43344 return;
43345 }
43346 if (dim === 'y') {
43347 range['y'] = _this._doYPan(ev);
43348 return;
43349 }
43350 });
43351 _this.renderRange(range);
43352 onPan === null || onPan === void 0 ? void 0 : onPan(ev);
43353 };
43354 _this.onPanEnd = function () {
43355 var scale = _this.scale;
43356 var onPanEnd = _this.props.onPanEnd;
43357 _this.onEnd();
43358 onPanEnd === null || onPanEnd === void 0 ? void 0 : onPanEnd({
43359 scale: scale
43360 });
43361 };
43362 _this.onPinchStart = function () {
43363 var onPinchStart = _this.props.onPinchStart;
43364 _this.onStart();
43365 onPinchStart === null || onPinchStart === void 0 ? void 0 : onPinchStart();
43366 };
43367 _this.onPinch = function (ev) {
43368 var onPinch = _this.props.onPinch;
43369 var dims = _this.dims;
43370 var range = {};
43371 each(dims, function (dim) {
43372 if (dim === 'x') {
43373 range['x'] = _this._doXPinch(ev);
43374 return;
43375 }
43376 if (dim === 'y') {
43377 range['y'] = _this._doYPinch(ev);
43378 return;
43379 }
43380 });
43381 _this.renderRange(range);
43382 onPinch === null || onPinch === void 0 ? void 0 : onPinch(ev);
43383 };
43384 _this.onPinchEnd = function () {
43385 var scale = _this.scale;
43386 var onPinchEnd = _this.props.onPinchEnd;
43387 _this.onEnd();
43388 onPinchEnd === null || onPinchEnd === void 0 ? void 0 : onPinchEnd({
43389 scale: scale
43390 });
43391 };
43392 _this.onStart = function () {
43393 var state = _this.state;
43394 var range = state.range;
43395 _this.startRange = range;
43396 _this._cancelAnimationFrame();
43397 };
43398 _this.onSwipe = function (ev) {
43399 var _a = _this,
43400 props = _a.props,
43401 state = _a.state;
43402 // 滑动速率
43403 var velocity = ev.velocity,
43404 direction = ev.direction,
43405 _b = ev.velocityX,
43406 velocityX = _b === void 0 ? 0 : _b,
43407 _c = ev.velocityY,
43408 velocityY = _c === void 0 ? 0 : _c,
43409 points = ev.points;
43410 var mode = props.mode,
43411 swipe = props.swipe;
43412 var range = state.range;
43413 if (!swipe || !mode) {
43414 return;
43415 }
43416 if (mode.length === 1) {
43417 _this.animateSwipe(mode, range[mode], direction === 'right' || direction === 'down' ? -velocity : velocity);
43418 return;
43419 }
43420 var _d = points[0],
43421 x = _d.x,
43422 y = _d.y;
43423 // 边界处理
43424 if (Math.abs((range === null || range === void 0 ? void 0 : range.x[0]) - 0) < 0.0005 && velocityX > 0) return;
43425 if (Math.abs((range === null || range === void 0 ? void 0 : range.x[1]) - 1) < 0.0005 && velocityX < 0) return;
43426 if (Math.abs((range === null || range === void 0 ? void 0 : range.y[0]) - 0) < 0.0005 && velocityY < 0) return;
43427 if (Math.abs((range === null || range === void 0 ? void 0 : range.x[1]) - 1) < 0.0005 && velocityY > 0) return;
43428 _this.swipeEnd = {
43429 startX: x,
43430 startY: y,
43431 endX: x + velocityX * 50,
43432 endY: y - velocityY * 50
43433 };
43434 _this.onStart();
43435 _this.update();
43436 };
43437 _this.onEnd = function () {
43438 _this.startRange = null;
43439 };
43440 var mode = props.mode;
43441 _this.dims = isArray(mode) ? mode : [mode];
43442 return _this;
43443 }
43444 Zoom.prototype.didMount = function () {
43445 var scale = this.scale;
43446 var onInit = this.props.onInit;
43447 onInit({
43448 scale: scale
43449 });
43450 this._bindEvents();
43451 };
43452 Zoom.prototype.willReceiveProps = function (nextProps) {
43453 // @ts-ignore
43454 var nextRange = nextProps.range,
43455 nextData = nextProps.data;
43456 var _a = this.props,
43457 lastRange = _a.range,
43458 lastData = _a.data;
43459 if (nextData !== lastData) {
43460 this._cancelAnimationFrame();
43461 }
43462 if (!equal(nextRange, lastRange)) {
43463 var cacheRange_1 = {};
43464 each(this.dims, function (dim) {
43465 cacheRange_1[dim] = nextRange;
43466 });
43467 this.state = {
43468 range: cacheRange_1
43469 };
43470 }
43471 };
43472 Zoom.prototype.willMount = function () {
43473 var _this = this;
43474 var _a = this,
43475 props = _a.props,
43476 dims = _a.dims;
43477 var minCount = props.minCount,
43478 range = props.range;
43479 var valueLength = Number.MIN_VALUE;
43480 var cacheRange = {};
43481 each(dims, function (dim) {
43482 var scale = _this._getScale(dim);
43483 var values = scale.values;
43484 valueLength = values.length > valueLength ? values.length : valueLength;
43485 _this.scale[dim] = scale;
43486 _this.originScale[dim] = cloneScale$1(scale);
43487 _this.updateRange(range, dim);
43488 cacheRange[dim] = range;
43489 });
43490 // 图表上最少显示 MIN_COUNT 个数据
43491 this.minScale = minCount / valueLength;
43492 this.renderRange(cacheRange);
43493 };
43494 Zoom.prototype.willUpdate = function () {
43495 var _this = this;
43496 var _a = this,
43497 props = _a.props,
43498 state = _a.state,
43499 dims = _a.dims;
43500 var minCount = props.minCount,
43501 range = props.range;
43502 var valueLength = Number.MIN_VALUE;
43503 var cacheRange = {};
43504 each(dims, function (dim) {
43505 var scale = _this._getScale(dim);
43506 // scale 没有变化, 不处理
43507 if (scale === _this.scale[dim]) {
43508 return;
43509 }
43510 var values = scale.values;
43511 valueLength = values.length > valueLength ? values.length : valueLength;
43512 _this.scale[dim] = scale;
43513 _this.originScale[dim] = cloneScale$1(scale);
43514 // 让 range 触发更新
43515 _this.state.range[dim] = [0, 1];
43516 _this.updateRange(range, dim);
43517 cacheRange[dim] = range;
43518 });
43519 // 有变化
43520 if (Object.keys(cacheRange).length > 0) {
43521 this.minScale = minCount / valueLength;
43522 var newRange = __assign(__assign({}, state.range), cacheRange);
43523 this.renderRange(newRange);
43524 }
43525 };
43526 Zoom.prototype.didUnmount = function () {
43527 this._cancelAnimationFrame();
43528 this._unBindEvents();
43529 };
43530 Zoom.prototype._requestAnimationFrame = function (calllback) {
43531 var context = this.context;
43532 var requestAnimationFrame = context.canvas.requestAnimationFrame;
43533 this.loop = requestAnimationFrame(calllback);
43534 return this.loop;
43535 };
43536 Zoom.prototype._cancelAnimationFrame = function () {
43537 var _a = this,
43538 loop = _a.loop,
43539 context = _a.context;
43540 if (loop) {
43541 context.canvas.cancelAnimationFrame(loop);
43542 }
43543 };
43544 Zoom.prototype._bindEvents = function () {
43545 var _a = this.props,
43546 chart = _a.chart,
43547 pan = _a.pan,
43548 pinch = _a.pinch,
43549 swipe = _a.swipe;
43550 // 统一绑定事件
43551 if (pan !== false) {
43552 chart.on('panstart', this.onPanStart);
43553 chart.on('pan', this.onPan);
43554 chart.on('panend', this.onPanEnd);
43555 }
43556 if (pinch !== false) {
43557 chart.on('pinch', this.onPinch);
43558 chart.on('pinchstart', this.onPinchStart);
43559 chart.on('pinchend', this.onPinchEnd);
43560 }
43561 if (swipe !== false) {
43562 chart.on('swipe', this.onSwipe);
43563 }
43564 };
43565 Zoom.prototype._unBindEvents = function () {
43566 var _a = this.props,
43567 chart = _a.chart,
43568 pan = _a.pan,
43569 pinch = _a.pinch,
43570 swipe = _a.swipe;
43571 // 统一绑定事件
43572 if (pan !== false) {
43573 chart.off('panstart', this.onPanStart);
43574 chart.off('pan', this.onPan);
43575 chart.off('panend', this.onPanEnd);
43576 }
43577 if (pinch !== false) {
43578 chart.off('pinch', this.onPinch);
43579 chart.off('pinchstart', this.onPinchStart);
43580 chart.off('pinchend', this.onPinchEnd);
43581 }
43582 if (swipe !== false) {
43583 chart.off('swipe', this.onSwipe);
43584 }
43585 };
43586 Zoom.prototype.update = function () {
43587 var _this = this;
43588 var _a = this.swipeEnd,
43589 startX = _a.startX,
43590 startY = _a.startY,
43591 endX = _a.endX,
43592 endY = _a.endY;
43593 var x = lerp$1(startX, endX, 0.05);
43594 var y = lerp$1(startY, endY, 0.05);
43595 this.swipeEnd = {
43596 startX: x,
43597 startY: y,
43598 endX: endX,
43599 endY: endY
43600 };
43601 var props = this.props;
43602 var coord = props.coord;
43603 var coordWidth = coord.width,
43604 coordHeight = coord.height;
43605 var range = {};
43606 range['x'] = this._doPan((x - startX) / coordWidth, 'x');
43607 range['y'] = this._doPan((y - startY) / coordHeight, 'y');
43608 this.renderRange(range);
43609 this.startRange = range;
43610 this._requestAnimationFrame(function () {
43611 return _this.update();
43612 });
43613 if (Math.abs(x - endX) < 0.0005 && Math.abs(y - endY) < 0.0005) {
43614 this.onEnd();
43615 this._cancelAnimationFrame();
43616 }
43617 };
43618 Zoom.prototype.animateSwipe = function (dim, dimRange, velocity) {
43619 var _this = this;
43620 var props = this.props;
43621 var _a = props.swipeDuration,
43622 swipeDuration = _a === void 0 ? 1000 : _a;
43623 var diff = (dimRange[1] - dimRange[0]) * velocity;
43624 var startTime = Date.now();
43625 var updateRange = function updateRange(t) {
43626 var newDimRange = [dimRange[0] + diff * t, dimRange[1] + diff * t];
43627 var newRange = _this.updateRange(newDimRange, dim);
43628 _this.renderRange({
43629 x: newRange
43630 });
43631 };
43632 // 更新动画
43633 var _update = function update() {
43634 // 计算动画已经进行的时间
43635 var currentTime = Date.now() - startTime;
43636 // 如果动画已经结束,则清除定时器
43637 if (currentTime >= swipeDuration) {
43638 updateRange(1);
43639 return;
43640 }
43641 // 计算缓动值
43642 var progress = currentTime / swipeDuration;
43643 var easedProgress = quadraticOut(progress);
43644 updateRange(easedProgress);
43645 _this._requestAnimationFrame(function () {
43646 _update();
43647 });
43648 };
43649 _update();
43650 };
43651 Zoom.prototype._doXPan = function (ev) {
43652 var direction = ev.direction,
43653 deltaX = ev.deltaX;
43654 if (this.props.mode.length === 1 && (direction === 'up' || direction === 'down')) {
43655 return this.state.range['x'];
43656 }
43657 ev.preventDefault && ev.preventDefault();
43658 var props = this.props;
43659 var coord = props.coord,
43660 _a = props.panSensitive,
43661 panSensitive = _a === void 0 ? 1 : _a;
43662 var coordWidth = coord.width;
43663 var ratio = deltaX / coordWidth * panSensitive;
43664 var newRange = this._doPan(ratio, 'x');
43665 return newRange;
43666 };
43667 Zoom.prototype._doYPan = function (ev) {
43668 var direction = ev.direction,
43669 deltaY = ev.deltaY;
43670 if (this.props.mode.length === 1 && (direction === 'left' || direction === 'right')) {
43671 return this.state.range['y'];
43672 }
43673 ev.preventDefault && ev.preventDefault();
43674 var props = this.props;
43675 var coord = props.coord,
43676 _a = props.panSensitive,
43677 panSensitive = _a === void 0 ? 1 : _a;
43678 var coordHeight = coord.height;
43679 var ratio = -deltaY / coordHeight * panSensitive;
43680 var newRange = this._doPan(ratio, 'y');
43681 return newRange;
43682 };
43683 Zoom.prototype._doPan = function (ratio, dim) {
43684 var startRange = this.startRange;
43685 var _a = startRange[dim],
43686 start = _a[0],
43687 end = _a[1];
43688 var rangeLen = end - start;
43689 var rangeOffset = rangeLen * ratio;
43690 var newStart = start - rangeOffset;
43691 var newEnd = end - rangeOffset;
43692 var newRange = this.updateRange([newStart, newEnd], dim);
43693 return newRange;
43694 };
43695 Zoom.prototype._doXPinch = function (ev) {
43696 ev.preventDefault && ev.preventDefault();
43697 var zoom = ev.zoom,
43698 center = ev.center;
43699 var props = this.props;
43700 var coord = props.coord;
43701 var coordWidth = coord.width,
43702 left = coord.left,
43703 right = coord.right;
43704 var leftLen = Math.abs(center.x - left);
43705 var rightLen = Math.abs(right - center.x);
43706 // 计算左右缩放的比例
43707 var leftZoom = leftLen / coordWidth;
43708 var rightZoom = rightLen / coordWidth;
43709 var newRange = this._doPinch(leftZoom, rightZoom, zoom, 'x');
43710 return newRange;
43711 };
43712 Zoom.prototype._doYPinch = function (ev) {
43713 ev.preventDefault && ev.preventDefault();
43714 var zoom = ev.zoom,
43715 center = ev.center;
43716 var props = this.props;
43717 var coord = props.coord;
43718 var coordHeight = coord.height,
43719 top = coord.top,
43720 bottom = coord.bottom;
43721 var topLen = Math.abs(center.y - top);
43722 var bottomLen = Math.abs(bottom - center.y);
43723 // 计算左右缩放的比例
43724 var topZoom = topLen / coordHeight;
43725 var bottomZoom = bottomLen / coordHeight;
43726 var newRange = this._doPinch(topZoom, bottomZoom, zoom, 'y');
43727 return newRange;
43728 };
43729 Zoom.prototype._doPinch = function (startRatio, endRatio, zoom, dim) {
43730 var _a = this,
43731 startRange = _a.startRange,
43732 minScale = _a.minScale,
43733 props = _a.props;
43734 var _b = props.pinchSensitive,
43735 pinchSensitive = _b === void 0 ? 1 : _b;
43736 var _c = startRange[dim],
43737 start = _c[0],
43738 end = _c[1];
43739 var zoomOffset = zoom < 1 ? (1 / zoom - 1) * pinchSensitive : (1 - zoom) * pinchSensitive;
43740 var rangeLen = end - start;
43741 var rangeOffset = rangeLen * zoomOffset;
43742 var startOffset = rangeOffset * startRatio;
43743 var endOffset = rangeOffset * endRatio;
43744 var newStart = Math.max(0, start - startOffset);
43745 var newEnd = Math.min(1, end + endOffset);
43746 var newRange = [newStart, newEnd];
43747 // 如果已经到了最小比例,则不能再继续再放大
43748 if (newEnd - newStart < minScale) {
43749 return this.state.range[dim];
43750 }
43751 return this.updateRange(newRange, dim);
43752 };
43753 Zoom.prototype.updateRange = function (originalRange, dim) {
43754 if (!originalRange) return;
43755 var start = originalRange[0],
43756 end = originalRange[1];
43757 var rangeLength = end - start;
43758 // 处理边界值
43759 var newRange;
43760 if (start < 0) {
43761 newRange = [0, rangeLength];
43762 } else if (end > 1) {
43763 newRange = [1 - rangeLength, 1];
43764 } else {
43765 newRange = originalRange;
43766 }
43767 var _a = this,
43768 props = _a.props,
43769 scale = _a.scale,
43770 originScale = _a.originScale,
43771 state = _a.state;
43772 var data = props.data,
43773 autoFit = props.autoFit;
43774 var range = state.range;
43775 if (range && isEqualRange(newRange, range[dim])) return newRange;
43776 // 更新主 scale
43777 updateRange(scale[dim], originScale[dim], newRange);
43778 if (autoFit) {
43779 var followScale = this._getFollowScales(dim);
43780 this.updateFollow(followScale, scale[dim], data);
43781 }
43782 return newRange;
43783 };
43784 Zoom.prototype.updateFollow = function (scales, mainScale, data) {
43785 updateFollow(scales, mainScale, data);
43786 };
43787 Zoom.prototype._getScale = function (dim) {
43788 var _a = this.props,
43789 coord = _a.coord,
43790 chart = _a.chart;
43791 if (dim === 'x') {
43792 return coord.transposed ? chart.getYScales()[0] : chart.getXScales()[0];
43793 } else {
43794 return coord.transposed ? chart.getXScales()[0] : chart.getYScales()[0];
43795 }
43796 };
43797 Zoom.prototype._getFollowScales = function (dim) {
43798 var _a = this.props,
43799 coord = _a.coord,
43800 chart = _a.chart;
43801 if (dim === 'x') {
43802 return coord.transposed ? chart.getXScales() : chart.getYScales();
43803 }
43804 if (dim === 'y') {
43805 return coord.transposed ? chart.getYScales() : chart.getXScales();
43806 }
43807 };
43808 Zoom.prototype.renderRange = function (range) {
43809 var _a = this,
43810 state = _a.state,
43811 props = _a.props;
43812 if (isEqualRange(range, state.range)) return;
43813 var chart = props.chart;
43814 // 手势变化不执行动画
43815 var animate = chart.animate;
43816 chart.setAnimate(false);
43817 // 后面的 forceUpdate 会强制更新,所以不用 setState,直接更新
43818 state.range = range;
43819 chart.forceUpdate(function () {
43820 chart.setAnimate(animate);
43821 });
43822 };
43823 Zoom.prototype.render = function () {
43824 return jsx(View, __assign({}, this.props, this.state));
43825 };
43826 return Zoom;
43827 }(Component);
43828 });
43829
43830 var withScrollBar = (function (View) {
43831 return /** @class */function (_super) {
43832 __extends(ScrollBar, _super);
43833 function ScrollBar() {
43834 return _super !== null && _super.apply(this, arguments) || this;
43835 }
43836 ScrollBar.prototype.willMount = function () {
43837 _super.prototype.willMount.call(this);
43838 var _a = this,
43839 context = _a.context,
43840 props = _a.props;
43841 var visible = props.visible,
43842 _b = props.position,
43843 position = _b === void 0 ? 'bottom' : _b,
43844 _c = props.margin,
43845 margin = _c === void 0 ? '16px' : _c,
43846 chart = props.chart;
43847 var marginNumber = context.px2hd(margin);
43848 if (visible === false) {
43849 return null;
43850 }
43851 chart.updateCoordFor(this, {
43852 position: position,
43853 width: position === 'left' || position === 'right' ? marginNumber : 0,
43854 height: position === 'bottom' || position === 'top' ? marginNumber : 0
43855 });
43856 };
43857 ScrollBar.prototype.render = function () {
43858 var _a = this,
43859 props = _a.props,
43860 state = _a.state;
43861 var visible = props.visible;
43862 if (visible === false) {
43863 return null;
43864 }
43865 return jsx(View, __assign({
43866 position: "bottom"
43867 }, props, state));
43868 };
43869 return ScrollBar;
43870 }(withZoom(View));
43871 });
43872
43873 var Horizontal = (function (props, context) {
43874 var coord = props.coord,
43875 range = props.range,
43876 position = props.position,
43877 layout = props.layout,
43878 style = props.style,
43879 background = props.background,
43880 barStyle = props.barStyle;
43881 var left = coord.left,
43882 width = coord.width;
43883 var top = layout.top,
43884 height = layout.height;
43885 var _a = (range === null || range === void 0 ? void 0 : range.x) || (range === null || range === void 0 ? void 0 : range.y),
43886 start = _a[0],
43887 end = _a[1];
43888 var barLeft = width * start;
43889 var barWidth = width * (end - start);
43890 if (isNaN(barWidth)) return;
43891 return jsx("group", {
43892 style: __assign({
43893 display: 'flex',
43894 left: left,
43895 top: position === 'top' ? top - context.px2hd('8px') : top + height
43896 }, style)
43897 }, jsx("line", {
43898 style: __assign({
43899 display: 'flex',
43900 position: 'absolute',
43901 left: 0,
43902 width: width,
43903 height: 0,
43904 stroke: 'rgba(202, 215, 239, .2)',
43905 lineCap: 'round',
43906 lineWidth: '8px'
43907 }, background)
43908 }), jsx("line", {
43909 style: __assign({
43910 display: 'flex',
43911 position: 'absolute',
43912 left: barLeft,
43913 width: barWidth,
43914 height: 0,
43915 stroke: 'rgba(202, 215, 239, .5)',
43916 lineCap: 'round',
43917 lineWidth: '8px'
43918 }, barStyle)
43919 }));
43920 });
43921
43922 var Vertical = (function (props, context) {
43923 var coord = props.coord,
43924 range = props.range,
43925 position = props.position,
43926 layout = props.layout,
43927 style = props.style,
43928 background = props.background,
43929 barStyle = props.barStyle;
43930 var top = coord.top,
43931 height = coord.height;
43932 var left = layout.left,
43933 width = layout.width;
43934 var _a = (range === null || range === void 0 ? void 0 : range.y) || (range === null || range === void 0 ? void 0 : range.x),
43935 start = _a[0],
43936 end = _a[1];
43937 var barTop = height * start;
43938 var barHeight = height * (end - start);
43939 return jsx("group", {
43940 style: __assign({
43941 display: 'flex',
43942 top: top,
43943 left: position === 'left' ? left - context.px2hd('8px') : left + width
43944 }, style)
43945 }, jsx("line", {
43946 style: __assign({
43947 position: 'absolute',
43948 top: 0,
43949 left: 0,
43950 width: 0,
43951 height: height,
43952 stroke: 'rgba(202, 215, 239, .2)',
43953 lineCap: 'round',
43954 lineWidth: '8px'
43955 }, background)
43956 }), jsx("line", {
43957 style: __assign({
43958 position: 'absolute',
43959 top: barTop,
43960 width: 0,
43961 height: barHeight,
43962 stroke: 'rgba(202, 215, 239, .5)',
43963 lineCap: 'round',
43964 lineWidth: '8px'
43965 }, barStyle)
43966 }));
43967 });
43968
43969 var ScrollBarView = (function (props) {
43970 var position = props.position,
43971 mode = props.mode;
43972 if (mode.length > 1) {
43973 return jsx("group", null, jsx(Vertical, __assign({}, props)), jsx(Horizontal, __assign({}, props)));
43974 }
43975 if (position === 'left' || position === 'right') {
43976 return jsx(Vertical, __assign({}, props));
43977 }
43978 return jsx(Horizontal, __assign({}, props));
43979 });
43980
43981 var index$c = withScrollBar(ScrollBarView);
43982
43983 // 默认配色
43984 var COLORS = ['#E62C3B', '#0E9976', '#999999' // 平盘
43985 ];
43986 var withCandlestick = (function (View) {
43987 return /** @class */function (_super) {
43988 __extends(Candlestick, _super);
43989 function Candlestick() {
43990 return _super !== null && _super.apply(this, arguments) || this;
43991 }
43992 Candlestick.prototype.getDefaultCfg = function () {
43993 return {
43994 geomType: 'candlestick'
43995 };
43996 };
43997 Candlestick.prototype.getSize = function () {
43998 var _a = this,
43999 attrs = _a.attrs,
44000 props = _a.props;
44001 var _b = props.sizeRatio,
44002 sizeRatio = _b === void 0 ? 0.5 : _b;
44003 var x = attrs.x;
44004 var scale = x.scale;
44005 var values = scale.values;
44006 return 1 / values.length * sizeRatio;
44007 };
44008 Candlestick.prototype._getColor = function (colors, child, prevChild) {
44009 var normalized = child.normalized;
44010 // 处理颜色
44011 var y = normalized.y;
44012 var open = y[0],
44013 close = y[1];
44014 if (close > open) {
44015 return colors[0];
44016 }
44017 if (close < open) {
44018 return colors[1];
44019 }
44020 // 相等的情况下,再和昨日的收盘价比较
44021 if (!prevChild) {
44022 // 第一个固定为涨
44023 return colors[0];
44024 }
44025 var prevNormalized = prevChild.normalized;
44026 // 处理颜色
44027 var prevY = prevNormalized.y;
44028 var prevClose = prevY[1];
44029 if (close > prevClose) {
44030 return colors[0];
44031 }
44032 if (close < prevClose) {
44033 return colors[1];
44034 }
44035 return colors[2];
44036 };
44037 Candlestick.prototype.mapping = function () {
44038 var records = _super.prototype.mapping.call(this);
44039 var props = this.props;
44040 var coord = props.coord;
44041 var y0 = this.getY0Value();
44042 var defaultSize = this.getSize();
44043 var colorAttr = this.getAttr('color');
44044 var colors = colorAttr ? colorAttr.range : COLORS;
44045 for (var i = 0, len = records.length; i < len; i++) {
44046 var record = records[i];
44047 var children = record.children;
44048 for (var j = 0, len_1 = children.length; j < len_1; j++) {
44049 var child = children[j];
44050 var normalized = child.normalized,
44051 mappedSize = child.size;
44052 // 没有指定size,则根据数据来计算默认size
44053 if (isNil(mappedSize)) {
44054 var x = normalized.x,
44055 y = normalized.y,
44056 _a = normalized.size,
44057 size = _a === void 0 ? defaultSize : _a;
44058 mix(child, coord.convertRect({
44059 x: x,
44060 y: y,
44061 y0: y0,
44062 size: size
44063 }));
44064 } else {
44065 var x = child.x,
44066 y = child.y;
44067 var rect = {
44068 x: x,
44069 y: y,
44070 y0: y0,
44071 size: mappedSize
44072 };
44073 mix(child, coord.transformToRect(rect));
44074 }
44075 // 处理颜色
44076 child.color = this._getColor(colors, child, children[j - 1]);
44077 mix(child.shape, this.getSelectionStyle(child));
44078 }
44079 }
44080 return records;
44081 };
44082 Candlestick.prototype.render = function () {
44083 var props = this.props;
44084 var records = this.mapping();
44085 return jsx(View, __assign({}, props, {
44086 records: records
44087 }));
44088 };
44089 return Candlestick;
44090 }(Geometry);
44091 });
44092
44093 var CandlestickView = (function (props) {
44094 var records = props.records,
44095 animation = props.animation,
44096 y0 = props.y0,
44097 onClick = props.onClick;
44098 return jsx("group", null, records.map(function (record) {
44099 var key = record.key,
44100 children = record.children;
44101 return jsx("group", {
44102 key: key
44103 }, children.map(function (item) {
44104 var key = item.key,
44105 xMin = item.xMin,
44106 xMax = item.xMax,
44107 yMin = item.yMin,
44108 yMax = item.yMax,
44109 x = item.x,
44110 y = item.y,
44111 color = item.color,
44112 shape = item.shape;
44113 if (isNaN(xMin) || isNaN(xMax) || isNaN(yMin) || isNaN(yMax)) {
44114 return null;
44115 }
44116 return jsx("group", null, jsx("line", {
44117 key: "".concat(key, "-line"),
44118 style: {
44119 x1: x,
44120 y1: y[2],
44121 x2: x,
44122 y2: y[3],
44123 stroke: color,
44124 lineWidth: '2px',
44125 lineCap: 'round'
44126 },
44127 animation: {
44128 appear: {
44129 easing: 'linear',
44130 duration: 300,
44131 property: ['y1', 'y2'],
44132 // @ts-ignore
44133 start: {
44134 y1: 0,
44135 y2: 0
44136 }
44137 },
44138 update: {
44139 easing: 'linear',
44140 duration: 300,
44141 property: ['x1', 'y1', 'x2', 'y2']
44142 }
44143 }
44144 }), jsx("rect", {
44145 key: "".concat(key, "-rect"),
44146 style: __assign({
44147 x: xMin,
44148 y: yMin,
44149 // 当 min === max 时,设置 1,否则会出现 0 的情况
44150 width: Math.max(xMax - xMin, 1),
44151 height: Math.max(yMax - yMin, 1),
44152 fill: color,
44153 radius: '2px'
44154 }, shape),
44155 onClick: onClick,
44156 animation: deepMix({
44157 appear: {
44158 easing: 'linear',
44159 duration: 300,
44160 property: ['y', 'height'],
44161 start: {
44162 y: y0,
44163 height: 0
44164 }
44165 },
44166 update: {
44167 easing: 'linear',
44168 duration: 300,
44169 property: ['x', 'y', 'width', 'height']
44170 }
44171 }, animation)
44172 }));
44173 }));
44174 }));
44175 });
44176
44177 var index$d = withCandlestick(CandlestickView);
44178
44179 var Pictorial = /** @class */function (_super) {
44180 __extends(Pictorial, _super);
44181 function Pictorial() {
44182 return _super !== null && _super.apply(this, arguments) || this;
44183 }
44184 Pictorial.prototype.render = function () {
44185 var _a = this,
44186 props = _a.props,
44187 context = _a.context;
44188 var px2hd = context.px2hd;
44189 var _Symbol = px2hd(props).symbol;
44190 var records = this.mapping();
44191 return jsx("group", null, records.map(function (record) {
44192 var key = record.key,
44193 children = record.children;
44194 return jsx("group", {
44195 key: key
44196 }, children.map(function (item) {
44197 var xMax = item.xMax,
44198 xMin = item.xMin,
44199 yMax = item.yMax,
44200 yMin = item.yMin;
44201 return jsx(_Symbol, __assign({}, item, {
44202 width: xMax - xMin,
44203 height: yMax - yMin,
44204 px2hd: px2hd
44205 }));
44206 }));
44207 }));
44208 };
44209 return Pictorial;
44210 }(withInterval({}));
44211
44212 // 把 FEngine 全部透出
44213 //@ts-ignore
44214 var index$e = {
44215 version: "\"5.5.2\""
44216 };
44217
44218 exports.ArcGuide = ArcGuide;
44219 exports.Area = index$1;
44220 exports.AreaView = AreaView;
44221 exports.Axis = index$4;
44222 exports.AxisView = AxisView;
44223 exports.Candlestick = index$d;
44224 exports.CandlestickView = CandlestickView;
44225 exports.Canvas = Canvas$1;
44226 exports.CanvasRenderer = Renderer;
44227 exports.Chart = Chart;
44228 exports.Children = Children;
44229 exports.Component = Component;
44230 exports.Fragment = fragment;
44231 exports.Gauge = index$b;
44232 exports.GaugeView = GaugeView;
44233 exports.Geometry = Geometry;
44234 exports.Gesture = Gesture;
44235 exports.Guide = index$6;
44236 exports.ImageGuide = ImageGuide;
44237 exports.Interval = index$2;
44238 exports.IntervalView = intervalView;
44239 exports.Legend = index$5;
44240 exports.LegendView = LegendView;
44241 exports.Line = index;
44242 exports.LineGuide = LineGuide;
44243 exports.LineView = LineView;
44244 exports.LottieGuide = LottieGuide;
44245 exports.Pictorial = Pictorial;
44246 exports.PieLabel = index$a;
44247 exports.PieLabelView = PieLabelView;
44248 exports.Player = Player;
44249 exports.Point = index$3;
44250 exports.PointGuide = PointGuide;
44251 exports.PointView = PointView;
44252 exports.PolylineGuide = PolylineGuide;
44253 exports.RectGuide = RectGuide;
44254 exports.Scale = Scale;
44255 exports.ScrollBar = index$c;
44256 exports.ScrollBarView = ScrollBarView;
44257 exports.Smooth = smooth;
44258 exports.Sunburst = index$9;
44259 exports.SunburstView = SunburstView;
44260 exports.TagGuide = TagGuide;
44261 exports.TextGuide = TextGuide;
44262 exports.Timeline = Timeline;
44263 exports.Tooltip = index$7;
44264 exports.TooltipView = TooltipView;
44265 exports.Treemap = index$8;
44266 exports.TreemapView = TreemapView;
44267 exports.Zoom = withZoom;
44268 exports.computeLayout = computeLayout$1;
44269 exports.createContext = createContext;
44270 exports.createElement = jsx;
44271 exports.createRef = createRef;
44272 exports.default = index$e;
44273 exports.isEqual = equal;
44274 exports.jsx = jsx;
44275 exports.parseColor = parseColor;
44276 exports.registerTag = registerTag;
44277 exports.withArea = withArea;
44278 exports.withAxis = withAxis;
44279 exports.withCandlestick = withCandlestick;
44280 exports.withGauge = withGauge;
44281 exports.withGuide = withGuide;
44282 exports.withInterval = withInterval;
44283 exports.withLegend = withLegend;
44284 exports.withLine = withLine;
44285 exports.withPieLabel = withPieLabel;
44286 exports.withPoint = withPoint;
44287 exports.withScrollBar = withScrollBar;
44288 exports.withSunburst = withSunburst;
44289 exports.withTooltip = withTooltip;
44290 exports.withTreemap = withTreemap;
44291
44292 Object.defineProperty(exports, '__esModule', { value: true });
44293
44294})));