html2canvas-pro 2.5.1 → 2.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -1
- package/dist/html2canvas-pro.cjs +1835 -1470
- package/dist/html2canvas-pro.cjs.map +1 -1
- package/dist/html2canvas-pro.esm.js +1835 -1470
- package/dist/html2canvas-pro.esm.js.map +1 -1
- package/dist/html2canvas-pro.js +1839 -1471
- package/dist/html2canvas-pro.js.map +1 -1
- package/dist/html2canvas-pro.min.js +6 -5
- package/dist/types/core/cache-storage.d.ts +6 -2
- package/dist/types/core/constants.d.ts +11 -0
- package/dist/types/core/context.d.ts +9 -1
- package/dist/types/core/features.d.ts +9 -5
- package/dist/types/core/origin-checker.d.ts +7 -4
- package/dist/types/core/validator.d.ts +0 -2
- package/dist/types/css/grouped/background-styles.d.ts +4 -0
- package/dist/types/css/grouped/border-styles.d.ts +4 -0
- package/dist/types/css/grouped/font-styles.d.ts +4 -0
- package/dist/types/css/grouped/layout-styles.d.ts +4 -0
- package/dist/types/css/index.d.ts +4 -0
- package/dist/types/css/property-descriptor.d.ts +11 -3
- package/dist/types/css/property-descriptors/scale.d.ts +9 -0
- package/dist/types/css/property-descriptors/translate.d.ts +10 -0
- package/dist/types/css/syntax/tokenizer.d.ts +8 -0
- package/dist/types/css/types/color-utilities.d.ts +21 -0
- package/dist/types/css/types/functions/color-mix.d.ts +17 -0
- package/dist/types/dom/adopted-styles.d.ts +23 -0
- package/dist/types/dom/document-cloner.d.ts +12 -0
- package/dist/types/dom/dom-normalizer.d.ts +2 -0
- package/dist/types/dom/elements/li-element-container.d.ts +2 -2
- package/dist/types/dom/elements/ol-element-container.d.ts +2 -2
- package/dist/types/dom/elements/select-element-container.d.ts +2 -2
- package/dist/types/dom/elements/textarea-element-container.d.ts +2 -2
- package/dist/types/dom/iframe-mount.d.ts +17 -0
- package/dist/types/dom/node-parser.d.ts +2 -2
- package/dist/types/dom/replaced-elements/canvas-element-container.d.ts +2 -2
- package/dist/types/dom/replaced-elements/iframe-element-container.d.ts +2 -2
- package/dist/types/dom/replaced-elements/image-element-container.d.ts +2 -2
- package/dist/types/dom/replaced-elements/input-element-container.d.ts +2 -2
- package/dist/types/dom/replaced-elements/svg-element-container.d.ts +2 -2
- package/dist/types/dom/slot-cloner.d.ts +10 -0
- package/dist/types/options.d.ts +24 -0
- package/dist/types/render/canvas/border-image-renderer.d.ts +7 -0
- package/dist/types/render/canvas/canvas-renderer.d.ts +2 -3
- package/dist/types/render/canvas/filter-surface.d.ts +37 -11
- package/dist/types/render/canvas/gradient-rasterizer.d.ts +53 -0
- package/dist/types/render/canvas/mask-renderer.d.ts +5 -2
- package/dist/types/render/canvas/text-clip-renderer.d.ts +0 -1
- package/dist/types/render/canvas/text-renderer.d.ts +1 -0
- package/package.json +9 -31
- package/dist/types/render/font-metrics.d.ts +0 -11
- package/dist/types/render/renderer-interface.d.ts +0 -28
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* html2canvas-pro 2.5.
|
|
2
|
+
* html2canvas-pro 2.5.2 <https://yorickshan.github.io/html2canvas-pro/>
|
|
3
3
|
* Copyright (c) 2024-present yorickshan and html2canvas-pro contributors
|
|
4
4
|
* Released under MIT License
|
|
5
5
|
*/
|
|
@@ -11,6 +11,9 @@
|
|
|
11
11
|
* Eliminates the need for global static variables.
|
|
12
12
|
*/
|
|
13
13
|
var Html2CanvasConfig = class Html2CanvasConfig {
|
|
14
|
+
window;
|
|
15
|
+
cspNonce;
|
|
16
|
+
cache;
|
|
14
17
|
constructor(options = {}) {
|
|
15
18
|
const resolvedWindow = options.window || (typeof window !== "undefined" ? window : void 0);
|
|
16
19
|
if (!resolvedWindow) throw new Error("Window object is required but not available");
|
|
@@ -51,6 +54,7 @@ var Html2CanvasConfig = class Html2CanvasConfig {
|
|
|
51
54
|
* Validates and sanitizes user inputs for security and correctness.
|
|
52
55
|
*/
|
|
53
56
|
var Validator = class {
|
|
57
|
+
config;
|
|
54
58
|
constructor(config = {}) {
|
|
55
59
|
this.config = {
|
|
56
60
|
maxImageTimeout: 3e5,
|
|
@@ -118,8 +122,7 @@ var Validator = class {
|
|
|
118
122
|
}
|
|
119
123
|
return {
|
|
120
124
|
valid: true,
|
|
121
|
-
sanitized: url
|
|
122
|
-
requiresRuntimeCheck: true
|
|
125
|
+
sanitized: url
|
|
123
126
|
};
|
|
124
127
|
}
|
|
125
128
|
return {
|
|
@@ -424,10 +427,13 @@ function createDefaultValidator(config = {}) {
|
|
|
424
427
|
* ```
|
|
425
428
|
*/
|
|
426
429
|
var PerformanceMonitor = class {
|
|
430
|
+
context;
|
|
431
|
+
activeMetrics = /* @__PURE__ */ new Map();
|
|
432
|
+
completedMetrics = [];
|
|
433
|
+
enabled;
|
|
434
|
+
getTime;
|
|
427
435
|
constructor(context, enabled = true) {
|
|
428
436
|
this.context = context;
|
|
429
|
-
this.activeMetrics = /* @__PURE__ */ new Map();
|
|
430
|
-
this.completedMetrics = [];
|
|
431
437
|
this.enabled = enabled;
|
|
432
438
|
this.getTime = typeof performance !== "undefined" && typeof performance.now === "function" ? () => performance.now() : () => Date.now();
|
|
433
439
|
}
|
|
@@ -574,6 +580,10 @@ var PerformanceMonitor = class {
|
|
|
574
580
|
//#endregion
|
|
575
581
|
//#region src/css/layout/bounds.ts
|
|
576
582
|
var Bounds = class Bounds {
|
|
583
|
+
left;
|
|
584
|
+
top;
|
|
585
|
+
width;
|
|
586
|
+
height;
|
|
577
587
|
constructor(left, top, width, height) {
|
|
578
588
|
this.left = left;
|
|
579
589
|
this.top = top;
|
|
@@ -593,9 +603,7 @@ var Bounds = class Bounds {
|
|
|
593
603
|
if (!domRect && rects.length > 0) domRect = rects[0];
|
|
594
604
|
return domRect ? new Bounds(domRect.left + context.windowBounds.left, domRect.top + context.windowBounds.top, domRect.width, domRect.height) : Bounds.EMPTY;
|
|
595
605
|
}
|
|
596
|
-
static
|
|
597
|
-
this.EMPTY = new Bounds(0, 0, 0, 0);
|
|
598
|
-
}
|
|
606
|
+
static EMPTY = new Bounds(0, 0, 0, 0);
|
|
599
607
|
};
|
|
600
608
|
const parseBounds = (context, node) => {
|
|
601
609
|
return Bounds.fromClientRect(context, node.getBoundingClientRect());
|
|
@@ -607,522 +615,6 @@ const parseDocumentSize = (document) => {
|
|
|
607
615
|
return new Bounds(0, 0, Math.max(Math.max(body.scrollWidth, documentElement.scrollWidth), Math.max(body.offsetWidth, documentElement.offsetWidth), Math.max(body.clientWidth, documentElement.clientWidth)), Math.max(Math.max(body.scrollHeight, documentElement.scrollHeight), Math.max(body.offsetHeight, documentElement.offsetHeight), Math.max(body.clientHeight, documentElement.clientHeight)));
|
|
608
616
|
};
|
|
609
617
|
//#endregion
|
|
610
|
-
//#region node_modules/.pnpm/css-line-break@2.1.0/node_modules/css-line-break/dist/css-line-break.es5.js
|
|
611
|
-
var toCodePoints$1 = function(str) {
|
|
612
|
-
var codePoints = [];
|
|
613
|
-
var i = 0;
|
|
614
|
-
var length = str.length;
|
|
615
|
-
while (i < length) {
|
|
616
|
-
var value = str.charCodeAt(i++);
|
|
617
|
-
if (value >= 55296 && value <= 56319 && i < length) {
|
|
618
|
-
var extra = str.charCodeAt(i++);
|
|
619
|
-
if ((extra & 64512) === 56320) codePoints.push(((value & 1023) << 10) + (extra & 1023) + 65536);
|
|
620
|
-
else {
|
|
621
|
-
codePoints.push(value);
|
|
622
|
-
i--;
|
|
623
|
-
}
|
|
624
|
-
} else codePoints.push(value);
|
|
625
|
-
}
|
|
626
|
-
return codePoints;
|
|
627
|
-
};
|
|
628
|
-
var fromCodePoint$1 = function() {
|
|
629
|
-
var codePoints = [];
|
|
630
|
-
for (var _i = 0; _i < arguments.length; _i++) codePoints[_i] = arguments[_i];
|
|
631
|
-
if (String.fromCodePoint) return String.fromCodePoint.apply(String, codePoints);
|
|
632
|
-
var length = codePoints.length;
|
|
633
|
-
if (!length) return "";
|
|
634
|
-
var codeUnits = [];
|
|
635
|
-
var index = -1;
|
|
636
|
-
var result = "";
|
|
637
|
-
while (++index < length) {
|
|
638
|
-
var codePoint = codePoints[index];
|
|
639
|
-
if (codePoint <= 65535) codeUnits.push(codePoint);
|
|
640
|
-
else {
|
|
641
|
-
codePoint -= 65536;
|
|
642
|
-
codeUnits.push((codePoint >> 10) + 55296, codePoint % 1024 + 56320);
|
|
643
|
-
}
|
|
644
|
-
if (index + 1 === length || codeUnits.length > 16384) {
|
|
645
|
-
result += String.fromCharCode.apply(String, codeUnits);
|
|
646
|
-
codeUnits.length = 0;
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
return result;
|
|
650
|
-
};
|
|
651
|
-
var chars$2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
652
|
-
var lookup$2 = typeof Uint8Array === "undefined" ? [] : /* @__PURE__ */ new Uint8Array(256);
|
|
653
|
-
for (var i$2 = 0; i$2 < chars$2.length; i$2++) lookup$2[chars$2.charCodeAt(i$2)] = i$2;
|
|
654
|
-
var chars$1$1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
655
|
-
var lookup$1$1 = typeof Uint8Array === "undefined" ? [] : /* @__PURE__ */ new Uint8Array(256);
|
|
656
|
-
for (var i$1$1 = 0; i$1$1 < chars$1$1.length; i$1$1++) lookup$1$1[chars$1$1.charCodeAt(i$1$1)] = i$1$1;
|
|
657
|
-
var decode$1 = function(base64) {
|
|
658
|
-
var bufferLength = base64.length * .75, len = base64.length, i, p = 0, encoded1, encoded2, encoded3, encoded4;
|
|
659
|
-
if (base64[base64.length - 1] === "=") {
|
|
660
|
-
bufferLength--;
|
|
661
|
-
if (base64[base64.length - 2] === "=") bufferLength--;
|
|
662
|
-
}
|
|
663
|
-
var buffer = typeof ArrayBuffer !== "undefined" && typeof Uint8Array !== "undefined" && typeof Uint8Array.prototype.slice !== "undefined" ? new ArrayBuffer(bufferLength) : new Array(bufferLength);
|
|
664
|
-
var bytes = Array.isArray(buffer) ? buffer : new Uint8Array(buffer);
|
|
665
|
-
for (i = 0; i < len; i += 4) {
|
|
666
|
-
encoded1 = lookup$1$1[base64.charCodeAt(i)];
|
|
667
|
-
encoded2 = lookup$1$1[base64.charCodeAt(i + 1)];
|
|
668
|
-
encoded3 = lookup$1$1[base64.charCodeAt(i + 2)];
|
|
669
|
-
encoded4 = lookup$1$1[base64.charCodeAt(i + 3)];
|
|
670
|
-
bytes[p++] = encoded1 << 2 | encoded2 >> 4;
|
|
671
|
-
bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2;
|
|
672
|
-
bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63;
|
|
673
|
-
}
|
|
674
|
-
return buffer;
|
|
675
|
-
};
|
|
676
|
-
var polyUint16Array$1 = function(buffer) {
|
|
677
|
-
var length = buffer.length;
|
|
678
|
-
var bytes = [];
|
|
679
|
-
for (var i = 0; i < length; i += 2) bytes.push(buffer[i + 1] << 8 | buffer[i]);
|
|
680
|
-
return bytes;
|
|
681
|
-
};
|
|
682
|
-
var polyUint32Array$1 = function(buffer) {
|
|
683
|
-
var length = buffer.length;
|
|
684
|
-
var bytes = [];
|
|
685
|
-
for (var i = 0; i < length; i += 4) bytes.push(buffer[i + 3] << 24 | buffer[i + 2] << 16 | buffer[i + 1] << 8 | buffer[i]);
|
|
686
|
-
return bytes;
|
|
687
|
-
};
|
|
688
|
-
/** Shift size for getting the index-2 table offset. */
|
|
689
|
-
var UTRIE2_SHIFT_2$1 = 5;
|
|
690
|
-
/** Shift size for getting the index-1 table offset. */
|
|
691
|
-
var UTRIE2_SHIFT_1$1 = 11;
|
|
692
|
-
/**
|
|
693
|
-
* Shift size for shifting left the index array values.
|
|
694
|
-
* Increases possible data size with 16-bit index values at the cost
|
|
695
|
-
* of compactability.
|
|
696
|
-
* This requires data blocks to be aligned by UTRIE2_DATA_GRANULARITY.
|
|
697
|
-
*/
|
|
698
|
-
var UTRIE2_INDEX_SHIFT$1 = 2;
|
|
699
|
-
/**
|
|
700
|
-
* Difference between the two shift sizes,
|
|
701
|
-
* for getting an index-1 offset from an index-2 offset. 6=11-5
|
|
702
|
-
*/
|
|
703
|
-
var UTRIE2_SHIFT_1_2$1 = UTRIE2_SHIFT_1$1 - UTRIE2_SHIFT_2$1;
|
|
704
|
-
/**
|
|
705
|
-
* The part of the index-2 table for U+D800..U+DBFF stores values for
|
|
706
|
-
* lead surrogate code _units_ not code _points_.
|
|
707
|
-
* Values for lead surrogate code _points_ are indexed with this portion of the table.
|
|
708
|
-
* Length=32=0x20=0x400>>UTRIE2_SHIFT_2. (There are 1024=0x400 lead surrogates.)
|
|
709
|
-
*/
|
|
710
|
-
var UTRIE2_LSCP_INDEX_2_OFFSET$1 = 65536 >> UTRIE2_SHIFT_2$1;
|
|
711
|
-
/** Mask for getting the lower bits for the in-data-block offset. */
|
|
712
|
-
var UTRIE2_DATA_MASK$1 = (1 << UTRIE2_SHIFT_2$1) - 1;
|
|
713
|
-
/**
|
|
714
|
-
* The index-1 table, only used for supplementary code points, at offset 2112=0x840.
|
|
715
|
-
* Variable length, for code points up to highStart, where the last single-value range starts.
|
|
716
|
-
* Maximum length 512=0x200=0x100000>>UTRIE2_SHIFT_1.
|
|
717
|
-
* (For 0x100000 supplementary code points U+10000..U+10ffff.)
|
|
718
|
-
*
|
|
719
|
-
* The part of the index-2 table for supplementary code points starts
|
|
720
|
-
* after this index-1 table.
|
|
721
|
-
*
|
|
722
|
-
* Both the index-1 table and the following part of the index-2 table
|
|
723
|
-
* are omitted completely if there is only BMP data.
|
|
724
|
-
*/
|
|
725
|
-
var UTRIE2_INDEX_1_OFFSET$1 = UTRIE2_LSCP_INDEX_2_OFFSET$1 + (1024 >> UTRIE2_SHIFT_2$1) + 32;
|
|
726
|
-
/**
|
|
727
|
-
* Number of index-1 entries for the BMP. 32=0x20
|
|
728
|
-
* This part of the index-1 table is omitted from the serialized form.
|
|
729
|
-
*/
|
|
730
|
-
var UTRIE2_OMITTED_BMP_INDEX_1_LENGTH$1 = 65536 >> UTRIE2_SHIFT_1$1;
|
|
731
|
-
/** Mask for getting the lower bits for the in-index-2-block offset. */
|
|
732
|
-
var UTRIE2_INDEX_2_MASK$1 = (1 << UTRIE2_SHIFT_1_2$1) - 1;
|
|
733
|
-
var slice16$1 = function(view, start, end) {
|
|
734
|
-
if (view.slice) return view.slice(start, end);
|
|
735
|
-
return new Uint16Array(Array.prototype.slice.call(view, start, end));
|
|
736
|
-
};
|
|
737
|
-
var slice32$1 = function(view, start, end) {
|
|
738
|
-
if (view.slice) return view.slice(start, end);
|
|
739
|
-
return new Uint32Array(Array.prototype.slice.call(view, start, end));
|
|
740
|
-
};
|
|
741
|
-
var createTrieFromBase64$1 = function(base64, _byteLength) {
|
|
742
|
-
var buffer = decode$1(base64);
|
|
743
|
-
var view32 = Array.isArray(buffer) ? polyUint32Array$1(buffer) : new Uint32Array(buffer);
|
|
744
|
-
var view16 = Array.isArray(buffer) ? polyUint16Array$1(buffer) : new Uint16Array(buffer);
|
|
745
|
-
var headerLength = 24;
|
|
746
|
-
var index = slice16$1(view16, headerLength / 2, view32[4] / 2);
|
|
747
|
-
var data = view32[5] === 2 ? slice16$1(view16, (headerLength + view32[4]) / 2) : slice32$1(view32, Math.ceil((headerLength + view32[4]) / 4));
|
|
748
|
-
return new Trie$1(view32[0], view32[1], view32[2], view32[3], index, data);
|
|
749
|
-
};
|
|
750
|
-
var Trie$1 = function() {
|
|
751
|
-
function Trie(initialValue, errorValue, highStart, highValueIndex, index, data) {
|
|
752
|
-
this.initialValue = initialValue;
|
|
753
|
-
this.errorValue = errorValue;
|
|
754
|
-
this.highStart = highStart;
|
|
755
|
-
this.highValueIndex = highValueIndex;
|
|
756
|
-
this.index = index;
|
|
757
|
-
this.data = data;
|
|
758
|
-
}
|
|
759
|
-
/**
|
|
760
|
-
* Get the value for a code point as stored in the Trie.
|
|
761
|
-
*
|
|
762
|
-
* @param codePoint the code point
|
|
763
|
-
* @return the value
|
|
764
|
-
*/
|
|
765
|
-
Trie.prototype.get = function(codePoint) {
|
|
766
|
-
var ix;
|
|
767
|
-
if (codePoint >= 0) {
|
|
768
|
-
if (codePoint < 55296 || codePoint > 56319 && codePoint <= 65535) {
|
|
769
|
-
ix = this.index[codePoint >> UTRIE2_SHIFT_2$1];
|
|
770
|
-
ix = (ix << UTRIE2_INDEX_SHIFT$1) + (codePoint & UTRIE2_DATA_MASK$1);
|
|
771
|
-
return this.data[ix];
|
|
772
|
-
}
|
|
773
|
-
if (codePoint <= 65535) {
|
|
774
|
-
ix = this.index[UTRIE2_LSCP_INDEX_2_OFFSET$1 + (codePoint - 55296 >> UTRIE2_SHIFT_2$1)];
|
|
775
|
-
ix = (ix << UTRIE2_INDEX_SHIFT$1) + (codePoint & UTRIE2_DATA_MASK$1);
|
|
776
|
-
return this.data[ix];
|
|
777
|
-
}
|
|
778
|
-
if (codePoint < this.highStart) {
|
|
779
|
-
ix = UTRIE2_INDEX_1_OFFSET$1 - UTRIE2_OMITTED_BMP_INDEX_1_LENGTH$1 + (codePoint >> UTRIE2_SHIFT_1$1);
|
|
780
|
-
ix = this.index[ix];
|
|
781
|
-
ix += codePoint >> UTRIE2_SHIFT_2$1 & UTRIE2_INDEX_2_MASK$1;
|
|
782
|
-
ix = this.index[ix];
|
|
783
|
-
ix = (ix << UTRIE2_INDEX_SHIFT$1) + (codePoint & UTRIE2_DATA_MASK$1);
|
|
784
|
-
return this.data[ix];
|
|
785
|
-
}
|
|
786
|
-
if (codePoint <= 1114111) return this.data[this.highValueIndex];
|
|
787
|
-
}
|
|
788
|
-
return this.errorValue;
|
|
789
|
-
};
|
|
790
|
-
return Trie;
|
|
791
|
-
}();
|
|
792
|
-
var chars$3 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
793
|
-
var lookup$3 = typeof Uint8Array === "undefined" ? [] : /* @__PURE__ */ new Uint8Array(256);
|
|
794
|
-
for (var i$3 = 0; i$3 < chars$3.length; i$3++) lookup$3[chars$3.charCodeAt(i$3)] = i$3;
|
|
795
|
-
var base64$1 = "KwAAAAAAAAAACA4AUD0AADAgAAACAAAAAAAIABAAGABAAEgAUABYAGAAaABgAGgAYgBqAF8AZwBgAGgAcQB5AHUAfQCFAI0AlQCdAKIAqgCyALoAYABoAGAAaABgAGgAwgDKAGAAaADGAM4A0wDbAOEA6QDxAPkAAQEJAQ8BFwF1AH0AHAEkASwBNAE6AUIBQQFJAVEBWQFhAWgBcAF4ATAAgAGGAY4BlQGXAZ8BpwGvAbUBvQHFAc0B0wHbAeMB6wHxAfkBAQIJAvEBEQIZAiECKQIxAjgCQAJGAk4CVgJeAmQCbAJ0AnwCgQKJApECmQKgAqgCsAK4ArwCxAIwAMwC0wLbAjAA4wLrAvMC+AIAAwcDDwMwABcDHQMlAy0DNQN1AD0DQQNJA0kDSQNRA1EDVwNZA1kDdQB1AGEDdQBpA20DdQN1AHsDdQCBA4kDkQN1AHUAmQOhA3UAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AKYDrgN1AHUAtgO+A8YDzgPWAxcD3gPjA+sD8wN1AHUA+wMDBAkEdQANBBUEHQQlBCoEFwMyBDgEYABABBcDSARQBFgEYARoBDAAcAQzAXgEgASIBJAEdQCXBHUAnwSnBK4EtgS6BMIEyAR1AHUAdQB1AHUAdQCVANAEYABgAGAAYABgAGAAYABgANgEYADcBOQEYADsBPQE/AQEBQwFFAUcBSQFLAU0BWQEPAVEBUsFUwVbBWAAYgVgAGoFcgV6BYIFigWRBWAAmQWfBaYFYABgAGAAYABgAKoFYACxBbAFuQW6BcEFwQXHBcEFwQXPBdMF2wXjBeoF8gX6BQIGCgYSBhoGIgYqBjIGOgZgAD4GRgZMBmAAUwZaBmAAYABgAGAAYABgAGAAYABgAGAAYABgAGIGYABpBnAGYABgAGAAYABgAGAAYABgAGAAYAB4Bn8GhQZgAGAAYAB1AHcDFQSLBmAAYABgAJMGdQA9A3UAmwajBqsGqwaVALMGuwbDBjAAywbSBtIG1QbSBtIG0gbSBtIG0gbdBuMG6wbzBvsGAwcLBxMHAwcbByMHJwcsBywHMQcsB9IGOAdAB0gHTgfSBkgHVgfSBtIG0gbSBtIG0gbSBtIG0gbSBiwHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAdgAGAALAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAdbB2MHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsB2kH0gZwB64EdQB1AHUAdQB1AHUAdQB1AHUHfQdgAIUHjQd1AHUAlQedB2AAYAClB6sHYACzB7YHvgfGB3UAzgfWBzMB3gfmB1EB7gf1B/0HlQENAQUIDQh1ABUIHQglCBcDLQg1CD0IRQhNCEEDUwh1AHUAdQBbCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIaQhjCGQIZQhmCGcIaAhpCGMIZAhlCGYIZwhoCGkIYwhkCGUIZghnCGgIcAh3CHoIMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwAIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIgggwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAALAcsBywHLAcsBywHLAcsBywHLAcsB4oILAcsB44I0gaWCJ4Ipgh1AHUAqgiyCHUAdQB1AHUAdQB1AHUAdQB1AHUAtwh8AXUAvwh1AMUIyQjRCNkI4AjoCHUAdQB1AO4I9gj+CAYJDgkTCS0HGwkjCYIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiCCIIIggiAAIAAAAFAAYABgAGIAXwBgAHEAdQBFAJUAogCyAKAAYABgAEIA4ABGANMA4QDxAMEBDwE1AFwBLAE6AQEBUQF4QkhCmEKoQrhCgAHIQsAB0MLAAcABwAHAAeDC6ABoAHDCwMMAAcABwAHAAdDDGMMAAcAB6MM4wwjDWMNow3jDaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAEjDqABWw6bDqABpg6gAaABoAHcDvwOPA+gAaABfA/8DvwO/A78DvwO/A78DvwO/A78DvwO/A78DvwO/A78DvwO/A78DvwO/A78DvwO/A78DvwO/A78DpcPAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcAB9cPKwkyCToJMAB1AHUAdQBCCUoJTQl1AFUJXAljCWcJawkwADAAMAAwAHMJdQB2CX4JdQCECYoJjgmWCXUAngkwAGAAYABxAHUApgn3A64JtAl1ALkJdQDACTAAMAAwADAAdQB1AHUAdQB1AHUAdQB1AHUAowYNBMUIMAAwADAAMADICcsJ0wnZCRUE4QkwAOkJ8An4CTAAMAB1AAAKvwh1AAgKDwoXCh8KdQAwACcKLgp1ADYKqAmICT4KRgowADAAdQB1AE4KMAB1AFYKdQBeCnUAZQowADAAMAAwADAAMAAwADAAMAAVBHUAbQowADAAdQC5CXUKMAAwAHwBxAijBogEMgF9CoQKiASMCpQKmgqIBKIKqgquCogEDQG2Cr4KxgrLCjAAMADTCtsKCgHjCusK8Qr5CgELMAAwADAAMAB1AIsECQsRC3UANAEZCzAAMAAwADAAMAB1ACELKQswAHUANAExCzkLdQBBC0kLMABRC1kLMAAwADAAMAAwADAAdQBhCzAAMAAwAGAAYABpC3ELdwt/CzAAMACHC4sLkwubC58Lpwt1AK4Ltgt1APsDMAAwADAAMAAwADAAMAAwAL4LwwvLC9IL1wvdCzAAMADlC+kL8Qv5C/8LSQswADAAMAAwADAAMAAwADAAMAAHDDAAMAAwADAAMAAODBYMHgx1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1ACYMMAAwADAAdQB1AHUALgx1AHUAdQB1AHUAdQA2DDAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwAHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AD4MdQBGDHUAdQB1AHUAdQB1AEkMdQB1AHUAdQB1AFAMMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwAHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQBYDHUAdQB1AF8MMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUA+wMVBGcMMAAwAHwBbwx1AHcMfwyHDI8MMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAYABgAJcMMAAwADAAdQB1AJ8MlQClDDAAMACtDCwHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsB7UMLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHdQB1AHUAdQB1AHUAdQB1AHUAdQB1AHUAdQB1AA0EMAC9DDAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAsBywHLAcsBywHLAcsBywHLQcwAMEMyAwsBywHLAcsBywHLAcsBywHLAcsBywHzAwwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwAHUAdQB1ANQM2QzhDDAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMABgAGAAYABgAGAAYABgAOkMYADxDGAA+AwADQYNYABhCWAAYAAODTAAMAAwADAAFg1gAGAAHg37AzAAMAAwADAAYABgACYNYAAsDTQNPA1gAEMNPg1LDWAAYABgAGAAYABgAGAAYABgAGAAUg1aDYsGVglhDV0NcQBnDW0NdQ15DWAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAlQCBDZUAiA2PDZcNMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAnw2nDTAAMAAwADAAMAAwAHUArw23DTAAMAAwADAAMAAwADAAMAAwADAAMAB1AL8NMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAB1AHUAdQB1AHUAdQDHDTAAYABgAM8NMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAA1w11ANwNMAAwAD0B5A0wADAAMAAwADAAMADsDfQN/A0EDgwOFA4wABsOMAAwADAAMAAwADAAMAAwANIG0gbSBtIG0gbSBtIG0gYjDigOwQUuDsEFMw7SBjoO0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIGQg5KDlIOVg7SBtIGXg5lDm0OdQ7SBtIGfQ6EDooOjQ6UDtIGmg6hDtIG0gaoDqwO0ga0DrwO0gZgAGAAYADEDmAAYAAkBtIGzA5gANIOYADaDokO0gbSBt8O5w7SBu8O0gb1DvwO0gZgAGAAxA7SBtIG0gbSBtIGYABgAGAAYAAED2AAsAUMD9IG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIGFA8sBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAccD9IGLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHJA8sBywHLAcsBywHLAccDywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywPLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAc0D9IG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIGLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAccD9IG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIGFA8sBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHLAcsBywHPA/SBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gbSBtIG0gYUD0QPlQCVAJUAMAAwADAAMACVAJUAlQCVAJUAlQCVAEwPMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAA//8EAAQABAAEAAQABAAEAAQABAANAAMAAQABAAIABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQACgATABcAHgAbABoAHgAXABYAEgAeABsAGAAPABgAHABLAEsASwBLAEsASwBLAEsASwBLABgAGAAeAB4AHgATAB4AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQABYAGwASAB4AHgAeAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAWAA0AEQAeAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAAQABAAEAAQABAAFAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAJABYAGgAbABsAGwAeAB0AHQAeAE8AFwAeAA0AHgAeABoAGwBPAE8ADgBQAB0AHQAdAE8ATwAXAE8ATwBPABYAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAFAAUABQAFAAUABQAFAAUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAFAAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAeAB4AHgAeAFAATwBAAE8ATwBPAEAATwBQAFAATwBQAB4AHgAeAB4AHgAeAB0AHQAdAB0AHgAdAB4ADgBQAFAAUABQAFAAHgAeAB4AHgAeAB4AHgBQAB4AUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4ABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAJAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAkACQAJAAkACQAJAAkABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAeAB4AHgAeAFAAHgAeAB4AKwArAFAAUABQAFAAGABQACsAKwArACsAHgAeAFAAHgBQAFAAUAArAFAAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4ABAAEAAQABAAEAAQABAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAUAAeAB4AHgAeAB4AHgBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAYAA0AKwArAB4AHgAbACsABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQADQAEAB4ABAAEAB4ABAAEABMABAArACsAKwArACsAKwArACsAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAKwArACsAKwBWAFYAVgBWAB4AHgArACsAKwArACsAKwArACsAKwArACsAHgAeAB4AHgAeAB4AHgAeAB4AGgAaABoAGAAYAB4AHgAEAAQABAAEAAQABAAEAAQABAAEAAQAEwAEACsAEwATAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABABLAEsASwBLAEsASwBLAEsASwBLABoAGQAZAB4AUABQAAQAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQABMAUAAEAAQABAAEAAQABAAEAB4AHgAEAAQABAAEAAQABABQAFAABAAEAB4ABAAEAAQABABQAFAASwBLAEsASwBLAEsASwBLAEsASwBQAFAAUAAeAB4AUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwAeAFAABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQABAAEAFAAKwArACsAKwArACsAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQAUABQAB4AHgAYABMAUAArACsABAAbABsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAFAABAAEAAQABAAEAFAABAAEAAQAUAAEAAQABAAEAAQAKwArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAArACsAHgArAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAB4ABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAFAABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAUAAEAAQABAAEAAQABAAEAFAAUABQAFAAUABQAFAAUABQAFAABAAEAA0ADQBLAEsASwBLAEsASwBLAEsASwBLAB4AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAArAFAAUABQAFAAUABQAFAAUAArACsAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAUAArACsAKwBQAFAAUABQACsAKwAEAFAABAAEAAQABAAEAAQABAArACsABAAEACsAKwAEAAQABABQACsAKwArACsAKwArACsAKwAEACsAKwArACsAUABQACsAUABQAFAABAAEACsAKwBLAEsASwBLAEsASwBLAEsASwBLAFAAUAAaABoAUABQAFAAUABQAEwAHgAbAFAAHgAEACsAKwAEAAQABAArAFAAUABQAFAAUABQACsAKwArACsAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAUABQACsAUABQACsAUABQACsAKwAEACsABAAEAAQABAAEACsAKwArACsABAAEACsAKwAEAAQABAArACsAKwAEACsAKwArACsAKwArACsAUABQAFAAUAArAFAAKwArACsAKwArACsAKwBLAEsASwBLAEsASwBLAEsASwBLAAQABABQAFAAUAAEAB4AKwArACsAKwArACsAKwArACsAKwAEAAQABAArAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAUABQACsAUABQAFAAUABQACsAKwAEAFAABAAEAAQABAAEAAQABAAEACsABAAEAAQAKwAEAAQABAArACsAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAABAAEACsAKwBLAEsASwBLAEsASwBLAEsASwBLAB4AGwArACsAKwArACsAKwArAFAABAAEAAQABAAEAAQAKwAEAAQABAArAFAAUABQAFAAUABQAFAAUAArACsAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAArACsABAAEACsAKwAEAAQABAArACsAKwArACsAKwArAAQABAAEACsAKwArACsAUABQACsAUABQAFAABAAEACsAKwBLAEsASwBLAEsASwBLAEsASwBLAB4AUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArAAQAUAArAFAAUABQAFAAUABQACsAKwArAFAAUABQACsAUABQAFAAUAArACsAKwBQAFAAKwBQACsAUABQACsAKwArAFAAUAArACsAKwBQAFAAUAArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArAAQABAAEAAQABAArACsAKwAEAAQABAArAAQABAAEAAQAKwArAFAAKwArACsAKwArACsABAArACsAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAUABQAFAAHgAeAB4AHgAeAB4AGwAeACsAKwArACsAKwAEAAQABAAEAAQAUABQAFAAUABQAFAAUABQACsAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAUAAEAAQABAAEAAQABAAEACsABAAEAAQAKwAEAAQABAAEACsAKwArACsAKwArACsABAAEACsAUABQAFAAKwArACsAKwArAFAAUAAEAAQAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAKwAOAFAAUABQAFAAUABQAFAAHgBQAAQABAAEAA4AUABQAFAAUABQAFAAUABQACsAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAKwArAAQAUAAEAAQABAAEAAQABAAEACsABAAEAAQAKwAEAAQABAAEACsAKwArACsAKwArACsABAAEACsAKwArACsAKwArACsAUAArAFAAUAAEAAQAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwBQAFAAKwArACsAKwArACsAKwArACsAKwArACsAKwAEAAQABAAEAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAFAABAAEAAQABAAEAAQABAArAAQABAAEACsABAAEAAQABABQAB4AKwArACsAKwBQAFAAUAAEAFAAUABQAFAAUABQAFAAUABQAFAABAAEACsAKwBLAEsASwBLAEsASwBLAEsASwBLAFAAUABQAFAAUABQAFAAUABQABoAUABQAFAAUABQAFAAKwAEAAQABAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQACsAUAArACsAUABQAFAAUABQAFAAUAArACsAKwAEACsAKwArACsABAAEAAQABAAEAAQAKwAEACsABAAEAAQABAAEAAQABAAEACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArAAQABAAeACsAKwArACsAKwArACsAKwArACsAKwArAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXAAqAFwAXAAqACoAKgAqACoAKgAqACsAKwArACsAGwBcAFwAXABcAFwAXABcACoAKgAqACoAKgAqACoAKgAeAEsASwBLAEsASwBLAEsASwBLAEsADQANACsAKwArACsAKwBcAFwAKwBcACsAXABcAFwAXABcACsAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcACsAXAArAFwAXABcAFwAXABcAFwAXABcAFwAKgBcAFwAKgAqACoAKgAqACoAKgAqACoAXAArACsAXABcAFwAXABcACsAXAArACoAKgAqACoAKgAqACsAKwBLAEsASwBLAEsASwBLAEsASwBLACsAKwBcAFwAXABcAFAADgAOAA4ADgAeAA4ADgAJAA4ADgANAAkAEwATABMAEwATAAkAHgATAB4AHgAeAAQABAAeAB4AHgAeAB4AHgBLAEsASwBLAEsASwBLAEsASwBLAFAAUABQAFAAUABQAFAAUABQAFAADQAEAB4ABAAeAAQAFgARABYAEQAEAAQAUABQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQADQAEAAQABAAEAAQADQAEAAQAUABQAFAAUABQAAQABAAEAAQABAAEAAQABAAEAAQABAArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArAA0ADQAeAB4AHgAeAB4AHgAEAB4AHgAeAB4AHgAeACsAHgAeAA4ADgANAA4AHgAeAB4AHgAeAAkACQArACsAKwArACsAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgBcAEsASwBLAEsASwBLAEsASwBLAEsADQANAB4AHgAeAB4AXABcAFwAXABcAFwAKgAqACoAKgBcAFwAXABcACoAKgAqAFwAKgAqACoAXABcACoAKgAqACoAKgAqACoAXABcAFwAKgAqACoAKgBcAFwAXABcAFwAXABcAFwAXABcAFwAXABcACoAKgAqACoAKgAqACoAKgAqACoAKgAqAFwAKgBLAEsASwBLAEsASwBLAEsASwBLACoAKgAqACoAKgAqAFAAUABQAFAAUABQACsAUAArACsAKwArACsAUAArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAHgBQAFAAUABQAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUAArACsAUABQAFAAUABQAFAAUAArAFAAKwBQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAKwArAFAAUABQAFAAUABQAFAAKwBQACsAUABQAFAAUAArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsABAAEAAQAHgANAB4AHgAeAB4AHgAeAB4AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwBQAFAAUABQAFAAUAArACsADQBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAHgAeAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAANAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAWABEAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAA0ADQANAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAAQABAAEACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAANAA0AKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUAArAAQABAArACsAKwArACsAKwArACsAKwArACsAKwBcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqAA0ADQAVAFwADQAeAA0AGwBcACoAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwAeAB4AEwATAA0ADQAOAB4AEwATAB4ABAAEAAQACQArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArAFAAUABQAFAAUAAEAAQAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQAUAArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwAEAAQABAAEAAQABAAEAAQABAAEAAQABAArACsAKwArAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwArACsAHgArACsAKwATABMASwBLAEsASwBLAEsASwBLAEsASwBcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXAArACsAXABcAFwAXABcACsAKwArACsAKwArACsAKwArACsAKwBcAFwAXABcAFwAXABcAFwAXABcAFwAXAArACsAKwArAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAXAArACsAKwAqACoAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAArACsAHgAeAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcACoAKgAqACoAKgAqACoAKgAqACoAKwAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKwArAAQASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArACsAKwBLAEsASwBLAEsASwBLAEsASwBLACsAKwArACsAKwArACoAKgAqACoAKgAqACoAXAAqACoAKgAqACoAKgArACsABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsABAAEAAQABAAEAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABABQAFAAUABQAFAAUABQACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwANAA0AHgANAA0ADQANAB4AHgAeAB4AHgAeAB4AHgAeAB4ABAAEAAQABAAEAAQABAAEAAQAHgAeAB4AHgAeAB4AHgAeAB4AKwArACsABAAEAAQAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQABAAEAAQABABQAFAASwBLAEsASwBLAEsASwBLAEsASwBQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwArACsAKwArACsAKwAeAB4AHgAeAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwArAA0ADQANAA0ADQBLAEsASwBLAEsASwBLAEsASwBLACsAKwArAFAAUABQAEsASwBLAEsASwBLAEsASwBLAEsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAA0ADQBQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwBQAFAAUAAeAB4AHgAeAB4AHgAeAB4AKwArACsAKwArACsAKwArAAQABAAEAB4ABAAEAAQABAAEAAQABAAEAAQABAAEAAQABABQAFAAUABQAAQAUABQAFAAUABQAFAABABQAFAABAAEAAQAUAArACsAKwArACsABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsABAAEAAQABAAEAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArAFAAUABQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAKwBQACsAUAArAFAAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACsAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArAB4AHgAeAB4AHgAeAB4AHgBQAB4AHgAeAFAAUABQACsAHgAeAB4AHgAeAB4AHgAeAB4AHgBQAFAAUABQACsAKwAeAB4AHgAeAB4AHgArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArAFAAUABQACsAHgAeAB4AHgAeAB4AHgAOAB4AKwANAA0ADQANAA0ADQANAAkADQANAA0ACAAEAAsABAAEAA0ACQANAA0ADAAdAB0AHgAXABcAFgAXABcAFwAWABcAHQAdAB4AHgAUABQAFAANAAEAAQAEAAQABAAEAAQACQAaABoAGgAaABoAGgAaABoAHgAXABcAHQAVABUAHgAeAB4AHgAeAB4AGAAWABEAFQAVABUAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4ADQAeAA0ADQANAA0AHgANAA0ADQAHAB4AHgAeAB4AKwAEAAQABAAEAAQABAAEAAQABAAEAFAAUAArACsATwBQAFAAUABQAFAAHgAeAB4AFgARAE8AUABPAE8ATwBPAFAAUABQAFAAUAAeAB4AHgAWABEAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArABsAGwAbABsAGwAbABsAGgAbABsAGwAbABsAGwAbABsAGwAbABsAGwAbABsAGgAbABsAGwAbABoAGwAbABoAGwAbABsAGwAbABsAGwAbABsAGwAbABsAGwAbABsAGwAbAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAHgAeAFAAGgAeAB0AHgBQAB4AGgAeAB4AHgAeAB4AHgAeAB4AHgBPAB4AUAAbAB4AHgBQAFAAUABQAFAAHgAeAB4AHQAdAB4AUAAeAFAAHgBQAB4AUABPAFAAUAAeAB4AHgAeAB4AHgAeAFAAUABQAFAAUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAFAAHgBQAFAAUABQAE8ATwBQAFAAUABQAFAATwBQAFAATwBQAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAFAAUABQAFAATwBPAE8ATwBPAE8ATwBPAE8ATwBQAFAAUABQAFAAUABQAFAAUAAeAB4AUABQAFAAUABPAB4AHgArACsAKwArAB0AHQAdAB0AHQAdAB0AHQAdAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB0AHgAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB4AHQAdAB4AHgAeAB0AHQAeAB4AHQAeAB4AHgAdAB4AHQAbABsAHgAdAB4AHgAeAB4AHQAeAB4AHQAdAB0AHQAeAB4AHQAeAB0AHgAdAB0AHQAdAB0AHQAeAB0AHgAeAB4AHgAeAB0AHQAdAB0AHgAeAB4AHgAdAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB4AHgAeAB0AHgAeAB4AHgAeAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB0AHgAeAB0AHQAdAB0AHgAeAB0AHQAeAB4AHQAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB0AHQAeAB4AHQAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHQAeAB4AHgAdAB4AHgAeAB4AHgAeAB4AHQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AFAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeABYAEQAWABEAHgAeAB4AHgAeAB4AHQAeAB4AHgAeAB4AHgAeACUAJQAeAB4AHgAeAB4AHgAeAB4AHgAWABEAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AJQAlACUAJQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAFAAHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHgAeAB4AHgAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAeAB4AHQAdAB0AHQAeAB4AHgAeAB4AHgAeAB4AHgAeAB0AHQAeAB0AHQAdAB0AHQAdAB0AHgAeAB4AHgAeAB4AHgAeAB0AHQAeAB4AHQAdAB4AHgAeAB4AHQAdAB4AHgAeAB4AHQAdAB0AHgAeAB0AHgAeAB0AHQAdAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB0AHQAdAB4AHgAeAB4AHgAeAB4AHgAeAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAlACUAJQAlAB4AHQAdAB4AHgAdAB4AHgAeAB4AHQAdAB4AHgAeAB4AJQAlAB0AHQAlAB4AJQAlACUAIAAlACUAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAlACUAJQAeAB4AHgAeAB0AHgAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB0AHgAdAB0AHQAeAB0AJQAdAB0AHgAdAB0AHgAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACUAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHQAdAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAlACUAJQAlACUAJQAlACUAJQAlACUAJQAdAB0AHQAdACUAHgAlACUAJQAdACUAJQAdAB0AHQAlACUAHQAdACUAHQAdACUAJQAlAB4AHQAeAB4AHgAeAB0AHQAlAB0AHQAdAB0AHQAdACUAJQAlACUAJQAdACUAJQAgACUAHQAdACUAJQAlACUAJQAlACUAJQAeAB4AHgAlACUAIAAgACAAIAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB0AHgAeAB4AFwAXABcAFwAXABcAHgATABMAJQAeAB4AHgAWABEAFgARABYAEQAWABEAFgARABYAEQAWABEATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeABYAEQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAWABEAFgARABYAEQAWABEAFgARAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AFgARABYAEQAWABEAFgARABYAEQAWABEAFgARABYAEQAWABEAFgARABYAEQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAWABEAFgARAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AFgARAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAdAB0AHQAdAB0AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AUABQAFAAUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAEAAQABAAeAB4AKwArACsAKwArABMADQANAA0AUAATAA0AUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAUAANACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAEAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXAA0ADQANAA0ADQANAA0ADQAeAA0AFgANAB4AHgAXABcAHgAeABcAFwAWABEAFgARABYAEQAWABEADQANAA0ADQATAFAADQANAB4ADQANAB4AHgAeAB4AHgAMAAwADQANAA0AHgANAA0AFgANAA0ADQANAA0ADQANAA0AHgANAB4ADQANAB4AHgAeACsAKwArACsAKwArACsAKwArACsAKwArACsAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACsAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAKwArACsAKwArACsAKwArACsAKwArACsAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAlACUAJQAlACUAJQAlACUAJQAlACUAJQArACsAKwArAA0AEQARACUAJQBHAFcAVwAWABEAFgARABYAEQAWABEAFgARACUAJQAWABEAFgARABYAEQAWABEAFQAWABEAEQAlAFcAVwBXAFcAVwBXAFcAVwBXAAQABAAEAAQABAAEACUAVwBXAFcAVwA2ACUAJQBXAFcAVwBHAEcAJQAlACUAKwBRAFcAUQBXAFEAVwBRAFcAUQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFEAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBRAFcAUQBXAFEAVwBXAFcAVwBXAFcAUQBXAFcAVwBXAFcAVwBRAFEAKwArAAQABAAVABUARwBHAFcAFQBRAFcAUQBXAFEAVwBRAFcAUQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFEAVwBRAFcAUQBXAFcAVwBXAFcAVwBRAFcAVwBXAFcAVwBXAFEAUQBXAFcAVwBXABUAUQBHAEcAVwArACsAKwArACsAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAKwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAKwAlACUAVwBXAFcAVwAlACUAJQAlACUAJQAlACUAJQAlACsAKwArACsAKwArACsAKwArACsAKwArAFEAUQBRAFEAUQBRAFEAUQBRAFEAUQBRAFEAUQBRAFEAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQArAFcAVwBXAFcAVwBXAFcAVwBXAFcAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQBPAE8ATwBPAE8ATwBPAE8AJQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACUAJQAlAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAEcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAKwArACsAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAADQATAA0AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABLAEsASwBLAEsASwBLAEsASwBLAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAFAABAAEAAQABAAeAAQABAAEAAQABAAEAAQABAAEAAQAHgBQAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AUABQAAQABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAeAA0ADQANAA0ADQArACsAKwArACsAKwArACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAFAAUABQAFAAUABQAFAAUABQAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AUAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgBQAB4AHgAeAB4AHgAeAFAAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAHgAeAB4AHgAeAB4AHgAeAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAeAB4AUABQAFAAUABQAFAAUABQAFAAUABQAAQAUABQAFAABABQAFAAUABQAAQAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAeAB4AHgAeAAQAKwArACsAUABQAFAAUABQAFAAHgAeABoAHgArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAADgAOABMAEwArACsAKwArACsAKwArACsABAAEAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAEACsAKwArACsAKwArACsAKwANAA0ASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArACsAKwAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABABQAFAAUABQAFAAUAAeAB4AHgBQAA4AUABQAAQAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAA0ADQBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAKwArACsAKwArACsAKwArACsAKwArAB4AWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYAFgAWABYACsAKwArAAQAHgAeAB4AHgAeAB4ADQANAA0AHgAeAB4AHgArAFAASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArAB4AHgBcAFwAXABcAFwAKgBcAFwAXABcAFwAXABcAFwAXABcAEsASwBLAEsASwBLAEsASwBLAEsAXABcAFwAXABcACsAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsAKwArACsAKwArACsAKwArAFAAUABQAAQAUABQAFAAUABQAFAAUABQAAQABAArACsASwBLAEsASwBLAEsASwBLAEsASwArACsAHgANAA0ADQBcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAKgAqACoAXAAqACoAKgBcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXAAqAFwAKgAqACoAXABcACoAKgBcAFwAXABcAFwAKgAqAFwAKgBcACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFwAXABcACoAKgBQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAA0ADQBQAFAAUAAEAAQAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUAArACsAUABQAFAAUABQAFAAKwArAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAHgAeACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQADQAEAAQAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAVABVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBUAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVAFUAVQBVACsAKwArACsAKwArACsAKwArACsAKwArAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAWQBZAFkAKwArACsAKwBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAWgBaAFoAKwArACsAKwAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYABgAGAAYAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACUAJQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAJQAlACUAJQAlACUAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAKwArACsAKwArAFYABABWAFYAVgBWAFYAVgBWAFYAVgBWAB4AVgBWAFYAVgBWAFYAVgBWAFYAVgBWAFYAVgArAFYAVgBWAFYAVgArAFYAKwBWAFYAKwBWAFYAKwBWAFYAVgBWAFYAVgBWAFYAVgBWAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAEQAWAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUAAaAB4AKwArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAGAARABEAGAAYABMAEwAWABEAFAArACsAKwArACsAKwAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACUAJQAlACUAJQAWABEAFgARABYAEQAWABEAFgARABYAEQAlACUAFgARACUAJQAlACUAJQAlACUAEQAlABEAKwAVABUAEwATACUAFgARABYAEQAWABEAJQAlACUAJQAlACUAJQAlACsAJQAbABoAJQArACsAKwArAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAAcAKwATACUAJQAbABoAJQAlABYAEQAlACUAEQAlABEAJQBXAFcAVwBXAFcAVwBXAFcAVwBXABUAFQAlACUAJQATACUAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXABYAJQARACUAJQAlAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwAWACUAEQAlABYAEQARABYAEQARABUAVwBRAFEAUQBRAFEAUQBRAFEAUQBRAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAEcARwArACsAVwBXAFcAVwBXAFcAKwArAFcAVwBXAFcAVwBXACsAKwBXAFcAVwBXAFcAVwArACsAVwBXAFcAKwArACsAGgAbACUAJQAlABsAGwArAB4AHgAeAB4AHgAeAB4AKwArACsAKwArACsAKwArACsAKwAEAAQABAAQAB0AKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsADQANAA0AKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArAB4AHgAeAB4AHgAeAB4AHgAeAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgBQAFAAHgAeAB4AKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAAQAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAEAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAA0AUABQAFAAUAArACsAKwArAFAAUABQAFAAUABQAFAAUAANAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArACsAKwAeACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAKwArAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUAArACsAKwBQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwANAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAeAB4AUABQAFAAUABQAFAAUAArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUAArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArAA0AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwAeAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAUABQAFAAUABQAAQABAAEACsABAAEACsAKwArACsAKwAEAAQABAAEAFAAUABQAFAAKwBQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAAQABAAEACsAKwArACsABABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArAA0ADQANAA0ADQANAA0ADQAeACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAeAFAAUABQAFAAUABQAFAAUAAeAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAArACsAKwArAFAAUABQAFAAUAANAA0ADQANAA0ADQAUACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsADQANAA0ADQANAA0ADQBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArAB4AHgAeAB4AKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArAFAAUABQAFAAUABQAAQABAAEAAQAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUAArAAQABAANACsAKwBQAFAAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAAQABAAEAAQABAAEAAQABAAEAAQABABQAFAAUABQAB4AHgAeAB4AHgArACsAKwArACsAKwAEAAQABAAEAAQABAAEAA0ADQAeAB4AHgAeAB4AKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAQABAAEAAQABAAEAAQABAAEAAQABAAeAB4AHgANAA0ADQANACsAKwArACsAKwArACsAKwArACsAKwAeACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwBLAEsASwBLAEsASwBLAEsASwBLACsAKwArACsAKwArAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEACsASwBLAEsASwBLAEsASwBLAEsASwANAA0ADQANAFAABAAEAFAAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAeAA4AUAArACsAKwArACsAKwArACsAKwAEAFAAUABQAFAADQANAB4ADQAEAAQABAAEAB4ABAAEAEsASwBLAEsASwBLAEsASwBLAEsAUAAOAFAADQANAA0AKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAANAA0AHgANAA0AHgAEACsAUABQAFAAUABQAFAAUAArAFAAKwBQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAA0AKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsABAAEAAQABAArAFAAUABQAFAAUABQAFAAUAArACsAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAUABQACsAUABQAFAAUABQACsABAAEAFAABAAEAAQABAAEAAQABAArACsABAAEACsAKwAEAAQABAArACsAUAArACsAKwArACsAKwAEACsAKwArACsAKwBQAFAAUABQAFAABAAEACsAKwAEAAQABAAEAAQABAAEACsAKwArAAQABAAEAAQABAArACsAKwArACsAKwArACsAKwArACsABAAEAAQABAAEAAQABABQAFAAUABQAA0ADQANAA0AHgBLAEsASwBLAEsASwBLAEsASwBLAA0ADQArAB4ABABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAEAAQABAAEAFAAUAAeAFAAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAArACsABAAEAAQABAAEAAQABAAEAAQADgANAA0AEwATAB4AHgAeAA0ADQANAA0ADQANAA0ADQANAA0ADQANAA0ADQANAFAAUABQAFAABAAEACsAKwAEAA0ADQAeAFAAKwArACsAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAFAAKwArACsAKwArACsAKwBLAEsASwBLAEsASwBLAEsASwBLACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAXABcAFwAKwArACoAKgAqACoAKgAqACoAKgAqACoAKgAqACoAKgAqACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwBcAFwADQANAA0AKgBQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAeACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwBQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAKwArAFAAKwArAFAAUABQAFAAUABQAFAAUAArAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQAKwAEAAQAKwArAAQABAAEAAQAUAAEAFAABAAEAA0ADQANACsAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAArACsABAAEAAQABAAEAAQABABQAA4AUAAEACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAABAAEAAQABAAEAAQABAAEAAQABABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAFAABAAEAAQABAAOAB4ADQANAA0ADQAOAB4ABAArACsAKwArACsAKwArACsAUAAEAAQABAAEAAQABAAEAAQABAAEAAQAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAA0ADQANAFAADgAOAA4ADQANACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAEAAQABAAEACsABAAEAAQABAAEAAQABAAEAFAADQANAA0ADQANACsAKwArACsAKwArACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwAOABMAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQACsAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAArACsAKwAEACsABAAEACsABAAEAAQABAAEAAQABABQAAQAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAUABQAFAAUABQAFAAKwBQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQAKwAEAAQAKwAEAAQABAAEAAQAUAArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAABAAEAAQABAAeAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAB4AHgAeAB4AHgAeAB4AHgAaABoAGgAaAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAKwArACsAKwArACsAKwArACsAKwArAA0AUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsADQANAA0ADQANACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAASABIAEgAQwBDAEMAUABQAFAAUABDAFAAUABQAEgAQwBIAEMAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAASABDAEMAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwAJAAkACQAJAAkACQAJABYAEQArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABIAEMAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwANAA0AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArAAQABAAEAAQABAANACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEAA0ADQANAB4AHgAeAB4AHgAeAFAAUABQAFAADQAeACsAKwArACsAKwArACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwArAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAANAA0AHgAeACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwAEAFAABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAKwArACsAKwArACsAKwAEAAQABAAEAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAARwBHABUARwAJACsAKwArACsAKwArACsAKwArACsAKwAEAAQAKwArACsAKwArACsAKwArACsAKwArACsAKwArAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACsAKwArACsAKwArACsAKwBXAFcAVwBXAFcAVwBXAFcAVwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUQBRAFEAKwArACsAKwArACsAKwArACsAKwArACsAKwBRAFEAUQBRACsAKwArACsAKwArACsAKwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUAArACsAHgAEAAQADQAEAAQABAAEACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAKwArACsAKwArACsAKwArAB4AHgAeAB4AHgAeAB4AKwArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAAQABAAEAAQABAAeAB4AHgAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAB4AHgAEAAQABAAEAAQABAAEAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4ABAAEAAQABAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4ABAAEAAQAHgArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwArACsAKwArACsAKwArACsAKwArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAKwArACsAKwArACsAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwBQAFAAKwArAFAAKwArAFAAUAArACsAUABQAFAAUAArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACsAUAArAFAAUABQAFAAUABQAFAAKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwBQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAHgAeAFAAUABQAFAAUAArAFAAKwArACsAUABQAFAAUABQAFAAUAArAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAHgBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgBQAFAAUABQAFAAUABQAFAAUABQAFAAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAB4AHgAeAB4AHgAeAB4AHgAeACsAKwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAEsASwBLAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAeAB4AHgAeAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAeAB4AHgAeAB4AHgAeAB4ABAAeAB4AHgAeAB4AHgAeAB4AHgAeAAQAHgAeAA0ADQANAA0AHgArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAEAAQABAAEAAQAKwAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAAQABAAEAAQABAAEAAQAKwAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAKwArAAQABAAEAAQABAAEAAQAKwAEAAQAKwAEAAQABAAEAAQAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwAEAAQABAAEAAQABAAEAFAAUABQAFAAUABQAFAAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwBQAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArABsAUABQAFAAUABQACsAKwBQAFAAUABQAFAAUABQAFAAUAAEAAQABAAEAAQABAAEACsAKwArACsAKwArACsAKwArAB4AHgAeAB4ABAAEAAQABAAEAAQABABQACsAKwArACsASwBLAEsASwBLAEsASwBLAEsASwArACsAKwArABYAFgArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAGgBQAFAAUAAaAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAeAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQACsAKwBQAFAAUABQACsAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwBQAFAAKwBQACsAKwBQACsAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAKwBQACsAUAArACsAKwArACsAKwBQACsAKwArACsAUAArAFAAKwBQACsAUABQAFAAKwBQAFAAKwBQACsAKwBQACsAUAArAFAAKwBQACsAUAArAFAAUAArAFAAKwArAFAAUABQAFAAKwBQAFAAUABQAFAAUABQACsAUABQAFAAUAArAFAAUABQAFAAKwBQACsAUABQAFAAUABQAFAAUABQAFAAUAArAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAArACsAKwArACsAUABQAFAAKwBQAFAAUABQAFAAKwBQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwAeAB4AKwArACsAKwArACsAKwArACsAKwArACsAKwArAE8ATwBPAE8ATwBPAE8ATwBPAE8ATwBPAE8AJQAlACUAHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHgAeAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB4AHgAeACUAJQAlAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAdAB0AHQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQApACkAKQApACkAKQApACkAKQApACkAKQApACkAKQApACkAKQApACkAKQApACkAKQApACkAJQAlACUAJQAlACAAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAeAB4AJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlAB4AHgAlACUAJQAlACUAHgAlACUAJQAlACUAIAAgACAAJQAlACAAJQAlACAAIAAgACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACEAIQAhACEAIQAlACUAIAAgACUAJQAgACAAIAAgACAAIAAgACAAIAAgACAAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAJQAlACUAIAAlACUAJQAlACAAIAAgACUAIAAgACAAJQAlACUAJQAlACUAJQAgACUAIAAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAHgAlAB4AJQAeACUAJQAlACUAJQAgACUAJQAlACUAHgAlAB4AHgAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlAB4AHgAeAB4AHgAeAB4AJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAeAB4AHgAeAB4AHgAeAB4AHgAeACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACAAIAAlACUAJQAlACAAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACAAJQAlACUAJQAgACAAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAHgAeAB4AHgAeAB4AHgAeACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAeAB4AHgAeAB4AHgAlACUAJQAlACUAJQAlACAAIAAgACUAJQAlACAAIAAgACAAIAAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeABcAFwAXABUAFQAVAB4AHgAeAB4AJQAlACUAIAAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACAAIAAgACUAJQAlACUAJQAlACUAJQAlACAAJQAlACUAJQAlACUAJQAlACUAJQAlACAAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AJQAlACUAJQAlACUAJQAlACUAJQAlACUAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AJQAlACUAJQAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeACUAJQAlACUAJQAlACUAJQAeAB4AHgAeAB4AHgAeAB4AHgAeACUAJQAlACUAJQAlAB4AHgAeAB4AHgAeAB4AHgAlACUAJQAlACUAJQAlACUAHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAgACUAJQAgACUAJQAlACUAJQAlACUAJQAgACAAIAAgACAAIAAgACAAJQAlACUAJQAlACUAIAAlACUAJQAlACUAJQAlACUAJQAgACAAIAAgACAAIAAgACAAIAAgACUAJQAgACAAIAAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAgACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACAAIAAlACAAIAAlACAAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAgACAAIAAlACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAJQAlAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AKwAeAB4AHgAeAB4AHgAeAB4AHgAeAB4AHgArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAEsASwBLAEsASwBLAEsASwBLAEsAKwArACsAKwArACsAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAKwArAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXACUAJQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwAlACUAJQAlACUAJQAlACUAJQAlACUAVwBXACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQBXAFcAVwBXAFcAVwBXAFcAVwBXAFcAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAJQAlACUAKwAEACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArACsAKwArAA==";
|
|
796
|
-
var LETTER_NUMBER_MODIFIER = 50;
|
|
797
|
-
var BK = 1;
|
|
798
|
-
var CR$1 = 2;
|
|
799
|
-
var LF$1 = 3;
|
|
800
|
-
var CM = 4;
|
|
801
|
-
var NL = 5;
|
|
802
|
-
var WJ = 7;
|
|
803
|
-
var ZW = 8;
|
|
804
|
-
var GL = 9;
|
|
805
|
-
var SP = 10;
|
|
806
|
-
var ZWJ$1 = 11;
|
|
807
|
-
var B2 = 12;
|
|
808
|
-
var BA = 13;
|
|
809
|
-
var BB = 14;
|
|
810
|
-
var HY = 15;
|
|
811
|
-
var CB = 16;
|
|
812
|
-
var CL = 17;
|
|
813
|
-
var CP = 18;
|
|
814
|
-
var EX = 19;
|
|
815
|
-
var IN = 20;
|
|
816
|
-
var NS = 21;
|
|
817
|
-
var OP = 22;
|
|
818
|
-
var QU = 23;
|
|
819
|
-
var IS = 24;
|
|
820
|
-
var NU = 25;
|
|
821
|
-
var PO = 26;
|
|
822
|
-
var PR = 27;
|
|
823
|
-
var SY = 28;
|
|
824
|
-
var AI = 29;
|
|
825
|
-
var AL = 30;
|
|
826
|
-
var CJ = 31;
|
|
827
|
-
var EB = 32;
|
|
828
|
-
var EM = 33;
|
|
829
|
-
var H2 = 34;
|
|
830
|
-
var H3 = 35;
|
|
831
|
-
var HL = 36;
|
|
832
|
-
var ID = 37;
|
|
833
|
-
var JL = 38;
|
|
834
|
-
var JV = 39;
|
|
835
|
-
var JT = 40;
|
|
836
|
-
var RI$1 = 41;
|
|
837
|
-
var SA = 42;
|
|
838
|
-
var XX = 43;
|
|
839
|
-
var ea_OP = [9001, 65288];
|
|
840
|
-
var BREAK_MANDATORY = "!";
|
|
841
|
-
var BREAK_NOT_ALLOWED$1 = "×";
|
|
842
|
-
var BREAK_ALLOWED$1 = "÷";
|
|
843
|
-
var UnicodeTrie$1 = createTrieFromBase64$1(base64$1);
|
|
844
|
-
var ALPHABETICS = [AL, HL];
|
|
845
|
-
var HARD_LINE_BREAKS = [
|
|
846
|
-
BK,
|
|
847
|
-
CR$1,
|
|
848
|
-
LF$1,
|
|
849
|
-
NL
|
|
850
|
-
];
|
|
851
|
-
var SPACE$1 = [SP, ZW];
|
|
852
|
-
var PREFIX_POSTFIX = [PR, PO];
|
|
853
|
-
var LINE_BREAKS = HARD_LINE_BREAKS.concat(SPACE$1);
|
|
854
|
-
var KOREAN_SYLLABLE_BLOCK = [
|
|
855
|
-
JL,
|
|
856
|
-
JV,
|
|
857
|
-
JT,
|
|
858
|
-
H2,
|
|
859
|
-
H3
|
|
860
|
-
];
|
|
861
|
-
var HYPHEN = [HY, BA];
|
|
862
|
-
var codePointsToCharacterClasses = function(codePoints, lineBreak) {
|
|
863
|
-
if (lineBreak === void 0) lineBreak = "strict";
|
|
864
|
-
var types = [];
|
|
865
|
-
var indices = [];
|
|
866
|
-
var categories = [];
|
|
867
|
-
codePoints.forEach(function(codePoint, index) {
|
|
868
|
-
var classType = UnicodeTrie$1.get(codePoint);
|
|
869
|
-
if (classType > LETTER_NUMBER_MODIFIER) {
|
|
870
|
-
categories.push(true);
|
|
871
|
-
classType -= LETTER_NUMBER_MODIFIER;
|
|
872
|
-
} else categories.push(false);
|
|
873
|
-
if ([
|
|
874
|
-
"normal",
|
|
875
|
-
"auto",
|
|
876
|
-
"loose"
|
|
877
|
-
].indexOf(lineBreak) !== -1) {
|
|
878
|
-
if ([
|
|
879
|
-
8208,
|
|
880
|
-
8211,
|
|
881
|
-
12316,
|
|
882
|
-
12448
|
|
883
|
-
].indexOf(codePoint) !== -1) {
|
|
884
|
-
indices.push(index);
|
|
885
|
-
return types.push(CB);
|
|
886
|
-
}
|
|
887
|
-
}
|
|
888
|
-
if (classType === CM || classType === ZWJ$1) {
|
|
889
|
-
if (index === 0) {
|
|
890
|
-
indices.push(index);
|
|
891
|
-
return types.push(AL);
|
|
892
|
-
}
|
|
893
|
-
var prev = types[index - 1];
|
|
894
|
-
if (LINE_BREAKS.indexOf(prev) === -1) {
|
|
895
|
-
indices.push(indices[index - 1]);
|
|
896
|
-
return types.push(prev);
|
|
897
|
-
}
|
|
898
|
-
indices.push(index);
|
|
899
|
-
return types.push(AL);
|
|
900
|
-
}
|
|
901
|
-
indices.push(index);
|
|
902
|
-
if (classType === CJ) return types.push(lineBreak === "strict" ? NS : ID);
|
|
903
|
-
if (classType === SA) return types.push(AL);
|
|
904
|
-
if (classType === AI) return types.push(AL);
|
|
905
|
-
if (classType === XX) {
|
|
906
|
-
if (codePoint >= 131072 && codePoint <= 196605 || codePoint >= 196608 && codePoint <= 262141) return types.push(ID);
|
|
907
|
-
else return types.push(AL);
|
|
908
|
-
}
|
|
909
|
-
types.push(classType);
|
|
910
|
-
});
|
|
911
|
-
return [
|
|
912
|
-
indices,
|
|
913
|
-
types,
|
|
914
|
-
categories
|
|
915
|
-
];
|
|
916
|
-
};
|
|
917
|
-
var isAdjacentWithSpaceIgnored = function(a, b, currentIndex, classTypes) {
|
|
918
|
-
var current = classTypes[currentIndex];
|
|
919
|
-
if (Array.isArray(a) ? a.indexOf(current) !== -1 : a === current) {
|
|
920
|
-
var i = currentIndex;
|
|
921
|
-
while (i <= classTypes.length) {
|
|
922
|
-
i++;
|
|
923
|
-
var next = classTypes[i];
|
|
924
|
-
if (next === b) return true;
|
|
925
|
-
if (next !== SP) break;
|
|
926
|
-
}
|
|
927
|
-
}
|
|
928
|
-
if (current === SP) {
|
|
929
|
-
var i = currentIndex;
|
|
930
|
-
while (i > 0) {
|
|
931
|
-
i--;
|
|
932
|
-
var prev = classTypes[i];
|
|
933
|
-
if (Array.isArray(a) ? a.indexOf(prev) !== -1 : a === prev) {
|
|
934
|
-
var n = currentIndex;
|
|
935
|
-
while (n <= classTypes.length) {
|
|
936
|
-
n++;
|
|
937
|
-
var next = classTypes[n];
|
|
938
|
-
if (next === b) return true;
|
|
939
|
-
if (next !== SP) break;
|
|
940
|
-
}
|
|
941
|
-
}
|
|
942
|
-
if (prev !== SP) break;
|
|
943
|
-
}
|
|
944
|
-
}
|
|
945
|
-
return false;
|
|
946
|
-
};
|
|
947
|
-
var previousNonSpaceClassType = function(currentIndex, classTypes) {
|
|
948
|
-
var i = currentIndex;
|
|
949
|
-
while (i >= 0) {
|
|
950
|
-
var type = classTypes[i];
|
|
951
|
-
if (type === SP) i--;
|
|
952
|
-
else return type;
|
|
953
|
-
}
|
|
954
|
-
return 0;
|
|
955
|
-
};
|
|
956
|
-
var _lineBreakAtIndex = function(codePoints, classTypes, indicies, index, forbiddenBreaks) {
|
|
957
|
-
if (indicies[index] === 0) return BREAK_NOT_ALLOWED$1;
|
|
958
|
-
var currentIndex = index - 1;
|
|
959
|
-
if (Array.isArray(forbiddenBreaks) && forbiddenBreaks[currentIndex] === true) return BREAK_NOT_ALLOWED$1;
|
|
960
|
-
var beforeIndex = currentIndex - 1;
|
|
961
|
-
var afterIndex = currentIndex + 1;
|
|
962
|
-
var current = classTypes[currentIndex];
|
|
963
|
-
var before = beforeIndex >= 0 ? classTypes[beforeIndex] : 0;
|
|
964
|
-
var next = classTypes[afterIndex];
|
|
965
|
-
if (current === CR$1 && next === LF$1) return BREAK_NOT_ALLOWED$1;
|
|
966
|
-
if (HARD_LINE_BREAKS.indexOf(current) !== -1) return BREAK_MANDATORY;
|
|
967
|
-
if (HARD_LINE_BREAKS.indexOf(next) !== -1) return BREAK_NOT_ALLOWED$1;
|
|
968
|
-
if (SPACE$1.indexOf(next) !== -1) return BREAK_NOT_ALLOWED$1;
|
|
969
|
-
if (previousNonSpaceClassType(currentIndex, classTypes) === ZW) return BREAK_ALLOWED$1;
|
|
970
|
-
if (UnicodeTrie$1.get(codePoints[currentIndex]) === ZWJ$1) return BREAK_NOT_ALLOWED$1;
|
|
971
|
-
if ((current === EB || current === EM) && UnicodeTrie$1.get(codePoints[afterIndex]) === ZWJ$1) return BREAK_NOT_ALLOWED$1;
|
|
972
|
-
if (current === WJ || next === WJ) return BREAK_NOT_ALLOWED$1;
|
|
973
|
-
if (current === GL) return BREAK_NOT_ALLOWED$1;
|
|
974
|
-
if ([
|
|
975
|
-
SP,
|
|
976
|
-
BA,
|
|
977
|
-
HY
|
|
978
|
-
].indexOf(current) === -1 && next === GL) return BREAK_NOT_ALLOWED$1;
|
|
979
|
-
if ([
|
|
980
|
-
CL,
|
|
981
|
-
CP,
|
|
982
|
-
EX,
|
|
983
|
-
IS,
|
|
984
|
-
SY
|
|
985
|
-
].indexOf(next) !== -1) return BREAK_NOT_ALLOWED$1;
|
|
986
|
-
if (previousNonSpaceClassType(currentIndex, classTypes) === OP) return BREAK_NOT_ALLOWED$1;
|
|
987
|
-
if (isAdjacentWithSpaceIgnored(QU, OP, currentIndex, classTypes)) return BREAK_NOT_ALLOWED$1;
|
|
988
|
-
if (isAdjacentWithSpaceIgnored([CL, CP], NS, currentIndex, classTypes)) return BREAK_NOT_ALLOWED$1;
|
|
989
|
-
if (isAdjacentWithSpaceIgnored(B2, B2, currentIndex, classTypes)) return BREAK_NOT_ALLOWED$1;
|
|
990
|
-
if (current === SP) return BREAK_ALLOWED$1;
|
|
991
|
-
if (current === QU || next === QU) return BREAK_NOT_ALLOWED$1;
|
|
992
|
-
if (next === CB || current === CB) return BREAK_ALLOWED$1;
|
|
993
|
-
if ([
|
|
994
|
-
BA,
|
|
995
|
-
HY,
|
|
996
|
-
NS
|
|
997
|
-
].indexOf(next) !== -1 || current === BB) return BREAK_NOT_ALLOWED$1;
|
|
998
|
-
if (before === HL && HYPHEN.indexOf(current) !== -1) return BREAK_NOT_ALLOWED$1;
|
|
999
|
-
if (current === SY && next === HL) return BREAK_NOT_ALLOWED$1;
|
|
1000
|
-
if (next === IN) return BREAK_NOT_ALLOWED$1;
|
|
1001
|
-
if (ALPHABETICS.indexOf(next) !== -1 && current === NU || ALPHABETICS.indexOf(current) !== -1 && next === NU) return BREAK_NOT_ALLOWED$1;
|
|
1002
|
-
if (current === PR && [
|
|
1003
|
-
ID,
|
|
1004
|
-
EB,
|
|
1005
|
-
EM
|
|
1006
|
-
].indexOf(next) !== -1 || [
|
|
1007
|
-
ID,
|
|
1008
|
-
EB,
|
|
1009
|
-
EM
|
|
1010
|
-
].indexOf(current) !== -1 && next === PO) return BREAK_NOT_ALLOWED$1;
|
|
1011
|
-
if (ALPHABETICS.indexOf(current) !== -1 && PREFIX_POSTFIX.indexOf(next) !== -1 || PREFIX_POSTFIX.indexOf(current) !== -1 && ALPHABETICS.indexOf(next) !== -1) return BREAK_NOT_ALLOWED$1;
|
|
1012
|
-
if ([PR, PO].indexOf(current) !== -1 && (next === NU || [OP, HY].indexOf(next) !== -1 && classTypes[afterIndex + 1] === NU) || [OP, HY].indexOf(current) !== -1 && next === NU || current === NU && [
|
|
1013
|
-
NU,
|
|
1014
|
-
SY,
|
|
1015
|
-
IS
|
|
1016
|
-
].indexOf(next) !== -1) return BREAK_NOT_ALLOWED$1;
|
|
1017
|
-
if ([
|
|
1018
|
-
NU,
|
|
1019
|
-
SY,
|
|
1020
|
-
IS,
|
|
1021
|
-
CL,
|
|
1022
|
-
CP
|
|
1023
|
-
].indexOf(next) !== -1) {
|
|
1024
|
-
var prevIndex = currentIndex;
|
|
1025
|
-
while (prevIndex >= 0) {
|
|
1026
|
-
var type = classTypes[prevIndex];
|
|
1027
|
-
if (type === NU) return BREAK_NOT_ALLOWED$1;
|
|
1028
|
-
else if ([SY, IS].indexOf(type) !== -1) prevIndex--;
|
|
1029
|
-
else break;
|
|
1030
|
-
}
|
|
1031
|
-
}
|
|
1032
|
-
if ([PR, PO].indexOf(next) !== -1) {
|
|
1033
|
-
var prevIndex = [CL, CP].indexOf(current) !== -1 ? beforeIndex : currentIndex;
|
|
1034
|
-
while (prevIndex >= 0) {
|
|
1035
|
-
var type = classTypes[prevIndex];
|
|
1036
|
-
if (type === NU) return BREAK_NOT_ALLOWED$1;
|
|
1037
|
-
else if ([SY, IS].indexOf(type) !== -1) prevIndex--;
|
|
1038
|
-
else break;
|
|
1039
|
-
}
|
|
1040
|
-
}
|
|
1041
|
-
if (JL === current && [
|
|
1042
|
-
JL,
|
|
1043
|
-
JV,
|
|
1044
|
-
H2,
|
|
1045
|
-
H3
|
|
1046
|
-
].indexOf(next) !== -1 || [JV, H2].indexOf(current) !== -1 && [JV, JT].indexOf(next) !== -1 || [JT, H3].indexOf(current) !== -1 && next === JT) return BREAK_NOT_ALLOWED$1;
|
|
1047
|
-
if (KOREAN_SYLLABLE_BLOCK.indexOf(current) !== -1 && [IN, PO].indexOf(next) !== -1 || KOREAN_SYLLABLE_BLOCK.indexOf(next) !== -1 && current === PR) return BREAK_NOT_ALLOWED$1;
|
|
1048
|
-
if (ALPHABETICS.indexOf(current) !== -1 && ALPHABETICS.indexOf(next) !== -1) return BREAK_NOT_ALLOWED$1;
|
|
1049
|
-
if (current === IS && ALPHABETICS.indexOf(next) !== -1) return BREAK_NOT_ALLOWED$1;
|
|
1050
|
-
if (ALPHABETICS.concat(NU).indexOf(current) !== -1 && next === OP && ea_OP.indexOf(codePoints[afterIndex]) === -1 || ALPHABETICS.concat(NU).indexOf(next) !== -1 && current === CP) return BREAK_NOT_ALLOWED$1;
|
|
1051
|
-
if (current === RI$1 && next === RI$1) {
|
|
1052
|
-
var i = indicies[currentIndex];
|
|
1053
|
-
var count = 1;
|
|
1054
|
-
while (i > 0) {
|
|
1055
|
-
i--;
|
|
1056
|
-
if (classTypes[i] === RI$1) count++;
|
|
1057
|
-
else break;
|
|
1058
|
-
}
|
|
1059
|
-
if (count % 2 !== 0) return BREAK_NOT_ALLOWED$1;
|
|
1060
|
-
}
|
|
1061
|
-
if (current === EB && next === EM) return BREAK_NOT_ALLOWED$1;
|
|
1062
|
-
return BREAK_ALLOWED$1;
|
|
1063
|
-
};
|
|
1064
|
-
var cssFormattedClasses = function(codePoints, options) {
|
|
1065
|
-
if (!options) options = {
|
|
1066
|
-
lineBreak: "normal",
|
|
1067
|
-
wordBreak: "normal"
|
|
1068
|
-
};
|
|
1069
|
-
var _a = codePointsToCharacterClasses(codePoints, options.lineBreak), indicies = _a[0], classTypes = _a[1], isLetterNumber = _a[2];
|
|
1070
|
-
if (options.wordBreak === "break-all" || options.wordBreak === "break-word") classTypes = classTypes.map(function(type) {
|
|
1071
|
-
return [
|
|
1072
|
-
NU,
|
|
1073
|
-
AL,
|
|
1074
|
-
SA
|
|
1075
|
-
].indexOf(type) !== -1 ? ID : type;
|
|
1076
|
-
});
|
|
1077
|
-
var forbiddenBreakpoints = options.wordBreak === "keep-all" ? isLetterNumber.map(function(letterNumber, i) {
|
|
1078
|
-
return letterNumber && codePoints[i] >= 19968 && codePoints[i] <= 40959;
|
|
1079
|
-
}) : void 0;
|
|
1080
|
-
return [
|
|
1081
|
-
indicies,
|
|
1082
|
-
classTypes,
|
|
1083
|
-
forbiddenBreakpoints
|
|
1084
|
-
];
|
|
1085
|
-
};
|
|
1086
|
-
var Break = function() {
|
|
1087
|
-
function Break(codePoints, lineBreak, start, end) {
|
|
1088
|
-
this.codePoints = codePoints;
|
|
1089
|
-
this.required = lineBreak === BREAK_MANDATORY;
|
|
1090
|
-
this.start = start;
|
|
1091
|
-
this.end = end;
|
|
1092
|
-
}
|
|
1093
|
-
Break.prototype.slice = function() {
|
|
1094
|
-
return fromCodePoint$1.apply(void 0, this.codePoints.slice(this.start, this.end));
|
|
1095
|
-
};
|
|
1096
|
-
return Break;
|
|
1097
|
-
}();
|
|
1098
|
-
var LineBreaker = function(str, options) {
|
|
1099
|
-
var codePoints = toCodePoints$1(str);
|
|
1100
|
-
var _a = cssFormattedClasses(codePoints, options), indicies = _a[0], classTypes = _a[1], forbiddenBreakpoints = _a[2];
|
|
1101
|
-
var length = codePoints.length;
|
|
1102
|
-
var lastEnd = 0;
|
|
1103
|
-
var nextIndex = 0;
|
|
1104
|
-
return { next: function() {
|
|
1105
|
-
if (nextIndex >= length) return {
|
|
1106
|
-
done: true,
|
|
1107
|
-
value: null
|
|
1108
|
-
};
|
|
1109
|
-
var lineBreak = BREAK_NOT_ALLOWED$1;
|
|
1110
|
-
while (nextIndex < length && (lineBreak = _lineBreakAtIndex(codePoints, classTypes, indicies, ++nextIndex, forbiddenBreakpoints)) === BREAK_NOT_ALLOWED$1);
|
|
1111
|
-
if (lineBreak !== BREAK_NOT_ALLOWED$1 || nextIndex === length) {
|
|
1112
|
-
var value = new Break(codePoints, lineBreak, lastEnd, nextIndex);
|
|
1113
|
-
lastEnd = nextIndex;
|
|
1114
|
-
return {
|
|
1115
|
-
value,
|
|
1116
|
-
done: false
|
|
1117
|
-
};
|
|
1118
|
-
}
|
|
1119
|
-
return {
|
|
1120
|
-
done: true,
|
|
1121
|
-
value: null
|
|
1122
|
-
};
|
|
1123
|
-
} };
|
|
1124
|
-
};
|
|
1125
|
-
//#endregion
|
|
1126
618
|
//#region src/core/util.ts
|
|
1127
619
|
/**
|
|
1128
620
|
* Indexed access where the shape/arity is guaranteed by construction (the CSS
|
|
@@ -1178,7 +670,7 @@ const stringToNumber = (codePoints) => {
|
|
|
1178
670
|
integers.push(at(codePoints, c));
|
|
1179
671
|
c++;
|
|
1180
672
|
}
|
|
1181
|
-
const int = integers.length ? parseInt(fromCodePoint
|
|
673
|
+
const int = integers.length ? parseInt(String.fromCodePoint(...integers), 10) : 0;
|
|
1182
674
|
if (codePoints[c] === 46) c++;
|
|
1183
675
|
const fraction = [];
|
|
1184
676
|
while (isDigit(codePoints[c] ?? NaN)) {
|
|
@@ -1186,7 +678,7 @@ const stringToNumber = (codePoints) => {
|
|
|
1186
678
|
c++;
|
|
1187
679
|
}
|
|
1188
680
|
const fracd = fraction.length;
|
|
1189
|
-
const frac = fracd ? parseInt(fromCodePoint
|
|
681
|
+
const frac = fracd ? parseInt(String.fromCodePoint(...fraction), 10) : 0;
|
|
1190
682
|
if (codePoints[c] === 69 || codePoints[c] === 101) c++;
|
|
1191
683
|
let expsign = 1;
|
|
1192
684
|
if (codePoints[c] === 43 || codePoints[c] === 45) {
|
|
@@ -1198,7 +690,7 @@ const stringToNumber = (codePoints) => {
|
|
|
1198
690
|
exponent.push(at(codePoints, c));
|
|
1199
691
|
c++;
|
|
1200
692
|
}
|
|
1201
|
-
const exp = exponent.length ? parseInt(fromCodePoint
|
|
693
|
+
const exp = exponent.length ? parseInt(String.fromCodePoint(...exponent), 10) : 0;
|
|
1202
694
|
return sign * (int + frac * Math.pow(10, -fracd)) * Math.pow(10, expsign * exp);
|
|
1203
695
|
};
|
|
1204
696
|
//#endregion
|
|
@@ -1227,12 +719,8 @@ const EOF_TOKEN = { type: 32 };
|
|
|
1227
719
|
//#endregion
|
|
1228
720
|
//#region src/css/syntax/tokenizer.ts
|
|
1229
721
|
var Tokenizer = class Tokenizer {
|
|
1230
|
-
static
|
|
1231
|
-
|
|
1232
|
-
}
|
|
1233
|
-
static {
|
|
1234
|
-
this.MAX_POOL_SIZE = 40;
|
|
1235
|
-
}
|
|
722
|
+
static _pool = [];
|
|
723
|
+
static MAX_POOL_SIZE = 40;
|
|
1236
724
|
static get() {
|
|
1237
725
|
return Tokenizer._pool.pop() || new Tokenizer();
|
|
1238
726
|
}
|
|
@@ -1242,14 +730,29 @@ var Tokenizer = class Tokenizer {
|
|
|
1242
730
|
Tokenizer._pool.push(tokenizer);
|
|
1243
731
|
}
|
|
1244
732
|
}
|
|
733
|
+
_value;
|
|
734
|
+
/**
|
|
735
|
+
* Read cursor into `_value`. Consumption advances the cursor instead of
|
|
736
|
+
* shifting the array — `Array.shift()` per code point makes tokenising a
|
|
737
|
+
* long value O(n²) (a 200 KB inline data-URI background alone would cost
|
|
738
|
+
* billions of operations, and background-image values are never parse-
|
|
739
|
+
* cached). `write()` compacts already-consumed prefix bytes.
|
|
740
|
+
*/
|
|
741
|
+
_cursor;
|
|
1245
742
|
constructor() {
|
|
1246
743
|
this._value = [];
|
|
744
|
+
this._cursor = 0;
|
|
1247
745
|
}
|
|
1248
746
|
_reset() {
|
|
1249
747
|
this._value = [];
|
|
748
|
+
this._cursor = 0;
|
|
1250
749
|
}
|
|
1251
750
|
write(chunk) {
|
|
1252
|
-
this.
|
|
751
|
+
if (this._cursor > 0) {
|
|
752
|
+
this._value = this._value.slice(this._cursor);
|
|
753
|
+
this._cursor = 0;
|
|
754
|
+
}
|
|
755
|
+
this._value = this._value.concat([...chunk].map((char) => char.codePointAt(0)));
|
|
1253
756
|
}
|
|
1254
757
|
read() {
|
|
1255
758
|
const tokens = [];
|
|
@@ -1417,19 +920,21 @@ var Tokenizer = class Tokenizer {
|
|
|
1417
920
|
}
|
|
1418
921
|
return {
|
|
1419
922
|
type: 6,
|
|
1420
|
-
value: fromCodePoint
|
|
923
|
+
value: String.fromCodePoint(codePoint)
|
|
1421
924
|
};
|
|
1422
925
|
}
|
|
1423
926
|
consumeCodePoint() {
|
|
1424
|
-
const value = this._value.
|
|
1425
|
-
|
|
927
|
+
const value = this._value[this._cursor];
|
|
928
|
+
if (value === void 0) return -1;
|
|
929
|
+
this._cursor++;
|
|
930
|
+
return value;
|
|
1426
931
|
}
|
|
1427
932
|
reconsumeCodePoint(codePoint) {
|
|
1428
|
-
this._value.
|
|
933
|
+
if (this._cursor > 0 && this._value[this._cursor - 1] === codePoint) this._cursor--;
|
|
934
|
+
else this._value.splice(this._cursor, 0, codePoint);
|
|
1429
935
|
}
|
|
1430
936
|
peekCodePoint(delta) {
|
|
1431
|
-
|
|
1432
|
-
const codePoint = this._value[delta];
|
|
937
|
+
const codePoint = this._value[this._cursor + delta];
|
|
1433
938
|
return codePoint !== void 0 ? codePoint : -1;
|
|
1434
939
|
}
|
|
1435
940
|
consumeUnicodeRangeToken() {
|
|
@@ -1447,10 +952,10 @@ var Tokenizer = class Tokenizer {
|
|
|
1447
952
|
}
|
|
1448
953
|
if (questionMarks) return {
|
|
1449
954
|
type: 30,
|
|
1450
|
-
start: parseInt(fromCodePoint
|
|
1451
|
-
end: parseInt(fromCodePoint
|
|
955
|
+
start: parseInt(String.fromCodePoint(...digits.map((digit) => digit === 63 ? 48 : digit)), 16),
|
|
956
|
+
end: parseInt(String.fromCodePoint(...digits.map((digit) => digit === 63 ? 70 : digit)), 16)
|
|
1452
957
|
};
|
|
1453
|
-
const start = parseInt(fromCodePoint
|
|
958
|
+
const start = parseInt(String.fromCodePoint(...digits), 16);
|
|
1454
959
|
if (codePoint === 45 && isHex(this.peekCodePoint(0))) {
|
|
1455
960
|
codePoint = this.consumeCodePoint();
|
|
1456
961
|
const endDigits = [];
|
|
@@ -1461,7 +966,7 @@ var Tokenizer = class Tokenizer {
|
|
|
1461
966
|
return {
|
|
1462
967
|
type: 30,
|
|
1463
968
|
start,
|
|
1464
|
-
end: parseInt(fromCodePoint
|
|
969
|
+
end: parseInt(String.fromCodePoint(...endDigits), 16)
|
|
1465
970
|
};
|
|
1466
971
|
} else return {
|
|
1467
972
|
type: 30,
|
|
@@ -1513,7 +1018,7 @@ var Tokenizer = class Tokenizer {
|
|
|
1513
1018
|
const codePoint = this.consumeCodePoint();
|
|
1514
1019
|
if (codePoint === -1 || codePoint === 41) return {
|
|
1515
1020
|
type: 22,
|
|
1516
|
-
value: fromCodePoint
|
|
1021
|
+
value: String.fromCodePoint(...value)
|
|
1517
1022
|
};
|
|
1518
1023
|
else if (isWhiteSpace(codePoint)) {
|
|
1519
1024
|
this.consumeWhiteSpace();
|
|
@@ -1521,7 +1026,7 @@ var Tokenizer = class Tokenizer {
|
|
|
1521
1026
|
this.consumeCodePoint();
|
|
1522
1027
|
return {
|
|
1523
1028
|
type: 22,
|
|
1524
|
-
value: fromCodePoint
|
|
1029
|
+
value: String.fromCodePoint(...value)
|
|
1525
1030
|
};
|
|
1526
1031
|
}
|
|
1527
1032
|
this.consumeBadUrlRemnants();
|
|
@@ -1551,19 +1056,21 @@ var Tokenizer = class Tokenizer {
|
|
|
1551
1056
|
consumeStringSlice(count) {
|
|
1552
1057
|
const SLICE_STACK_SIZE = 5e4;
|
|
1553
1058
|
let value = "";
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1059
|
+
const end = this._cursor + count;
|
|
1060
|
+
let from = this._cursor;
|
|
1061
|
+
while (from < end) {
|
|
1062
|
+
const to = Math.min(end, from + SLICE_STACK_SIZE);
|
|
1063
|
+
value += String.fromCodePoint(...this._value.slice(from, to));
|
|
1064
|
+
from = to;
|
|
1065
|
+
}
|
|
1066
|
+
this._cursor = end + 1;
|
|
1560
1067
|
return value;
|
|
1561
1068
|
}
|
|
1562
1069
|
consumeStringToken(endingCodePoint) {
|
|
1563
1070
|
let value = "";
|
|
1564
1071
|
let i = 0;
|
|
1565
1072
|
do {
|
|
1566
|
-
const codePoint = this._value[i];
|
|
1073
|
+
const codePoint = this._value[this._cursor + i];
|
|
1567
1074
|
if (codePoint === -1 || codePoint === void 0 || codePoint === endingCodePoint) {
|
|
1568
1075
|
value += this.consumeStringSlice(i);
|
|
1569
1076
|
return {
|
|
@@ -1572,19 +1079,19 @@ var Tokenizer = class Tokenizer {
|
|
|
1572
1079
|
};
|
|
1573
1080
|
}
|
|
1574
1081
|
if (codePoint === 10) {
|
|
1575
|
-
this.
|
|
1082
|
+
this._cursor += i;
|
|
1576
1083
|
return BAD_STRING_TOKEN;
|
|
1577
1084
|
}
|
|
1578
1085
|
if (codePoint === 92) {
|
|
1579
|
-
const next = this._value[i + 1];
|
|
1086
|
+
const next = this._value[this._cursor + i + 1];
|
|
1580
1087
|
if (next !== -1 && next !== void 0) {
|
|
1581
1088
|
if (next === 10) {
|
|
1582
1089
|
value += this.consumeStringSlice(i);
|
|
1583
1090
|
i = -1;
|
|
1584
|
-
this.
|
|
1091
|
+
this._cursor++;
|
|
1585
1092
|
} else if (isValidEscape(codePoint, next)) {
|
|
1586
1093
|
value += this.consumeStringSlice(i);
|
|
1587
|
-
value += fromCodePoint
|
|
1094
|
+
value += String.fromCodePoint(this.consumeEscapedCodePoint());
|
|
1588
1095
|
i = -1;
|
|
1589
1096
|
}
|
|
1590
1097
|
}
|
|
@@ -1643,8 +1150,8 @@ var Tokenizer = class Tokenizer {
|
|
|
1643
1150
|
consumeEscapedCodePoint() {
|
|
1644
1151
|
const codePoint = this.consumeCodePoint();
|
|
1645
1152
|
if (isHex(codePoint)) {
|
|
1646
|
-
let hex = fromCodePoint
|
|
1647
|
-
while (isHex(this.peekCodePoint(0)) && hex.length < 6) hex += fromCodePoint
|
|
1153
|
+
let hex = String.fromCodePoint(codePoint);
|
|
1154
|
+
while (isHex(this.peekCodePoint(0)) && hex.length < 6) hex += String.fromCodePoint(this.consumeCodePoint());
|
|
1648
1155
|
if (isWhiteSpace(this.peekCodePoint(0))) this.consumeCodePoint();
|
|
1649
1156
|
const hexCodePoint = parseInt(hex, 16);
|
|
1650
1157
|
if (hexCodePoint === 0 || isSurrogateCodePoint(hexCodePoint) || hexCodePoint > 1114111) return REPLACEMENT_CHARACTER;
|
|
@@ -1657,8 +1164,8 @@ var Tokenizer = class Tokenizer {
|
|
|
1657
1164
|
let result = "";
|
|
1658
1165
|
while (true) {
|
|
1659
1166
|
const codePoint = this.consumeCodePoint();
|
|
1660
|
-
if (isNameCodePoint(codePoint)) result += fromCodePoint
|
|
1661
|
-
else if (isValidEscape(codePoint, this.peekCodePoint(0))) result += fromCodePoint
|
|
1167
|
+
if (isNameCodePoint(codePoint)) result += String.fromCodePoint(codePoint);
|
|
1168
|
+
else if (isValidEscape(codePoint, this.peekCodePoint(0))) result += String.fromCodePoint(this.consumeEscapedCodePoint());
|
|
1662
1169
|
else {
|
|
1663
1170
|
this.reconsumeCodePoint(codePoint);
|
|
1664
1171
|
return result;
|
|
@@ -1669,6 +1176,7 @@ var Tokenizer = class Tokenizer {
|
|
|
1669
1176
|
//#endregion
|
|
1670
1177
|
//#region src/css/syntax/parser.ts
|
|
1671
1178
|
var Parser = class Parser {
|
|
1179
|
+
_tokens;
|
|
1672
1180
|
constructor(tokens) {
|
|
1673
1181
|
this._tokens = tokens;
|
|
1674
1182
|
}
|
|
@@ -2198,13 +1706,17 @@ const packXYZ = (args) => {
|
|
|
2198
1706
|
};
|
|
2199
1707
|
const packLab = (_context, args) => {
|
|
2200
1708
|
if (isRelativeTransform(args.filter(nonFunctionArgSeparator))) throw new Error("Relative color not supported for lab()");
|
|
2201
|
-
const [
|
|
1709
|
+
const [extractedL, a, b, alpha] = extractLabComponents(args), l = isPercentageLightness(args) ? extractedL * 100 : extractedL, rgb = srgbLinear2rgb(xyz2rgbLinear(lab2xyz([
|
|
2202
1710
|
l,
|
|
2203
1711
|
a,
|
|
2204
1712
|
b
|
|
2205
1713
|
])));
|
|
2206
1714
|
return pack(clamp(Math.round(rgb[0] * 255), 0, 255), clamp(Math.round(rgb[1] * 255), 0, 255), clamp(Math.round(rgb[2] * 255), 0, 255), alpha);
|
|
2207
1715
|
};
|
|
1716
|
+
const isPercentageLightness = (args) => {
|
|
1717
|
+
const t0 = args.filter(nonFunctionArgSeparator)[0];
|
|
1718
|
+
return t0 !== void 0 && t0.type === 16;
|
|
1719
|
+
};
|
|
2208
1720
|
const packOkLab = (_context, args) => {
|
|
2209
1721
|
if (isRelativeTransform(args.filter(nonFunctionArgSeparator))) throw new Error("Relative color not supported for oklab()");
|
|
2210
1722
|
const [l, a, b, alpha] = extractLabComponents(args), rgb = srgbLinear2rgb(xyz2rgbLinear(oklab2xyz([
|
|
@@ -2233,7 +1745,7 @@ const packLch = (_context, args) => {
|
|
|
2233
1745
|
return pack(clamp(Math.round(rgb[0] * 255), 0, 255), clamp(Math.round(rgb[1] * 255), 0, 255), clamp(Math.round(rgb[2] * 255), 0, 255), a);
|
|
2234
1746
|
};
|
|
2235
1747
|
const extractHslComponents = (context, args) => {
|
|
2236
|
-
const tokens = args.filter(nonFunctionArgSeparator), hue = tokens[0], saturation = tokens[1], lightness = tokens[2], alpha = tokens[3];
|
|
1748
|
+
const tokens = args.filter(nonFunctionArgSeparator), hue = tokens[0], saturation = tokens[1], lightness = tokens[2], slash = tokens[3], alpha = slash !== void 0 && slash.type === 6 && slash.value === "/" ? tokens[4] : tokens[3];
|
|
2237
1749
|
return [
|
|
2238
1750
|
hue ? (hue.type === 17 ? deg(hue.number) : angle.parse(context, hue)) / (Math.PI * 2) : 0,
|
|
2239
1751
|
saturation !== void 0 && isLengthPercentage(saturation) ? saturation.number / 100 : 0,
|
|
@@ -2248,7 +1760,7 @@ const packHSL = (context, args) => {
|
|
|
2248
1760
|
s,
|
|
2249
1761
|
l
|
|
2250
1762
|
]);
|
|
2251
|
-
return pack(rgb[0] * 255, rgb[1] * 255, rgb[2] * 255,
|
|
1763
|
+
return pack(rgb[0] * 255, rgb[1] * 255, rgb[2] * 255, a);
|
|
2252
1764
|
};
|
|
2253
1765
|
const extractLchComponents = (args) => {
|
|
2254
1766
|
const tokens = args.filter(nonFunctionArgSeparator), t0 = tokens[0], t1 = tokens[1], t2 = tokens[2], t4 = tokens[4];
|
|
@@ -2323,9 +1835,9 @@ const hue2rgb = (t1, t2, hue) => {
|
|
|
2323
1835
|
};
|
|
2324
1836
|
const hsl2rgb = ([h, s, l]) => {
|
|
2325
1837
|
if (s === 0) return [
|
|
2326
|
-
l
|
|
2327
|
-
l
|
|
2328
|
-
l
|
|
1838
|
+
l,
|
|
1839
|
+
l,
|
|
1840
|
+
l
|
|
2329
1841
|
];
|
|
2330
1842
|
const t2 = l <= .5 ? l * (s + 1) : l + s - l * s, t1 = l * 2 - t2;
|
|
2331
1843
|
return [
|
|
@@ -3075,6 +2587,393 @@ const convertRec2020 = (args) => {
|
|
|
3075
2587
|
]);
|
|
3076
2588
|
};
|
|
3077
2589
|
//#endregion
|
|
2590
|
+
//#region src/css/types/functions/color-mix.ts
|
|
2591
|
+
const HUE_DEG_INDEX = {
|
|
2592
|
+
lch: 2,
|
|
2593
|
+
oklch: 2,
|
|
2594
|
+
hsl: 0
|
|
2595
|
+
};
|
|
2596
|
+
const XYZ_FROM_LMS = [
|
|
2597
|
+
1.2268798758459243,
|
|
2598
|
+
-.5578149944602171,
|
|
2599
|
+
.2813910456659647,
|
|
2600
|
+
-.0405757452148008,
|
|
2601
|
+
1.112286803280317,
|
|
2602
|
+
-.0717110580655164,
|
|
2603
|
+
-.0763729366746601,
|
|
2604
|
+
-.4214933324022432,
|
|
2605
|
+
1.5869240198367816
|
|
2606
|
+
];
|
|
2607
|
+
const LMS_FROM_OKLAB = [
|
|
2608
|
+
1,
|
|
2609
|
+
.3963377773761749,
|
|
2610
|
+
.2158037573099136,
|
|
2611
|
+
1,
|
|
2612
|
+
-.1055613458156586,
|
|
2613
|
+
-.0638541728258133,
|
|
2614
|
+
1,
|
|
2615
|
+
-.0894841775298119,
|
|
2616
|
+
-1.2914855480194092
|
|
2617
|
+
];
|
|
2618
|
+
const matrix3Inverse = (m) => {
|
|
2619
|
+
const a = m[0], b = m[1], c = m[2], d = m[3], e = m[4], f = m[5], g = m[6], h = m[7], i = m[8];
|
|
2620
|
+
const det = a * (e * i - f * h) - b * (d * i - f * g) + c * (d * h - e * g);
|
|
2621
|
+
return [
|
|
2622
|
+
(e * i - f * h) / det,
|
|
2623
|
+
(c * h - b * i) / det,
|
|
2624
|
+
(b * f - c * e) / det,
|
|
2625
|
+
(f * g - d * i) / det,
|
|
2626
|
+
(a * i - c * g) / det,
|
|
2627
|
+
(c * d - a * f) / det,
|
|
2628
|
+
(d * h - e * g) / det,
|
|
2629
|
+
(b * g - a * h) / det,
|
|
2630
|
+
(a * e - b * d) / det
|
|
2631
|
+
];
|
|
2632
|
+
};
|
|
2633
|
+
const XYZ_TO_LMS = matrix3Inverse(XYZ_FROM_LMS);
|
|
2634
|
+
const OKLAB_FROM_LMS = matrix3Inverse(LMS_FROM_OKLAB);
|
|
2635
|
+
const LAB_K = 24389 / 27;
|
|
2636
|
+
const LAB_E = 24 / 116;
|
|
2637
|
+
const LAB_E3 = LAB_E * LAB_E * LAB_E;
|
|
2638
|
+
const LAB_X_SCALE = .3457 / .3585;
|
|
2639
|
+
const LAB_Z_SCALE = .2958 / .3585;
|
|
2640
|
+
const unpackSrgb = (color) => [
|
|
2641
|
+
(255 & color >> 24) / 255,
|
|
2642
|
+
(255 & color >> 16) / 255,
|
|
2643
|
+
(255 & color >> 8) / 255
|
|
2644
|
+
];
|
|
2645
|
+
/** Inverse of color-utilities' lab2xyz: D65 XYZ → CIE Lab (0..100 scale). */
|
|
2646
|
+
const xyzD65ToLab = (xyz) => {
|
|
2647
|
+
const [x50, y50, z50] = d65toD50([
|
|
2648
|
+
xyz[0],
|
|
2649
|
+
xyz[1],
|
|
2650
|
+
xyz[2]
|
|
2651
|
+
]);
|
|
2652
|
+
const xi = x50 / LAB_X_SCALE;
|
|
2653
|
+
const yi = y50;
|
|
2654
|
+
const zi = z50 / LAB_Z_SCALE;
|
|
2655
|
+
const fx = xi > LAB_E3 ? Math.cbrt(xi) : (LAB_K * xi + 16) / 116;
|
|
2656
|
+
const fy = yi > LAB_E3 ? Math.cbrt(yi) : (LAB_K * yi + 16) / 116;
|
|
2657
|
+
const fz = zi > LAB_E3 ? Math.cbrt(zi) : (LAB_K * zi + 16) / 116;
|
|
2658
|
+
return [
|
|
2659
|
+
116 * fy - 16,
|
|
2660
|
+
500 * (fx - fy),
|
|
2661
|
+
200 * (fy - fz)
|
|
2662
|
+
];
|
|
2663
|
+
};
|
|
2664
|
+
/** D65 XYZ → OKLab via the inverted forward matrices. */
|
|
2665
|
+
const xyzD65ToOklab = (xyz) => {
|
|
2666
|
+
const lms = multiplyMatrices(XYZ_TO_LMS, xyz);
|
|
2667
|
+
const lmsCbrt = [
|
|
2668
|
+
Math.cbrt(lms[0]),
|
|
2669
|
+
Math.cbrt(lms[1]),
|
|
2670
|
+
Math.cbrt(lms[2])
|
|
2671
|
+
];
|
|
2672
|
+
return multiplyMatrices(OKLAB_FROM_LMS, lmsCbrt);
|
|
2673
|
+
};
|
|
2674
|
+
/** Lab/Oklab rectangular coordinates → polar LCH (hue in degrees). */
|
|
2675
|
+
const labToLch = (lab) => {
|
|
2676
|
+
const c = Math.hypot(lab[1], lab[2]);
|
|
2677
|
+
const h = Math.atan2(lab[2], lab[1]) * 180 / Math.PI;
|
|
2678
|
+
return [
|
|
2679
|
+
lab[0],
|
|
2680
|
+
c,
|
|
2681
|
+
(h + 360) % 360
|
|
2682
|
+
];
|
|
2683
|
+
};
|
|
2684
|
+
/** Gamma sRGB (0..1) → HSL with hue in turns (0..1), matching hsl2rgb input. */
|
|
2685
|
+
const rgbToHslTurns = (rgb) => {
|
|
2686
|
+
const r = rgb[0], g = rgb[1], b = rgb[2];
|
|
2687
|
+
const max = Math.max(r, g, b);
|
|
2688
|
+
const min = Math.min(r, g, b);
|
|
2689
|
+
const l = (max + min) / 2;
|
|
2690
|
+
if (max === min) return [
|
|
2691
|
+
0,
|
|
2692
|
+
0,
|
|
2693
|
+
l
|
|
2694
|
+
];
|
|
2695
|
+
const d = max - min;
|
|
2696
|
+
const s = l > .5 ? d / (2 - max - min) : d / (max + min);
|
|
2697
|
+
let h;
|
|
2698
|
+
if (max === r) h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
|
|
2699
|
+
else if (max === g) h = ((b - r) / d + 2) / 6;
|
|
2700
|
+
else h = ((r - g) / d + 4) / 6;
|
|
2701
|
+
return [
|
|
2702
|
+
h,
|
|
2703
|
+
s,
|
|
2704
|
+
l
|
|
2705
|
+
];
|
|
2706
|
+
};
|
|
2707
|
+
/** Packed color → coordinates in the given space, alpha kept on a 0..1 scale. */
|
|
2708
|
+
const toCoords = (color, space) => {
|
|
2709
|
+
const a = (255 & color) / 255;
|
|
2710
|
+
const rgb = unpackSrgb(color);
|
|
2711
|
+
const linear = rgb2rgbLinear(rgb);
|
|
2712
|
+
const xyz = rgbLinear2xyz(linear);
|
|
2713
|
+
let coords;
|
|
2714
|
+
switch (space) {
|
|
2715
|
+
case "srgb":
|
|
2716
|
+
coords = rgb;
|
|
2717
|
+
break;
|
|
2718
|
+
case "srgb-linear":
|
|
2719
|
+
coords = linear;
|
|
2720
|
+
break;
|
|
2721
|
+
case "xyz":
|
|
2722
|
+
case "xyz-d65":
|
|
2723
|
+
coords = xyz;
|
|
2724
|
+
break;
|
|
2725
|
+
case "xyz-d50":
|
|
2726
|
+
coords = d65toD50(xyz);
|
|
2727
|
+
break;
|
|
2728
|
+
case "lab":
|
|
2729
|
+
coords = xyzD65ToLab(xyz);
|
|
2730
|
+
break;
|
|
2731
|
+
case "oklab":
|
|
2732
|
+
coords = xyzD65ToOklab(xyz);
|
|
2733
|
+
break;
|
|
2734
|
+
case "lch":
|
|
2735
|
+
coords = labToLch(xyzD65ToLab(xyz));
|
|
2736
|
+
break;
|
|
2737
|
+
case "oklch":
|
|
2738
|
+
coords = labToLch(xyzD65ToOklab(xyz));
|
|
2739
|
+
break;
|
|
2740
|
+
case "hsl": coords = [
|
|
2741
|
+
rgbToHslTurns(rgb)[0] * 360,
|
|
2742
|
+
rgbToHslTurns(rgb)[1],
|
|
2743
|
+
rgbToHslTurns(rgb)[2]
|
|
2744
|
+
];
|
|
2745
|
+
}
|
|
2746
|
+
return [
|
|
2747
|
+
coords[0],
|
|
2748
|
+
coords[1],
|
|
2749
|
+
coords[2],
|
|
2750
|
+
a
|
|
2751
|
+
];
|
|
2752
|
+
};
|
|
2753
|
+
/** Coordinates in the given space → packed color. */
|
|
2754
|
+
const fromCoords = (coords, space) => {
|
|
2755
|
+
const c0 = coords[0], c1 = coords[1], c2 = coords[2], a = coords[3];
|
|
2756
|
+
switch (space) {
|
|
2757
|
+
case "srgb": return packSrgb([
|
|
2758
|
+
c0,
|
|
2759
|
+
c1,
|
|
2760
|
+
c2,
|
|
2761
|
+
a
|
|
2762
|
+
]);
|
|
2763
|
+
case "srgb-linear": return packSrgbLinear([
|
|
2764
|
+
c0,
|
|
2765
|
+
c1,
|
|
2766
|
+
c2,
|
|
2767
|
+
a
|
|
2768
|
+
]);
|
|
2769
|
+
case "xyz":
|
|
2770
|
+
case "xyz-d65": return packXYZ([
|
|
2771
|
+
c0,
|
|
2772
|
+
c1,
|
|
2773
|
+
c2,
|
|
2774
|
+
a
|
|
2775
|
+
]);
|
|
2776
|
+
case "xyz-d50": return packXYZ([...d50toD65([
|
|
2777
|
+
c0,
|
|
2778
|
+
c1,
|
|
2779
|
+
c2
|
|
2780
|
+
]), a]);
|
|
2781
|
+
case "lab": return packViaXyz(lab2xyz([
|
|
2782
|
+
c0,
|
|
2783
|
+
c1,
|
|
2784
|
+
c2
|
|
2785
|
+
]), a);
|
|
2786
|
+
case "oklab": return packViaXyz(oklab2xyz([
|
|
2787
|
+
c0,
|
|
2788
|
+
c1,
|
|
2789
|
+
c2
|
|
2790
|
+
]), a);
|
|
2791
|
+
case "lch": return packViaXyz(lab2xyz(lch2lab([
|
|
2792
|
+
c0,
|
|
2793
|
+
c1,
|
|
2794
|
+
c2
|
|
2795
|
+
])), a);
|
|
2796
|
+
case "oklch": return packViaXyz(oklab2xyz(lch2lab([
|
|
2797
|
+
c0,
|
|
2798
|
+
c1,
|
|
2799
|
+
c2
|
|
2800
|
+
])), a);
|
|
2801
|
+
case "hsl": {
|
|
2802
|
+
const rgb = hsl2rgb([
|
|
2803
|
+
c0 / 360,
|
|
2804
|
+
c1,
|
|
2805
|
+
c2
|
|
2806
|
+
]);
|
|
2807
|
+
return packSrgb([
|
|
2808
|
+
rgb[0],
|
|
2809
|
+
rgb[1],
|
|
2810
|
+
rgb[2],
|
|
2811
|
+
a
|
|
2812
|
+
]);
|
|
2813
|
+
}
|
|
2814
|
+
}
|
|
2815
|
+
};
|
|
2816
|
+
const packViaXyz = (xyz, a) => {
|
|
2817
|
+
const rgb = srgbLinear2rgb(xyz2rgbLinear(xyz));
|
|
2818
|
+
return packSrgb([
|
|
2819
|
+
rgb[0],
|
|
2820
|
+
rgb[1],
|
|
2821
|
+
rgb[2],
|
|
2822
|
+
a
|
|
2823
|
+
]);
|
|
2824
|
+
};
|
|
2825
|
+
/**
|
|
2826
|
+
* Interpolate a hue angle in degrees per css-color-4 §12.4. `weight1` and
|
|
2827
|
+
* `weight2` are the (normalized) mix weights; the hue travels from h1 towards
|
|
2828
|
+
* h2 by the shared fraction. Exported for unit tests.
|
|
2829
|
+
*/
|
|
2830
|
+
const interpolateHue = (h1, h2, weight1, weight2, method = "shorter") => {
|
|
2831
|
+
const wSum = weight1 + weight2;
|
|
2832
|
+
if (wSum === 0) return h1;
|
|
2833
|
+
let d = ((h2 - h1) % 360 + 360) % 360;
|
|
2834
|
+
switch (method) {
|
|
2835
|
+
case "shorter":
|
|
2836
|
+
if (d > 180) d -= 360;
|
|
2837
|
+
break;
|
|
2838
|
+
case "longer":
|
|
2839
|
+
if (d < 180) d -= 360;
|
|
2840
|
+
break;
|
|
2841
|
+
case "increasing": break;
|
|
2842
|
+
case "decreasing": if (d > 0) d -= 360;
|
|
2843
|
+
}
|
|
2844
|
+
return h1 + d * (weight2 / wSum);
|
|
2845
|
+
};
|
|
2846
|
+
const parseMixComponent = (context, tokens) => {
|
|
2847
|
+
let colorToken;
|
|
2848
|
+
let percentage = null;
|
|
2849
|
+
for (const token of tokens) {
|
|
2850
|
+
if (token.type === 31 || token.type === 4) continue;
|
|
2851
|
+
if (token.type === 16) percentage = token.number;
|
|
2852
|
+
else if (isIdentToken(token) && token.value === "none") {
|
|
2853
|
+
if (percentage === null) percentage = 0;
|
|
2854
|
+
} else if (colorToken === void 0) colorToken = token;
|
|
2855
|
+
else throw new Error(`Unexpected token in color-mix() component`);
|
|
2856
|
+
}
|
|
2857
|
+
if (colorToken === void 0) throw new Error("color-mix() component is missing a color");
|
|
2858
|
+
const token = colorToken;
|
|
2859
|
+
return {
|
|
2860
|
+
color: color$1.parse(context, token),
|
|
2861
|
+
percentage
|
|
2862
|
+
};
|
|
2863
|
+
};
|
|
2864
|
+
const SUPPORTED_SPACES = [
|
|
2865
|
+
"srgb",
|
|
2866
|
+
"srgb-linear",
|
|
2867
|
+
"lab",
|
|
2868
|
+
"oklab",
|
|
2869
|
+
"lch",
|
|
2870
|
+
"oklch",
|
|
2871
|
+
"hsl",
|
|
2872
|
+
"xyz",
|
|
2873
|
+
"xyz-d50",
|
|
2874
|
+
"xyz-d65"
|
|
2875
|
+
];
|
|
2876
|
+
const mixCoords = (c1, c2, w1, w2, space, hueMethod) => {
|
|
2877
|
+
const hueIdx = HUE_DEG_INDEX[space];
|
|
2878
|
+
const p1 = [
|
|
2879
|
+
c1[0] * c1[3],
|
|
2880
|
+
c1[1] * c1[3],
|
|
2881
|
+
c1[2] * c1[3],
|
|
2882
|
+
c1[3]
|
|
2883
|
+
];
|
|
2884
|
+
const p2 = [
|
|
2885
|
+
c2[0] * c2[3],
|
|
2886
|
+
c2[1] * c2[3],
|
|
2887
|
+
c2[2] * c2[3],
|
|
2888
|
+
c2[3]
|
|
2889
|
+
];
|
|
2890
|
+
const alpha = w1 * p1[3] + w2 * p2[3];
|
|
2891
|
+
if (alpha <= 0) return [
|
|
2892
|
+
0,
|
|
2893
|
+
0,
|
|
2894
|
+
0,
|
|
2895
|
+
0
|
|
2896
|
+
];
|
|
2897
|
+
const out = [
|
|
2898
|
+
0,
|
|
2899
|
+
0,
|
|
2900
|
+
0,
|
|
2901
|
+
alpha
|
|
2902
|
+
];
|
|
2903
|
+
for (let i = 0; i < 3; i++) {
|
|
2904
|
+
if (i === hueIdx) continue;
|
|
2905
|
+
out[i] = (w1 * at(p1, i) + w2 * at(p2, i)) / alpha;
|
|
2906
|
+
}
|
|
2907
|
+
if (hueIdx !== void 0) {
|
|
2908
|
+
let h1 = at(c1, hueIdx);
|
|
2909
|
+
let h2 = at(c2, hueIdx);
|
|
2910
|
+
if (c1[1] === 0) h1 = h2;
|
|
2911
|
+
if (c2[1] === 0) h2 = h1;
|
|
2912
|
+
out[hueIdx] = interpolateHue(h1, h2, w1, w2, hueMethod);
|
|
2913
|
+
}
|
|
2914
|
+
return out;
|
|
2915
|
+
};
|
|
2916
|
+
const computeColorMix = (context, args) => {
|
|
2917
|
+
const groups = [[]];
|
|
2918
|
+
for (const token of args) if (token.type === 4) groups.push([]);
|
|
2919
|
+
else groups[groups.length - 1].push(token);
|
|
2920
|
+
const meaningful = groups.map((group) => group.filter((t) => t.type !== 31));
|
|
2921
|
+
if (meaningful.length !== 3) throw new Error("color-mix() requires exactly two color components");
|
|
2922
|
+
const header = meaningful[0];
|
|
2923
|
+
const inKeyword = header ? header[0] : void 0;
|
|
2924
|
+
const hasInKeyword = inKeyword !== void 0 && isIdentToken(inKeyword) && inKeyword.value === "in";
|
|
2925
|
+
if (!header || header.length < 2 || !hasInKeyword) throw new Error("color-mix() requires an interpolation space after `in`");
|
|
2926
|
+
const spaceIdent = header[1];
|
|
2927
|
+
if (!spaceIdent || !isIdentToken(spaceIdent)) throw new Error("color-mix() space must be an identifier");
|
|
2928
|
+
const space = spaceIdent.value;
|
|
2929
|
+
if (SUPPORTED_SPACES.indexOf(space) === -1) throw new Error(`Unsupported color-mix() interpolation space "${space}"`);
|
|
2930
|
+
let hueMethod = "shorter";
|
|
2931
|
+
const rest = header.slice(2);
|
|
2932
|
+
if (rest.length > 0) {
|
|
2933
|
+
const method = rest[0];
|
|
2934
|
+
const hueKeyword = rest[1];
|
|
2935
|
+
if (!method || !hueKeyword || !isIdentToken(method) || !isIdentToken(hueKeyword) || hueKeyword.value !== "hue") throw new Error("Unsupported color-mix() hue method syntax");
|
|
2936
|
+
if ([
|
|
2937
|
+
"shorter",
|
|
2938
|
+
"longer",
|
|
2939
|
+
"increasing",
|
|
2940
|
+
"decreasing"
|
|
2941
|
+
].indexOf(method.value) === -1) throw new Error(`Unsupported color-mix() hue method "${method.value}"`);
|
|
2942
|
+
hueMethod = method.value;
|
|
2943
|
+
}
|
|
2944
|
+
const group1 = meaningful[1];
|
|
2945
|
+
const group2 = meaningful[2];
|
|
2946
|
+
if (!group1 || !group2) throw new Error("color-mix() requires exactly two color components");
|
|
2947
|
+
const component1 = parseMixComponent(context, group1);
|
|
2948
|
+
const component2 = parseMixComponent(context, group2);
|
|
2949
|
+
let p1 = component1.percentage;
|
|
2950
|
+
let p2 = component2.percentage;
|
|
2951
|
+
if (p1 === null && p2 === null) {
|
|
2952
|
+
p1 = 50;
|
|
2953
|
+
p2 = 50;
|
|
2954
|
+
} else if (p1 === null) p1 = 100 - (p2 ?? 0);
|
|
2955
|
+
else if (p2 === null) p2 = 100 - p1;
|
|
2956
|
+
else {
|
|
2957
|
+
const sum = p1 + p2;
|
|
2958
|
+
if (sum > 0) {
|
|
2959
|
+
p1 = p1 / sum * 100;
|
|
2960
|
+
p2 = p2 / sum * 100;
|
|
2961
|
+
}
|
|
2962
|
+
}
|
|
2963
|
+
const weight1 = (p1 ?? 0) / 100;
|
|
2964
|
+
const weight2 = (p2 ?? 0) / 100;
|
|
2965
|
+
const mixed = mixCoords(toCoords(component1.color, space), toCoords(component2.color, space), weight1, weight2, space, hueMethod);
|
|
2966
|
+
return fromCoords(mixed, space);
|
|
2967
|
+
};
|
|
2968
|
+
const colorMix = (context, args) => {
|
|
2969
|
+
try {
|
|
2970
|
+
return computeColorMix(context, args);
|
|
2971
|
+
} catch (e) {
|
|
2972
|
+
context.logger.warn(`Unsupported color-mix() value: ${e instanceof Error ? e.message : e}`);
|
|
2973
|
+
return 0;
|
|
2974
|
+
}
|
|
2975
|
+
};
|
|
2976
|
+
//#endregion
|
|
3078
2977
|
//#region src/css/types/color.ts
|
|
3079
2978
|
const color$1 = {
|
|
3080
2979
|
name: "color",
|
|
@@ -3324,7 +3223,8 @@ const SUPPORTED_COLOR_FUNCTIONS = {
|
|
|
3324
3223
|
oklch: packOkLch,
|
|
3325
3224
|
oklab: packOkLab,
|
|
3326
3225
|
lab: packLab,
|
|
3327
|
-
color: _color
|
|
3226
|
+
color: _color,
|
|
3227
|
+
"color-mix": colorMix
|
|
3328
3228
|
};
|
|
3329
3229
|
const parseColor = (context, value) => color$1.parse(context, Parser.create(value).parseComponentValue());
|
|
3330
3230
|
const COLORS = {
|
|
@@ -3607,9 +3507,7 @@ const contains = (bit, value) => (bit & value) !== 0;
|
|
|
3607
3507
|
//#endregion
|
|
3608
3508
|
//#region src/css/types/functions/counter.ts
|
|
3609
3509
|
var CounterState = class {
|
|
3610
|
-
|
|
3611
|
-
this.counters = {};
|
|
3612
|
-
}
|
|
3510
|
+
counters = {};
|
|
3613
3511
|
getCounterValue(name) {
|
|
3614
3512
|
const counter = this.counters[name];
|
|
3615
3513
|
if (counter && counter.length) return at(counter, counter.length - 1);
|
|
@@ -3936,7 +3834,7 @@ const createCounterStyleWithSymbolResolver = (value, codePointRangeLength, isNum
|
|
|
3936
3834
|
};
|
|
3937
3835
|
const createCounterStyleFromRange = (value, codePointRangeStart, codePointRangeEnd, isNumeric, suffix) => {
|
|
3938
3836
|
const codePointRangeLength = codePointRangeEnd - codePointRangeStart + 1;
|
|
3939
|
-
return (value < 0 ? "-" : "") + (createCounterStyleWithSymbolResolver(Math.abs(value), codePointRangeLength, isNumeric, (codePoint) => fromCodePoint
|
|
3837
|
+
return (value < 0 ? "-" : "") + (createCounterStyleWithSymbolResolver(Math.abs(value), codePointRangeLength, isNumeric, (codePoint) => String.fromCodePoint(Math.floor(codePoint % codePointRangeLength) + codePointRangeStart)) + suffix);
|
|
3940
3838
|
};
|
|
3941
3839
|
const createCounterStyleFromSymbols = (value, symbols, suffix = ". ") => {
|
|
3942
3840
|
const codePointRangeLength = symbols.length;
|
|
@@ -4521,7 +4419,7 @@ const ELLIPSE = "ellipse";
|
|
|
4521
4419
|
const COVER = "cover";
|
|
4522
4420
|
const CONTAIN = "contain";
|
|
4523
4421
|
const radialGradient = (context, tokens) => {
|
|
4524
|
-
let shape =
|
|
4422
|
+
let shape = 1;
|
|
4525
4423
|
let size = 3;
|
|
4526
4424
|
const stops = [];
|
|
4527
4425
|
const position = [];
|
|
@@ -4594,7 +4492,7 @@ const radialGradient = (context, tokens) => {
|
|
|
4594
4492
|
//#endregion
|
|
4595
4493
|
//#region src/css/types/functions/-prefix-radial-gradient.ts
|
|
4596
4494
|
const prefixRadialGradient = (context, tokens) => {
|
|
4597
|
-
let shape =
|
|
4495
|
+
let shape = 1;
|
|
4598
4496
|
let size = 3;
|
|
4599
4497
|
const stops = [];
|
|
4600
4498
|
const position = [];
|
|
@@ -5987,28 +5885,37 @@ const filter = {
|
|
|
5987
5885
|
if (first.type === 20 && first.value === "none") return null;
|
|
5988
5886
|
}
|
|
5989
5887
|
const parts = [];
|
|
5990
|
-
for (const token of tokens)
|
|
5991
|
-
|
|
5992
|
-
|
|
5993
|
-
|
|
5994
|
-
|
|
5995
|
-
|
|
5996
|
-
|
|
5997
|
-
|
|
5998
|
-
|
|
5999
|
-
|
|
6000
|
-
|
|
6001
|
-
|
|
6002
|
-
|
|
6003
|
-
|
|
6004
|
-
|
|
6005
|
-
|
|
6006
|
-
|
|
6007
|
-
|
|
6008
|
-
|
|
6009
|
-
|
|
6010
|
-
|
|
6011
|
-
|
|
5888
|
+
for (const token of tokens) {
|
|
5889
|
+
if (token.type === 22) {
|
|
5890
|
+
parts.push(`url("${token.value}")`);
|
|
5891
|
+
continue;
|
|
5892
|
+
}
|
|
5893
|
+
if (token.type === 18) {
|
|
5894
|
+
const fn = token;
|
|
5895
|
+
const renderedArgs = renderFilterArgs(fn.values);
|
|
5896
|
+
switch (fn.name) {
|
|
5897
|
+
case "blur":
|
|
5898
|
+
parts.push(`blur(${renderedArgs})`);
|
|
5899
|
+
break;
|
|
5900
|
+
case "brightness":
|
|
5901
|
+
case "contrast":
|
|
5902
|
+
case "invert":
|
|
5903
|
+
case "opacity":
|
|
5904
|
+
case "saturate":
|
|
5905
|
+
case "sepia":
|
|
5906
|
+
parts.push(`${fn.name}(${renderedArgs})`);
|
|
5907
|
+
break;
|
|
5908
|
+
case "grayscale":
|
|
5909
|
+
parts.push(`grayscale(${renderedArgs})`);
|
|
5910
|
+
break;
|
|
5911
|
+
case "hue-rotate":
|
|
5912
|
+
parts.push(`hue-rotate(${renderedArgs})`);
|
|
5913
|
+
break;
|
|
5914
|
+
case "drop-shadow":
|
|
5915
|
+
parts.push(`drop-shadow(${renderedArgs})`);
|
|
5916
|
+
break;
|
|
5917
|
+
default: parts.push(`${fn.name}(${renderedArgs})`);
|
|
5918
|
+
}
|
|
6012
5919
|
}
|
|
6013
5920
|
}
|
|
6014
5921
|
return parts.length > 0 ? parts.join(" ") : null;
|
|
@@ -6577,8 +6484,47 @@ const webkitBoxReflect = {
|
|
|
6577
6484
|
};
|
|
6578
6485
|
}
|
|
6579
6486
|
};
|
|
6487
|
+
//#endregion
|
|
6488
|
+
//#region src/css/property-descriptors/translate.ts
|
|
6489
|
+
const translate = {
|
|
6490
|
+
name: "translate",
|
|
6491
|
+
initialValue: "none",
|
|
6492
|
+
prefix: false,
|
|
6493
|
+
type: 1,
|
|
6494
|
+
parse: (_context, tokens) => {
|
|
6495
|
+
const values = [];
|
|
6496
|
+
for (const token of tokens) if (isLengthPercentage(token)) values.push(token);
|
|
6497
|
+
if (values.length === 0) return null;
|
|
6498
|
+
return [at(values, 0), values.length > 1 ? at(values, 1) : ZERO_LENGTH];
|
|
6499
|
+
}
|
|
6500
|
+
};
|
|
6501
|
+
//#endregion
|
|
6502
|
+
//#region src/css/property-descriptors/scale.ts
|
|
6503
|
+
const scale = {
|
|
6504
|
+
name: "scale",
|
|
6505
|
+
initialValue: "none",
|
|
6506
|
+
prefix: false,
|
|
6507
|
+
type: 1,
|
|
6508
|
+
parse: (_context, tokens) => {
|
|
6509
|
+
const numbers = [];
|
|
6510
|
+
for (const token of tokens) if (isNumberToken(token)) numbers.push(token.number);
|
|
6511
|
+
if (numbers.length === 0) return null;
|
|
6512
|
+
return [at(numbers, 0), numbers.length > 1 ? at(numbers, 1) : at(numbers, 0)];
|
|
6513
|
+
}
|
|
6514
|
+
};
|
|
6580
6515
|
/** Z-axis mask offset used during box-shadow rendering. */
|
|
6581
6516
|
const SHADOW_MASK_OFFSET = 1e4;
|
|
6517
|
+
/**
|
|
6518
|
+
* Total time (ms) to wait for the cloned iframe document to become ready
|
|
6519
|
+
* after its load event. A missed deadline resolves with a warning (the
|
|
6520
|
+
* capture continues with a possibly incomplete document).
|
|
6521
|
+
*/
|
|
6522
|
+
const CLONE_READY_TIMEOUT_MS = 3e4;
|
|
6523
|
+
/**
|
|
6524
|
+
* Hard ceiling (ms) for the cloned iframe's load event itself. If the event
|
|
6525
|
+
* never fires, the mount is rejected instead of hanging forever.
|
|
6526
|
+
*/
|
|
6527
|
+
const IFRAME_LOAD_WATCHDOG_MS = 6e4;
|
|
6582
6528
|
//#endregion
|
|
6583
6529
|
//#region src/css/parse.ts
|
|
6584
6530
|
const STANDARD_PROPERTIES = [
|
|
@@ -6892,6 +6838,16 @@ const STANDARD_PROPERTIES = [
|
|
|
6892
6838
|
rotate,
|
|
6893
6839
|
"rotate"
|
|
6894
6840
|
],
|
|
6841
|
+
[
|
|
6842
|
+
"translate",
|
|
6843
|
+
translate,
|
|
6844
|
+
"translate"
|
|
6845
|
+
],
|
|
6846
|
+
[
|
|
6847
|
+
"scale",
|
|
6848
|
+
scale,
|
|
6849
|
+
"scale"
|
|
6850
|
+
],
|
|
6895
6851
|
[
|
|
6896
6852
|
"visibility",
|
|
6897
6853
|
visibility,
|
|
@@ -7143,10 +7099,15 @@ const parse = (context, descriptor, style) => {
|
|
|
7143
7099
|
/**
|
|
7144
7100
|
* Read-only grouped accessor for border-related CSS properties.
|
|
7145
7101
|
*
|
|
7102
|
+
* Convenience accessors only — the render pipeline reads the top-level
|
|
7103
|
+
* parsed fields directly. Some underlying properties are parsed but not
|
|
7104
|
+
* rendered; see docs/features.md "Known unsupported CSS features".
|
|
7105
|
+
*
|
|
7146
7106
|
* Provides structured access: `styles.border.topColor` as an alternative
|
|
7147
7107
|
* to the flat `styles.borderTopColor`. Both forms remain valid.
|
|
7148
7108
|
*/
|
|
7149
7109
|
var BorderStyles = class {
|
|
7110
|
+
styles;
|
|
7150
7111
|
constructor(styles) {
|
|
7151
7112
|
this.styles = styles;
|
|
7152
7113
|
}
|
|
@@ -7215,8 +7176,13 @@ var BorderStyles = class {
|
|
|
7215
7176
|
//#region src/css/grouped/background-styles.ts
|
|
7216
7177
|
/**
|
|
7217
7178
|
* Read-only grouped accessor for background-related CSS properties.
|
|
7179
|
+
*
|
|
7180
|
+
* Convenience accessors only — the render pipeline reads the top-level
|
|
7181
|
+
* parsed fields directly. Some underlying properties are parsed but not
|
|
7182
|
+
* rendered; see docs/features.md "Known unsupported CSS features".
|
|
7218
7183
|
*/
|
|
7219
7184
|
var BackgroundStyles = class {
|
|
7185
|
+
styles;
|
|
7220
7186
|
constructor(styles) {
|
|
7221
7187
|
this.styles = styles;
|
|
7222
7188
|
}
|
|
@@ -7249,8 +7215,13 @@ var BackgroundStyles = class {
|
|
|
7249
7215
|
//#region src/css/grouped/font-styles.ts
|
|
7250
7216
|
/**
|
|
7251
7217
|
* Read-only grouped accessor for font/text-related CSS properties.
|
|
7218
|
+
*
|
|
7219
|
+
* Convenience accessors only — the render pipeline reads the top-level
|
|
7220
|
+
* parsed fields directly. Some underlying properties are parsed but not
|
|
7221
|
+
* rendered; see docs/features.md "Known unsupported CSS features".
|
|
7252
7222
|
*/
|
|
7253
7223
|
var FontStyles = class {
|
|
7224
|
+
styles;
|
|
7254
7225
|
constructor(styles) {
|
|
7255
7226
|
this.styles = styles;
|
|
7256
7227
|
}
|
|
@@ -7340,8 +7311,13 @@ var FontStyles = class {
|
|
|
7340
7311
|
//#region src/css/grouped/layout-styles.ts
|
|
7341
7312
|
/**
|
|
7342
7313
|
* Read-only grouped accessor for layout/display/positioning CSS properties.
|
|
7314
|
+
*
|
|
7315
|
+
* Convenience accessors only — the render pipeline reads the top-level
|
|
7316
|
+
* parsed fields directly. Some underlying properties are parsed but not
|
|
7317
|
+
* rendered; see docs/features.md "Known unsupported CSS features".
|
|
7343
7318
|
*/
|
|
7344
7319
|
var LayoutStyles = class {
|
|
7320
|
+
styles;
|
|
7345
7321
|
constructor(styles) {
|
|
7346
7322
|
this.styles = styles;
|
|
7347
7323
|
}
|
|
@@ -7463,6 +7439,117 @@ var LayoutStyles = class {
|
|
|
7463
7439
|
//#endregion
|
|
7464
7440
|
//#region src/css/index.ts
|
|
7465
7441
|
var CSSParsedDeclaration = class {
|
|
7442
|
+
animationDuration;
|
|
7443
|
+
backgroundClip;
|
|
7444
|
+
backgroundColor;
|
|
7445
|
+
backgroundImage;
|
|
7446
|
+
backgroundOrigin;
|
|
7447
|
+
backgroundPosition;
|
|
7448
|
+
backgroundRepeat;
|
|
7449
|
+
backgroundSize;
|
|
7450
|
+
borderTopColor;
|
|
7451
|
+
borderRightColor;
|
|
7452
|
+
borderBottomColor;
|
|
7453
|
+
borderLeftColor;
|
|
7454
|
+
borderTopLeftRadius;
|
|
7455
|
+
borderTopRightRadius;
|
|
7456
|
+
borderBottomRightRadius;
|
|
7457
|
+
borderBottomLeftRadius;
|
|
7458
|
+
borderTopStyle;
|
|
7459
|
+
borderRightStyle;
|
|
7460
|
+
borderBottomStyle;
|
|
7461
|
+
borderLeftStyle;
|
|
7462
|
+
borderTopWidth;
|
|
7463
|
+
borderRightWidth;
|
|
7464
|
+
borderBottomWidth;
|
|
7465
|
+
borderLeftWidth;
|
|
7466
|
+
boxShadow;
|
|
7467
|
+
clipPath;
|
|
7468
|
+
color;
|
|
7469
|
+
direction;
|
|
7470
|
+
display;
|
|
7471
|
+
float;
|
|
7472
|
+
fontFamily;
|
|
7473
|
+
fontSize;
|
|
7474
|
+
fontStyle;
|
|
7475
|
+
fontVariant;
|
|
7476
|
+
fontWeight;
|
|
7477
|
+
letterSpacing;
|
|
7478
|
+
lineBreak;
|
|
7479
|
+
lineHeight;
|
|
7480
|
+
listStyleImage;
|
|
7481
|
+
listStylePosition;
|
|
7482
|
+
listStyleType;
|
|
7483
|
+
marginTop;
|
|
7484
|
+
marginRight;
|
|
7485
|
+
marginBottom;
|
|
7486
|
+
marginLeft;
|
|
7487
|
+
opacity;
|
|
7488
|
+
overflowX;
|
|
7489
|
+
overflowY;
|
|
7490
|
+
overflowWrap;
|
|
7491
|
+
paddingTop;
|
|
7492
|
+
paddingRight;
|
|
7493
|
+
paddingBottom;
|
|
7494
|
+
paddingLeft;
|
|
7495
|
+
paintOrder;
|
|
7496
|
+
position;
|
|
7497
|
+
textAlign;
|
|
7498
|
+
textDecorationColor;
|
|
7499
|
+
textDecorationLine;
|
|
7500
|
+
textDecorationStyle;
|
|
7501
|
+
textDecorationThickness;
|
|
7502
|
+
textUnderlineOffset;
|
|
7503
|
+
textShadow;
|
|
7504
|
+
textTransform;
|
|
7505
|
+
textOverflow;
|
|
7506
|
+
transform;
|
|
7507
|
+
transformOrigin;
|
|
7508
|
+
rotate;
|
|
7509
|
+
translate;
|
|
7510
|
+
scale;
|
|
7511
|
+
visibility;
|
|
7512
|
+
webkitTextStrokeColor;
|
|
7513
|
+
webkitTextStrokeWidth;
|
|
7514
|
+
webkitLineClamp;
|
|
7515
|
+
wordBreak;
|
|
7516
|
+
whiteSpace;
|
|
7517
|
+
writingMode;
|
|
7518
|
+
zIndex;
|
|
7519
|
+
objectFit;
|
|
7520
|
+
imageRendering;
|
|
7521
|
+
mixBlendMode;
|
|
7522
|
+
filter;
|
|
7523
|
+
fontVariantLigatures;
|
|
7524
|
+
zoom;
|
|
7525
|
+
objectPosition;
|
|
7526
|
+
backgroundBlendMode;
|
|
7527
|
+
borderImageSource;
|
|
7528
|
+
borderImageSlice;
|
|
7529
|
+
borderImageRepeat;
|
|
7530
|
+
boxDecorationBreak;
|
|
7531
|
+
accentColor;
|
|
7532
|
+
webkitTextFillColor;
|
|
7533
|
+
isolation;
|
|
7534
|
+
outlineColor;
|
|
7535
|
+
outlineStyle;
|
|
7536
|
+
outlineWidth;
|
|
7537
|
+
outlineOffset;
|
|
7538
|
+
backdropFilter;
|
|
7539
|
+
maskImage;
|
|
7540
|
+
maskPosition;
|
|
7541
|
+
maskRepeat;
|
|
7542
|
+
maskSize;
|
|
7543
|
+
textEmphasisStyle;
|
|
7544
|
+
textEmphasisColor;
|
|
7545
|
+
textEmphasisPosition;
|
|
7546
|
+
borderImageWidth;
|
|
7547
|
+
borderImageOutset;
|
|
7548
|
+
webkitBoxReflect;
|
|
7549
|
+
_border;
|
|
7550
|
+
_background;
|
|
7551
|
+
_font;
|
|
7552
|
+
_layout;
|
|
7466
7553
|
get border() {
|
|
7467
7554
|
return this._border ?? (this._border = new BorderStyles(this));
|
|
7468
7555
|
}
|
|
@@ -7492,7 +7579,7 @@ var CSSParsedDeclaration = class {
|
|
|
7492
7579
|
return isTransparent(this.backgroundColor);
|
|
7493
7580
|
}
|
|
7494
7581
|
isTransformed() {
|
|
7495
|
-
return this.transform !== null || this.rotate !== null;
|
|
7582
|
+
return this.transform !== null || this.rotate !== null || this.translate !== null || this.scale !== null;
|
|
7496
7583
|
}
|
|
7497
7584
|
isPositioned() {
|
|
7498
7585
|
return this.position !== 0;
|
|
@@ -7527,12 +7614,16 @@ const parseSpecialDeclarations = (context, declaration) => {
|
|
|
7527
7614
|
};
|
|
7528
7615
|
};
|
|
7529
7616
|
var CSSParsedPseudoDeclaration = class {
|
|
7617
|
+
content;
|
|
7618
|
+
quotes;
|
|
7530
7619
|
constructor(context, declaration) {
|
|
7531
7620
|
this.content = parse(context, content, declaration.content);
|
|
7532
7621
|
this.quotes = parse(context, quotes, declaration.quotes);
|
|
7533
7622
|
}
|
|
7534
7623
|
};
|
|
7535
7624
|
var CSSParsedCounterDeclaration = class {
|
|
7625
|
+
counterIncrement;
|
|
7626
|
+
counterReset;
|
|
7536
7627
|
constructor(context, declaration) {
|
|
7537
7628
|
this.counterIncrement = parse(context, counterIncrement, declaration.counterIncrement);
|
|
7538
7629
|
this.counterReset = parse(context, counterReset, declaration.counterReset);
|
|
@@ -7556,6 +7647,48 @@ const isDebugging = (element, type) => {
|
|
|
7556
7647
|
return elementType === 1 || type === elementType;
|
|
7557
7648
|
};
|
|
7558
7649
|
//#endregion
|
|
7650
|
+
//#region src/dom/adopted-styles.ts
|
|
7651
|
+
/**
|
|
7652
|
+
* Constructable stylesheet cloning (adoptedStyleSheets).
|
|
7653
|
+
*
|
|
7654
|
+
* `adoptedStyleSheets` on a Document or ShadowRoot is the standard way Lit,
|
|
7655
|
+
* React and other frameworks inject component styles, but the sheets are not
|
|
7656
|
+
* part of the node tree — cloneNode never carries them. A shadow root that
|
|
7657
|
+
* relies on adopted sheets (and whose computed styles are not inlined per
|
|
7658
|
+
* element, i.e. copyStyles is false) would otherwise lose those rules in the
|
|
7659
|
+
* clone. The rules are re-materialised as a regular <style> element, which
|
|
7660
|
+
* also cascades last like the spec treats adopted sheets.
|
|
7661
|
+
*/
|
|
7662
|
+
/**
|
|
7663
|
+
* Serialize the CSS rules of the given sheets into one stylesheet string.
|
|
7664
|
+
* Sheets that cannot be read (e.g. detached) are skipped rather than failing
|
|
7665
|
+
* the render.
|
|
7666
|
+
*/
|
|
7667
|
+
const serializeStyleSheetRules = (sheets) => {
|
|
7668
|
+
let css = "";
|
|
7669
|
+
for (const sheet of sheets) try {
|
|
7670
|
+
const rules = sheet.cssRules;
|
|
7671
|
+
for (let i = 0; i < rules.length; i++) {
|
|
7672
|
+
const rule = rules[i];
|
|
7673
|
+
if (rule && typeof rule.cssText === "string") css += rule.cssText;
|
|
7674
|
+
}
|
|
7675
|
+
} catch (e) {}
|
|
7676
|
+
return css;
|
|
7677
|
+
};
|
|
7678
|
+
/**
|
|
7679
|
+
* Build a <style> element carrying the rules of the given adopted sheets, or
|
|
7680
|
+
* null when there is nothing to clone. `styleDocument` must be the document
|
|
7681
|
+
* the clone lives in.
|
|
7682
|
+
*/
|
|
7683
|
+
const createAdoptedStylesElement = (styleDocument, sheets, nonce) => {
|
|
7684
|
+
const css = serializeStyleSheetRules(sheets);
|
|
7685
|
+
if (!css) return null;
|
|
7686
|
+
const style = styleDocument.createElement("style");
|
|
7687
|
+
style.textContent = css;
|
|
7688
|
+
if (nonce) style.nonce = nonce;
|
|
7689
|
+
return style;
|
|
7690
|
+
};
|
|
7691
|
+
//#endregion
|
|
7559
7692
|
//#region src/dom/slot-cloner.ts
|
|
7560
7693
|
/** Exported for reuse in document-cloner.ts */
|
|
7561
7694
|
const IGNORE_ATTRIBUTE = "data-html2canvas-ignore";
|
|
@@ -7564,6 +7697,9 @@ const IGNORE_ATTRIBUTE = "data-html2canvas-ignore";
|
|
|
7564
7697
|
* Extracted from DocumentCloner to reduce file size and improve separation of concerns.
|
|
7565
7698
|
*/
|
|
7566
7699
|
var SlotCloner = class {
|
|
7700
|
+
cloneNodeFn;
|
|
7701
|
+
options;
|
|
7702
|
+
context;
|
|
7567
7703
|
constructor(cloneNodeFn, options, context) {
|
|
7568
7704
|
this.cloneNodeFn = cloneNodeFn;
|
|
7569
7705
|
this.options = options;
|
|
@@ -7642,6 +7778,7 @@ var SlotCloner = class {
|
|
|
7642
7778
|
cloneShadowDOMChildren(shadowRoot, targetShadowRoot, copyStyles) {
|
|
7643
7779
|
for (let child = shadowRoot.firstChild; child; child = child.nextSibling) if (isElementNode(child) && isSlotElement(child)) this.cloneSlotElement(child, targetShadowRoot, copyStyles);
|
|
7644
7780
|
else this.safeAppendClonedChild(targetShadowRoot, child, copyStyles);
|
|
7781
|
+
this.appendAdoptedStyleSheets(shadowRoot, targetShadowRoot, copyStyles);
|
|
7645
7782
|
}
|
|
7646
7783
|
/**
|
|
7647
7784
|
* Clone light DOM children to the target element.
|
|
@@ -7670,6 +7807,23 @@ var SlotCloner = class {
|
|
|
7670
7807
|
cloneShadowDOMAsLightDOM(shadowRoot, clone, copyStyles) {
|
|
7671
7808
|
for (let child = shadowRoot.firstChild; child; child = child.nextSibling) if (isElementNode(child) && isSlotElement(child)) this.cloneSlotElementAsLightDOM(child, clone, copyStyles);
|
|
7672
7809
|
else this.appendChildNode(clone, child, copyStyles);
|
|
7810
|
+
this.appendAdoptedStyleSheets(shadowRoot, clone, copyStyles);
|
|
7811
|
+
}
|
|
7812
|
+
/**
|
|
7813
|
+
* Re-materialise the shadow root's constructable stylesheets (adoptedStyleSheets)
|
|
7814
|
+
* as a <style> element in the clone — cloneNode never carries them.
|
|
7815
|
+
*
|
|
7816
|
+
* Skipped when computed styles are inlined per element (copyStyles), mirroring
|
|
7817
|
+
* how <style> elements inside shadow roots are dropped in that mode.
|
|
7818
|
+
*/
|
|
7819
|
+
appendAdoptedStyleSheets(shadowRoot, target, copyStyles) {
|
|
7820
|
+
if (copyStyles) return;
|
|
7821
|
+
const sheets = shadowRoot.adoptedStyleSheets;
|
|
7822
|
+
if (!sheets || sheets.length === 0) return;
|
|
7823
|
+
const styleDocument = "host" in target ? target.host.ownerDocument : target.ownerDocument;
|
|
7824
|
+
if (!styleDocument) return;
|
|
7825
|
+
const style = createAdoptedStylesElement(styleDocument, sheets, this.options.cspNonce);
|
|
7826
|
+
if (style) target.appendChild(style);
|
|
7673
7827
|
}
|
|
7674
7828
|
};
|
|
7675
7829
|
//#endregion
|
|
@@ -7744,10 +7898,12 @@ const createStyles = (body, styles, cspNonce) => {
|
|
|
7744
7898
|
* pairing across the whole clone walk, shared with the cloner's counter state.
|
|
7745
7899
|
*/
|
|
7746
7900
|
var PseudoContentResolver = class {
|
|
7901
|
+
context;
|
|
7902
|
+
counters;
|
|
7903
|
+
quoteDepth = 0;
|
|
7747
7904
|
constructor(context, counters) {
|
|
7748
7905
|
this.context = context;
|
|
7749
7906
|
this.counters = counters;
|
|
7750
|
-
this.quoteDepth = 0;
|
|
7751
7907
|
}
|
|
7752
7908
|
resolvePseudoContent(node, clone, style, pseudoElt) {
|
|
7753
7909
|
if (!style) return;
|
|
@@ -7807,7 +7963,44 @@ var PseudoContentResolver = class {
|
|
|
7807
7963
|
}
|
|
7808
7964
|
};
|
|
7809
7965
|
//#endregion
|
|
7966
|
+
//#region src/core/abort-helper.ts
|
|
7967
|
+
/**
|
|
7968
|
+
* AbortSignal helper utilities.
|
|
7969
|
+
*/
|
|
7970
|
+
/**
|
|
7971
|
+
* Throw a DOMException if the given AbortSignal is already aborted.
|
|
7972
|
+
* Used at checkpoints throughout the rendering pipeline to support
|
|
7973
|
+
* cancellable renders.
|
|
7974
|
+
*
|
|
7975
|
+
* @param signal - The AbortSignal to check. If undefined or not aborted, this is a no-op.
|
|
7976
|
+
* @throws {DOMException} With name 'AbortError' if the signal has been aborted.
|
|
7977
|
+
*/
|
|
7978
|
+
const throwIfAborted = (signal) => {
|
|
7979
|
+
if (signal?.aborted) throw new DOMException("The operation was aborted.", "AbortError");
|
|
7980
|
+
};
|
|
7981
|
+
//#endregion
|
|
7810
7982
|
//#region src/dom/iframe-mount.ts
|
|
7983
|
+
const trustedTypePolicies = /* @__PURE__ */ new WeakMap();
|
|
7984
|
+
/**
|
|
7985
|
+
* Resolve the Trusted Types policy used for writing the clone document.
|
|
7986
|
+
* Returns null when Trusted Types are unavailable or the policy could not be
|
|
7987
|
+
* created — document.write is not a Trusted Types sink, so the plain string
|
|
7988
|
+
* stays functional in both cases.
|
|
7989
|
+
* @internal – exported for testing only.
|
|
7990
|
+
*/
|
|
7991
|
+
const resolveTrustedTypesPolicy = (ownerWindow) => {
|
|
7992
|
+
const factory = ownerWindow && ownerWindow.trustedTypes;
|
|
7993
|
+
if (!factory) return null;
|
|
7994
|
+
if (trustedTypePolicies.has(factory)) return trustedTypePolicies.get(factory) ?? null;
|
|
7995
|
+
let policy = null;
|
|
7996
|
+
try {
|
|
7997
|
+
policy = factory.getPolicy?.("html2canvas-pro") ?? factory.createPolicy("html2canvas-pro", { createHTML: (s) => s });
|
|
7998
|
+
} catch (e) {
|
|
7999
|
+
policy = null;
|
|
8000
|
+
}
|
|
8001
|
+
trustedTypePolicies.set(factory, policy);
|
|
8002
|
+
return policy;
|
|
8003
|
+
};
|
|
7811
8004
|
const createIFrameContainer = (ownerDocument, bounds, customContainer) => {
|
|
7812
8005
|
const cloneIframeContainer = ownerDocument.createElement("iframe");
|
|
7813
8006
|
cloneIframeContainer.className = "html2canvas-container";
|
|
@@ -7840,26 +8033,45 @@ const imageReady = (img) => {
|
|
|
7840
8033
|
const imagesReady = (document) => {
|
|
7841
8034
|
return Promise.all([].slice.call(document.images, 0).map(imageReady));
|
|
7842
8035
|
};
|
|
7843
|
-
const iframeLoader = (iframe) => {
|
|
8036
|
+
const iframeLoader = (iframe, logger, signal) => {
|
|
7844
8037
|
return new Promise((resolve, reject) => {
|
|
7845
8038
|
const cloneWindow = iframe.contentWindow;
|
|
7846
8039
|
if (!cloneWindow) return reject(`No window assigned for iframe`);
|
|
7847
8040
|
const documentClone = cloneWindow.document;
|
|
8041
|
+
let interval;
|
|
8042
|
+
const watchdog = setTimeout(() => {
|
|
8043
|
+
if (interval) clearInterval(interval);
|
|
8044
|
+
reject(/* @__PURE__ */ new Error(`Cloned iframe did not fire its load event within ${IFRAME_LOAD_WATCHDOG_MS}ms`));
|
|
8045
|
+
}, IFRAME_LOAD_WATCHDOG_MS);
|
|
8046
|
+
const onAbort = () => {
|
|
8047
|
+
if (interval) clearInterval(interval);
|
|
8048
|
+
clearTimeout(watchdog);
|
|
8049
|
+
reject(new DOMException("The operation was aborted.", "AbortError"));
|
|
8050
|
+
};
|
|
7848
8051
|
cloneWindow.onload = iframe.onload = () => {
|
|
7849
8052
|
cloneWindow.onload = iframe.onload = null;
|
|
7850
|
-
const
|
|
8053
|
+
const maxAttempts = Math.ceil(CLONE_READY_TIMEOUT_MS / 50);
|
|
7851
8054
|
let attempts = 0;
|
|
7852
|
-
|
|
8055
|
+
interval = setInterval(() => {
|
|
7853
8056
|
attempts++;
|
|
7854
|
-
if (
|
|
8057
|
+
if (signal?.aborted) onAbort();
|
|
8058
|
+
else if (documentClone.body.childNodes.length > 0 && documentClone.readyState === "complete") {
|
|
7855
8059
|
clearInterval(interval);
|
|
8060
|
+
interval = void 0;
|
|
8061
|
+
clearTimeout(watchdog);
|
|
7856
8062
|
resolve(iframe);
|
|
7857
|
-
} else if (attempts >=
|
|
8063
|
+
} else if (attempts >= maxAttempts) {
|
|
7858
8064
|
clearInterval(interval);
|
|
8065
|
+
interval = void 0;
|
|
8066
|
+
logger?.warn(`Cloned iframe did not become ready within ${CLONE_READY_TIMEOUT_MS / 1e3} seconds; continuing with a possibly incomplete document`);
|
|
7859
8067
|
resolve(iframe);
|
|
7860
8068
|
}
|
|
7861
8069
|
}, 50);
|
|
7862
8070
|
};
|
|
8071
|
+
if (signal) {
|
|
8072
|
+
if (signal.aborted) onAbort();
|
|
8073
|
+
else signal.addEventListener("abort", onAbort, { once: true });
|
|
8074
|
+
}
|
|
7863
8075
|
});
|
|
7864
8076
|
};
|
|
7865
8077
|
/**
|
|
@@ -7904,14 +8116,19 @@ const mountCloneInIFrame = (context, ownerDocument, windowSize, mount) => {
|
|
|
7904
8116
|
const scrollY = ownerDocument.defaultView.pageYOffset;
|
|
7905
8117
|
const cloneWindow = iframe.contentWindow;
|
|
7906
8118
|
const documentClone = cloneWindow.document;
|
|
7907
|
-
const iframeLoad = iframeLoader(iframe).then(async () => {
|
|
8119
|
+
const iframeLoad = iframeLoader(iframe, context.logger, mount.signal).then(async () => {
|
|
7908
8120
|
mount.scrolledElements.forEach(restoreNodeScroll);
|
|
7909
8121
|
if (cloneWindow) cloneWindow.scrollTo(windowSize.left, windowSize.top);
|
|
7910
8122
|
const onclone = mount.onclone;
|
|
7911
8123
|
const referenceElement = mount.clonedReferenceElement;
|
|
7912
8124
|
if (typeof referenceElement === "undefined") throw new Error(`Error finding the ${mount.referenceElementName} in the cloned document`);
|
|
8125
|
+
throwIfAborted(mount.signal);
|
|
7913
8126
|
if (documentClone.fonts && documentClone.fonts.ready) await documentClone.fonts.ready;
|
|
7914
|
-
|
|
8127
|
+
throwIfAborted(mount.signal);
|
|
8128
|
+
if (/(AppleWebKit)/g.test(navigator.userAgent)) {
|
|
8129
|
+
await imagesReady(documentClone);
|
|
8130
|
+
throwIfAborted(mount.signal);
|
|
8131
|
+
}
|
|
7915
8132
|
if (typeof onclone === "function") await Promise.resolve().then(() => onclone(documentClone, referenceElement));
|
|
7916
8133
|
cloneWindow.scrollTo(windowSize.left, windowSize.top);
|
|
7917
8134
|
if (/AppleWebKit/g.test(navigator.userAgent) && (cloneWindow.scrollY !== windowSize.top || cloneWindow.scrollX !== windowSize.left)) {
|
|
@@ -7927,12 +8144,9 @@ const mountCloneInIFrame = (context, ownerDocument, windowSize, mount) => {
|
|
|
7927
8144
|
*/
|
|
7928
8145
|
const baseUri = ownerDocument.baseURI;
|
|
7929
8146
|
documentClone.open();
|
|
7930
|
-
const rawHTML = serializeDoctype(
|
|
8147
|
+
const rawHTML = serializeDoctype(ownerDocument.doctype) + "<html></html>";
|
|
7931
8148
|
try {
|
|
7932
|
-
const
|
|
7933
|
-
const trustedTypesFactory = ownerWindow && ownerWindow.trustedTypes;
|
|
7934
|
-
let policy = trustedTypesFactory?.getPolicy?.("html2canvas-pro");
|
|
7935
|
-
if (!policy && trustedTypesFactory) policy = trustedTypesFactory.createPolicy("html2canvas-pro", { createHTML: (s) => s });
|
|
8149
|
+
const policy = resolveTrustedTypesPolicy(ownerDocument.defaultView);
|
|
7936
8150
|
const html = policy ? policy.createHTML(rawHTML) : rawHTML;
|
|
7937
8151
|
documentClone.write(html);
|
|
7938
8152
|
} catch (_e) {
|
|
@@ -7979,6 +8193,15 @@ const findParentShadowRoot = (element) => {
|
|
|
7979
8193
|
return null;
|
|
7980
8194
|
};
|
|
7981
8195
|
var DocumentCloner = class {
|
|
8196
|
+
context;
|
|
8197
|
+
options;
|
|
8198
|
+
scrolledElements;
|
|
8199
|
+
referenceElement;
|
|
8200
|
+
clonedReferenceElement;
|
|
8201
|
+
documentElement;
|
|
8202
|
+
counters;
|
|
8203
|
+
pseudoContents;
|
|
8204
|
+
slotCloner;
|
|
7982
8205
|
constructor(context, element, options) {
|
|
7983
8206
|
this.context = context;
|
|
7984
8207
|
this.options = options;
|
|
@@ -7988,7 +8211,8 @@ var DocumentCloner = class {
|
|
|
7988
8211
|
this.pseudoContents = new PseudoContentResolver(context, this.counters);
|
|
7989
8212
|
this.slotCloner = new SlotCloner((node, copyStyles) => this.cloneNode(node, copyStyles), {
|
|
7990
8213
|
ignoreElements: options.ignoreElements,
|
|
7991
|
-
copyStyles: options.copyStyles ?? true
|
|
8214
|
+
copyStyles: options.copyStyles ?? true,
|
|
8215
|
+
cspNonce: options.cspNonce
|
|
7992
8216
|
}, context);
|
|
7993
8217
|
if (!element.ownerDocument) throw new Error("Cloned element does not have an owner document");
|
|
7994
8218
|
if (!this.options.iframeContainer) {
|
|
@@ -7996,15 +8220,35 @@ var DocumentCloner = class {
|
|
|
7996
8220
|
if (shadowRoot) this.options.iframeContainer = shadowRoot;
|
|
7997
8221
|
}
|
|
7998
8222
|
this.documentElement = this.cloneNode(element.ownerDocument.documentElement, false);
|
|
8223
|
+
this.appendDocumentAdoptedStyles(element.ownerDocument);
|
|
7999
8224
|
}
|
|
8000
|
-
|
|
8001
|
-
|
|
8225
|
+
/**
|
|
8226
|
+
* Re-materialise the source document's constructable stylesheets
|
|
8227
|
+
* (document.adoptedStyleSheets) as a <style> at the end of the clone's
|
|
8228
|
+
* <head>: cloneNode never carries them, and they cascade after all author
|
|
8229
|
+
* sheets, which appending last approximates.
|
|
8230
|
+
*
|
|
8231
|
+
* Skipped when computed styles are inlined per element (copyStyles), like
|
|
8232
|
+
* the other stylesheet-cloning paths.
|
|
8233
|
+
*/
|
|
8234
|
+
appendDocumentAdoptedStyles(ownerDocument) {
|
|
8235
|
+
if (this.options.copyStyles) return;
|
|
8236
|
+
const sheets = ownerDocument.adoptedStyleSheets;
|
|
8237
|
+
if (!sheets || sheets.length === 0) return;
|
|
8238
|
+
const head = this.documentElement.getElementsByTagName("head").item(0);
|
|
8239
|
+
if (!head) return;
|
|
8240
|
+
const style = createAdoptedStylesElement(this.documentElement.ownerDocument ?? ownerDocument, sheets, this.options.cspNonce);
|
|
8241
|
+
if (style) head.appendChild(style);
|
|
8242
|
+
}
|
|
8243
|
+
toIFrame(ownerDocument, windowSize) {
|
|
8244
|
+
return mountCloneInIFrame(this.context, ownerDocument, windowSize, {
|
|
8002
8245
|
documentElement: this.documentElement,
|
|
8003
8246
|
clonedReferenceElement: this.clonedReferenceElement,
|
|
8004
8247
|
referenceElementName: this.referenceElement.nodeName,
|
|
8005
8248
|
scrolledElements: this.scrolledElements,
|
|
8006
8249
|
onclone: this.options.onclone,
|
|
8007
|
-
container: this.options.iframeContainer
|
|
8250
|
+
container: this.options.iframeContainer,
|
|
8251
|
+
signal: this.options.signal
|
|
8008
8252
|
});
|
|
8009
8253
|
}
|
|
8010
8254
|
createElementClone(node) {
|
|
@@ -8122,7 +8366,7 @@ var DocumentCloner = class {
|
|
|
8122
8366
|
this.slotCloner.cloneChildNodes(node, clone, copyStyles);
|
|
8123
8367
|
}
|
|
8124
8368
|
cloneNode(node, copyStyles) {
|
|
8125
|
-
if (isTextNode(node)) return document.createTextNode(node.data);
|
|
8369
|
+
if (isTextNode(node)) return (node.ownerDocument ?? document).createTextNode(node.data);
|
|
8126
8370
|
if (!node.ownerDocument) return node.cloneNode(false);
|
|
8127
8371
|
const window = node.ownerDocument.defaultView;
|
|
8128
8372
|
if (window && isElementNode(node) && (isHTMLElementNode(node) || isSVGElementNode(node))) {
|
|
@@ -8208,7 +8452,7 @@ var DOMNormalizer = class {
|
|
|
8208
8452
|
*/
|
|
8209
8453
|
static normalizeElement(element, styles) {
|
|
8210
8454
|
const originalStyles = {};
|
|
8211
|
-
if (!isHTMLElementNode(element)) return originalStyles;
|
|
8455
|
+
if (!isHTMLElementNode(element) && !isSVGElementNode(element)) return originalStyles;
|
|
8212
8456
|
if (styles.animationDuration.some((duration) => duration > 0)) {
|
|
8213
8457
|
originalStyles.animationDuration = element.style.animationDuration;
|
|
8214
8458
|
element.style.animationDuration = "0s";
|
|
@@ -8217,13 +8461,25 @@ var DOMNormalizer = class {
|
|
|
8217
8461
|
originalStyles.transform = element.style.transform;
|
|
8218
8462
|
element.style.transform = "translate(0, 0)";
|
|
8219
8463
|
}
|
|
8464
|
+
let needsContainingBlockFallback = false;
|
|
8220
8465
|
if (styles.rotate !== null) {
|
|
8221
8466
|
originalStyles.rotate = element.style.rotate;
|
|
8222
8467
|
element.style.rotate = "0deg";
|
|
8223
|
-
|
|
8224
|
-
|
|
8225
|
-
|
|
8226
|
-
|
|
8468
|
+
needsContainingBlockFallback = true;
|
|
8469
|
+
}
|
|
8470
|
+
if (styles.translate !== null) {
|
|
8471
|
+
originalStyles.translate = element.style.translate;
|
|
8472
|
+
element.style.translate = "0px";
|
|
8473
|
+
needsContainingBlockFallback = true;
|
|
8474
|
+
}
|
|
8475
|
+
if (styles.scale !== null) {
|
|
8476
|
+
originalStyles.scale = element.style.scale;
|
|
8477
|
+
element.style.scale = "1";
|
|
8478
|
+
needsContainingBlockFallback = true;
|
|
8479
|
+
}
|
|
8480
|
+
if (needsContainingBlockFallback && originalStyles.transform === void 0) {
|
|
8481
|
+
originalStyles.transform = element.style.transform;
|
|
8482
|
+
element.style.transform = "translate(0, 0)";
|
|
8227
8483
|
}
|
|
8228
8484
|
return originalStyles;
|
|
8229
8485
|
}
|
|
@@ -8234,26 +8490,39 @@ var DOMNormalizer = class {
|
|
|
8234
8490
|
* @param originalStyles - Original styles to restore
|
|
8235
8491
|
*/
|
|
8236
8492
|
static restoreElement(element, originalStyles) {
|
|
8237
|
-
if (!isHTMLElementNode(element)) return;
|
|
8493
|
+
if (!isHTMLElementNode(element) && !isSVGElementNode(element)) return;
|
|
8238
8494
|
if (originalStyles.animationDuration !== void 0) element.style.animationDuration = originalStyles.animationDuration;
|
|
8239
8495
|
if (originalStyles.transform !== void 0) element.style.transform = originalStyles.transform;
|
|
8240
8496
|
if (originalStyles.rotate !== void 0) element.style.rotate = originalStyles.rotate;
|
|
8497
|
+
if (originalStyles.translate !== void 0) element.style.translate = originalStyles.translate;
|
|
8498
|
+
if (originalStyles.scale !== void 0) element.style.scale = originalStyles.scale;
|
|
8241
8499
|
}
|
|
8242
8500
|
};
|
|
8243
8501
|
//#endregion
|
|
8244
8502
|
//#region src/dom/element-container.ts
|
|
8245
8503
|
var ElementContainer = class {
|
|
8504
|
+
context;
|
|
8505
|
+
styles;
|
|
8506
|
+
textNodes = [];
|
|
8507
|
+
elements = [];
|
|
8508
|
+
bounds;
|
|
8509
|
+
/**
|
|
8510
|
+
* Bounds of the <legend> child of a <fieldset>, when present. Browsers break
|
|
8511
|
+
* the fieldset's top border where the legend sits; the renderer uses these
|
|
8512
|
+
* bounds to leave a matching gap (issue #227).
|
|
8513
|
+
*/
|
|
8514
|
+
legendBounds;
|
|
8515
|
+
createsStackingContext = false;
|
|
8516
|
+
createsRealStackingContext = false;
|
|
8517
|
+
isListOwner = false;
|
|
8518
|
+
debugRender = false;
|
|
8519
|
+
originalStyles;
|
|
8520
|
+
originalElement;
|
|
8246
8521
|
constructor(context, element, options = {}) {
|
|
8247
8522
|
this.context = context;
|
|
8248
|
-
this.textNodes = [];
|
|
8249
|
-
this.elements = [];
|
|
8250
|
-
this.createsStackingContext = false;
|
|
8251
|
-
this.createsRealStackingContext = false;
|
|
8252
|
-
this.isListOwner = false;
|
|
8253
|
-
this.debugRender = false;
|
|
8254
8523
|
if (isDebugging(element, 3)) debugger;
|
|
8255
8524
|
this.styles = new CSSParsedDeclaration(context, context.config.window.getComputedStyle(element, null));
|
|
8256
|
-
if (options.normalizeDom !== false && isHTMLElementNode(element)) {
|
|
8525
|
+
if (options.normalizeDom !== false && (isHTMLElementNode(element) || isSVGElementNode(element))) {
|
|
8257
8526
|
this.originalStyles = DOMNormalizer.normalizeElement(element, this.styles);
|
|
8258
8527
|
this.originalElement = element;
|
|
8259
8528
|
}
|
|
@@ -8290,278 +8559,16 @@ var ElementContainer = class {
|
|
|
8290
8559
|
}
|
|
8291
8560
|
};
|
|
8292
8561
|
//#endregion
|
|
8293
|
-
//#region node_modules/.pnpm/text-segmentation@1.0.3/node_modules/text-segmentation/dist/text-segmentation.es5.js
|
|
8294
|
-
var base64 = "AAAAAAAAAAAAEA4AGBkAAFAaAAACAAAAAAAIABAAGAAwADgACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAAQABIAEQATAAIABAACAAQAAgAEAAIABAAVABcAAgAEAAIABAACAAQAGAAaABwAHgAgACIAI4AlgAIABAAmwCjAKgAsAC2AL4AvQDFAMoA0gBPAVYBWgEIAAgACACMANoAYgFkAWwBdAF8AX0BhQGNAZUBlgGeAaMBlQGWAasBswF8AbsBwwF0AcsBYwHTAQgA2wG/AOMBdAF8AekB8QF0AfkB+wHiAHQBfAEIAAMC5gQIAAsCEgIIAAgAFgIeAggAIgIpAggAMQI5AkACygEIAAgASAJQAlgCYAIIAAgACAAKBQoFCgUTBRMFGQUrBSsFCAAIAAgACAAIAAgACAAIAAgACABdAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACABoAmgCrwGvAQgAbgJ2AggAHgEIAAgACADnAXsCCAAIAAgAgwIIAAgACAAIAAgACACKAggAkQKZAggAPADJAAgAoQKkAqwCsgK6AsICCADJAggA0AIIAAgACAAIANYC3gIIAAgACAAIAAgACABAAOYCCAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAkASoB+QIEAAgACAA8AEMCCABCBQgACABJBVAFCAAIAAgACAAIAAgACAAIAAgACABTBVoFCAAIAFoFCABfBWUFCAAIAAgACAAIAAgAbQUIAAgACAAIAAgACABzBXsFfQWFBYoFigWKBZEFigWKBYoFmAWfBaYFrgWxBbkFCAAIAAgACAAIAAgACAAIAAgACAAIAMEFCAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAMgFCADQBQgACAAIAAgACAAIAAgACAAIAAgACAAIAO4CCAAIAAgAiQAIAAgACABAAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAD0AggACAD8AggACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIANYFCAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAMDvwAIAAgAJAIIAAgACAAIAAgACAAIAAgACwMTAwgACAB9BOsEGwMjAwgAKwMyAwsFYgE3A/MEPwMIAEUDTQNRAwgAWQOsAGEDCAAIAAgACAAIAAgACABpAzQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFIQUoBSwFCAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACABtAwgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACABMAEwACAAIAAgACAAIABgACAAIAAgACAC/AAgACAAyAQgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACACAAIAAwAAgACAAIAAgACAAIAAgACAAIAAAARABIAAgACAAIABQASAAIAAgAIABwAEAAjgCIABsAqAC2AL0AigDQAtwC+IJIQqVAZUBWQqVAZUBlQGVAZUBlQGrC5UBlQGVAZUBlQGVAZUBlQGVAXsKlQGVAbAK6wsrDGUMpQzlDJUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAfAKAAuZA64AtwCJALoC6ADwAAgAuACgA/oEpgO6AqsD+AAIAAgAswMIAAgACAAIAIkAuwP5AfsBwwPLAwgACAAIAAgACADRA9kDCAAIAOED6QMIAAgACAAIAAgACADuA/YDCAAIAP4DyQAIAAgABgQIAAgAXQAOBAgACAAIAAgACAAIABMECAAIAAgACAAIAAgACAD8AAQBCAAIAAgAGgQiBCoECAExBAgAEAEIAAgACAAIAAgACAAIAAgACAAIAAgACAA4BAgACABABEYECAAIAAgATAQYAQgAVAQIAAgACAAIAAgACAAIAAgACAAIAFoECAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAOQEIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAB+BAcACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAEABhgSMBAgACAAIAAgAlAQIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAwAEAAQABAADAAMAAwADAAQABAAEAAQABAAEAAQABHATAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAdQMIAAgACAAIAAgACAAIAMkACAAIAAgAfQMIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACACFA4kDCAAIAAgACAAIAOcBCAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAIcDCAAIAAgACAAIAAgACAAIAAgACAAIAJEDCAAIAAgACADFAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACABgBAgAZgQIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAbAQCBXIECAAIAHkECAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACABAAJwEQACjBKoEsgQIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAC6BMIECAAIAAgACAAIAAgACABmBAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAxwQIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAGYECAAIAAgAzgQIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAigWKBYoFigWKBYoFigWKBd0FXwUIAOIF6gXxBYoF3gT5BQAGCAaKBYoFigWKBYoFigWKBYoFigWKBYoFigXWBIoFigWKBYoFigWKBYoFigWKBYsFEAaKBYoFigWKBYoFigWKBRQGCACKBYoFigWKBQgACAAIANEECAAIABgGigUgBggAJgYIAC4GMwaKBYoF0wQ3Bj4GigWKBYoFigWKBYoFigWKBYoFigWKBYoFigUIAAgACAAIAAgACAAIAAgAigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWLBf///////wQABAAEAAQABAAEAAQABAAEAAQAAwAEAAQAAgAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAQADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAUAAAAFAAUAAAAFAAUAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAEAAQABAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUAAQAAAAUABQAFAAUABQAFAAAAAAAFAAUAAAAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAFAAUAAQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABwAFAAUABQAFAAAABwAHAAcAAAAHAAcABwAFAAEAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAFAAUABQAFAAcABwAFAAUAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAAAQABAAAAAAAAAAAAAAAFAAUABQAFAAAABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAHAAcABwAHAAcAAAAHAAcAAAAAAAUABQAHAAUAAQAHAAEABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABwABAAUABQAFAAUAAAAAAAAAAAAAAAEAAQABAAEAAQABAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABwAFAAUAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUAAQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABQANAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAEAAQABAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAEAAQABAAEAAQABAAEAAQABAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAQABAAEAAQABAAEAAQABAAAAAAAAAAAAAAAAAAAAAAABQAHAAUABQAFAAAAAAAAAAcABQAFAAUABQAFAAQABAAEAAQABAAEAAQABAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUAAAAFAAUABQAFAAUAAAAFAAUABQAAAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAAAAAAAAAAAAUABQAFAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAHAAUAAAAHAAcABwAFAAUABQAFAAUABQAFAAUABwAHAAcABwAFAAcABwAAAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABwAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAUABwAHAAUABQAFAAUAAAAAAAcABwAAAAAABwAHAAUAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAABQAFAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAABwAHAAcABQAFAAAAAAAAAAAABQAFAAAAAAAFAAUABQAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAFAAUABQAFAAUAAAAFAAUABwAAAAcABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAFAAUABwAFAAUABQAFAAAAAAAHAAcAAAAAAAcABwAFAAAAAAAAAAAAAAAAAAAABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAcABwAAAAAAAAAHAAcABwAAAAcABwAHAAUAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAABQAHAAcABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABwAHAAcABwAAAAUABQAFAAAABQAFAAUABQAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAcABQAHAAcABQAHAAcAAAAFAAcABwAAAAcABwAFAAUAAAAAAAAAAAAAAAAAAAAFAAUAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAUABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAFAAcABwAFAAUABQAAAAUAAAAHAAcABwAHAAcABwAHAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAHAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAABwAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAUAAAAFAAAAAAAAAAAABwAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABwAFAAUABQAFAAUAAAAFAAUAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABwAFAAUABQAFAAUABQAAAAUABQAHAAcABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABQAFAAAAAAAAAAAABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAcABQAFAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAHAAUABQAFAAUABQAFAAUABwAHAAcABwAHAAcABwAHAAUABwAHAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABwAHAAcABwAFAAUABwAHAAcAAAAAAAAAAAAHAAcABQAHAAcABwAHAAcABwAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAcABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABQAHAAUABQAFAAUABQAFAAUAAAAFAAAABQAAAAAABQAFAAUABQAFAAUABQAFAAcABwAHAAcABwAHAAUABQAFAAUABQAFAAUABQAFAAUAAAAAAAUABQAFAAUABQAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABwAFAAcABwAHAAcABwAFAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAUABQAFAAUABwAHAAUABQAHAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAcABQAFAAcABwAHAAUABwAFAAUABQAHAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAcABwAHAAcABwAHAAUABQAFAAUABQAFAAUABQAHAAcABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUAAAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAcABQAFAAUABQAFAAUABQAAAAAAAAAAAAUAAAAAAAAAAAAAAAAABQAAAAAABwAFAAUAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAAABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUAAAAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAABQAAAAAAAAAFAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAUABQAHAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABwAHAAcABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAFAAUABQAHAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAcABwAFAAUABQAFAAcABwAFAAUABwAHAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAcABwAFAAUABwAHAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAFAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAFAAUABQAAAAAABQAFAAAAAAAAAAAAAAAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABQAFAAcABwAAAAAAAAAAAAAABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABwAFAAcABwAFAAcABwAAAAcABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAAAAAAAAAAAAAAAAAFAAUABQAAAAUABQAAAAAAAAAAAAAABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABQAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABwAFAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAcABQAFAAUABQAFAAUABQAFAAUABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAFAAUABQAHAAcABQAHAAUABQAAAAAAAAAAAAAAAAAFAAAABwAHAAcABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABwAHAAcABwAAAAAABwAHAAAAAAAHAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAAAAAAFAAUABQAFAAUABQAFAAAAAAAAAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAFAAUABQAFAAUABQAFAAUABwAHAAUABQAFAAcABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAHAAcABQAFAAUABQAFAAUABwAFAAcABwAFAAcABQAFAAcABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAHAAcABQAFAAUABQAAAAAABwAHAAcABwAFAAUABwAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABwAHAAUABQAFAAUABQAFAAUABQAHAAcABQAHAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABwAFAAcABwAFAAUABQAFAAUABQAHAAUAAAAAAAAAAAAAAAAAAAAAAAcABwAFAAUABQAFAAcABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAFAAUABQAFAAUABQAFAAUABQAHAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAFAAUABQAFAAAAAAAFAAUABwAHAAcABwAFAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABwAHAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABQAFAAUABQAFAAUABQAAAAUABQAFAAUABQAFAAcABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAAAHAAUABQAFAAUABQAFAAUABwAFAAUABwAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUAAAAAAAAABQAAAAUABQAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAHAAcAAAAFAAUAAAAHAAcABQAHAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABwAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAAAAAAAAAAAAAAAAAAABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAUABQAFAAAAAAAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAAAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAAAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAAABQAFAAUABQAFAAUABQAAAAUABQAAAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAFAAUABQAFAAUADgAOAA4ADgAOAA4ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAAAAAAAAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAMAAwADAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAAAAAAAAAAAAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAAAAAAAAAAAAsADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwACwAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAOAAAAAAAAAAAADgAOAA4AAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAAAA4ADgAOAA4ADgAOAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4AAAAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4AAAAAAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAAAA4AAAAOAAAAAAAAAAAAAAAAAA4AAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAADgAAAAAAAAAAAA4AAAAOAAAAAAAAAAAADgAOAA4AAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAAAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAAAAA4ADgAOAA4ADgAOAA4ADgAOAAAADgAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4AAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4AAAAAAAAAAAAAAAAAAAAAAA4ADgAOAA4ADgAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4AAAAOAA4ADgAOAA4ADgAAAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4AAAAAAAAAAAA=";
|
|
8295
|
-
var chars$1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
8296
|
-
var lookup$1 = typeof Uint8Array === "undefined" ? [] : /* @__PURE__ */ new Uint8Array(256);
|
|
8297
|
-
for (var i$1 = 0; i$1 < chars$1.length; i$1++) lookup$1[chars$1.charCodeAt(i$1)] = i$1;
|
|
8298
|
-
var decode = function(base64) {
|
|
8299
|
-
var bufferLength = base64.length * .75, len = base64.length, i, p = 0, encoded1, encoded2, encoded3, encoded4;
|
|
8300
|
-
if (base64[base64.length - 1] === "=") {
|
|
8301
|
-
bufferLength--;
|
|
8302
|
-
if (base64[base64.length - 2] === "=") bufferLength--;
|
|
8303
|
-
}
|
|
8304
|
-
var buffer = typeof ArrayBuffer !== "undefined" && typeof Uint8Array !== "undefined" && typeof Uint8Array.prototype.slice !== "undefined" ? new ArrayBuffer(bufferLength) : new Array(bufferLength);
|
|
8305
|
-
var bytes = Array.isArray(buffer) ? buffer : new Uint8Array(buffer);
|
|
8306
|
-
for (i = 0; i < len; i += 4) {
|
|
8307
|
-
encoded1 = lookup$1[base64.charCodeAt(i)];
|
|
8308
|
-
encoded2 = lookup$1[base64.charCodeAt(i + 1)];
|
|
8309
|
-
encoded3 = lookup$1[base64.charCodeAt(i + 2)];
|
|
8310
|
-
encoded4 = lookup$1[base64.charCodeAt(i + 3)];
|
|
8311
|
-
bytes[p++] = encoded1 << 2 | encoded2 >> 4;
|
|
8312
|
-
bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2;
|
|
8313
|
-
bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63;
|
|
8314
|
-
}
|
|
8315
|
-
return buffer;
|
|
8316
|
-
};
|
|
8317
|
-
var polyUint16Array = function(buffer) {
|
|
8318
|
-
var length = buffer.length;
|
|
8319
|
-
var bytes = [];
|
|
8320
|
-
for (var i = 0; i < length; i += 2) bytes.push(buffer[i + 1] << 8 | buffer[i]);
|
|
8321
|
-
return bytes;
|
|
8322
|
-
};
|
|
8323
|
-
var polyUint32Array = function(buffer) {
|
|
8324
|
-
var length = buffer.length;
|
|
8325
|
-
var bytes = [];
|
|
8326
|
-
for (var i = 0; i < length; i += 4) bytes.push(buffer[i + 3] << 24 | buffer[i + 2] << 16 | buffer[i + 1] << 8 | buffer[i]);
|
|
8327
|
-
return bytes;
|
|
8328
|
-
};
|
|
8329
|
-
/** Shift size for getting the index-2 table offset. */
|
|
8330
|
-
var UTRIE2_SHIFT_2 = 5;
|
|
8331
|
-
/** Shift size for getting the index-1 table offset. */
|
|
8332
|
-
var UTRIE2_SHIFT_1 = 11;
|
|
8333
|
-
/**
|
|
8334
|
-
* Shift size for shifting left the index array values.
|
|
8335
|
-
* Increases possible data size with 16-bit index values at the cost
|
|
8336
|
-
* of compactability.
|
|
8337
|
-
* This requires data blocks to be aligned by UTRIE2_DATA_GRANULARITY.
|
|
8338
|
-
*/
|
|
8339
|
-
var UTRIE2_INDEX_SHIFT = 2;
|
|
8340
|
-
/**
|
|
8341
|
-
* Difference between the two shift sizes,
|
|
8342
|
-
* for getting an index-1 offset from an index-2 offset. 6=11-5
|
|
8343
|
-
*/
|
|
8344
|
-
var UTRIE2_SHIFT_1_2 = UTRIE2_SHIFT_1 - UTRIE2_SHIFT_2;
|
|
8345
|
-
/**
|
|
8346
|
-
* The part of the index-2 table for U+D800..U+DBFF stores values for
|
|
8347
|
-
* lead surrogate code _units_ not code _points_.
|
|
8348
|
-
* Values for lead surrogate code _points_ are indexed with this portion of the table.
|
|
8349
|
-
* Length=32=0x20=0x400>>UTRIE2_SHIFT_2. (There are 1024=0x400 lead surrogates.)
|
|
8350
|
-
*/
|
|
8351
|
-
var UTRIE2_LSCP_INDEX_2_OFFSET = 65536 >> UTRIE2_SHIFT_2;
|
|
8352
|
-
/** Mask for getting the lower bits for the in-data-block offset. */
|
|
8353
|
-
var UTRIE2_DATA_MASK = (1 << UTRIE2_SHIFT_2) - 1;
|
|
8354
|
-
/**
|
|
8355
|
-
* The index-1 table, only used for supplementary code points, at offset 2112=0x840.
|
|
8356
|
-
* Variable length, for code points up to highStart, where the last single-value range starts.
|
|
8357
|
-
* Maximum length 512=0x200=0x100000>>UTRIE2_SHIFT_1.
|
|
8358
|
-
* (For 0x100000 supplementary code points U+10000..U+10ffff.)
|
|
8359
|
-
*
|
|
8360
|
-
* The part of the index-2 table for supplementary code points starts
|
|
8361
|
-
* after this index-1 table.
|
|
8362
|
-
*
|
|
8363
|
-
* Both the index-1 table and the following part of the index-2 table
|
|
8364
|
-
* are omitted completely if there is only BMP data.
|
|
8365
|
-
*/
|
|
8366
|
-
var UTRIE2_INDEX_1_OFFSET = UTRIE2_LSCP_INDEX_2_OFFSET + (1024 >> UTRIE2_SHIFT_2) + 32;
|
|
8367
|
-
/**
|
|
8368
|
-
* Number of index-1 entries for the BMP. 32=0x20
|
|
8369
|
-
* This part of the index-1 table is omitted from the serialized form.
|
|
8370
|
-
*/
|
|
8371
|
-
var UTRIE2_OMITTED_BMP_INDEX_1_LENGTH = 65536 >> UTRIE2_SHIFT_1;
|
|
8372
|
-
/** Mask for getting the lower bits for the in-index-2-block offset. */
|
|
8373
|
-
var UTRIE2_INDEX_2_MASK = (1 << UTRIE2_SHIFT_1_2) - 1;
|
|
8374
|
-
var slice16 = function(view, start, end) {
|
|
8375
|
-
if (view.slice) return view.slice(start, end);
|
|
8376
|
-
return new Uint16Array(Array.prototype.slice.call(view, start, end));
|
|
8377
|
-
};
|
|
8378
|
-
var slice32 = function(view, start, end) {
|
|
8379
|
-
if (view.slice) return view.slice(start, end);
|
|
8380
|
-
return new Uint32Array(Array.prototype.slice.call(view, start, end));
|
|
8381
|
-
};
|
|
8382
|
-
var createTrieFromBase64 = function(base64, _byteLength) {
|
|
8383
|
-
var buffer = decode(base64);
|
|
8384
|
-
var view32 = Array.isArray(buffer) ? polyUint32Array(buffer) : new Uint32Array(buffer);
|
|
8385
|
-
var view16 = Array.isArray(buffer) ? polyUint16Array(buffer) : new Uint16Array(buffer);
|
|
8386
|
-
var headerLength = 24;
|
|
8387
|
-
var index = slice16(view16, headerLength / 2, view32[4] / 2);
|
|
8388
|
-
var data = view32[5] === 2 ? slice16(view16, (headerLength + view32[4]) / 2) : slice32(view32, Math.ceil((headerLength + view32[4]) / 4));
|
|
8389
|
-
return new Trie(view32[0], view32[1], view32[2], view32[3], index, data);
|
|
8390
|
-
};
|
|
8391
|
-
var Trie = function() {
|
|
8392
|
-
function Trie(initialValue, errorValue, highStart, highValueIndex, index, data) {
|
|
8393
|
-
this.initialValue = initialValue;
|
|
8394
|
-
this.errorValue = errorValue;
|
|
8395
|
-
this.highStart = highStart;
|
|
8396
|
-
this.highValueIndex = highValueIndex;
|
|
8397
|
-
this.index = index;
|
|
8398
|
-
this.data = data;
|
|
8399
|
-
}
|
|
8400
|
-
/**
|
|
8401
|
-
* Get the value for a code point as stored in the Trie.
|
|
8402
|
-
*
|
|
8403
|
-
* @param codePoint the code point
|
|
8404
|
-
* @return the value
|
|
8405
|
-
*/
|
|
8406
|
-
Trie.prototype.get = function(codePoint) {
|
|
8407
|
-
var ix;
|
|
8408
|
-
if (codePoint >= 0) {
|
|
8409
|
-
if (codePoint < 55296 || codePoint > 56319 && codePoint <= 65535) {
|
|
8410
|
-
ix = this.index[codePoint >> UTRIE2_SHIFT_2];
|
|
8411
|
-
ix = (ix << UTRIE2_INDEX_SHIFT) + (codePoint & UTRIE2_DATA_MASK);
|
|
8412
|
-
return this.data[ix];
|
|
8413
|
-
}
|
|
8414
|
-
if (codePoint <= 65535) {
|
|
8415
|
-
ix = this.index[UTRIE2_LSCP_INDEX_2_OFFSET + (codePoint - 55296 >> UTRIE2_SHIFT_2)];
|
|
8416
|
-
ix = (ix << UTRIE2_INDEX_SHIFT) + (codePoint & UTRIE2_DATA_MASK);
|
|
8417
|
-
return this.data[ix];
|
|
8418
|
-
}
|
|
8419
|
-
if (codePoint < this.highStart) {
|
|
8420
|
-
ix = UTRIE2_INDEX_1_OFFSET - UTRIE2_OMITTED_BMP_INDEX_1_LENGTH + (codePoint >> UTRIE2_SHIFT_1);
|
|
8421
|
-
ix = this.index[ix];
|
|
8422
|
-
ix += codePoint >> UTRIE2_SHIFT_2 & UTRIE2_INDEX_2_MASK;
|
|
8423
|
-
ix = this.index[ix];
|
|
8424
|
-
ix = (ix << UTRIE2_INDEX_SHIFT) + (codePoint & UTRIE2_DATA_MASK);
|
|
8425
|
-
return this.data[ix];
|
|
8426
|
-
}
|
|
8427
|
-
if (codePoint <= 1114111) return this.data[this.highValueIndex];
|
|
8428
|
-
}
|
|
8429
|
-
return this.errorValue;
|
|
8430
|
-
};
|
|
8431
|
-
return Trie;
|
|
8432
|
-
}();
|
|
8433
|
-
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
8434
|
-
var lookup = typeof Uint8Array === "undefined" ? [] : /* @__PURE__ */ new Uint8Array(256);
|
|
8435
|
-
for (var i = 0; i < chars.length; i++) lookup[chars.charCodeAt(i)] = i;
|
|
8436
|
-
var Prepend = 1;
|
|
8437
|
-
var CR = 2;
|
|
8438
|
-
var LF = 3;
|
|
8439
|
-
var Control = 4;
|
|
8440
|
-
var Extend = 5;
|
|
8441
|
-
var SpacingMark = 7;
|
|
8442
|
-
var L = 8;
|
|
8443
|
-
var V = 9;
|
|
8444
|
-
var T = 10;
|
|
8445
|
-
var LV = 11;
|
|
8446
|
-
var LVT = 12;
|
|
8447
|
-
var ZWJ = 13;
|
|
8448
|
-
var Extended_Pictographic = 14;
|
|
8449
|
-
var RI = 15;
|
|
8450
|
-
var toCodePoints = function(str) {
|
|
8451
|
-
var codePoints = [];
|
|
8452
|
-
var i = 0;
|
|
8453
|
-
var length = str.length;
|
|
8454
|
-
while (i < length) {
|
|
8455
|
-
var value = str.charCodeAt(i++);
|
|
8456
|
-
if (value >= 55296 && value <= 56319 && i < length) {
|
|
8457
|
-
var extra = str.charCodeAt(i++);
|
|
8458
|
-
if ((extra & 64512) === 56320) codePoints.push(((value & 1023) << 10) + (extra & 1023) + 65536);
|
|
8459
|
-
else {
|
|
8460
|
-
codePoints.push(value);
|
|
8461
|
-
i--;
|
|
8462
|
-
}
|
|
8463
|
-
} else codePoints.push(value);
|
|
8464
|
-
}
|
|
8465
|
-
return codePoints;
|
|
8466
|
-
};
|
|
8467
|
-
var fromCodePoint = function() {
|
|
8468
|
-
var codePoints = [];
|
|
8469
|
-
for (var _i = 0; _i < arguments.length; _i++) codePoints[_i] = arguments[_i];
|
|
8470
|
-
if (String.fromCodePoint) return String.fromCodePoint.apply(String, codePoints);
|
|
8471
|
-
var length = codePoints.length;
|
|
8472
|
-
if (!length) return "";
|
|
8473
|
-
var codeUnits = [];
|
|
8474
|
-
var index = -1;
|
|
8475
|
-
var result = "";
|
|
8476
|
-
while (++index < length) {
|
|
8477
|
-
var codePoint = codePoints[index];
|
|
8478
|
-
if (codePoint <= 65535) codeUnits.push(codePoint);
|
|
8479
|
-
else {
|
|
8480
|
-
codePoint -= 65536;
|
|
8481
|
-
codeUnits.push((codePoint >> 10) + 55296, codePoint % 1024 + 56320);
|
|
8482
|
-
}
|
|
8483
|
-
if (index + 1 === length || codeUnits.length > 16384) {
|
|
8484
|
-
result += String.fromCharCode.apply(String, codeUnits);
|
|
8485
|
-
codeUnits.length = 0;
|
|
8486
|
-
}
|
|
8487
|
-
}
|
|
8488
|
-
return result;
|
|
8489
|
-
};
|
|
8490
|
-
var UnicodeTrie = createTrieFromBase64(base64);
|
|
8491
|
-
var BREAK_NOT_ALLOWED = "×";
|
|
8492
|
-
var BREAK_ALLOWED = "÷";
|
|
8493
|
-
var codePointToClass = function(codePoint) {
|
|
8494
|
-
return UnicodeTrie.get(codePoint);
|
|
8495
|
-
};
|
|
8496
|
-
var _graphemeBreakAtIndex = function(_codePoints, classTypes, index) {
|
|
8497
|
-
var prevIndex = index - 2;
|
|
8498
|
-
var prev = classTypes[prevIndex];
|
|
8499
|
-
var current = classTypes[index - 1];
|
|
8500
|
-
var next = classTypes[index];
|
|
8501
|
-
if (current === CR && next === LF) return BREAK_NOT_ALLOWED;
|
|
8502
|
-
if (current === CR || current === LF || current === Control) return BREAK_ALLOWED;
|
|
8503
|
-
if (next === CR || next === LF || next === Control) return BREAK_ALLOWED;
|
|
8504
|
-
if (current === L && [
|
|
8505
|
-
L,
|
|
8506
|
-
V,
|
|
8507
|
-
LV,
|
|
8508
|
-
LVT
|
|
8509
|
-
].indexOf(next) !== -1) return BREAK_NOT_ALLOWED;
|
|
8510
|
-
if ((current === LV || current === V) && (next === V || next === T)) return BREAK_NOT_ALLOWED;
|
|
8511
|
-
if ((current === LVT || current === T) && next === T) return BREAK_NOT_ALLOWED;
|
|
8512
|
-
if (next === ZWJ || next === Extend) return BREAK_NOT_ALLOWED;
|
|
8513
|
-
if (next === SpacingMark) return BREAK_NOT_ALLOWED;
|
|
8514
|
-
if (current === Prepend) return BREAK_NOT_ALLOWED;
|
|
8515
|
-
if (current === ZWJ && next === Extended_Pictographic) {
|
|
8516
|
-
while (prev === Extend) prev = classTypes[--prevIndex];
|
|
8517
|
-
if (prev === Extended_Pictographic) return BREAK_NOT_ALLOWED;
|
|
8518
|
-
}
|
|
8519
|
-
if (current === RI && next === RI) {
|
|
8520
|
-
var countRI = 0;
|
|
8521
|
-
while (prev === RI) {
|
|
8522
|
-
countRI++;
|
|
8523
|
-
prev = classTypes[--prevIndex];
|
|
8524
|
-
}
|
|
8525
|
-
if (countRI % 2 === 0) return BREAK_NOT_ALLOWED;
|
|
8526
|
-
}
|
|
8527
|
-
return BREAK_ALLOWED;
|
|
8528
|
-
};
|
|
8529
|
-
var GraphemeBreaker = function(str) {
|
|
8530
|
-
var codePoints = toCodePoints(str);
|
|
8531
|
-
var length = codePoints.length;
|
|
8532
|
-
var index = 0;
|
|
8533
|
-
var lastEnd = 0;
|
|
8534
|
-
var classTypes = codePoints.map(codePointToClass);
|
|
8535
|
-
return { next: function() {
|
|
8536
|
-
if (index >= length) return {
|
|
8537
|
-
done: true,
|
|
8538
|
-
value: null
|
|
8539
|
-
};
|
|
8540
|
-
var graphemeBreak = BREAK_NOT_ALLOWED;
|
|
8541
|
-
while (index < length && (graphemeBreak = _graphemeBreakAtIndex(codePoints, classTypes, ++index)) === BREAK_NOT_ALLOWED);
|
|
8542
|
-
if (graphemeBreak !== BREAK_NOT_ALLOWED || index === length) {
|
|
8543
|
-
var value = fromCodePoint.apply(null, codePoints.slice(lastEnd, index));
|
|
8544
|
-
lastEnd = index;
|
|
8545
|
-
return {
|
|
8546
|
-
value,
|
|
8547
|
-
done: false
|
|
8548
|
-
};
|
|
8549
|
-
}
|
|
8550
|
-
return {
|
|
8551
|
-
done: true,
|
|
8552
|
-
value: null
|
|
8553
|
-
};
|
|
8554
|
-
} };
|
|
8555
|
-
};
|
|
8556
|
-
var splitGraphemes = function(str) {
|
|
8557
|
-
var breaker = GraphemeBreaker(str);
|
|
8558
|
-
var graphemes = [];
|
|
8559
|
-
var bk;
|
|
8560
|
-
while (!(bk = breaker.next()).done) if (bk.value) graphemes.push(bk.value.slice());
|
|
8561
|
-
return graphemes;
|
|
8562
|
-
};
|
|
8563
|
-
//#endregion
|
|
8564
8562
|
//#region src/core/features.ts
|
|
8563
|
+
/**
|
|
8564
|
+
* Runtime feature detection.
|
|
8565
|
+
*
|
|
8566
|
+
* Only checks that still gate real behaviour are kept: range-bounds
|
|
8567
|
+
* measurement (iOS 13 quirk), SVG drawing and CORS image support.
|
|
8568
|
+
* Dead probes (IE-era CORS XHR / XHR response-type checks) were removed —
|
|
8569
|
+
* every supported browser exposes `crossOrigin`, `responseType` and
|
|
8570
|
+
* `withCredentials`; Intl.Segmenter is used unconditionally.
|
|
8571
|
+
*/
|
|
8565
8572
|
const testRangeBounds = (document) => {
|
|
8566
8573
|
const TEST_HEIGHT = 123;
|
|
8567
8574
|
if (document.createRange) {
|
|
@@ -8580,35 +8587,7 @@ const testRangeBounds = (document) => {
|
|
|
8580
8587
|
}
|
|
8581
8588
|
return false;
|
|
8582
8589
|
};
|
|
8583
|
-
const testIOSLineBreak = (document) => {
|
|
8584
|
-
const testElement = document.createElement("boundtest");
|
|
8585
|
-
testElement.style.width = "50px";
|
|
8586
|
-
testElement.style.display = "block";
|
|
8587
|
-
testElement.style.fontSize = "12px";
|
|
8588
|
-
testElement.style.letterSpacing = "0px";
|
|
8589
|
-
testElement.style.wordSpacing = "0px";
|
|
8590
|
-
document.body.appendChild(testElement);
|
|
8591
|
-
const range = document.createRange();
|
|
8592
|
-
testElement.innerHTML = typeof "".repeat === "function" ? "👨".repeat(10) : "";
|
|
8593
|
-
const node = testElement.firstChild;
|
|
8594
|
-
const textList = toCodePoints$1(node.data).map((i) => fromCodePoint$1(i));
|
|
8595
|
-
let offset = 0;
|
|
8596
|
-
let prev = {};
|
|
8597
|
-
const supports = textList.every((text, i) => {
|
|
8598
|
-
range.setStart(node, offset);
|
|
8599
|
-
range.setEnd(node, offset + text.length);
|
|
8600
|
-
const rect = range.getBoundingClientRect();
|
|
8601
|
-
offset += text.length;
|
|
8602
|
-
const boundAhead = rect.x > prev.x || rect.y > prev.y;
|
|
8603
|
-
prev = rect;
|
|
8604
|
-
if (i === 0) return true;
|
|
8605
|
-
return boundAhead;
|
|
8606
|
-
});
|
|
8607
|
-
document.body.removeChild(testElement);
|
|
8608
|
-
return supports;
|
|
8609
|
-
};
|
|
8610
8590
|
const testCORS = () => typeof new Image().crossOrigin !== "undefined";
|
|
8611
|
-
const testResponseType = () => typeof new XMLHttpRequest().responseType === "string";
|
|
8612
8591
|
const testSVG = (document) => {
|
|
8613
8592
|
const img = new Image();
|
|
8614
8593
|
const canvas = document.createElement("canvas");
|
|
@@ -8623,36 +8602,6 @@ const testSVG = (document) => {
|
|
|
8623
8602
|
}
|
|
8624
8603
|
return true;
|
|
8625
8604
|
};
|
|
8626
|
-
const isGreenPixel = (data) => data[0] === 0 && data[1] === 255 && data[2] === 0 && data[3] === 255;
|
|
8627
|
-
const testForeignObject = (document) => {
|
|
8628
|
-
const canvas = document.createElement("canvas");
|
|
8629
|
-
const size = 100;
|
|
8630
|
-
canvas.width = size;
|
|
8631
|
-
canvas.height = size;
|
|
8632
|
-
const ctx = canvas.getContext("2d");
|
|
8633
|
-
if (!ctx) return Promise.reject(/* @__PURE__ */ new Error("Failed to get 2D rendering context"));
|
|
8634
|
-
ctx.fillStyle = "rgb(0, 255, 0)";
|
|
8635
|
-
ctx.fillRect(0, 0, size, size);
|
|
8636
|
-
const img = new Image();
|
|
8637
|
-
const greenImageSrc = canvas.toDataURL();
|
|
8638
|
-
img.src = greenImageSrc;
|
|
8639
|
-
const svg = createForeignObjectSVG(size, size, 0, 0, img);
|
|
8640
|
-
ctx.fillStyle = "red";
|
|
8641
|
-
ctx.fillRect(0, 0, size, size);
|
|
8642
|
-
return loadSerializedSVG(svg).then((img) => {
|
|
8643
|
-
ctx.drawImage(img, 0, 0);
|
|
8644
|
-
const data = ctx.getImageData(0, 0, size, size).data;
|
|
8645
|
-
ctx.fillStyle = "red";
|
|
8646
|
-
ctx.fillRect(0, 0, size, size);
|
|
8647
|
-
const node = document.createElement("div");
|
|
8648
|
-
node.style.backgroundImage = `url(${greenImageSrc})`;
|
|
8649
|
-
node.style.height = `${size}px`;
|
|
8650
|
-
return isGreenPixel(data) ? loadSerializedSVG(createForeignObjectSVG(size, size, 0, 0, node)) : Promise.reject(/* @__PURE__ */ new Error("ForeignObject rendering not supported"));
|
|
8651
|
-
}).then((img) => {
|
|
8652
|
-
ctx.drawImage(img, 0, 0);
|
|
8653
|
-
return isGreenPixel(ctx.getImageData(0, 0, size, size).data);
|
|
8654
|
-
}).catch(() => false);
|
|
8655
|
-
};
|
|
8656
8605
|
const createForeignObjectSVG = (width, height, x, y, node) => {
|
|
8657
8606
|
const xmlns = "http://www.w3.org/2000/svg";
|
|
8658
8607
|
const svg = document.createElementNS(xmlns, "svg");
|
|
@@ -8683,52 +8632,24 @@ const FEATURES = {
|
|
|
8683
8632
|
Object.defineProperty(FEATURES, "SUPPORT_RANGE_BOUNDS", { value });
|
|
8684
8633
|
return value;
|
|
8685
8634
|
},
|
|
8686
|
-
get SUPPORT_WORD_BREAKING() {
|
|
8687
|
-
"use strict";
|
|
8688
|
-
const value = FEATURES.SUPPORT_RANGE_BOUNDS && testIOSLineBreak(document);
|
|
8689
|
-
Object.defineProperty(FEATURES, "SUPPORT_WORD_BREAKING", { value });
|
|
8690
|
-
return value;
|
|
8691
|
-
},
|
|
8692
8635
|
get SUPPORT_SVG_DRAWING() {
|
|
8693
8636
|
"use strict";
|
|
8694
8637
|
const value = testSVG(document);
|
|
8695
8638
|
Object.defineProperty(FEATURES, "SUPPORT_SVG_DRAWING", { value });
|
|
8696
8639
|
return value;
|
|
8697
8640
|
},
|
|
8698
|
-
get SUPPORT_FOREIGNOBJECT_DRAWING() {
|
|
8699
|
-
"use strict";
|
|
8700
|
-
const value = typeof Array.from === "function" && typeof window.fetch === "function" ? testForeignObject(document) : Promise.resolve(false);
|
|
8701
|
-
Object.defineProperty(FEATURES, "SUPPORT_FOREIGNOBJECT_DRAWING", { value });
|
|
8702
|
-
return value;
|
|
8703
|
-
},
|
|
8704
8641
|
get SUPPORT_CORS_IMAGES() {
|
|
8705
8642
|
"use strict";
|
|
8706
8643
|
const value = testCORS();
|
|
8707
8644
|
Object.defineProperty(FEATURES, "SUPPORT_CORS_IMAGES", { value });
|
|
8708
8645
|
return value;
|
|
8709
|
-
},
|
|
8710
|
-
get SUPPORT_RESPONSE_TYPE() {
|
|
8711
|
-
"use strict";
|
|
8712
|
-
const value = testResponseType();
|
|
8713
|
-
Object.defineProperty(FEATURES, "SUPPORT_RESPONSE_TYPE", { value });
|
|
8714
|
-
return value;
|
|
8715
|
-
},
|
|
8716
|
-
get SUPPORT_CORS_XHR() {
|
|
8717
|
-
"use strict";
|
|
8718
|
-
const value = "withCredentials" in new XMLHttpRequest();
|
|
8719
|
-
Object.defineProperty(FEATURES, "SUPPORT_CORS_XHR", { value });
|
|
8720
|
-
return value;
|
|
8721
|
-
},
|
|
8722
|
-
get SUPPORT_NATIVE_TEXT_SEGMENTATION() {
|
|
8723
|
-
"use strict";
|
|
8724
|
-
const value = !!(typeof Intl !== "undefined" && Intl.Segmenter);
|
|
8725
|
-
Object.defineProperty(FEATURES, "SUPPORT_NATIVE_TEXT_SEGMENTATION", { value });
|
|
8726
|
-
return value;
|
|
8727
8646
|
}
|
|
8728
8647
|
};
|
|
8729
8648
|
//#endregion
|
|
8730
8649
|
//#region src/css/layout/text.ts
|
|
8731
8650
|
var TextBounds = class {
|
|
8651
|
+
text;
|
|
8652
|
+
bounds;
|
|
8732
8653
|
constructor(text, bounds) {
|
|
8733
8654
|
this.text = text;
|
|
8734
8655
|
this.bounds = bounds;
|
|
@@ -8787,58 +8708,24 @@ const segmenterCache = /* @__PURE__ */ new Map();
|
|
|
8787
8708
|
const getSegmenter = (granularity) => {
|
|
8788
8709
|
let segmenter = segmenterCache.get(granularity);
|
|
8789
8710
|
if (!segmenter) {
|
|
8790
|
-
|
|
8791
|
-
segmenter = new Segmenter(void 0, { granularity });
|
|
8711
|
+
segmenter = new Intl.Segmenter(void 0, { granularity });
|
|
8792
8712
|
segmenterCache.set(granularity, segmenter);
|
|
8793
8713
|
}
|
|
8794
8714
|
return segmenter;
|
|
8795
8715
|
};
|
|
8796
|
-
const segmentGraphemes = (value) =>
|
|
8797
|
-
|
|
8798
|
-
return
|
|
8799
|
-
};
|
|
8800
|
-
const segmentWords = (value, styles) => {
|
|
8801
|
-
if (FEATURES.SUPPORT_NATIVE_TEXT_SEGMENTATION) return Array.from(getSegmenter("word").segment(value)).map((s) => s.segment);
|
|
8802
|
-
return breakWords(value, styles);
|
|
8716
|
+
const segmentGraphemes = (value) => Array.from(getSegmenter("grapheme").segment(value), (s) => s.segment);
|
|
8717
|
+
const segmentWords = (value) => {
|
|
8718
|
+
return Array.from(getSegmenter("word").segment(value), (s) => s.segment);
|
|
8803
8719
|
};
|
|
8804
8720
|
const breakText = (value, styles) => {
|
|
8805
8721
|
if (isVerticalWritingMode(styles.writingMode)) return segmentGraphemes(value);
|
|
8806
|
-
return styles.letterSpacing !== 0 ? segmentGraphemes(value) : segmentWords(value
|
|
8807
|
-
};
|
|
8808
|
-
const wordSeparators = [
|
|
8809
|
-
32,
|
|
8810
|
-
160,
|
|
8811
|
-
4961,
|
|
8812
|
-
65792,
|
|
8813
|
-
65793,
|
|
8814
|
-
4153,
|
|
8815
|
-
4241
|
|
8816
|
-
];
|
|
8817
|
-
const breakWords = (str, styles) => {
|
|
8818
|
-
const breaker = LineBreaker(str, {
|
|
8819
|
-
lineBreak: styles.lineBreak,
|
|
8820
|
-
wordBreak: styles.overflowWrap === "break-word" ? "break-word" : styles.wordBreak
|
|
8821
|
-
});
|
|
8822
|
-
const words = [];
|
|
8823
|
-
let bk;
|
|
8824
|
-
while (!(bk = breaker.next()).done) if (bk.value) {
|
|
8825
|
-
const codePoints = toCodePoints$1(bk.value.slice());
|
|
8826
|
-
let word = "";
|
|
8827
|
-
codePoints.forEach((codePoint) => {
|
|
8828
|
-
if (wordSeparators.indexOf(codePoint) === -1) word += fromCodePoint$1(codePoint);
|
|
8829
|
-
else {
|
|
8830
|
-
if (word.length) words.push(word);
|
|
8831
|
-
words.push(fromCodePoint$1(codePoint));
|
|
8832
|
-
word = "";
|
|
8833
|
-
}
|
|
8834
|
-
});
|
|
8835
|
-
if (word.length) words.push(word);
|
|
8836
|
-
}
|
|
8837
|
-
return words;
|
|
8722
|
+
return styles.letterSpacing !== 0 ? segmentGraphemes(value) : segmentWords(value);
|
|
8838
8723
|
};
|
|
8839
8724
|
//#endregion
|
|
8840
8725
|
//#region src/dom/text-container.ts
|
|
8841
8726
|
var TextContainer = class {
|
|
8727
|
+
text;
|
|
8728
|
+
textBounds;
|
|
8842
8729
|
constructor(context, node, styles) {
|
|
8843
8730
|
this.text = transform(node.data, styles.textTransform);
|
|
8844
8731
|
if (this.text.length !== node.data.length) node.data = this.text;
|
|
@@ -8861,8 +8748,11 @@ const capitalize = (m, p1, p2) => {
|
|
|
8861
8748
|
//#endregion
|
|
8862
8749
|
//#region src/dom/replaced-elements/image-element-container.ts
|
|
8863
8750
|
var ImageElementContainer = class extends ElementContainer {
|
|
8864
|
-
|
|
8865
|
-
|
|
8751
|
+
src;
|
|
8752
|
+
intrinsicWidth;
|
|
8753
|
+
intrinsicHeight;
|
|
8754
|
+
constructor(context, img, options = {}) {
|
|
8755
|
+
super(context, img, options);
|
|
8866
8756
|
this.src = img.currentSrc || img.src;
|
|
8867
8757
|
this.intrinsicWidth = img.naturalWidth;
|
|
8868
8758
|
this.intrinsicHeight = img.naturalHeight;
|
|
@@ -8872,8 +8762,11 @@ var ImageElementContainer = class extends ElementContainer {
|
|
|
8872
8762
|
//#endregion
|
|
8873
8763
|
//#region src/dom/replaced-elements/canvas-element-container.ts
|
|
8874
8764
|
var CanvasElementContainer = class extends ElementContainer {
|
|
8875
|
-
|
|
8876
|
-
|
|
8765
|
+
canvas;
|
|
8766
|
+
intrinsicWidth;
|
|
8767
|
+
intrinsicHeight;
|
|
8768
|
+
constructor(context, canvas, options = {}) {
|
|
8769
|
+
super(context, canvas, options);
|
|
8877
8770
|
this.canvas = canvas;
|
|
8878
8771
|
this.intrinsicWidth = canvas.width;
|
|
8879
8772
|
this.intrinsicHeight = canvas.height;
|
|
@@ -8915,8 +8808,11 @@ const serializeWithoutBoxOffsets = (serializer, img) => {
|
|
|
8915
8808
|
return serialized;
|
|
8916
8809
|
};
|
|
8917
8810
|
var SVGElementContainer = class extends ElementContainer {
|
|
8918
|
-
|
|
8919
|
-
|
|
8811
|
+
svg;
|
|
8812
|
+
intrinsicWidth;
|
|
8813
|
+
intrinsicHeight;
|
|
8814
|
+
constructor(context, img, options = {}) {
|
|
8815
|
+
super(context, img, options);
|
|
8920
8816
|
const s = new XMLSerializer();
|
|
8921
8817
|
const bounds = parseBounds(context, img);
|
|
8922
8818
|
img.setAttribute("width", `${bounds.width}px`);
|
|
@@ -8930,16 +8826,19 @@ var SVGElementContainer = class extends ElementContainer {
|
|
|
8930
8826
|
//#endregion
|
|
8931
8827
|
//#region src/dom/elements/li-element-container.ts
|
|
8932
8828
|
var LIElementContainer = class extends ElementContainer {
|
|
8933
|
-
|
|
8934
|
-
|
|
8829
|
+
value;
|
|
8830
|
+
constructor(context, element, options = {}) {
|
|
8831
|
+
super(context, element, options);
|
|
8935
8832
|
this.value = element.value;
|
|
8936
8833
|
}
|
|
8937
8834
|
};
|
|
8938
8835
|
//#endregion
|
|
8939
8836
|
//#region src/dom/elements/ol-element-container.ts
|
|
8940
8837
|
var OLElementContainer = class extends ElementContainer {
|
|
8941
|
-
|
|
8942
|
-
|
|
8838
|
+
start;
|
|
8839
|
+
reversed;
|
|
8840
|
+
constructor(context, element, options = {}) {
|
|
8841
|
+
super(context, element, options);
|
|
8943
8842
|
this.start = element.start;
|
|
8944
8843
|
this.reversed = typeof element.reversed === "boolean" && element.reversed === true;
|
|
8945
8844
|
}
|
|
@@ -8973,8 +8872,12 @@ const CHECKBOX = "checkbox";
|
|
|
8973
8872
|
const RADIO = "radio";
|
|
8974
8873
|
const PLACEHOLDER_COLOR = 1970632191;
|
|
8975
8874
|
var InputElementContainer = class extends ElementContainer {
|
|
8976
|
-
|
|
8977
|
-
|
|
8875
|
+
type;
|
|
8876
|
+
checked;
|
|
8877
|
+
value;
|
|
8878
|
+
isPlaceholder;
|
|
8879
|
+
constructor(context, input, options = {}) {
|
|
8880
|
+
super(context, input, options);
|
|
8978
8881
|
this.type = input.type.toLowerCase();
|
|
8979
8882
|
this.checked = input.checked;
|
|
8980
8883
|
this.value = getInputValue(input);
|
|
@@ -8999,8 +8902,9 @@ var InputElementContainer = class extends ElementContainer {
|
|
|
8999
8902
|
//#endregion
|
|
9000
8903
|
//#region src/dom/elements/select-element-container.ts
|
|
9001
8904
|
var SelectElementContainer = class extends ElementContainer {
|
|
9002
|
-
|
|
9003
|
-
|
|
8905
|
+
value;
|
|
8906
|
+
constructor(context, element, options = {}) {
|
|
8907
|
+
super(context, element, options);
|
|
9004
8908
|
const option = element.options[element.selectedIndex || 0];
|
|
9005
8909
|
this.value = option ? option.text || "" : "";
|
|
9006
8910
|
}
|
|
@@ -9008,29 +8912,42 @@ var SelectElementContainer = class extends ElementContainer {
|
|
|
9008
8912
|
//#endregion
|
|
9009
8913
|
//#region src/dom/elements/textarea-element-container.ts
|
|
9010
8914
|
var TextareaElementContainer = class extends ElementContainer {
|
|
9011
|
-
|
|
9012
|
-
|
|
8915
|
+
value;
|
|
8916
|
+
constructor(context, element, options = {}) {
|
|
8917
|
+
super(context, element, options);
|
|
9013
8918
|
this.value = element.value;
|
|
9014
8919
|
}
|
|
9015
8920
|
};
|
|
9016
8921
|
//#endregion
|
|
9017
8922
|
//#region src/dom/replaced-elements/iframe-element-container.ts
|
|
9018
8923
|
var IFrameElementContainer = class extends ElementContainer {
|
|
9019
|
-
|
|
9020
|
-
|
|
8924
|
+
src;
|
|
8925
|
+
width;
|
|
8926
|
+
height;
|
|
8927
|
+
tree;
|
|
8928
|
+
backgroundColor;
|
|
8929
|
+
parseTreeFn;
|
|
8930
|
+
constructor(context, iframe, parseTreeFn, options = {}) {
|
|
8931
|
+
super(context, iframe, options);
|
|
9021
8932
|
this.src = iframe.src;
|
|
9022
8933
|
this.width = parseInt(iframe.width, 10) || 0;
|
|
9023
8934
|
this.height = parseInt(iframe.height, 10) || 0;
|
|
9024
8935
|
this.backgroundColor = this.styles.backgroundColor;
|
|
9025
8936
|
this.parseTreeFn = parseTreeFn;
|
|
9026
8937
|
try {
|
|
9027
|
-
|
|
9028
|
-
|
|
9029
|
-
|
|
9030
|
-
|
|
8938
|
+
const contentWindow = iframe.contentWindow;
|
|
8939
|
+
const contentDocument = contentWindow?.document;
|
|
8940
|
+
if (contentWindow && contentDocument && contentDocument.documentElement && this.parseTreeFn) {
|
|
8941
|
+
this.tree = this.parseTreeFn(context, contentDocument.documentElement);
|
|
8942
|
+
const documentBackgroundColor = parseColor(context, contentWindow.getComputedStyle(contentDocument.documentElement).backgroundColor);
|
|
8943
|
+
const bodyBackgroundColor = contentDocument.body ? parseColor(context, contentWindow.getComputedStyle(contentDocument.body).backgroundColor) : 0;
|
|
9031
8944
|
this.backgroundColor = isTransparent(documentBackgroundColor) ? isTransparent(bodyBackgroundColor) ? this.styles.backgroundColor : bodyBackgroundColor : documentBackgroundColor;
|
|
9032
8945
|
}
|
|
9033
|
-
} catch (e) {
|
|
8946
|
+
} catch (e) {
|
|
8947
|
+
const error = e instanceof Error ? e : new Error(String(e));
|
|
8948
|
+
this.context.logger.warn(`Unable to render iframe content${this.src ? ` from ${this.src}` : ""}: ${error.message}`);
|
|
8949
|
+
this.context.onError?.(error);
|
|
8950
|
+
}
|
|
9034
8951
|
}
|
|
9035
8952
|
};
|
|
9036
8953
|
//#endregion
|
|
@@ -9040,10 +8957,10 @@ const LIST_OWNERS = [
|
|
|
9040
8957
|
"UL",
|
|
9041
8958
|
"MENU"
|
|
9042
8959
|
];
|
|
9043
|
-
const parseNodeTree = (context, node, parent, root, zoomScale = 1) => {
|
|
8960
|
+
const parseNodeTree = (context, node, parent, root, zoomScale = 1, options = {}) => {
|
|
9044
8961
|
for (let childNode = node.firstChild, nextNode; childNode; childNode = nextNode) {
|
|
9045
8962
|
nextNode = childNode.nextSibling;
|
|
9046
|
-
parseChildNode(context, childNode, parent, root, zoomScale);
|
|
8963
|
+
parseChildNode(context, childNode, parent, root, zoomScale, options);
|
|
9047
8964
|
}
|
|
9048
8965
|
};
|
|
9049
8966
|
/**
|
|
@@ -9054,7 +8971,7 @@ const parseNodeTree = (context, node, parent, root, zoomScale = 1) => {
|
|
|
9054
8971
|
* this, slotted shadow-DOM content such as web component labels was silently
|
|
9055
8972
|
* dropped because `parseNodeTree` only iterates `node.firstChild` (issue #226).
|
|
9056
8973
|
*/
|
|
9057
|
-
const parseChildNode = (context, childNode, parent, root, zoomScale = 1) => {
|
|
8974
|
+
const parseChildNode = (context, childNode, parent, root, zoomScale = 1, options = {}) => {
|
|
9058
8975
|
if (isTextNode(childNode) && childNode.data.length > 0) {
|
|
9059
8976
|
const textContainer = new TextContainer(context, childNode, parent.styles);
|
|
9060
8977
|
if (zoomScale !== 1) {
|
|
@@ -9064,9 +8981,9 @@ const parseChildNode = (context, childNode, parent, root, zoomScale = 1) => {
|
|
|
9064
8981
|
}
|
|
9065
8982
|
parent.textNodes.push(textContainer);
|
|
9066
8983
|
} else if (isElementNode(childNode)) {
|
|
9067
|
-
if (isSlotElement(childNode) && childNode.assignedNodes) childNode.assignedNodes().forEach((assignedNode) => parseChildNode(context, assignedNode, parent, root, zoomScale));
|
|
8984
|
+
if (isSlotElement(childNode) && childNode.assignedNodes) childNode.assignedNodes().forEach((assignedNode) => parseChildNode(context, assignedNode, parent, root, zoomScale, options));
|
|
9068
8985
|
else {
|
|
9069
|
-
const container = createContainer(context, childNode);
|
|
8986
|
+
const container = createContainer(context, childNode, options);
|
|
9070
8987
|
const ownZoom = container.styles.zoom || 1;
|
|
9071
8988
|
if (ownZoom !== 1) container.bounds = new Bounds(container.bounds.left, container.bounds.top, container.bounds.width / ownZoom, container.bounds.height / ownZoom);
|
|
9072
8989
|
if (container.styles.isVisible()) {
|
|
@@ -9075,28 +8992,28 @@ const parseChildNode = (context, childNode, parent, root, zoomScale = 1) => {
|
|
|
9075
8992
|
if (LIST_OWNERS.indexOf(childNode.tagName) !== -1) container.isListOwner = true;
|
|
9076
8993
|
parent.elements.push(container);
|
|
9077
8994
|
const childZoom = zoomScale * (container.styles.zoom || 1);
|
|
9078
|
-
if (childNode.shadowRoot) parseNodeTree(context, childNode.shadowRoot, container, root, childZoom);
|
|
9079
|
-
else if (!isTextareaElement(childNode) && !isSVGElement(childNode) && !isSelectElement(childNode)) parseNodeTree(context, childNode, container, root, childZoom);
|
|
8995
|
+
if (childNode.shadowRoot) parseNodeTree(context, childNode.shadowRoot, container, root, childZoom, options);
|
|
8996
|
+
else if (!isTextareaElement(childNode) && !isSVGElement(childNode) && !isSelectElement(childNode)) parseNodeTree(context, childNode, container, root, childZoom, options);
|
|
9080
8997
|
}
|
|
9081
8998
|
}
|
|
9082
8999
|
}
|
|
9083
9000
|
};
|
|
9084
|
-
const createContainer = (context, element) => {
|
|
9085
|
-
if (isImageElement(element)) return new ImageElementContainer(context, element);
|
|
9086
|
-
if (isCanvasElement(element)) return new CanvasElementContainer(context, element);
|
|
9087
|
-
if (isSVGElement(element)) return new SVGElementContainer(context, element);
|
|
9088
|
-
if (isLIElement(element)) return new LIElementContainer(context, element);
|
|
9089
|
-
if (isOLElement(element)) return new OLElementContainer(context, element);
|
|
9090
|
-
if (isInputElement(element)) return new InputElementContainer(context, element);
|
|
9091
|
-
if (isSelectElement(element)) return new SelectElementContainer(context, element);
|
|
9092
|
-
if (isTextareaElement(element)) return new TextareaElementContainer(context, element);
|
|
9093
|
-
if (isIFrameElement(element)) return new IFrameElementContainer(context, element, parseTree);
|
|
9094
|
-
return new ElementContainer(context, element);
|
|
9001
|
+
const createContainer = (context, element, options = {}) => {
|
|
9002
|
+
if (isImageElement(element)) return new ImageElementContainer(context, element, options);
|
|
9003
|
+
if (isCanvasElement(element)) return new CanvasElementContainer(context, element, options);
|
|
9004
|
+
if (isSVGElement(element)) return new SVGElementContainer(context, element, options);
|
|
9005
|
+
if (isLIElement(element)) return new LIElementContainer(context, element, options);
|
|
9006
|
+
if (isOLElement(element)) return new OLElementContainer(context, element, options);
|
|
9007
|
+
if (isInputElement(element)) return new InputElementContainer(context, element, options);
|
|
9008
|
+
if (isSelectElement(element)) return new SelectElementContainer(context, element, options);
|
|
9009
|
+
if (isTextareaElement(element)) return new TextareaElementContainer(context, element, options);
|
|
9010
|
+
if (isIFrameElement(element)) return new IFrameElementContainer(context, element, (ctx, node) => parseTree(ctx, node, options), options);
|
|
9011
|
+
return new ElementContainer(context, element, options);
|
|
9095
9012
|
};
|
|
9096
|
-
const parseTree = (context, element) => {
|
|
9097
|
-
const container = createContainer(context, element);
|
|
9013
|
+
const parseTree = (context, element, options = {}) => {
|
|
9014
|
+
const container = createContainer(context, element, options);
|
|
9098
9015
|
container.createsRealStackingContext = true;
|
|
9099
|
-
parseNodeTree(context, element, container, container);
|
|
9016
|
+
parseNodeTree(context, element, container, container, 1, options);
|
|
9100
9017
|
return container;
|
|
9101
9018
|
};
|
|
9102
9019
|
const createsRealStackingContext = (node, container, root) => {
|
|
@@ -9127,6 +9044,9 @@ const transformPath = (path, deltaX, deltaY, deltaW, deltaH) => {
|
|
|
9127
9044
|
//#endregion
|
|
9128
9045
|
//#region src/render/vector.ts
|
|
9129
9046
|
var Vector = class Vector {
|
|
9047
|
+
type;
|
|
9048
|
+
x;
|
|
9049
|
+
y;
|
|
9130
9050
|
constructor(x, y) {
|
|
9131
9051
|
this.type = 0;
|
|
9132
9052
|
this.x = x;
|
|
@@ -9142,6 +9062,11 @@ const lerp = (a, b, t) => {
|
|
|
9142
9062
|
return new Vector(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t);
|
|
9143
9063
|
};
|
|
9144
9064
|
var BezierCurve = class BezierCurve {
|
|
9065
|
+
type;
|
|
9066
|
+
start;
|
|
9067
|
+
startControl;
|
|
9068
|
+
endControl;
|
|
9069
|
+
end;
|
|
9145
9070
|
constructor(start, startControl, endControl, end) {
|
|
9146
9071
|
this.type = 1;
|
|
9147
9072
|
this.start = start;
|
|
@@ -9169,6 +9094,30 @@ const isBezierCurve = (path) => path.type === 1;
|
|
|
9169
9094
|
//#endregion
|
|
9170
9095
|
//#region src/render/bound-curves.ts
|
|
9171
9096
|
var BoundCurves = class {
|
|
9097
|
+
topLeftBorderDoubleOuterBox;
|
|
9098
|
+
topRightBorderDoubleOuterBox;
|
|
9099
|
+
bottomRightBorderDoubleOuterBox;
|
|
9100
|
+
bottomLeftBorderDoubleOuterBox;
|
|
9101
|
+
topLeftBorderDoubleInnerBox;
|
|
9102
|
+
topRightBorderDoubleInnerBox;
|
|
9103
|
+
bottomRightBorderDoubleInnerBox;
|
|
9104
|
+
bottomLeftBorderDoubleInnerBox;
|
|
9105
|
+
topLeftBorderStroke;
|
|
9106
|
+
topRightBorderStroke;
|
|
9107
|
+
bottomRightBorderStroke;
|
|
9108
|
+
bottomLeftBorderStroke;
|
|
9109
|
+
topLeftBorderBox;
|
|
9110
|
+
topRightBorderBox;
|
|
9111
|
+
bottomRightBorderBox;
|
|
9112
|
+
bottomLeftBorderBox;
|
|
9113
|
+
topLeftPaddingBox;
|
|
9114
|
+
topRightPaddingBox;
|
|
9115
|
+
bottomRightPaddingBox;
|
|
9116
|
+
bottomLeftPaddingBox;
|
|
9117
|
+
topLeftContentBox;
|
|
9118
|
+
topRightContentBox;
|
|
9119
|
+
bottomRightContentBox;
|
|
9120
|
+
bottomLeftContentBox;
|
|
9172
9121
|
constructor(element) {
|
|
9173
9122
|
const styles = element.styles;
|
|
9174
9123
|
const bounds = element.bounds;
|
|
@@ -9205,15 +9154,15 @@ var BoundCurves = class {
|
|
|
9205
9154
|
const paddingBottom = getAbsoluteValue(styles.paddingBottom, element.bounds.width);
|
|
9206
9155
|
const paddingLeft = getAbsoluteValue(styles.paddingLeft, element.bounds.width);
|
|
9207
9156
|
this.topLeftBorderDoubleOuterBox = tlh > 0 || tlv > 0 ? getCurvePoints(bounds.left + borderLeftWidth / 3, bounds.top + borderTopWidth / 3, tlh - borderLeftWidth / 3, tlv - borderTopWidth / 3, 0) : new Vector(bounds.left + borderLeftWidth / 3, bounds.top + borderTopWidth / 3);
|
|
9208
|
-
this.topRightBorderDoubleOuterBox =
|
|
9157
|
+
this.topRightBorderDoubleOuterBox = trh > 0 || trv > 0 ? getCurvePoints(bounds.left + topWidth, bounds.top + borderTopWidth / 3, trh - borderRightWidth / 3, trv - borderTopWidth / 3, 1) : new Vector(bounds.left + bounds.width - borderRightWidth / 3, bounds.top + borderTopWidth / 3);
|
|
9209
9158
|
this.bottomRightBorderDoubleOuterBox = brh > 0 || brv > 0 ? getCurvePoints(bounds.left + bottomWidth, bounds.top + rightHeight, brh - borderRightWidth / 3, brv - borderBottomWidth / 3, 2) : new Vector(bounds.left + bounds.width - borderRightWidth / 3, bounds.top + bounds.height - borderBottomWidth / 3);
|
|
9210
9159
|
this.bottomLeftBorderDoubleOuterBox = blh > 0 || blv > 0 ? getCurvePoints(bounds.left + borderLeftWidth / 3, bounds.top + leftHeight, blh - borderLeftWidth / 3, blv - borderBottomWidth / 3, 3) : new Vector(bounds.left + borderLeftWidth / 3, bounds.top + bounds.height - borderBottomWidth / 3);
|
|
9211
9160
|
this.topLeftBorderDoubleInnerBox = tlh > 0 || tlv > 0 ? getCurvePoints(bounds.left + borderLeftWidth * 2 / 3, bounds.top + borderTopWidth * 2 / 3, tlh - borderLeftWidth * 2 / 3, tlv - borderTopWidth * 2 / 3, 0) : new Vector(bounds.left + borderLeftWidth * 2 / 3, bounds.top + borderTopWidth * 2 / 3);
|
|
9212
|
-
this.topRightBorderDoubleInnerBox =
|
|
9161
|
+
this.topRightBorderDoubleInnerBox = trh > 0 || trv > 0 ? getCurvePoints(bounds.left + topWidth, bounds.top + borderTopWidth * 2 / 3, trh - borderRightWidth * 2 / 3, trv - borderTopWidth * 2 / 3, 1) : new Vector(bounds.left + bounds.width - borderRightWidth * 2 / 3, bounds.top + borderTopWidth * 2 / 3);
|
|
9213
9162
|
this.bottomRightBorderDoubleInnerBox = brh > 0 || brv > 0 ? getCurvePoints(bounds.left + bottomWidth, bounds.top + rightHeight, brh - borderRightWidth * 2 / 3, brv - borderBottomWidth * 2 / 3, 2) : new Vector(bounds.left + bounds.width - borderRightWidth * 2 / 3, bounds.top + bounds.height - borderBottomWidth * 2 / 3);
|
|
9214
9163
|
this.bottomLeftBorderDoubleInnerBox = blh > 0 || blv > 0 ? getCurvePoints(bounds.left + borderLeftWidth * 2 / 3, bounds.top + leftHeight, blh - borderLeftWidth * 2 / 3, blv - borderBottomWidth * 2 / 3, 3) : new Vector(bounds.left + borderLeftWidth * 2 / 3, bounds.top + bounds.height - borderBottomWidth * 2 / 3);
|
|
9215
9164
|
this.topLeftBorderStroke = tlh > 0 || tlv > 0 ? getCurvePoints(bounds.left + borderLeftWidth / 2, bounds.top + borderTopWidth / 2, tlh - borderLeftWidth / 2, tlv - borderTopWidth / 2, 0) : new Vector(bounds.left + borderLeftWidth / 2, bounds.top + borderTopWidth / 2);
|
|
9216
|
-
this.topRightBorderStroke =
|
|
9165
|
+
this.topRightBorderStroke = trh > 0 || trv > 0 ? getCurvePoints(bounds.left + topWidth, bounds.top + borderTopWidth / 2, trh - borderRightWidth / 2, trv - borderTopWidth / 2, 1) : new Vector(bounds.left + bounds.width - borderRightWidth / 2, bounds.top + borderTopWidth / 2);
|
|
9217
9166
|
this.bottomRightBorderStroke = brh > 0 || brv > 0 ? getCurvePoints(bounds.left + bottomWidth, bounds.top + rightHeight, brh - borderRightWidth / 2, brv - borderBottomWidth / 2, 2) : new Vector(bounds.left + bounds.width - borderRightWidth / 2, bounds.top + bounds.height - borderBottomWidth / 2);
|
|
9218
9167
|
this.bottomLeftBorderStroke = blh > 0 || blv > 0 ? getCurvePoints(bounds.left + borderLeftWidth / 2, bounds.top + leftHeight, blh - borderLeftWidth / 2, blv - borderBottomWidth / 2, 3) : new Vector(bounds.left + borderLeftWidth / 2, bounds.top + bounds.height - borderBottomWidth / 2);
|
|
9219
9168
|
this.topLeftBorderBox = tlh > 0 || tlv > 0 ? getCurvePoints(bounds.left, bounds.top, tlh, tlv, 0) : new Vector(bounds.left, bounds.top);
|
|
@@ -9270,26 +9219,32 @@ const calculatePaddingBoxPath = (curves) => {
|
|
|
9270
9219
|
//#endregion
|
|
9271
9220
|
//#region src/render/effects.ts
|
|
9272
9221
|
var TransformEffect = class {
|
|
9222
|
+
offsetX;
|
|
9223
|
+
offsetY;
|
|
9224
|
+
matrix;
|
|
9225
|
+
type = 0;
|
|
9226
|
+
target = 6;
|
|
9273
9227
|
constructor(offsetX, offsetY, matrix) {
|
|
9274
9228
|
this.offsetX = offsetX;
|
|
9275
9229
|
this.offsetY = offsetY;
|
|
9276
9230
|
this.matrix = matrix;
|
|
9277
|
-
this.type = 0;
|
|
9278
|
-
this.target = 6;
|
|
9279
9231
|
}
|
|
9280
9232
|
};
|
|
9281
9233
|
var ClipEffect = class {
|
|
9234
|
+
path;
|
|
9235
|
+
target;
|
|
9236
|
+
type = 1;
|
|
9282
9237
|
constructor(path, target) {
|
|
9283
9238
|
this.path = path;
|
|
9284
9239
|
this.target = target;
|
|
9285
|
-
this.type = 1;
|
|
9286
9240
|
}
|
|
9287
9241
|
};
|
|
9288
9242
|
var OpacityEffect = class {
|
|
9243
|
+
opacity;
|
|
9244
|
+
type = 2;
|
|
9245
|
+
target = 6;
|
|
9289
9246
|
constructor(opacity) {
|
|
9290
9247
|
this.opacity = opacity;
|
|
9291
|
-
this.type = 2;
|
|
9292
|
-
this.target = 6;
|
|
9293
9248
|
}
|
|
9294
9249
|
};
|
|
9295
9250
|
/**
|
|
@@ -9299,10 +9254,11 @@ var OpacityEffect = class {
|
|
|
9299
9254
|
* the path is constructed (arc, ellipse, lineTo, Path2D, etc.).
|
|
9300
9255
|
*/
|
|
9301
9256
|
var ClipPathEffect = class {
|
|
9257
|
+
applyClip;
|
|
9258
|
+
type = 3;
|
|
9259
|
+
target = 6;
|
|
9302
9260
|
constructor(applyClip) {
|
|
9303
9261
|
this.applyClip = applyClip;
|
|
9304
|
-
this.type = 3;
|
|
9305
|
-
this.target = 6;
|
|
9306
9262
|
}
|
|
9307
9263
|
};
|
|
9308
9264
|
/**
|
|
@@ -9329,17 +9285,23 @@ const MIX_BLEND_MODE_TO_COMPOSITE = {
|
|
|
9329
9285
|
[MIX_BLEND_MODE$1.LUMINOSITY]: "luminosity"
|
|
9330
9286
|
};
|
|
9331
9287
|
var BlendEffect = class {
|
|
9288
|
+
mixBlendMode;
|
|
9289
|
+
type = 4;
|
|
9290
|
+
target = 6;
|
|
9291
|
+
compositeOperation;
|
|
9332
9292
|
constructor(mixBlendMode) {
|
|
9333
9293
|
this.mixBlendMode = mixBlendMode;
|
|
9334
|
-
this.type = 4;
|
|
9335
|
-
this.target = 6;
|
|
9336
9294
|
this.compositeOperation = MIX_BLEND_MODE_TO_COMPOSITE[mixBlendMode];
|
|
9337
9295
|
}
|
|
9338
9296
|
};
|
|
9339
9297
|
var FilterEffect = class FilterEffect {
|
|
9298
|
+
type = 5;
|
|
9299
|
+
target = 6;
|
|
9300
|
+
/** CSS filter string with drop-shadow() stripped (safe for ctx.filter). */
|
|
9301
|
+
safeFilterString;
|
|
9302
|
+
/** Shadow params for drop-shadow(), if present and successfully parsed. */
|
|
9303
|
+
shadow;
|
|
9340
9304
|
constructor(filterString) {
|
|
9341
|
-
this.type = 5;
|
|
9342
|
-
this.target = 6;
|
|
9343
9305
|
const parsed = FilterEffect.parseDropShadow(filterString);
|
|
9344
9306
|
this.shadow = parsed.shadow;
|
|
9345
9307
|
this.safeFilterString = parsed.safeFilterString;
|
|
@@ -9465,6 +9427,14 @@ const isFilterEffect = (effect) => effect.type === 5;
|
|
|
9465
9427
|
//#endregion
|
|
9466
9428
|
//#region src/render/stacking-context.ts
|
|
9467
9429
|
var StackingContext = class {
|
|
9430
|
+
element;
|
|
9431
|
+
negativeZIndex;
|
|
9432
|
+
zeroOrAutoZIndexOrTransformedOrOpacity;
|
|
9433
|
+
positiveZIndex;
|
|
9434
|
+
nonPositionedFloats;
|
|
9435
|
+
nonPositionedInlineLevel;
|
|
9436
|
+
inlineLevel;
|
|
9437
|
+
nonInlineLevel;
|
|
9468
9438
|
constructor(container) {
|
|
9469
9439
|
this.element = container;
|
|
9470
9440
|
this.inlineLevel = [];
|
|
@@ -9477,13 +9447,34 @@ var StackingContext = class {
|
|
|
9477
9447
|
}
|
|
9478
9448
|
};
|
|
9479
9449
|
var ElementPaint = class {
|
|
9450
|
+
container;
|
|
9451
|
+
parent;
|
|
9452
|
+
effects = [];
|
|
9453
|
+
curves;
|
|
9454
|
+
listValue;
|
|
9455
|
+
/** Memoised getEffects results for the plain (surfaceRoot-less) render path. */
|
|
9456
|
+
plainEffectsCache = null;
|
|
9480
9457
|
constructor(container, parent) {
|
|
9481
9458
|
this.container = container;
|
|
9482
9459
|
this.parent = parent;
|
|
9483
|
-
this.effects = [];
|
|
9484
|
-
this.plainEffectsCache = null;
|
|
9485
9460
|
this.curves = new BoundCurves(this.container);
|
|
9486
9461
|
if (this.container.styles.opacity < 1) this.effects.push(new OpacityEffect(this.container.styles.opacity));
|
|
9462
|
+
if (this.container.styles.translate !== null) {
|
|
9463
|
+
const origin = this.container.styles.transformOrigin;
|
|
9464
|
+
const offsetX = this.container.bounds.left + getAbsoluteValue(origin[0], this.container.bounds.width);
|
|
9465
|
+
const offsetY = this.container.bounds.top + getAbsoluteValue(origin[1], this.container.bounds.height);
|
|
9466
|
+
const [tx, ty] = this.container.styles.translate;
|
|
9467
|
+
const dx = getAbsoluteValue(tx, this.container.bounds.width);
|
|
9468
|
+
const dy = getAbsoluteValue(ty, this.container.bounds.height);
|
|
9469
|
+
this.effects.push(new TransformEffect(offsetX, offsetY, [
|
|
9470
|
+
1,
|
|
9471
|
+
0,
|
|
9472
|
+
0,
|
|
9473
|
+
1,
|
|
9474
|
+
dx,
|
|
9475
|
+
dy
|
|
9476
|
+
]));
|
|
9477
|
+
}
|
|
9487
9478
|
if (this.container.styles.rotate !== null) {
|
|
9488
9479
|
const origin = this.container.styles.transformOrigin;
|
|
9489
9480
|
const offsetX = this.container.bounds.left + getAbsoluteValue(origin[0], this.container.bounds.width);
|
|
@@ -9501,6 +9492,20 @@ var ElementPaint = class {
|
|
|
9501
9492
|
];
|
|
9502
9493
|
this.effects.push(new TransformEffect(offsetX, offsetY, rotateMatrix));
|
|
9503
9494
|
}
|
|
9495
|
+
if (this.container.styles.scale !== null) {
|
|
9496
|
+
const origin = this.container.styles.transformOrigin;
|
|
9497
|
+
const offsetX = this.container.bounds.left + getAbsoluteValue(origin[0], this.container.bounds.width);
|
|
9498
|
+
const offsetY = this.container.bounds.top + getAbsoluteValue(origin[1], this.container.bounds.height);
|
|
9499
|
+
const [sx, sy] = this.container.styles.scale;
|
|
9500
|
+
this.effects.push(new TransformEffect(offsetX, offsetY, [
|
|
9501
|
+
sx,
|
|
9502
|
+
0,
|
|
9503
|
+
0,
|
|
9504
|
+
sy,
|
|
9505
|
+
0,
|
|
9506
|
+
0
|
|
9507
|
+
]));
|
|
9508
|
+
}
|
|
9504
9509
|
if (this.container.styles.transform !== null) {
|
|
9505
9510
|
const origin = this.container.styles.transformOrigin;
|
|
9506
9511
|
const offsetX = this.container.bounds.left + getAbsoluteValue(origin[0], this.container.bounds.width);
|
|
@@ -9696,8 +9701,8 @@ const parseStackTree = (parent, stackingContext, realStackingContext, listItems)
|
|
|
9696
9701
|
if (order < 0) {
|
|
9697
9702
|
let index = 0;
|
|
9698
9703
|
parentStack.negativeZIndex.some((current, i) => {
|
|
9699
|
-
if (order
|
|
9700
|
-
index = i;
|
|
9704
|
+
if (order >= current.element.container.styles.zIndex.order) {
|
|
9705
|
+
index = i + 1;
|
|
9701
9706
|
return false;
|
|
9702
9707
|
} else if (index > 0) return true;
|
|
9703
9708
|
return false;
|
|
@@ -9744,6 +9749,86 @@ const parseStackingContexts = (container) => {
|
|
|
9744
9749
|
return root;
|
|
9745
9750
|
};
|
|
9746
9751
|
//#endregion
|
|
9752
|
+
//#region src/render/canvas/gradient-rasterizer.ts
|
|
9753
|
+
const clampStop = (stop) => Math.min(1, Math.max(0, stop));
|
|
9754
|
+
/**
|
|
9755
|
+
* Stack the one-cycle stop list periodically across [0, 1]. Returns null for
|
|
9756
|
+
* a degenerate period (all stops clamped to one point) — CSS renders the
|
|
9757
|
+
* last colour across the whole area in that case, and callers should paint
|
|
9758
|
+
* the last colour instead of stacking.
|
|
9759
|
+
*/
|
|
9760
|
+
const stackRepeatingStops = (processed) => {
|
|
9761
|
+
const first = at(processed, 0);
|
|
9762
|
+
const last = at(processed, processed.length - 1);
|
|
9763
|
+
if (last.stop - first.stop < 1e-6) return null;
|
|
9764
|
+
const period = Math.max(last.stop - first.stop, .01);
|
|
9765
|
+
const stops = [];
|
|
9766
|
+
const cycles = Math.ceil(1 / period);
|
|
9767
|
+
for (let k = 0; k < cycles; k++) for (const s of processed) {
|
|
9768
|
+
const stop = k * period + (s.stop - first.stop);
|
|
9769
|
+
if (stop > 1) break;
|
|
9770
|
+
stops.push({
|
|
9771
|
+
stop,
|
|
9772
|
+
color: asString(s.color)
|
|
9773
|
+
});
|
|
9774
|
+
}
|
|
9775
|
+
const lastPushed = stops[stops.length - 1];
|
|
9776
|
+
if (!lastPushed || lastPushed.stop < 1) stops.push({
|
|
9777
|
+
stop: 1,
|
|
9778
|
+
color: asString(last.color)
|
|
9779
|
+
});
|
|
9780
|
+
return stops;
|
|
9781
|
+
};
|
|
9782
|
+
/** Map parsed stops to string-colour stops clamped into the canvas [0, 1] range. */
|
|
9783
|
+
const toCanvasStops = (processed) => processed.map((s) => ({
|
|
9784
|
+
stop: clampStop(s.stop),
|
|
9785
|
+
color: asString(s.color)
|
|
9786
|
+
}));
|
|
9787
|
+
/**
|
|
9788
|
+
* Rasterise a radial gradient's ending-shape ellipse to an offscreen canvas.
|
|
9789
|
+
*
|
|
9790
|
+
* The ellipse is a circle of radius rx scaled vertically by ry / rx around
|
|
9791
|
+
* the canvas centre, so the offscreen canvas is the ellipse's full 2rx × 2ry
|
|
9792
|
+
* bounding box and callers draw it at (centre - rx, centre - ry). Handles the
|
|
9793
|
+
* repeating variant by stacking stops across the [0, 1] gradient range.
|
|
9794
|
+
*/
|
|
9795
|
+
const rasterizeRadialGradient = (ownerDocument, rx, ry, stops, repeating = false) => {
|
|
9796
|
+
const processed = processColorStops(stops, rx);
|
|
9797
|
+
const last = at(processed, processed.length - 1);
|
|
9798
|
+
const lastColor = asString(last.color);
|
|
9799
|
+
const canvas = ownerDocument.createElement("canvas");
|
|
9800
|
+
canvas.width = Math.max(1, Math.ceil(rx * 2));
|
|
9801
|
+
canvas.height = Math.max(1, Math.ceil(ry * 2));
|
|
9802
|
+
const ctx = canvas.getContext("2d");
|
|
9803
|
+
if (!ctx) return null;
|
|
9804
|
+
let colorStops;
|
|
9805
|
+
if (repeating) {
|
|
9806
|
+
const stacked = stackRepeatingStops(processed);
|
|
9807
|
+
if (!stacked) {
|
|
9808
|
+
ctx.fillStyle = lastColor;
|
|
9809
|
+
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
9810
|
+
return {
|
|
9811
|
+
canvas,
|
|
9812
|
+
lastColor,
|
|
9813
|
+
rx,
|
|
9814
|
+
ry
|
|
9815
|
+
};
|
|
9816
|
+
}
|
|
9817
|
+
colorStops = stacked;
|
|
9818
|
+
} else colorStops = toCanvasStops(processed);
|
|
9819
|
+
const gradient = ctx.createRadialGradient(rx, rx, 0, rx, rx, rx);
|
|
9820
|
+
colorStops.forEach((s) => gradient.addColorStop(clampStop(s.stop), s.color));
|
|
9821
|
+
ctx.fillStyle = gradient;
|
|
9822
|
+
if (rx !== ry) ctx.scale(1, ry / rx);
|
|
9823
|
+
ctx.fillRect(0, 0, rx * 2, rx * 2);
|
|
9824
|
+
return {
|
|
9825
|
+
canvas,
|
|
9826
|
+
lastColor,
|
|
9827
|
+
rx,
|
|
9828
|
+
ry
|
|
9829
|
+
};
|
|
9830
|
+
};
|
|
9831
|
+
//#endregion
|
|
9747
9832
|
//#region src/render/box-sizing.ts
|
|
9748
9833
|
const paddingBox = (element) => {
|
|
9749
9834
|
const bounds = element.bounds;
|
|
@@ -9862,67 +9947,184 @@ const calculateBackgroundRepeatPath = (repeat, [x, y], [width, height], backgrou
|
|
|
9862
9947
|
}
|
|
9863
9948
|
};
|
|
9864
9949
|
//#endregion
|
|
9865
|
-
//#region src/core/abort-helper.ts
|
|
9866
|
-
/**
|
|
9867
|
-
* AbortSignal helper utilities.
|
|
9868
|
-
*/
|
|
9869
|
-
/**
|
|
9870
|
-
* Throw a DOMException if the given AbortSignal is already aborted.
|
|
9871
|
-
* Used at checkpoints throughout the rendering pipeline to support
|
|
9872
|
-
* cancellable renders.
|
|
9873
|
-
*
|
|
9874
|
-
* @param signal - The AbortSignal to check. If undefined or not aborted, this is a no-op.
|
|
9875
|
-
* @throws {DOMException} With name 'AbortError' if the signal has been aborted.
|
|
9876
|
-
*/
|
|
9877
|
-
const throwIfAborted = (signal) => {
|
|
9878
|
-
if (signal?.aborted) throw new DOMException("The operation was aborted.", "AbortError");
|
|
9879
|
-
};
|
|
9880
|
-
//#endregion
|
|
9881
9950
|
//#region src/render/canvas/filter-surface.ts
|
|
9882
9951
|
var FilterSurfaceError = class extends Error {};
|
|
9883
9952
|
const releaseSurface = (canvas) => {
|
|
9884
9953
|
canvas.width = canvas.height = 0;
|
|
9885
9954
|
};
|
|
9886
|
-
const
|
|
9887
|
-
|
|
9888
|
-
|
|
9889
|
-
|
|
9890
|
-
|
|
9955
|
+
const UNITLESS_NAMES = [
|
|
9956
|
+
"brightness",
|
|
9957
|
+
"contrast",
|
|
9958
|
+
"grayscale",
|
|
9959
|
+
"hue-rotate",
|
|
9960
|
+
"invert",
|
|
9961
|
+
"opacity",
|
|
9962
|
+
"saturate",
|
|
9963
|
+
"sepia"
|
|
9964
|
+
];
|
|
9965
|
+
const PARSED_FILTER_CACHE_MAX = 256;
|
|
9966
|
+
const parsedFilterCache = /* @__PURE__ */ new Map();
|
|
9967
|
+
const EMPTY_FILTER = { functions: [] };
|
|
9968
|
+
function parseFilterChain(value) {
|
|
9969
|
+
if (!value || value === "none") return EMPTY_FILTER;
|
|
9970
|
+
const cached = parsedFilterCache.get(value);
|
|
9891
9971
|
if (cached !== void 0) {
|
|
9892
|
-
|
|
9893
|
-
|
|
9972
|
+
parsedFilterCache.delete(value);
|
|
9973
|
+
parsedFilterCache.set(value, cached);
|
|
9894
9974
|
return cached;
|
|
9895
9975
|
}
|
|
9896
|
-
const parsed =
|
|
9897
|
-
if (
|
|
9898
|
-
const oldest =
|
|
9899
|
-
if (oldest !== void 0)
|
|
9976
|
+
const parsed = computeFilterChain(value);
|
|
9977
|
+
if (parsedFilterCache.size >= PARSED_FILTER_CACHE_MAX) {
|
|
9978
|
+
const oldest = parsedFilterCache.keys().next().value;
|
|
9979
|
+
if (oldest !== void 0) parsedFilterCache.delete(oldest);
|
|
9900
9980
|
}
|
|
9901
|
-
|
|
9981
|
+
parsedFilterCache.set(value, parsed);
|
|
9902
9982
|
return parsed;
|
|
9903
9983
|
}
|
|
9904
|
-
|
|
9905
|
-
const
|
|
9906
|
-
|
|
9907
|
-
|
|
9908
|
-
|
|
9909
|
-
|
|
9910
|
-
|
|
9984
|
+
const computeFilterChain = (value) => {
|
|
9985
|
+
const functions = [];
|
|
9986
|
+
let index = 0;
|
|
9987
|
+
while (index < value.length) {
|
|
9988
|
+
const char = value[index];
|
|
9989
|
+
if (char === " " || char === "\n" || char === " ") {
|
|
9990
|
+
index++;
|
|
9991
|
+
continue;
|
|
9992
|
+
}
|
|
9993
|
+
const open = value.indexOf("(", index);
|
|
9994
|
+
if (open === -1) return null;
|
|
9995
|
+
const name = value.slice(index, open).trim();
|
|
9996
|
+
if (!/^[a-zA-Z-]+$/.test(name)) return null;
|
|
9997
|
+
const bodyEnd = matchingParenthesis(value, open);
|
|
9998
|
+
if (bodyEnd === -1) return null;
|
|
9999
|
+
const fn = parseFilterFunction(name, value.slice(open + 1, bodyEnd).trim());
|
|
10000
|
+
if (!fn) return null;
|
|
10001
|
+
functions.push(fn);
|
|
10002
|
+
index = bodyEnd + 1;
|
|
10003
|
+
}
|
|
10004
|
+
return { functions };
|
|
10005
|
+
};
|
|
10006
|
+
/** Index of the ')' matching the '(' at `open`, or -1. */
|
|
10007
|
+
const matchingParenthesis = (value, open) => {
|
|
10008
|
+
let depth = 1;
|
|
10009
|
+
for (let i = open + 1; i < value.length; i++) {
|
|
10010
|
+
const char = value[i];
|
|
10011
|
+
if (char === "(") depth++;
|
|
10012
|
+
else if (char === ")") {
|
|
10013
|
+
depth--;
|
|
10014
|
+
if (depth === 0) return i;
|
|
10015
|
+
}
|
|
10016
|
+
}
|
|
10017
|
+
return -1;
|
|
10018
|
+
};
|
|
10019
|
+
const PX_LENGTH_RE = /^-?\d+(?:\.\d+)?px$/;
|
|
10020
|
+
const parseFilterFunction = (name, body) => {
|
|
10021
|
+
if (name === "blur") {
|
|
10022
|
+
if (body === "0") return {
|
|
10023
|
+
kind: "blur",
|
|
10024
|
+
value: 0
|
|
10025
|
+
};
|
|
10026
|
+
if (!PX_LENGTH_RE.test(body)) return null;
|
|
10027
|
+
const value = Number.parseFloat(body);
|
|
10028
|
+
return value < 0 ? null : {
|
|
10029
|
+
kind: "blur",
|
|
10030
|
+
value
|
|
10031
|
+
};
|
|
10032
|
+
}
|
|
10033
|
+
if (name === "drop-shadow") return parseDropShadowBody(body);
|
|
10034
|
+
if (UNITLESS_NAMES.indexOf(name) !== -1) {
|
|
10035
|
+
const unitless = name;
|
|
10036
|
+
if (unitless === "hue-rotate") {
|
|
10037
|
+
const degrees = parseAngleDegrees(body);
|
|
10038
|
+
return degrees === null ? null : {
|
|
10039
|
+
kind: "unitless",
|
|
10040
|
+
name: unitless,
|
|
10041
|
+
value: degrees
|
|
10042
|
+
};
|
|
10043
|
+
}
|
|
10044
|
+
const trimmed = body.trim();
|
|
10045
|
+
const percentage = trimmed.endsWith("%");
|
|
10046
|
+
const numeric = percentage ? trimmed.slice(0, -1) : trimmed;
|
|
10047
|
+
if (!/^-?\d+(?:\.\d+)?$/.test(numeric)) return null;
|
|
10048
|
+
return {
|
|
10049
|
+
kind: "unitless",
|
|
10050
|
+
name: unitless,
|
|
10051
|
+
value: Number.parseFloat(numeric) * (percentage ? 1 / 100 : 1)
|
|
10052
|
+
};
|
|
10053
|
+
}
|
|
10054
|
+
return null;
|
|
10055
|
+
};
|
|
10056
|
+
/** Split on whitespace outside parentheses so rgba(...) colours stay one token. */
|
|
10057
|
+
const splitTopLevel = (body) => {
|
|
10058
|
+
const parts = [];
|
|
10059
|
+
let depth = 0;
|
|
10060
|
+
let current = "";
|
|
10061
|
+
for (const char of body) {
|
|
10062
|
+
if (char === "(") depth++;
|
|
10063
|
+
else if (char === ")") depth--;
|
|
10064
|
+
if (char === " " && depth === 0) {
|
|
10065
|
+
if (current) parts.push(current);
|
|
10066
|
+
current = "";
|
|
10067
|
+
continue;
|
|
10068
|
+
}
|
|
10069
|
+
current += char;
|
|
10070
|
+
}
|
|
10071
|
+
if (current) parts.push(current);
|
|
10072
|
+
return parts;
|
|
10073
|
+
};
|
|
10074
|
+
const parseDropShadowBody = (body) => {
|
|
10075
|
+
const parts = splitTopLevel(body);
|
|
10076
|
+
const lengths = parts.filter((part) => PX_LENGTH_RE.test(part)).map((part) => Number.parseFloat(part));
|
|
10077
|
+
if (lengths.length < 2 || lengths.length > 3) return null;
|
|
10078
|
+
const colors = parts.filter((part) => !PX_LENGTH_RE.test(part));
|
|
10079
|
+
if (parts.length - colors.length !== lengths.length) return null;
|
|
9911
10080
|
return {
|
|
9912
|
-
|
|
9913
|
-
|
|
9914
|
-
|
|
9915
|
-
|
|
9916
|
-
|
|
9917
|
-
color: effect.shadow.color
|
|
9918
|
-
} : void 0
|
|
10081
|
+
kind: "drop-shadow",
|
|
10082
|
+
x: lengths[0],
|
|
10083
|
+
y: lengths[1],
|
|
10084
|
+
blur: lengths[2] ?? 0,
|
|
10085
|
+
color: colors.join(" ") || "rgba(0, 0, 0, 0)"
|
|
9919
10086
|
};
|
|
9920
|
-
}
|
|
10087
|
+
};
|
|
10088
|
+
const parseAngleDegrees = (body) => {
|
|
10089
|
+
const trimmed = body.trim();
|
|
10090
|
+
if (trimmed === "0") return 0;
|
|
10091
|
+
const numeric = Number.parseFloat(trimmed);
|
|
10092
|
+
if (Number.isNaN(numeric)) return null;
|
|
10093
|
+
if (trimmed.endsWith("deg")) return numeric;
|
|
10094
|
+
if (trimmed.endsWith("grad")) return numeric * .9;
|
|
10095
|
+
if (trimmed.endsWith("rad")) return numeric * 180 / Math.PI;
|
|
10096
|
+
if (trimmed.endsWith("turn")) return numeric * 360;
|
|
10097
|
+
return null;
|
|
10098
|
+
};
|
|
10099
|
+
/**
|
|
10100
|
+
* Render the chain as a canvas ctx.filter string, scaling all device-space
|
|
10101
|
+
* lengths (blur radii, shadow offsets) by the capture scale. Unitless
|
|
10102
|
+
* functions and hue angles are scale-invariant.
|
|
10103
|
+
*/
|
|
10104
|
+
const nativeFilterString = (filter, scale) => filter.functions.map((fn) => {
|
|
10105
|
+
switch (fn.kind) {
|
|
10106
|
+
case "blur": return `blur(${fn.value * scale}px)`;
|
|
10107
|
+
case "drop-shadow": return `drop-shadow(${fn.x * scale}px ${fn.y * scale}px ${fn.blur * scale}px ${fn.color})`;
|
|
10108
|
+
case "unitless": return fn.name === "hue-rotate" ? `hue-rotate(${fn.value}deg)` : `${fn.name}(${fn.value})`;
|
|
10109
|
+
}
|
|
10110
|
+
}).join(" ");
|
|
10111
|
+
/**
|
|
10112
|
+
* Outset (in CSS pixels) a surface must grow so blur/shadow spillover is not
|
|
10113
|
+
* cropped. Unitless functions never spread beyond the bounds. Consecutive
|
|
10114
|
+
* blurs compound, so their radii sum.
|
|
10115
|
+
*/
|
|
9921
10116
|
function filterOutset(filter) {
|
|
9922
|
-
|
|
10117
|
+
let blurSum = 0;
|
|
10118
|
+
let maxShadowOffset = 0;
|
|
10119
|
+
for (const fn of filter.functions) if (fn.kind === "blur") blurSum += fn.value;
|
|
10120
|
+
else if (fn.kind === "drop-shadow") {
|
|
10121
|
+
blurSum += fn.blur;
|
|
10122
|
+
maxShadowOffset = Math.max(maxShadowOffset, Math.abs(fn.x), Math.abs(fn.y));
|
|
10123
|
+
}
|
|
10124
|
+
return Math.ceil(3 * blurSum + maxShadowOffset);
|
|
9923
10125
|
}
|
|
9924
10126
|
function canvasLike(source) {
|
|
9925
|
-
const canvas = document.createElement("canvas");
|
|
10127
|
+
const canvas = (source.ownerDocument ?? document).createElement("canvas");
|
|
9926
10128
|
canvas.width = source.width;
|
|
9927
10129
|
canvas.height = source.height;
|
|
9928
10130
|
return canvas;
|
|
@@ -9970,7 +10172,7 @@ function supportsNativeFilters(owner = document) {
|
|
|
9970
10172
|
canvasFilterSupport.set(owner, supported);
|
|
9971
10173
|
return supported;
|
|
9972
10174
|
}
|
|
9973
|
-
function tryNativeFilterSurface(source,
|
|
10175
|
+
function tryNativeFilterSurface(source, filter, opacity, scale, signal) {
|
|
9974
10176
|
let filtered;
|
|
9975
10177
|
let output;
|
|
9976
10178
|
let complete = false;
|
|
@@ -9979,11 +10181,8 @@ function tryNativeFilterSurface(source, { blur, shadow }, opacity, scale, signal
|
|
|
9979
10181
|
filtered = canvasLike(source);
|
|
9980
10182
|
const context = filtered.getContext("2d");
|
|
9981
10183
|
if (!context || !("filter" in context)) return null;
|
|
9982
|
-
|
|
9983
|
-
if (
|
|
9984
|
-
if (shadow) functions.push(`drop-shadow(${shadow.x * scale}px ${shadow.y * scale}px ${shadow.blur * scale}px ${shadow.color})`);
|
|
9985
|
-
context.filter = functions.join(" ");
|
|
9986
|
-
if (context.filter === "none") return null;
|
|
10184
|
+
context.filter = nativeFilterString(filter, scale);
|
|
10185
|
+
if (context.filter === "none" || context.filter === "") return null;
|
|
9987
10186
|
context.drawImage(source, 0, 0);
|
|
9988
10187
|
throwIfAborted(signal);
|
|
9989
10188
|
output = canvasLike(source);
|
|
@@ -10002,17 +10201,43 @@ function tryNativeFilterSurface(source, { blur, shadow }, opacity, scale, signal
|
|
|
10002
10201
|
if (output && !complete) releaseSurface(output);
|
|
10003
10202
|
}
|
|
10004
10203
|
}
|
|
10204
|
+
/**
|
|
10205
|
+
* The SVG fallback predates the ordered-chain parser and only expresses the
|
|
10206
|
+
* blur + single drop-shadow subset (at most one of each, blur before the
|
|
10207
|
+
* shadow). Chains outside that subset reject with FilterSurfaceError so the
|
|
10208
|
+
* caller keeps its legacy renderer instead of rendering a wrong filter.
|
|
10209
|
+
*/
|
|
10210
|
+
const isSvgExpressible = (filter) => {
|
|
10211
|
+
let blurs = 0;
|
|
10212
|
+
let shadows = 0;
|
|
10213
|
+
for (const fn of filter.functions) if (fn.kind === "blur") blurs++;
|
|
10214
|
+
else if (fn.kind === "drop-shadow") shadows++;
|
|
10215
|
+
else return false;
|
|
10216
|
+
if (blurs > 1 || shadows > 1) return false;
|
|
10217
|
+
if (blurs > 0 && shadows > 0) return filter.functions.findIndex((fn) => fn.kind === "blur") < filter.functions.findIndex((fn) => fn.kind === "drop-shadow");
|
|
10218
|
+
return true;
|
|
10219
|
+
};
|
|
10005
10220
|
async function renderFilterSurface(source, filter, opacity, scale, signal) {
|
|
10006
10221
|
throwIfAborted(signal);
|
|
10007
|
-
if (
|
|
10222
|
+
if (filter.functions.length > 0 && supportsNativeFilters(source.ownerDocument ?? document)) {
|
|
10008
10223
|
const output = tryNativeFilterSurface(source, filter, opacity, scale, signal);
|
|
10009
10224
|
if (output) return output;
|
|
10010
10225
|
}
|
|
10226
|
+
if (!isSvgExpressible(filter)) throw new FilterSurfaceError("Filter chain requires native canvas filters");
|
|
10011
10227
|
return renderSvgFilterSurface(source, filter, opacity, scale, signal);
|
|
10012
10228
|
}
|
|
10013
|
-
async function renderSvgFilterSurface(source,
|
|
10229
|
+
async function renderSvgFilterSurface(source, filter, opacity, scale, signal) {
|
|
10014
10230
|
throwIfAborted(signal);
|
|
10015
|
-
|
|
10231
|
+
const blur = filter.functions.find((fn) => fn.kind === "blur");
|
|
10232
|
+
const shadow = filter.functions.find((fn) => fn.kind === "drop-shadow");
|
|
10233
|
+
const blurValue = blur && blur.kind === "blur" ? blur.value : 0;
|
|
10234
|
+
const shadowValue = shadow && shadow.kind === "drop-shadow" ? {
|
|
10235
|
+
x: shadow.x,
|
|
10236
|
+
y: shadow.y,
|
|
10237
|
+
blur: shadow.blur,
|
|
10238
|
+
color: shadow.color
|
|
10239
|
+
} : void 0;
|
|
10240
|
+
if (!blurValue && !shadowValue) {
|
|
10016
10241
|
const output = canvasLike(source);
|
|
10017
10242
|
const context = output.getContext("2d");
|
|
10018
10243
|
if (!context) {
|
|
@@ -10029,8 +10254,9 @@ async function renderSvgFilterSurface(source, { blur, shadow }, opacity, scale,
|
|
|
10029
10254
|
}
|
|
10030
10255
|
}
|
|
10031
10256
|
const namespace = "http://www.w3.org/2000/svg";
|
|
10257
|
+
const svgDocument = source.ownerDocument ?? document;
|
|
10032
10258
|
const element = (tag, attributes = {}) => {
|
|
10033
|
-
const node =
|
|
10259
|
+
const node = svgDocument.createElementNS(namespace, tag);
|
|
10034
10260
|
Object.entries(attributes).forEach(([key, value]) => node.setAttribute(key, String(value)));
|
|
10035
10261
|
return node;
|
|
10036
10262
|
};
|
|
@@ -10040,7 +10266,7 @@ async function renderSvgFilterSurface(source, { blur, shadow }, opacity, scale,
|
|
|
10040
10266
|
viewBox: `0 0 ${source.width} ${source.height}`
|
|
10041
10267
|
});
|
|
10042
10268
|
const defs = element("defs");
|
|
10043
|
-
const
|
|
10269
|
+
const filterElement = element("filter", {
|
|
10044
10270
|
id: "composited-filter",
|
|
10045
10271
|
filterUnits: "userSpaceOnUse",
|
|
10046
10272
|
x: 0,
|
|
@@ -10049,31 +10275,31 @@ async function renderSvgFilterSurface(source, { blur, shadow }, opacity, scale,
|
|
|
10049
10275
|
height: source.height,
|
|
10050
10276
|
"color-interpolation-filters": "sRGB"
|
|
10051
10277
|
});
|
|
10052
|
-
if (
|
|
10053
|
-
stdDeviation:
|
|
10278
|
+
if (blurValue) filterElement.appendChild(element("feGaussianBlur", {
|
|
10279
|
+
stdDeviation: blurValue * scale,
|
|
10054
10280
|
result: "blurred-source"
|
|
10055
10281
|
}));
|
|
10056
|
-
if (
|
|
10057
|
-
|
|
10058
|
-
in:
|
|
10059
|
-
stdDeviation:
|
|
10282
|
+
if (shadowValue) {
|
|
10283
|
+
filterElement.appendChild(element("feGaussianBlur", {
|
|
10284
|
+
in: blurValue ? "blurred-source" : "SourceAlpha",
|
|
10285
|
+
stdDeviation: shadowValue.blur * scale
|
|
10060
10286
|
}));
|
|
10061
|
-
|
|
10062
|
-
dx:
|
|
10063
|
-
dy:
|
|
10287
|
+
filterElement.appendChild(element("feOffset", {
|
|
10288
|
+
dx: shadowValue.x * scale,
|
|
10289
|
+
dy: shadowValue.y * scale,
|
|
10064
10290
|
result: "offset-shadow"
|
|
10065
10291
|
}));
|
|
10066
|
-
|
|
10067
|
-
|
|
10292
|
+
filterElement.appendChild(element("feFlood", { "flood-color": shadowValue.color }));
|
|
10293
|
+
filterElement.appendChild(element("feComposite", {
|
|
10068
10294
|
in2: "offset-shadow",
|
|
10069
10295
|
operator: "in"
|
|
10070
10296
|
}));
|
|
10071
10297
|
const merge = element("feMerge");
|
|
10072
10298
|
merge.appendChild(element("feMergeNode"));
|
|
10073
|
-
merge.appendChild(element("feMergeNode", { in:
|
|
10074
|
-
|
|
10299
|
+
merge.appendChild(element("feMergeNode", { in: blurValue ? "blurred-source" : "SourceGraphic" }));
|
|
10300
|
+
filterElement.appendChild(merge);
|
|
10075
10301
|
}
|
|
10076
|
-
defs.appendChild(
|
|
10302
|
+
defs.appendChild(filterElement);
|
|
10077
10303
|
svg.appendChild(defs);
|
|
10078
10304
|
let sourceUrl;
|
|
10079
10305
|
try {
|
|
@@ -10088,7 +10314,8 @@ async function renderSvgFilterSurface(source, { blur, shadow }, opacity, scale,
|
|
|
10088
10314
|
href: sourceUrl,
|
|
10089
10315
|
filter: "url(#composited-filter)"
|
|
10090
10316
|
}));
|
|
10091
|
-
const
|
|
10317
|
+
const imageWindow = svgDocument.defaultView;
|
|
10318
|
+
const image = imageWindow?.Image ? new imageWindow.Image() : new Image();
|
|
10092
10319
|
let output;
|
|
10093
10320
|
try {
|
|
10094
10321
|
image.src = `data:image/svg+xml,${encodeURIComponent(new XMLSerializer().serializeToString(svg))}`;
|
|
@@ -10129,7 +10356,7 @@ function surfaceBounds(container) {
|
|
|
10129
10356
|
for (const shadow of styles.textShadow) bounds = union(bounds, expand(ink.add(shadow.offsetX.number, shadow.offsetY.number, 0, 0), 3 * shadow.blur.number));
|
|
10130
10357
|
}
|
|
10131
10358
|
for (const child of container.elements) if (child.styles.isVisible()) bounds = union(bounds, surfaceBounds(child));
|
|
10132
|
-
const filter =
|
|
10359
|
+
const filter = parseFilterChain(styles.filter);
|
|
10133
10360
|
return expand(bounds, filter ? filterOutset(filter) : 0);
|
|
10134
10361
|
}
|
|
10135
10362
|
function cropSurface(bounds, viewport, margin, scale) {
|
|
@@ -10143,11 +10370,12 @@ function cropSurface(bounds, viewport, margin, scale) {
|
|
|
10143
10370
|
//#endregion
|
|
10144
10371
|
//#region src/render/canvas/text/text-decoration-renderer.ts
|
|
10145
10372
|
var TextDecorationRenderer = class {
|
|
10373
|
+
ctx;
|
|
10146
10374
|
constructor(ctx) {
|
|
10147
10375
|
this.ctx = ctx;
|
|
10148
10376
|
}
|
|
10149
10377
|
render(bounds, styles) {
|
|
10150
|
-
this.ctx.fillStyle = asString(styles.textDecorationColor
|
|
10378
|
+
this.ctx.fillStyle = asString(styles.textDecorationColor ?? styles.color);
|
|
10151
10379
|
let thickness = 1;
|
|
10152
10380
|
if (typeof styles.textDecorationThickness === "number") thickness = styles.textDecorationThickness;
|
|
10153
10381
|
else if (styles.textDecorationThickness === "from-font") thickness = Math.max(1, Math.floor(styles.fontSize.number * .05));
|
|
@@ -10266,7 +10494,6 @@ const measureBaseline = (ctx, fallback) => {
|
|
|
10266
10494
|
};
|
|
10267
10495
|
//#endregion
|
|
10268
10496
|
//#region src/render/canvas/text-renderer.ts
|
|
10269
|
-
const iOSBrokenFonts = ["-apple-system", "system-ui"];
|
|
10270
10497
|
const TEXT_OVERFLOW_EPSILON = 1;
|
|
10271
10498
|
/**
|
|
10272
10499
|
* Detect CJK (Chinese, Japanese, Korean) characters in a string.
|
|
@@ -10285,29 +10512,19 @@ const TEXT_OVERFLOW_EPSILON = 1;
|
|
|
10285
10512
|
const CJK_CHAR_REGEX = /[\u2E80-\u2FFF\u3000-\u30FF\u3400-\u4DBF\u4E00-\u9FFF\uAC00-\uD7AF\uF900-\uFAFF\uFF01-\uFFEF]/;
|
|
10286
10513
|
const hasCJKCharacters = (text) => CJK_CHAR_REGEX.test(text);
|
|
10287
10514
|
/**
|
|
10288
|
-
*
|
|
10289
|
-
*
|
|
10515
|
+
* Chromium-based engines render stroked text with visibly sharper joins when
|
|
10516
|
+
* `miter` is requested, closely matching their own -webkit-text-stroke
|
|
10517
|
+
* output; other engines need `round` joins to avoid glyph spikes. No CSS or
|
|
10518
|
+
* platform API expresses this behavioural difference, so engine detection is
|
|
10519
|
+
* the only reliable signal: `navigator.userAgentData` is Chromium-only, with
|
|
10520
|
+
* the legacy `window.chrome` marker as a fallback for older webviews.
|
|
10290
10521
|
*/
|
|
10291
|
-
const
|
|
10292
|
-
if (typeof navigator === "undefined") return
|
|
10293
|
-
|
|
10294
|
-
|
|
10295
|
-
const isIPadOS = /Macintosh/.test(userAgent) && navigator.maxTouchPoints && navigator.maxTouchPoints > 1;
|
|
10296
|
-
if (!isIOS && !isIPadOS) return null;
|
|
10297
|
-
for (const pattern of [/(?:iPhone|CPU(?:\siPhone)?)\sOS\s(\d+)[\._](\d+)/, /Version\/(\d+)\.(\d+)/]) {
|
|
10298
|
-
const match = userAgent.match(pattern);
|
|
10299
|
-
if (match && match[1]) return parseInt(match[1], 10);
|
|
10300
|
-
}
|
|
10301
|
-
return null;
|
|
10302
|
-
};
|
|
10303
|
-
const fixIOSSystemFonts = (fontFamilies) => {
|
|
10304
|
-
const iosVersion = getIOSVersion();
|
|
10305
|
-
if (iosVersion !== null && iosVersion >= 15 && iosVersion < 17) return fontFamilies.map((fontFamily) => iOSBrokenFonts.indexOf(fontFamily) !== -1 ? `-apple-system, "Helvetica Neue", Arial, sans-serif` : fontFamily);
|
|
10306
|
-
return fontFamilies;
|
|
10307
|
-
};
|
|
10308
|
-
const getTextStrokeLineJoin = () => {
|
|
10309
|
-
return (typeof window !== "undefined" ? window : void 0)?.chrome ? "miter" : "round";
|
|
10522
|
+
const isChromiumEngine = () => {
|
|
10523
|
+
if (typeof navigator === "undefined") return false;
|
|
10524
|
+
if (navigator.userAgentData !== void 0) return true;
|
|
10525
|
+
return (typeof window !== "undefined" ? window : void 0)?.chrome !== void 0;
|
|
10310
10526
|
};
|
|
10527
|
+
const getTextStrokeLineJoin = () => isChromiumEngine() ? "miter" : "round";
|
|
10311
10528
|
/**
|
|
10312
10529
|
* Text Renderer
|
|
10313
10530
|
*
|
|
@@ -10315,9 +10532,23 @@ const getTextStrokeLineJoin = () => {
|
|
|
10315
10532
|
* Extracted from CanvasRenderer to improve code organization and maintainability.
|
|
10316
10533
|
*/
|
|
10317
10534
|
var TextRenderer = class {
|
|
10535
|
+
ctx;
|
|
10536
|
+
options;
|
|
10537
|
+
decorationRenderer;
|
|
10538
|
+
/**
|
|
10539
|
+
* Baseline ascent per font string. Consecutive text nodes overwhelmingly
|
|
10540
|
+
* share a font, and each measureBaseline call issues a canvas measureText,
|
|
10541
|
+
* so repeated fonts are memoised (bounded; cleared if the working set
|
|
10542
|
+
* exceeds the cap).
|
|
10543
|
+
*/
|
|
10544
|
+
baselineCache = /* @__PURE__ */ new Map();
|
|
10545
|
+
/**
|
|
10546
|
+
* Per-render glyph width cache. Keyed by glyph + font string,
|
|
10547
|
+
* avoids redundant `measureText` calls when letter-spacing is non-zero.
|
|
10548
|
+
* Cleared at the start of each renderTextNode call.
|
|
10549
|
+
*/
|
|
10550
|
+
glyphWidthCache = null;
|
|
10318
10551
|
constructor(deps) {
|
|
10319
|
-
this.baselineCache = /* @__PURE__ */ new Map();
|
|
10320
|
-
this.glyphWidthCache = null;
|
|
10321
10552
|
this.ctx = deps.ctx;
|
|
10322
10553
|
this.options = deps.options;
|
|
10323
10554
|
this.decorationRenderer = new TextDecorationRenderer(deps.ctx);
|
|
@@ -10510,7 +10741,7 @@ var TextRenderer = class {
|
|
|
10510
10741
|
*/
|
|
10511
10742
|
createFontStyle(styles) {
|
|
10512
10743
|
const fontVariant = styles.fontVariant.filter((variant) => variant === "normal" || variant === "small-caps").join("");
|
|
10513
|
-
const fontFamily =
|
|
10744
|
+
const fontFamily = styles.fontFamily.join(", ");
|
|
10514
10745
|
const fontSize = isDimensionToken(styles.fontSize) ? `${styles.fontSize.number}${styles.fontSize.unit}` : `${styles.fontSize.number}px`;
|
|
10515
10746
|
return [
|
|
10516
10747
|
[
|
|
@@ -10539,7 +10770,7 @@ var TextRenderer = class {
|
|
|
10539
10770
|
* only the first N-1 complete lines followed by an ellipsis on the Nth line.
|
|
10540
10771
|
*/
|
|
10541
10772
|
renderLineClampedText(text, styles, paintOrder, baseline, containerBounds) {
|
|
10542
|
-
const lineHeight = styles.fontSize.number
|
|
10773
|
+
const lineHeight = computeLineHeight(styles.lineHeight, styles.fontSize.number);
|
|
10543
10774
|
const lines = [];
|
|
10544
10775
|
let currentLine = [];
|
|
10545
10776
|
let currentLineTop = at(text.textBounds, 0).bounds.top;
|
|
@@ -10572,7 +10803,7 @@ var TextRenderer = class {
|
|
|
10572
10803
|
* Returns true if ellipsis was applied (caller should skip normal rendering).
|
|
10573
10804
|
*/
|
|
10574
10805
|
renderEllipsisText(text, styles, paintOrder, baseline, containerBounds) {
|
|
10575
|
-
const lineHeight = styles.fontSize.number
|
|
10806
|
+
const lineHeight = computeLineHeight(styles.lineHeight, styles.fontSize.number);
|
|
10576
10807
|
const firstTop = at(text.textBounds, 0).bounds.top;
|
|
10577
10808
|
if (!text.textBounds.every((tb) => Math.abs(tb.bounds.top - firstTop) < lineHeight * .5)) return false;
|
|
10578
10809
|
let fullText = text.textBounds.map((tb) => tb.text).join("").replace(/\s+/g, " ").trim();
|
|
@@ -10721,6 +10952,8 @@ const createCanvasPath = (ctx, paths) => {
|
|
|
10721
10952
|
* ```
|
|
10722
10953
|
*/
|
|
10723
10954
|
var LRUMap = class {
|
|
10955
|
+
maxSize;
|
|
10956
|
+
_map;
|
|
10724
10957
|
constructor(maxSize) {
|
|
10725
10958
|
this.maxSize = maxSize;
|
|
10726
10959
|
this._map = /* @__PURE__ */ new Map();
|
|
@@ -10769,8 +11002,17 @@ var LRUMap = class {
|
|
|
10769
11002
|
* Extracted from CanvasRenderer to improve code organization and maintainability.
|
|
10770
11003
|
*/
|
|
10771
11004
|
var BackgroundRenderer = class {
|
|
11005
|
+
ctx;
|
|
11006
|
+
context;
|
|
11007
|
+
canvas;
|
|
11008
|
+
/**
|
|
11009
|
+
* Instance-level LRU cache for background-image patterns.
|
|
11010
|
+
* CanvasPatterns are tied to the rendering context and must not be
|
|
11011
|
+
* shared across different render passes. This cache lives for the
|
|
11012
|
+
* duration of one html2canvas() call.
|
|
11013
|
+
*/
|
|
11014
|
+
patternCache = new LRUMap(50);
|
|
10772
11015
|
constructor(deps) {
|
|
10773
|
-
this.patternCache = new LRUMap(50);
|
|
10774
11016
|
this.ctx = deps.ctx;
|
|
10775
11017
|
this.context = deps.context;
|
|
10776
11018
|
this.canvas = deps.canvas;
|
|
@@ -10817,7 +11059,6 @@ var BackgroundRenderer = class {
|
|
|
10817
11059
|
image = await this.context.cache.match(url);
|
|
10818
11060
|
} catch (e) {
|
|
10819
11061
|
this.context.logger.error(`Error loading background-image ${url}`);
|
|
10820
|
-
this.context.onError?.(e instanceof Error ? e : new Error(String(e)));
|
|
10821
11062
|
}
|
|
10822
11063
|
if (image) {
|
|
10823
11064
|
const imageWidth = isNaN(image.width) || image.width === 0 ? 1 : image.width;
|
|
@@ -10856,34 +11097,13 @@ var BackgroundRenderer = class {
|
|
|
10856
11097
|
const gy0 = y + ly0;
|
|
10857
11098
|
const gy1 = y + ly1;
|
|
10858
11099
|
const processedStops = processColorStops(backgroundImage.stops, lineLength || 1);
|
|
10859
|
-
const
|
|
10860
|
-
const firstStop = at(processedStops, 0);
|
|
10861
|
-
const period = Math.max(lastStop.stop - firstStop.stop, .01);
|
|
10862
|
-
if (lastStop.stop - firstStop.stop < 1e-6) {
|
|
10863
|
-
const gradient = this.ctx.createLinearGradient(gx0, gy0, gx1, gy1);
|
|
10864
|
-
gradient.addColorStop(0, asString(lastStop.color));
|
|
10865
|
-
gradient.addColorStop(1, asString(lastStop.color));
|
|
10866
|
-
this.path(path);
|
|
10867
|
-
this.ctx.fillStyle = gradient;
|
|
10868
|
-
this.ctx.fill();
|
|
10869
|
-
return;
|
|
10870
|
-
}
|
|
10871
|
-
const stops = [];
|
|
10872
|
-
const cycles = Math.ceil(1 / period);
|
|
10873
|
-
for (let k = 0; k < cycles; k++) for (const s of processedStops) {
|
|
10874
|
-
const stop = k * period + (s.stop - firstStop.stop);
|
|
10875
|
-
if (stop > 1) break;
|
|
10876
|
-
stops.push({
|
|
10877
|
-
stop,
|
|
10878
|
-
color: asString(s.color)
|
|
10879
|
-
});
|
|
10880
|
-
}
|
|
10881
|
-
stops.push({
|
|
10882
|
-
stop: 1,
|
|
10883
|
-
color: asString(lastStop.color)
|
|
10884
|
-
});
|
|
11100
|
+
const stacked = stackRepeatingStops(processedStops);
|
|
10885
11101
|
const gradient = this.ctx.createLinearGradient(gx0, gy0, gx1, gy1);
|
|
10886
|
-
|
|
11102
|
+
if (!stacked) {
|
|
11103
|
+
const lastColor = asString(at(processedStops, processedStops.length - 1).color);
|
|
11104
|
+
gradient.addColorStop(0, lastColor);
|
|
11105
|
+
gradient.addColorStop(1, lastColor);
|
|
11106
|
+
} else stacked.forEach((s) => gradient.addColorStop(Math.min(1, Math.max(0, s.stop)), s.color));
|
|
10887
11107
|
this.path(path);
|
|
10888
11108
|
this.ctx.fillStyle = gradient;
|
|
10889
11109
|
this.ctx.fill();
|
|
@@ -10936,37 +11156,25 @@ var BackgroundRenderer = class {
|
|
|
10936
11156
|
}
|
|
10937
11157
|
if (rx > 0 && ry > 0) {
|
|
10938
11158
|
const cacheKey = `rg|${Math.round(x)}x${Math.round(y)}|${Math.round(rx)}x${Math.round(ry)}|${JSON.stringify(backgroundImage.stops)}`;
|
|
10939
|
-
const
|
|
10940
|
-
const
|
|
11159
|
+
const processed = processColorStops(backgroundImage.stops, rx);
|
|
11160
|
+
const lastColor = asString(at(processed, processed.length - 1).color);
|
|
10941
11161
|
let pattern = this.patternCache.get(cacheKey);
|
|
10942
11162
|
if (!pattern) {
|
|
10943
|
-
const
|
|
10944
|
-
|
|
10945
|
-
|
|
10946
|
-
|
|
10947
|
-
|
|
10948
|
-
const gradient = offCtx.createRadialGradient(rx, rx, 0, rx, rx, rx);
|
|
10949
|
-
stops.forEach((s) => gradient.addColorStop(s.stop, asString(s.color)));
|
|
10950
|
-
offCtx.fillStyle = gradient;
|
|
10951
|
-
if (rx !== ry) offCtx.scale(1, ry / rx);
|
|
10952
|
-
offCtx.fillRect(0, 0, rx * 2, rx * 2);
|
|
10953
|
-
pattern = this.ctx.createPattern(offscreen, "no-repeat");
|
|
10954
|
-
this.patternCache.set(cacheKey, pattern);
|
|
10955
|
-
}
|
|
10956
|
-
}
|
|
10957
|
-
if (pattern) {
|
|
10958
|
-
this.path(path);
|
|
10959
|
-
this.ctx.save();
|
|
10960
|
-
this.ctx.clip();
|
|
10961
|
-
if (lastStop) {
|
|
10962
|
-
this.ctx.fillStyle = asString(lastStop.color);
|
|
10963
|
-
this.ctx.fill();
|
|
10964
|
-
}
|
|
10965
|
-
this.ctx.translate(left + x - rx, top + y - ry);
|
|
10966
|
-
this.ctx.fillStyle = pattern;
|
|
10967
|
-
this.ctx.fillRect(0, 0, rx * 2, ry * 2);
|
|
10968
|
-
this.ctx.restore();
|
|
11163
|
+
const ownerDocument = this.canvas.ownerDocument ?? document;
|
|
11164
|
+
const rasterized = rasterizeRadialGradient(ownerDocument, rx, ry, backgroundImage.stops, false);
|
|
11165
|
+
if (!rasterized) return;
|
|
11166
|
+
pattern = this.ctx.createPattern(rasterized.canvas, "no-repeat");
|
|
11167
|
+
this.patternCache.set(cacheKey, pattern);
|
|
10969
11168
|
}
|
|
11169
|
+
this.path(path);
|
|
11170
|
+
this.ctx.save();
|
|
11171
|
+
this.ctx.clip();
|
|
11172
|
+
this.ctx.fillStyle = lastColor;
|
|
11173
|
+
this.ctx.fill();
|
|
11174
|
+
this.ctx.translate(left + x - rx, top + y - ry);
|
|
11175
|
+
this.ctx.fillStyle = pattern;
|
|
11176
|
+
this.ctx.fillRect(0, 0, rx * 2, ry * 2);
|
|
11177
|
+
this.ctx.restore();
|
|
10970
11178
|
}
|
|
10971
11179
|
}
|
|
10972
11180
|
/**
|
|
@@ -10993,40 +11201,14 @@ var BackgroundRenderer = class {
|
|
|
10993
11201
|
ry = Math.max(ry, .01);
|
|
10994
11202
|
}
|
|
10995
11203
|
if (!(rx > 0 && ry > 0)) return;
|
|
10996
|
-
const
|
|
10997
|
-
const firstStop = at(processed, 0);
|
|
10998
|
-
const lastStop = at(processed, processed.length - 1);
|
|
10999
|
-
const period = Math.max(lastStop.stop - firstStop.stop, .01);
|
|
11000
|
-
const stops = [];
|
|
11001
|
-
const rings = Math.ceil(1 / period);
|
|
11002
|
-
for (let k = 0; k < rings; k++) for (const s of processed) {
|
|
11003
|
-
const stop = k * period + (s.stop - firstStop.stop);
|
|
11004
|
-
if (stop > 1) break;
|
|
11005
|
-
stops.push({
|
|
11006
|
-
stop,
|
|
11007
|
-
color: asString(s.color)
|
|
11008
|
-
});
|
|
11009
|
-
}
|
|
11010
|
-
stops.push({
|
|
11011
|
-
stop: 1,
|
|
11012
|
-
color: asString(lastStop.color)
|
|
11013
|
-
});
|
|
11014
|
-
const cacheKey = `rrg|${Math.round(x)}x${Math.round(y)}|${Math.round(rx)}x${Math.round(ry)}|${stops.length}|${JSON.stringify(backgroundImage.stops)}`;
|
|
11204
|
+
const cacheKey = `rrg|${Math.round(x)}x${Math.round(y)}|${Math.round(rx)}x${Math.round(ry)}|${JSON.stringify(backgroundImage.stops)}`;
|
|
11015
11205
|
let pattern = this.patternCache.get(cacheKey);
|
|
11016
11206
|
if (!pattern) {
|
|
11017
|
-
const
|
|
11018
|
-
|
|
11019
|
-
|
|
11020
|
-
|
|
11021
|
-
|
|
11022
|
-
const gradient = offCtx.createRadialGradient(rx, rx, 0, rx, rx, rx);
|
|
11023
|
-
stops.forEach((s) => gradient.addColorStop(s.stop, s.color));
|
|
11024
|
-
offCtx.fillStyle = gradient;
|
|
11025
|
-
if (rx !== ry) offCtx.scale(1, ry / rx);
|
|
11026
|
-
offCtx.fillRect(0, 0, rx * 2, ry * 2);
|
|
11027
|
-
pattern = this.ctx.createPattern(offscreen, "no-repeat");
|
|
11028
|
-
this.patternCache.set(cacheKey, pattern);
|
|
11029
|
-
}
|
|
11207
|
+
const ownerDocument = this.canvas.ownerDocument ?? document;
|
|
11208
|
+
const rasterized = rasterizeRadialGradient(ownerDocument, rx, ry, backgroundImage.stops, true);
|
|
11209
|
+
if (!rasterized) return;
|
|
11210
|
+
pattern = this.ctx.createPattern(rasterized.canvas, "no-repeat");
|
|
11211
|
+
this.patternCache.set(cacheKey, pattern);
|
|
11030
11212
|
}
|
|
11031
11213
|
if (pattern) {
|
|
11032
11214
|
this.path(path);
|
|
@@ -11238,6 +11420,8 @@ const createPathFromCurves = (outer1, inner1, outer2, inner2) => {
|
|
|
11238
11420
|
* Extracted from CanvasRenderer to improve code organization and maintainability.
|
|
11239
11421
|
*/
|
|
11240
11422
|
var BorderRenderer = class {
|
|
11423
|
+
ctx;
|
|
11424
|
+
pathCallbacks;
|
|
11241
11425
|
constructor(deps, pathCallbacks) {
|
|
11242
11426
|
this.ctx = deps.ctx;
|
|
11243
11427
|
this.pathCallbacks = pathCallbacks;
|
|
@@ -11414,6 +11598,7 @@ const resolveBorderImageOutset = (outset, borderWidths) => {
|
|
|
11414
11598
|
};
|
|
11415
11599
|
};
|
|
11416
11600
|
var BorderImageRenderer = class {
|
|
11601
|
+
ctx;
|
|
11417
11602
|
constructor(ctx) {
|
|
11418
11603
|
this.ctx = ctx;
|
|
11419
11604
|
}
|
|
@@ -11451,7 +11636,8 @@ var BorderImageRenderer = class {
|
|
|
11451
11636
|
dy: top,
|
|
11452
11637
|
dw: width - dL - dR,
|
|
11453
11638
|
dh: dT,
|
|
11454
|
-
repeat: repeat.horizontal
|
|
11639
|
+
repeat: repeat.horizontal,
|
|
11640
|
+
horizontal: true
|
|
11455
11641
|
},
|
|
11456
11642
|
{
|
|
11457
11643
|
sx: imgW - sR,
|
|
@@ -11462,7 +11648,8 @@ var BorderImageRenderer = class {
|
|
|
11462
11648
|
dy: top + dT,
|
|
11463
11649
|
dw: dR,
|
|
11464
11650
|
dh: height - dT - dB,
|
|
11465
|
-
repeat: repeat.vertical
|
|
11651
|
+
repeat: repeat.vertical,
|
|
11652
|
+
horizontal: false
|
|
11466
11653
|
},
|
|
11467
11654
|
{
|
|
11468
11655
|
sx: sL,
|
|
@@ -11473,7 +11660,8 @@ var BorderImageRenderer = class {
|
|
|
11473
11660
|
dy: top + height - dB,
|
|
11474
11661
|
dw: width - dL - dR,
|
|
11475
11662
|
dh: dB,
|
|
11476
|
-
repeat: repeat.horizontal
|
|
11663
|
+
repeat: repeat.horizontal,
|
|
11664
|
+
horizontal: true
|
|
11477
11665
|
},
|
|
11478
11666
|
{
|
|
11479
11667
|
sx: 0,
|
|
@@ -11484,33 +11672,33 @@ var BorderImageRenderer = class {
|
|
|
11484
11672
|
dy: top + dT,
|
|
11485
11673
|
dw: dL,
|
|
11486
11674
|
dh: height - dT - dB,
|
|
11487
|
-
repeat: repeat.vertical
|
|
11675
|
+
repeat: repeat.vertical,
|
|
11676
|
+
horizontal: false
|
|
11488
11677
|
}
|
|
11489
11678
|
];
|
|
11490
11679
|
for (const edge of edges) {
|
|
11491
11680
|
if (edge.sw <= 0 || edge.sh <= 0 || edge.dw <= 0 || edge.dh <= 0) continue;
|
|
11492
|
-
const isHorizontal = edge.dw >= edge.dh;
|
|
11493
11681
|
if (edge.repeat === 0) this.ctx.drawImage(image, edge.sx, edge.sy, edge.sw, edge.sh, edge.dx, edge.dy, edge.dw, edge.dh);
|
|
11494
|
-
else if (edge.repeat === 1 || edge.repeat === 2) this.drawRepeatedEdge(image, edge,
|
|
11495
|
-
}
|
|
11496
|
-
if (slice.fill) {
|
|
11497
|
-
|
|
11498
|
-
|
|
11499
|
-
|
|
11500
|
-
|
|
11501
|
-
|
|
11502
|
-
|
|
11503
|
-
|
|
11504
|
-
|
|
11505
|
-
|
|
11506
|
-
}
|
|
11682
|
+
else if (edge.repeat === 1 || edge.repeat === 2) this.drawRepeatedEdge(image, edge, edge.horizontal, edge.repeat === 2);
|
|
11683
|
+
}
|
|
11684
|
+
if (slice.fill) this.drawCenterRegion(image, {
|
|
11685
|
+
sx: sL,
|
|
11686
|
+
sy: sT,
|
|
11687
|
+
sw: imgW - sL - sR,
|
|
11688
|
+
sh: imgH - sT - sB
|
|
11689
|
+
}, {
|
|
11690
|
+
dx: left + dL,
|
|
11691
|
+
dy: top + dT,
|
|
11692
|
+
dw: width - dL - dR,
|
|
11693
|
+
dh: height - dT - dB
|
|
11694
|
+
}, repeat);
|
|
11507
11695
|
}
|
|
11508
11696
|
drawRegion(image, sx, sy, sw, sh, dx, dy, dw, dh) {
|
|
11509
11697
|
if (sw > 0 && sh > 0 && dw > 0 && dh > 0) this.ctx.drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh);
|
|
11510
11698
|
}
|
|
11511
|
-
drawRepeatedEdge(image, edge,
|
|
11512
|
-
const srcLength =
|
|
11513
|
-
const tgLength =
|
|
11699
|
+
drawRepeatedEdge(image, edge, horizontal, round) {
|
|
11700
|
+
const srcLength = horizontal ? edge.sw : edge.sh;
|
|
11701
|
+
const tgLength = horizontal ? edge.dw : edge.dh;
|
|
11514
11702
|
if (srcLength <= 0 || tgLength <= 0) return;
|
|
11515
11703
|
let tileSize;
|
|
11516
11704
|
let tileCount;
|
|
@@ -11527,14 +11715,45 @@ var BorderImageRenderer = class {
|
|
|
11527
11715
|
this.ctx.clip();
|
|
11528
11716
|
for (let i = 0; i < tileCount; i++) {
|
|
11529
11717
|
const offset = i * tileSize;
|
|
11530
|
-
|
|
11531
|
-
|
|
11532
|
-
if (clampedSize <= 0) break;
|
|
11533
|
-
if (isHorizontal) this.ctx.drawImage(image, edge.sx, edge.sy, edge.sw, edge.sh, edge.dx + offset, edge.dy, clampedSize, edge.dh);
|
|
11534
|
-
else this.ctx.drawImage(image, edge.sx, edge.sy, edge.sw, edge.sh, edge.dx, edge.dy + offset, edge.dw, clampedSize);
|
|
11718
|
+
if (horizontal) this.ctx.drawImage(image, edge.sx, edge.sy, edge.sw, edge.sh, edge.dx + offset, edge.dy, tileSize, edge.dh);
|
|
11719
|
+
else this.ctx.drawImage(image, edge.sx, edge.sy, edge.sw, edge.sh, edge.dx, edge.dy + offset, edge.dw, tileSize);
|
|
11535
11720
|
}
|
|
11536
11721
|
this.ctx.restore();
|
|
11537
11722
|
}
|
|
11723
|
+
/**
|
|
11724
|
+
* Draw the center region of the border image, tiling each axis per its
|
|
11725
|
+
* border-image-repeat keyword (stretch spans the whole axis, repeat
|
|
11726
|
+
* tiles at source size with the overflow cropped, round scales the tile
|
|
11727
|
+
* to divide the axis evenly).
|
|
11728
|
+
*/
|
|
11729
|
+
drawCenterRegion(image, src, dst, repeat) {
|
|
11730
|
+
if (src.sw <= 0 || src.sh <= 0 || dst.dw <= 0 || dst.dh <= 0) return;
|
|
11731
|
+
const axis = (mode, srcLen, dstLen) => {
|
|
11732
|
+
if (mode === 0) return {
|
|
11733
|
+
size: dstLen,
|
|
11734
|
+
count: 1
|
|
11735
|
+
};
|
|
11736
|
+
if (mode === 2) {
|
|
11737
|
+
const count = Math.max(1, Math.round(dstLen / srcLen));
|
|
11738
|
+
return {
|
|
11739
|
+
size: dstLen / count,
|
|
11740
|
+
count
|
|
11741
|
+
};
|
|
11742
|
+
}
|
|
11743
|
+
return {
|
|
11744
|
+
size: srcLen,
|
|
11745
|
+
count: Math.max(1, Math.ceil(dstLen / srcLen))
|
|
11746
|
+
};
|
|
11747
|
+
};
|
|
11748
|
+
const columns = axis(repeat.horizontal, src.sw, dst.dw);
|
|
11749
|
+
const rows = axis(repeat.vertical, src.sh, dst.dh);
|
|
11750
|
+
this.ctx.save();
|
|
11751
|
+
this.ctx.beginPath();
|
|
11752
|
+
this.ctx.rect(dst.dx, dst.dy, dst.dw, dst.dh);
|
|
11753
|
+
this.ctx.clip();
|
|
11754
|
+
for (let row = 0; row < rows.count; row++) for (let column = 0; column < columns.count; column++) this.ctx.drawImage(image, src.sx, src.sy, src.sw, src.sh, dst.dx + column * columns.size, dst.dy + row * rows.size, columns.size, rows.size);
|
|
11755
|
+
this.ctx.restore();
|
|
11756
|
+
}
|
|
11538
11757
|
};
|
|
11539
11758
|
//#endregion
|
|
11540
11759
|
//#region src/render/canvas/effects-renderer.ts
|
|
@@ -11588,10 +11807,17 @@ const scaleFilterBlur = (filter, scale) => scale === 1 ? filter : filter.replace
|
|
|
11588
11807
|
* `restore()` **once** when that effect is popped.
|
|
11589
11808
|
*/
|
|
11590
11809
|
var EffectsRenderer = class {
|
|
11810
|
+
ctx;
|
|
11811
|
+
pathCallback;
|
|
11812
|
+
scale;
|
|
11813
|
+
activeEffects = [];
|
|
11814
|
+
/** Whether a canvas state save was performed for the current batch. */
|
|
11815
|
+
didSave = false;
|
|
11816
|
+
/** Index (0-based, from start of activeEffects array) of the last
|
|
11817
|
+
* heavyweight effect in the batch — the one whose pop triggers
|
|
11818
|
+
* restore(). Set to -1 when no save was performed. */
|
|
11819
|
+
saveAtDepth = -1;
|
|
11591
11820
|
constructor(deps, pathCallback) {
|
|
11592
|
-
this.activeEffects = [];
|
|
11593
|
-
this.didSave = false;
|
|
11594
|
-
this.saveAtDepth = -1;
|
|
11595
11821
|
this.ctx = deps.ctx;
|
|
11596
11822
|
this.pathCallback = pathCallback;
|
|
11597
11823
|
this.scale = deps.scale ?? 1;
|
|
@@ -11692,8 +11918,11 @@ var EffectsRenderer = class {
|
|
|
11692
11918
|
* always fills the whole area — a mask surface is about alpha coverage, not
|
|
11693
11919
|
* about what is visible underneath.
|
|
11694
11920
|
*
|
|
11695
|
-
*
|
|
11696
|
-
*
|
|
11921
|
+
* Gradient layers share the rasterisation primitives of the background
|
|
11922
|
+
* renderer (gradient-rasterizer.ts): repeating gradients stack their stop
|
|
11923
|
+
* cycles, and the area beyond a radial gradient's ending shape keeps the
|
|
11924
|
+
* last stop's colour. Limitations (v1): mask-mode is alpha-only; layers
|
|
11925
|
+
* composite with source-over (≈ the spec-default `add`).
|
|
11697
11926
|
*/
|
|
11698
11927
|
/**
|
|
11699
11928
|
* CSS layer lists cycle: a single mask-size applies to every mask-image
|
|
@@ -11759,17 +11988,12 @@ const paintRadialLayer = (ctx, layer, area) => {
|
|
|
11759
11988
|
let [rx, ry] = calculateRadius(layer, cx, cy, width, height);
|
|
11760
11989
|
rx = Math.max(rx, .01);
|
|
11761
11990
|
ry = Math.max(ry, .01);
|
|
11762
|
-
const
|
|
11763
|
-
|
|
11764
|
-
|
|
11765
|
-
|
|
11766
|
-
|
|
11767
|
-
|
|
11768
|
-
processColorStops(layer.stops, rx * 2).forEach((s) => gradient.addColorStop(Math.min(1, Math.max(0, s.stop)), asString(s.color)));
|
|
11769
|
-
offCtx.fillStyle = gradient;
|
|
11770
|
-
if (rx !== ry) offCtx.scale(1, ry / rx);
|
|
11771
|
-
offCtx.fillRect(0, 0, rx * 2, ry * 2);
|
|
11772
|
-
ctx.drawImage(offscreen, area.left + cx - rx, area.top + cy - ry, rx * 2, ry * 2);
|
|
11991
|
+
const ownerDocument = ctx.canvas.ownerDocument ?? document;
|
|
11992
|
+
const rasterized = rasterizeRadialGradient(ownerDocument, rx, ry, layer.stops, isRepeatingRadialGradient(layer));
|
|
11993
|
+
if (!rasterized) return;
|
|
11994
|
+
ctx.fillStyle = rasterized.lastColor;
|
|
11995
|
+
ctx.fillRect(area.left, area.top, area.width, area.height);
|
|
11996
|
+
ctx.drawImage(rasterized.canvas, area.left + cx - rx, area.top + cy - ry, rx * 2, ry * 2);
|
|
11773
11997
|
};
|
|
11774
11998
|
/** Draw one gradient layer filling the whole mask area. */
|
|
11775
11999
|
const paintGradientLayer = (ctx, layer, area) => {
|
|
@@ -11783,12 +12007,31 @@ const paintGradientLayer = (ctx, layer, area) => {
|
|
|
11783
12007
|
if (layer.type === 1 || layer.type === 3) {
|
|
11784
12008
|
const linear = layer;
|
|
11785
12009
|
const [lineLength, lx0, lx1, ly0, ly1] = calculateGradientDirection(linear.angle || 0, width, height);
|
|
11786
|
-
|
|
11787
|
-
|
|
11788
|
-
|
|
12010
|
+
const processed = processColorStops(linear.stops, lineLength || 1);
|
|
12011
|
+
if (layer.type === 3) {
|
|
12012
|
+
const stacked = stackRepeatingStops(processed);
|
|
12013
|
+
if (!stacked) {
|
|
12014
|
+
ctx.fillStyle = asString(at(processed, processed.length - 1).color);
|
|
12015
|
+
ctx.fillRect(area.left, area.top, width, height);
|
|
12016
|
+
return;
|
|
12017
|
+
}
|
|
12018
|
+
gradient = ctx.createLinearGradient(area.left + lx0, area.top + ly0, area.left + lx1, area.top + ly1);
|
|
12019
|
+
stacked.forEach((s) => gradient.addColorStop(Math.min(1, Math.max(0, s.stop)), s.color));
|
|
12020
|
+
} else {
|
|
12021
|
+
gradient = ctx.createLinearGradient(area.left + lx0, area.top + ly0, area.left + lx1, area.top + ly1);
|
|
12022
|
+
toCanvasStops(processed).forEach((s) => gradient.addColorStop(s.stop, s.color));
|
|
12023
|
+
}
|
|
12024
|
+
} else if (layer.type === 5 || layer.type === 6) {
|
|
11789
12025
|
const conic = layer;
|
|
12026
|
+
const processed = processColorStops(conic.stops, 1);
|
|
12027
|
+
const repeating = layer.type === 6;
|
|
12028
|
+
if (repeating && !stackRepeatingStops(processed)) {
|
|
12029
|
+
ctx.fillStyle = asString(at(processed, processed.length - 1).color);
|
|
12030
|
+
ctx.fillRect(area.left, area.top, width, height);
|
|
12031
|
+
return;
|
|
12032
|
+
}
|
|
11790
12033
|
gradient = ctx.createConicGradient(conic.angle - Math.PI / 2, area.left + width / 2, area.top + height / 2);
|
|
11791
|
-
|
|
12034
|
+
((repeating ? stackRepeatingStops(processed) : null) ?? toCanvasStops(processed)).forEach((s) => gradient.addColorStop(Math.min(1, Math.max(0, s.stop)), s.color));
|
|
11792
12035
|
}
|
|
11793
12036
|
if (gradient) {
|
|
11794
12037
|
ctx.fillStyle = gradient;
|
|
@@ -11855,7 +12098,11 @@ const calculateObjectFitRendering = (intrinsicWidth, intrinsicHeight, box, objec
|
|
|
11855
12098
|
dh = sh;
|
|
11856
12099
|
}
|
|
11857
12100
|
} else if (objectFit === 16) {
|
|
11858
|
-
|
|
12101
|
+
const containW = imgRatio > boxRatio ? dw : dh * imgRatio;
|
|
12102
|
+
const containH = imgRatio > boxRatio ? dw / imgRatio : dh;
|
|
12103
|
+
const noneW = Math.min(sw, dw);
|
|
12104
|
+
const noneH = Math.min(sh, dh);
|
|
12105
|
+
if (containW * containH < noneW * noneH) {
|
|
11859
12106
|
if (imgRatio > boxRatio) {
|
|
11860
12107
|
dh = dw / imgRatio;
|
|
11861
12108
|
dy += (box.height - dh) * posY;
|
|
@@ -11906,14 +12153,12 @@ async function renderReplacedElements(ctx, context, options, iframeRendererFacto
|
|
|
11906
12153
|
ctx.imageSmoothingEnabled = prevSmoothing;
|
|
11907
12154
|
} catch (e) {
|
|
11908
12155
|
context.logger.error(`Error loading image ${container.src}`);
|
|
11909
|
-
context.onError?.(e instanceof Error ? e : new Error(String(e)));
|
|
11910
12156
|
}
|
|
11911
12157
|
if (container instanceof CanvasElementContainer) renderReplacedElementFn(container, curves, container.canvas);
|
|
11912
12158
|
if (container instanceof SVGElementContainer) try {
|
|
11913
12159
|
renderReplacedElementFn(container, curves, await context.cache.match(container.svg));
|
|
11914
12160
|
} catch (e) {
|
|
11915
12161
|
context.logger.error(`Error loading svg ${container.svg.substring(0, 255)}`);
|
|
11916
|
-
context.onError?.(e instanceof Error ? e : new Error(String(e)));
|
|
11917
12162
|
}
|
|
11918
12163
|
if (container instanceof IFrameElementContainer && container.tree) {
|
|
11919
12164
|
const canvas = await iframeRendererFactory(context, {
|
|
@@ -12061,7 +12306,6 @@ async function renderListMarker(ctx, context, textRenderer, paint, container, st
|
|
|
12061
12306
|
ctx.drawImage(image, container.bounds.left - (markerWidth + 10), markerCenterY - markerHeight / 2, markerWidth, markerHeight);
|
|
12062
12307
|
} catch (e) {
|
|
12063
12308
|
context.logger.error(`Error loading list-style-image ${url}`);
|
|
12064
|
-
context.onError?.(e instanceof Error ? e : new Error(String(e)));
|
|
12065
12309
|
}
|
|
12066
12310
|
}
|
|
12067
12311
|
} else if (paint.listValue && container.styles.listStyleType !== -1) {
|
|
@@ -12248,7 +12492,10 @@ const paintShadowSurface = async (ctx, paint, shadow, options, budget, space) =>
|
|
|
12248
12492
|
else createCanvasPath(sourceCtx, path);
|
|
12249
12493
|
sourceCtx.fillStyle = asString(shadow.color);
|
|
12250
12494
|
sourceCtx.fill(shadow.inset ? "evenodd" : "nonzero");
|
|
12251
|
-
filtered = await renderFilterSurface(source, {
|
|
12495
|
+
filtered = await renderFilterSurface(source, { functions: [{
|
|
12496
|
+
kind: "blur",
|
|
12497
|
+
value: blur
|
|
12498
|
+
}] }, 1, space.scale, options.signal);
|
|
12252
12499
|
ctx.save();
|
|
12253
12500
|
try {
|
|
12254
12501
|
if (shadow.inset) {
|
|
@@ -12334,6 +12581,10 @@ const paintBoxShadow = async (ctx, paint, shadow, options, budget) => {
|
|
|
12334
12581
|
//#endregion
|
|
12335
12582
|
//#region src/render/canvas/text-clip-renderer.ts
|
|
12336
12583
|
var TextClipRenderer = class {
|
|
12584
|
+
ctx;
|
|
12585
|
+
context;
|
|
12586
|
+
scale;
|
|
12587
|
+
createFontStyle;
|
|
12337
12588
|
constructor(deps) {
|
|
12338
12589
|
this.ctx = deps.ctx;
|
|
12339
12590
|
this.context = deps.context;
|
|
@@ -12353,59 +12604,69 @@ var TextClipRenderer = class {
|
|
|
12353
12604
|
const deviceHeight = Math.ceil(bounds.height * scale);
|
|
12354
12605
|
const offscreen = this.createLayer(ownerDocument, deviceWidth, deviceHeight);
|
|
12355
12606
|
if (!offscreen) return;
|
|
12356
|
-
|
|
12357
|
-
|
|
12358
|
-
|
|
12359
|
-
|
|
12360
|
-
|
|
12361
|
-
|
|
12362
|
-
|
|
12363
|
-
|
|
12364
|
-
|
|
12365
|
-
|
|
12366
|
-
|
|
12367
|
-
|
|
12368
|
-
|
|
12369
|
-
|
|
12370
|
-
|
|
12371
|
-
|
|
12372
|
-
|
|
12373
|
-
|
|
12374
|
-
|
|
12375
|
-
|
|
12376
|
-
|
|
12377
|
-
|
|
12378
|
-
|
|
12379
|
-
|
|
12380
|
-
|
|
12381
|
-
|
|
12382
|
-
bounds,
|
|
12383
|
-
|
|
12384
|
-
|
|
12385
|
-
|
|
12386
|
-
|
|
12387
|
-
|
|
12388
|
-
|
|
12389
|
-
|
|
12390
|
-
|
|
12391
|
-
mask
|
|
12392
|
-
mask
|
|
12393
|
-
|
|
12394
|
-
|
|
12395
|
-
|
|
12396
|
-
|
|
12397
|
-
|
|
12398
|
-
|
|
12399
|
-
|
|
12400
|
-
|
|
12401
|
-
|
|
12402
|
-
|
|
12403
|
-
|
|
12404
|
-
|
|
12405
|
-
|
|
12406
|
-
|
|
12407
|
-
|
|
12408
|
-
|
|
12607
|
+
let mask = null;
|
|
12608
|
+
let composite = null;
|
|
12609
|
+
let shadowCanvases = null;
|
|
12610
|
+
try {
|
|
12611
|
+
offscreen.ctx.scale(scale, scale);
|
|
12612
|
+
const [fontString] = this.createFontStyle(styles);
|
|
12613
|
+
offscreen.ctx.font = fontString ?? "";
|
|
12614
|
+
offscreen.ctx.textBaseline = "alphabetic";
|
|
12615
|
+
offscreen.ctx.textAlign = "left";
|
|
12616
|
+
offscreen.ctx.direction = styles.direction === 1 ? "rtl" : "ltr";
|
|
12617
|
+
const baseline = measureBaseline(offscreen.ctx, styles.fontSize.number);
|
|
12618
|
+
const bgRenderer = new BackgroundRenderer({
|
|
12619
|
+
ctx: offscreen.ctx,
|
|
12620
|
+
context: this.context,
|
|
12621
|
+
canvas: offscreen.canvas,
|
|
12622
|
+
options: {
|
|
12623
|
+
width,
|
|
12624
|
+
height,
|
|
12625
|
+
scale: 1
|
|
12626
|
+
}
|
|
12627
|
+
});
|
|
12628
|
+
if (!isTransparent(styles.backgroundColor)) {
|
|
12629
|
+
offscreen.ctx.fillStyle = asString(styles.backgroundColor);
|
|
12630
|
+
offscreen.ctx.fillRect(0, 0, width, height);
|
|
12631
|
+
}
|
|
12632
|
+
offscreen.ctx.save();
|
|
12633
|
+
offscreen.ctx.translate(-bounds.left, -bounds.top);
|
|
12634
|
+
await bgRenderer.renderBackgroundImage(container);
|
|
12635
|
+
offscreen.ctx.restore();
|
|
12636
|
+
const drawOptions = {
|
|
12637
|
+
bounds,
|
|
12638
|
+
baseline,
|
|
12639
|
+
letterSpacing: styles.letterSpacing,
|
|
12640
|
+
writingMode: styles.writingMode
|
|
12641
|
+
};
|
|
12642
|
+
mask = this.createGlyphLayer(ownerDocument, deviceWidth, deviceHeight, offscreen.ctx);
|
|
12643
|
+
if (!mask) return;
|
|
12644
|
+
const hasStroke = !!styles.webkitTextStrokeWidth;
|
|
12645
|
+
if (hasStroke) {
|
|
12646
|
+
mask.ctx.strokeStyle = asString(styles.webkitTextStrokeColor);
|
|
12647
|
+
mask.ctx.lineWidth = styles.webkitTextStrokeWidth;
|
|
12648
|
+
mask.ctx.lineJoin = getTextStrokeLineJoin();
|
|
12649
|
+
}
|
|
12650
|
+
for (const textNode of container.textNodes) for (const textBound of textNode.textBounds) this.drawGlyphs(mask, textBound, drawOptions, (ctx, text, x, y) => {
|
|
12651
|
+
ctx.fillText(text, x, y);
|
|
12652
|
+
if (hasStroke) ctx.strokeText(text, x, y);
|
|
12653
|
+
});
|
|
12654
|
+
offscreen.ctx.globalCompositeOperation = "destination-in";
|
|
12655
|
+
offscreen.ctx.drawImage(mask.canvas, 0, 0, width, height);
|
|
12656
|
+
shadowCanvases = this.renderShadowSilhouettes(paint, ownerDocument, deviceWidth, deviceHeight, offscreen.ctx, styles, drawOptions);
|
|
12657
|
+
if (shadowCanvases) {
|
|
12658
|
+
composite = this.createLayer(ownerDocument, deviceWidth, deviceHeight);
|
|
12659
|
+
if (!composite) return;
|
|
12660
|
+
for (const shadowCanvas of shadowCanvases) composite.ctx.drawImage(shadowCanvas, 0, 0);
|
|
12661
|
+
composite.ctx.drawImage(offscreen.canvas, 0, 0);
|
|
12662
|
+
this.ctx.drawImage(composite.canvas, bounds.left, bounds.top, bounds.width, bounds.height);
|
|
12663
|
+
} else this.ctx.drawImage(offscreen.canvas, bounds.left, bounds.top, bounds.width, bounds.height);
|
|
12664
|
+
} finally {
|
|
12665
|
+
releaseSurface(offscreen.canvas);
|
|
12666
|
+
if (mask) releaseSurface(mask.canvas);
|
|
12667
|
+
if (composite) releaseSurface(composite.canvas);
|
|
12668
|
+
if (shadowCanvases) shadowCanvases.forEach(releaseSurface);
|
|
12669
|
+
}
|
|
12409
12670
|
}
|
|
12410
12671
|
createLayer(ownerDocument, width, height) {
|
|
12411
12672
|
const canvas = ownerDocument.createElement("canvas");
|
|
@@ -12477,20 +12738,29 @@ var TextClipRenderer = class {
|
|
|
12477
12738
|
}
|
|
12478
12739
|
return canvases.length ? canvases : null;
|
|
12479
12740
|
}
|
|
12480
|
-
getTextStrokeLineJoin() {
|
|
12481
|
-
return (typeof window !== "undefined" ? window : void 0)?.chrome ? "miter" : "round";
|
|
12482
|
-
}
|
|
12483
12741
|
};
|
|
12484
12742
|
//#endregion
|
|
12485
12743
|
//#region src/render/canvas/canvas-renderer.ts
|
|
12486
12744
|
var CanvasRenderer = class CanvasRenderer {
|
|
12745
|
+
surfaceRoot;
|
|
12746
|
+
surfaceBudget;
|
|
12747
|
+
canvas;
|
|
12748
|
+
ctx;
|
|
12749
|
+
context;
|
|
12750
|
+
options;
|
|
12751
|
+
backgroundRenderer;
|
|
12752
|
+
borderRenderer;
|
|
12753
|
+
borderImageRenderer;
|
|
12754
|
+
effectsRenderer;
|
|
12755
|
+
textRenderer;
|
|
12756
|
+
textClipRenderer;
|
|
12757
|
+
legacySubtree = false;
|
|
12487
12758
|
constructor(context, options, surfaceRoot, surfaceBudget = { pixels: 0 }) {
|
|
12488
12759
|
this.surfaceRoot = surfaceRoot;
|
|
12489
12760
|
this.surfaceBudget = surfaceBudget;
|
|
12490
|
-
this.legacySubtree = false;
|
|
12491
12761
|
this.context = context;
|
|
12492
12762
|
this.options = options;
|
|
12493
|
-
this.canvas = options.canvas ? options.canvas :
|
|
12763
|
+
this.canvas = options.canvas ? options.canvas : context.resourceDocument.createElement("canvas");
|
|
12494
12764
|
const ctx = this.canvas.getContext("2d");
|
|
12495
12765
|
if (!ctx) {
|
|
12496
12766
|
if (!options.canvas) releaseSurface(this.canvas);
|
|
@@ -12543,11 +12813,12 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
12543
12813
|
async renderStack(stack) {
|
|
12544
12814
|
const styles = stack.element.container.styles;
|
|
12545
12815
|
if (styles.isVisible()) {
|
|
12546
|
-
const filter =
|
|
12816
|
+
const filter = parseFilterChain(styles.filter);
|
|
12817
|
+
const hasFilter = filter !== null && filter.functions.length > 0;
|
|
12547
12818
|
const hasMask = styles.maskImage.length > 0;
|
|
12548
12819
|
const reflect = styles.webkitBoxReflect;
|
|
12549
12820
|
const hasBlend = styles.mixBlendMode !== MIX_BLEND_MODE$1.NORMAL;
|
|
12550
|
-
if (stack.element !== this.surfaceRoot && !this.legacySubtree && (hasMask || reflect || hasBlend || filter && (
|
|
12821
|
+
if (stack.element !== this.surfaceRoot && !this.legacySubtree && (hasMask || reflect || hasBlend || filter !== null && (hasFilter || styles.opacity < 1)) && this.canComposite(stack.element)) {
|
|
12551
12822
|
if (!await this.renderCompositedStack(stack, filter, hasMask, reflect, hasBlend)) {
|
|
12552
12823
|
this.legacySubtree = true;
|
|
12553
12824
|
try {
|
|
@@ -12564,7 +12835,7 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
12564
12835
|
canComposite(paint) {
|
|
12565
12836
|
const supported = (container) => {
|
|
12566
12837
|
const styles = container.styles;
|
|
12567
|
-
return !styles.isTransformed() && styles.zoom === 1 && styles.clipPath.type === 0 && !contains(styles.display, 2048) &&
|
|
12838
|
+
return !styles.isTransformed() && styles.zoom === 1 && styles.clipPath.type === 0 && !contains(styles.display, 2048) && parseFilterChain(styles.filter) !== null;
|
|
12568
12839
|
};
|
|
12569
12840
|
const subtree = (container) => supported(container) && container.elements.every(subtree);
|
|
12570
12841
|
let ancestor = paint.parent;
|
|
@@ -12632,7 +12903,7 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
12632
12903
|
async applyMask(surface, styles, bounds) {
|
|
12633
12904
|
const ctx = surface.getContext("2d");
|
|
12634
12905
|
if (!ctx) return;
|
|
12635
|
-
const maskCanvas =
|
|
12906
|
+
const maskCanvas = this.context.resourceDocument.createElement("canvas");
|
|
12636
12907
|
maskCanvas.width = surface.width;
|
|
12637
12908
|
maskCanvas.height = surface.height;
|
|
12638
12909
|
const maskCtx = maskCanvas.getContext("2d");
|
|
@@ -12674,7 +12945,7 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
12674
12945
|
let refCanvas;
|
|
12675
12946
|
let maskCanvas;
|
|
12676
12947
|
try {
|
|
12677
|
-
refCanvas =
|
|
12948
|
+
refCanvas = this.context.resourceDocument.createElement("canvas");
|
|
12678
12949
|
refCanvas.width = w;
|
|
12679
12950
|
refCanvas.height = h;
|
|
12680
12951
|
const ctx = refCanvas.getContext("2d");
|
|
@@ -12696,7 +12967,7 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
12696
12967
|
ctx.restore();
|
|
12697
12968
|
}
|
|
12698
12969
|
if (reflect.mask) {
|
|
12699
|
-
maskCanvas =
|
|
12970
|
+
maskCanvas = this.context.resourceDocument.createElement("canvas");
|
|
12700
12971
|
maskCanvas.width = w;
|
|
12701
12972
|
maskCanvas.height = h;
|
|
12702
12973
|
const mctx = maskCanvas.getContext("2d");
|
|
@@ -12820,18 +13091,6 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
12820
13091
|
await this.renderStack(child);
|
|
12821
13092
|
}
|
|
12822
13093
|
}
|
|
12823
|
-
mask(paths) {
|
|
12824
|
-
this.ctx.beginPath();
|
|
12825
|
-
const x = this.options.x;
|
|
12826
|
-
const y = this.options.y;
|
|
12827
|
-
this.ctx.moveTo(x, y);
|
|
12828
|
-
this.ctx.lineTo(x + this.options.width, y);
|
|
12829
|
-
this.ctx.lineTo(x + this.options.width, y + this.options.height);
|
|
12830
|
-
this.ctx.lineTo(x, y + this.options.height);
|
|
12831
|
-
this.ctx.lineTo(x, y);
|
|
12832
|
-
this.formatPath(paths.slice(0).reverse());
|
|
12833
|
-
this.ctx.closePath();
|
|
12834
|
-
}
|
|
12835
13094
|
path(paths) {
|
|
12836
13095
|
createCanvasPath(this.ctx, paths);
|
|
12837
13096
|
}
|
|
@@ -12853,7 +13112,7 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
12853
13112
|
let source;
|
|
12854
13113
|
let filtered;
|
|
12855
13114
|
try {
|
|
12856
|
-
source =
|
|
13115
|
+
source = this.context.resourceDocument.createElement("canvas");
|
|
12857
13116
|
source.width = width;
|
|
12858
13117
|
source.height = height;
|
|
12859
13118
|
const ctx = source.getContext("2d");
|
|
@@ -12863,7 +13122,10 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
12863
13122
|
createCanvasPath(ctx, transformPath(calculateBorderBoxPath(paint.curves), -spread, -spread, 2 * spread, 2 * spread));
|
|
12864
13123
|
ctx.fillStyle = asString(shadow.color);
|
|
12865
13124
|
ctx.fill();
|
|
12866
|
-
filtered = await renderFilterSurface(source, {
|
|
13125
|
+
filtered = await renderFilterSurface(source, { functions: [{
|
|
13126
|
+
kind: "blur",
|
|
13127
|
+
value: blur
|
|
13128
|
+
}] }, 1, scale, this.options.signal);
|
|
12867
13129
|
this.ctx.save();
|
|
12868
13130
|
try {
|
|
12869
13131
|
this.ctx.beginPath();
|
|
@@ -13039,9 +13301,19 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
13039
13301
|
if (source.type === 1 || source.type === 3) {
|
|
13040
13302
|
const gradientImage = source;
|
|
13041
13303
|
const [lineLength, x0, y0, x1, y1] = calculateGradientDirection(gradientImage.angle, width, height);
|
|
13304
|
+
const processed = processColorStops(gradientImage.stops, lineLength || width);
|
|
13305
|
+
const repeating = source.type === 3;
|
|
13306
|
+
const stacked = repeating ? stackRepeatingStops(processed) : null;
|
|
13042
13307
|
const gradient = ctx.createLinearGradient(x0, y0, x1, y1);
|
|
13043
|
-
|
|
13044
|
-
gradient.addColorStop(Math.min(1, Math.max(0, colorStop.stop)),
|
|
13308
|
+
if (stacked) stacked.forEach((colorStop) => {
|
|
13309
|
+
gradient.addColorStop(Math.min(1, Math.max(0, colorStop.stop)), colorStop.color);
|
|
13310
|
+
});
|
|
13311
|
+
else if (repeating) {
|
|
13312
|
+
const lastColor = asString(at(processed, processed.length - 1).color);
|
|
13313
|
+
gradient.addColorStop(0, lastColor);
|
|
13314
|
+
gradient.addColorStop(1, lastColor);
|
|
13315
|
+
} else toCanvasStops(processed).forEach((colorStop) => {
|
|
13316
|
+
gradient.addColorStop(colorStop.stop, colorStop.color);
|
|
13045
13317
|
});
|
|
13046
13318
|
ctx.fillStyle = gradient;
|
|
13047
13319
|
ctx.fillRect(0, 0, width, height);
|
|
@@ -13049,21 +13321,17 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
13049
13321
|
}
|
|
13050
13322
|
if (source.type === 2 || source.type === 4) {
|
|
13051
13323
|
const gradientImage = source;
|
|
13052
|
-
const
|
|
13053
|
-
const
|
|
13324
|
+
const position = gradientImage.position.length === 0 ? [FIFTY_PERCENT] : gradientImage.position;
|
|
13325
|
+
const cx = getAbsoluteValue(at(position, 0), width);
|
|
13326
|
+
const cy = getAbsoluteValue(at(position, position.length - 1), height);
|
|
13054
13327
|
const [rx, ry] = calculateRadius(gradientImage, cx, cy, width, height);
|
|
13055
13328
|
if (rx <= 0 || ry <= 0) return null;
|
|
13056
|
-
ctx.
|
|
13057
|
-
|
|
13058
|
-
|
|
13059
|
-
ctx.
|
|
13060
|
-
const gradient = ctx.createRadialGradient(cx, cy, 0, cx, cy, rx);
|
|
13061
|
-
processColorStops(gradientImage.stops, rx).forEach((colorStop) => {
|
|
13062
|
-
gradient.addColorStop(Math.min(1, Math.max(0, colorStop.stop)), asString(colorStop.color));
|
|
13063
|
-
});
|
|
13064
|
-
ctx.fillStyle = gradient;
|
|
13329
|
+
const ownerDocument = this.ctx.canvas.ownerDocument ?? document;
|
|
13330
|
+
const rasterized = rasterizeRadialGradient(ownerDocument, rx, ry, gradientImage.stops, source.type === 4);
|
|
13331
|
+
if (!rasterized) return null;
|
|
13332
|
+
ctx.fillStyle = rasterized.lastColor;
|
|
13065
13333
|
ctx.fillRect(0, 0, width, height);
|
|
13066
|
-
ctx.
|
|
13334
|
+
ctx.drawImage(rasterized.canvas, cx - rx, cy - ry, rx * 2, ry * 2);
|
|
13067
13335
|
return canvas;
|
|
13068
13336
|
}
|
|
13069
13337
|
if (source.type === 5 || source.type === 6) {
|
|
@@ -13108,12 +13376,12 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
13108
13376
|
}
|
|
13109
13377
|
/**
|
|
13110
13378
|
* Filter the already-painted content beneath the element's border box and
|
|
13111
|
-
* paint the result back, approximating CSS backdrop-filter for the
|
|
13112
|
-
*
|
|
13379
|
+
* paint the result back, approximating CSS backdrop-filter for the chain
|
|
13380
|
+
* subset the filter surface backends support.
|
|
13113
13381
|
*/
|
|
13114
13382
|
async renderBackdropFilter(paint) {
|
|
13115
|
-
const filter =
|
|
13116
|
-
if (!filter ||
|
|
13383
|
+
const filter = parseFilterChain(paint.container.styles.backdropFilter);
|
|
13384
|
+
if (!filter || filter.functions.length === 0) return;
|
|
13117
13385
|
const bounds = paint.container.bounds;
|
|
13118
13386
|
if (bounds.width <= 0 || bounds.height <= 0) return;
|
|
13119
13387
|
const scale = this.options.scale;
|
|
@@ -13125,7 +13393,7 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
13125
13393
|
let source;
|
|
13126
13394
|
let filtered;
|
|
13127
13395
|
try {
|
|
13128
|
-
source =
|
|
13396
|
+
source = this.context.resourceDocument.createElement("canvas");
|
|
13129
13397
|
source.width = width;
|
|
13130
13398
|
source.height = height;
|
|
13131
13399
|
const srcCtx = source.getContext("2d");
|
|
@@ -13133,7 +13401,15 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
13133
13401
|
const sx = Math.round((bounds.left - this.options.x) * scale);
|
|
13134
13402
|
const sy = Math.round((bounds.top - this.options.y) * scale);
|
|
13135
13403
|
srcCtx.drawImage(this.canvas, sx, sy, width, height, 0, 0, width, height);
|
|
13136
|
-
|
|
13404
|
+
try {
|
|
13405
|
+
filtered = await renderFilterSurface(source, filter, 1, scale, this.options.signal);
|
|
13406
|
+
} catch (error) {
|
|
13407
|
+
if (error instanceof FilterSurfaceError) {
|
|
13408
|
+
this.context.logger.info(`${error.message}; rendering without the backdrop effect`);
|
|
13409
|
+
return;
|
|
13410
|
+
}
|
|
13411
|
+
throw error;
|
|
13412
|
+
}
|
|
13137
13413
|
if (this.options.signal?.aborted) throw new DOMException("The operation was aborted.", "AbortError");
|
|
13138
13414
|
this.ctx.save();
|
|
13139
13415
|
try {
|
|
@@ -13180,10 +13456,14 @@ const hasTextBackgroundClip = (styles) => {
|
|
|
13180
13456
|
//#endregion
|
|
13181
13457
|
//#region src/render/canvas/foreignobject-renderer.ts
|
|
13182
13458
|
var ForeignObjectRenderer = class {
|
|
13459
|
+
canvas;
|
|
13460
|
+
ctx;
|
|
13461
|
+
options;
|
|
13462
|
+
context;
|
|
13183
13463
|
constructor(context, options) {
|
|
13184
13464
|
this.context = context;
|
|
13185
13465
|
this.options = options;
|
|
13186
|
-
this.canvas = options.canvas ? options.canvas :
|
|
13466
|
+
this.canvas = options.canvas ? options.canvas : context.resourceDocument.createElement("canvas");
|
|
13187
13467
|
const ctx = this.canvas.getContext("2d");
|
|
13188
13468
|
if (!ctx) throw new Error("Failed to get 2D rendering context from canvas");
|
|
13189
13469
|
this.ctx = ctx;
|
|
@@ -13197,19 +13477,49 @@ var ForeignObjectRenderer = class {
|
|
|
13197
13477
|
}
|
|
13198
13478
|
async render(element) {
|
|
13199
13479
|
if (this.options.signal?.aborted) throw new DOMException("The operation was aborted.", "AbortError");
|
|
13200
|
-
const
|
|
13201
|
-
const
|
|
13480
|
+
const restoreRootOffsets = stripRootOffsets(element);
|
|
13481
|
+
const svg = createForeignObjectSVG(this.options.width, this.options.height, 0, 0, element);
|
|
13482
|
+
const imagePromise = loadSerializedSVG(svg);
|
|
13483
|
+
restoreRootOffsets();
|
|
13484
|
+
const img = await imagePromise;
|
|
13485
|
+
if (this.options.signal?.aborted) throw new DOMException("The operation was aborted.", "AbortError");
|
|
13202
13486
|
if (this.options.backgroundColor) {
|
|
13203
13487
|
this.ctx.fillStyle = asString(this.options.backgroundColor);
|
|
13204
|
-
this.ctx.fillRect(
|
|
13488
|
+
this.ctx.fillRect(this.options.x, this.options.y, this.options.width, this.options.height);
|
|
13205
13489
|
}
|
|
13206
|
-
this.ctx.drawImage(img,
|
|
13490
|
+
this.ctx.drawImage(img, this.options.x, this.options.y, this.options.width, this.options.height);
|
|
13207
13491
|
return this.canvas;
|
|
13208
13492
|
}
|
|
13209
13493
|
};
|
|
13494
|
+
/**
|
|
13495
|
+
* Temporarily neutralize the root element's layout offsets for SVG
|
|
13496
|
+
* serialization. `top/right/bottom/left` reset to `auto` (inset values of
|
|
13497
|
+
* positioned elements are baked into the capture rect); margins to `0`.
|
|
13498
|
+
*/
|
|
13499
|
+
const ROOT_OFFSET_PROPERTIES = [
|
|
13500
|
+
"marginTop",
|
|
13501
|
+
"marginRight",
|
|
13502
|
+
"marginBottom",
|
|
13503
|
+
"marginLeft",
|
|
13504
|
+
"top",
|
|
13505
|
+
"right",
|
|
13506
|
+
"bottom",
|
|
13507
|
+
"left"
|
|
13508
|
+
];
|
|
13509
|
+
const stripRootOffsets = (element) => {
|
|
13510
|
+
const style = element.style;
|
|
13511
|
+
const previous = ROOT_OFFSET_PROPERTIES.map((property) => [property, style[property]]);
|
|
13512
|
+
for (const property of ROOT_OFFSET_PROPERTIES) style[property] = property.startsWith("margin") ? "0px" : "auto";
|
|
13513
|
+
return () => {
|
|
13514
|
+
for (const [property, value] of previous) style[property] = value;
|
|
13515
|
+
};
|
|
13516
|
+
};
|
|
13210
13517
|
//#endregion
|
|
13211
13518
|
//#region src/core/logger.ts
|
|
13212
13519
|
var Logger = class {
|
|
13520
|
+
id;
|
|
13521
|
+
enabled;
|
|
13522
|
+
start;
|
|
13213
13523
|
constructor({ id, enabled }) {
|
|
13214
13524
|
this.id = id;
|
|
13215
13525
|
this.enabled = enabled;
|
|
@@ -13245,17 +13555,33 @@ var Logger = class {
|
|
|
13245
13555
|
//#endregion
|
|
13246
13556
|
//#region src/core/cache-storage.ts
|
|
13247
13557
|
var Cache = class {
|
|
13558
|
+
context;
|
|
13559
|
+
_options;
|
|
13560
|
+
_cache = /* @__PURE__ */ new Map();
|
|
13561
|
+
maxSize;
|
|
13562
|
+
_pendingOperations = /* @__PURE__ */ new Map();
|
|
13563
|
+
/** When true, addImage() collects URLs without starting loads. */
|
|
13564
|
+
_deferMode = false;
|
|
13565
|
+
/** URLs collected during defer mode, pending batch preload. */
|
|
13566
|
+
_collectedUrls = /* @__PURE__ */ new Set();
|
|
13567
|
+
/**
|
|
13568
|
+
* Eviction is suspended between startDefer() and the end of preloadAll():
|
|
13569
|
+
* the render pipeline loads every image it is going to paint inside that
|
|
13570
|
+
* window, and match() never reloads, so an LRU eviction there would
|
|
13571
|
+
* silently drop images from the output on pages with more unique images
|
|
13572
|
+
* than maxSize.
|
|
13573
|
+
*
|
|
13574
|
+
* A counter (not a flag) keeps nested/overlapping defer windows — e.g.
|
|
13575
|
+
* two renders sharing one cache via `config.cache` — suspended until the
|
|
13576
|
+
* last one finishes preloading.
|
|
13577
|
+
*/
|
|
13578
|
+
_evictionSuspendCount = 0;
|
|
13248
13579
|
get _evictionEnabled() {
|
|
13249
13580
|
return this._evictionSuspendCount === 0;
|
|
13250
13581
|
}
|
|
13251
13582
|
constructor(context, _options) {
|
|
13252
13583
|
this.context = context;
|
|
13253
13584
|
this._options = _options;
|
|
13254
|
-
this._cache = /* @__PURE__ */ new Map();
|
|
13255
|
-
this._pendingOperations = /* @__PURE__ */ new Map();
|
|
13256
|
-
this._deferMode = false;
|
|
13257
|
-
this._collectedUrls = /* @__PURE__ */ new Set();
|
|
13258
|
-
this._evictionSuspendCount = 0;
|
|
13259
13585
|
this.maxSize = _options.maxCacheSize ?? 100;
|
|
13260
13586
|
if (this.maxSize < 1) throw new Error("Cache maxSize must be at least 1");
|
|
13261
13587
|
if (this.maxSize > 1e4) this.context.logger.warn(`Cache maxSize ${this.maxSize} is very large and may cause memory issues. Consider using a smaller value (recommended: 100-1000).`);
|
|
@@ -13273,14 +13599,18 @@ var Cache = class {
|
|
|
13273
13599
|
* an optional concurrency cap to avoid overwhelming the browser's network
|
|
13274
13600
|
* stack (default: 10 concurrent loads).
|
|
13275
13601
|
* After this call returns, all images are either loaded (cache hit) or
|
|
13276
|
-
* failed (logged). Subsequent cache.match()
|
|
13602
|
+
* failed (logged and reported via onError). Subsequent cache.match()
|
|
13603
|
+
* calls return immediately.
|
|
13277
13604
|
*
|
|
13278
13605
|
* @param concurrency - Max concurrent image loads (1–100, default 10).
|
|
13279
13606
|
* @param onProgress - Invoked once before loading and after each settled
|
|
13280
13607
|
* batch with (settledCount, totalCount), enabling coarse progress UI.
|
|
13281
13608
|
* Not invoked when there is nothing to load.
|
|
13609
|
+
* @param signal - Checked before each batch; aborting rejects the whole
|
|
13610
|
+
* preload with an AbortError instead of waiting for the remaining
|
|
13611
|
+
* batches to finish.
|
|
13282
13612
|
*/
|
|
13283
|
-
async preloadAll(concurrency = 10, onProgress) {
|
|
13613
|
+
async preloadAll(concurrency = 10, onProgress, signal) {
|
|
13284
13614
|
this._deferMode = false;
|
|
13285
13615
|
const urls = Array.from(this._collectedUrls);
|
|
13286
13616
|
this._collectedUrls.clear();
|
|
@@ -13289,11 +13619,19 @@ var Cache = class {
|
|
|
13289
13619
|
const limit = Math.max(1, Math.min(concurrency, 100));
|
|
13290
13620
|
this.context.logger.debug(`Preloading ${urls.length} image(s) with concurrency ${limit}`);
|
|
13291
13621
|
let settled = 0;
|
|
13622
|
+
const abortPromise = signal ? new Promise((_, reject) => {
|
|
13623
|
+
const onAbort = () => reject(new DOMException("The operation was aborted.", "AbortError"));
|
|
13624
|
+
if (signal.aborted) onAbort();
|
|
13625
|
+
else signal.addEventListener("abort", onAbort, { once: true });
|
|
13626
|
+
}) : null;
|
|
13627
|
+
abortPromise?.catch(() => void 0);
|
|
13292
13628
|
onProgress?.(0, urls.length);
|
|
13293
13629
|
for (let i = 0; i < urls.length; i += limit) {
|
|
13630
|
+
throwIfAborted(signal);
|
|
13294
13631
|
const batch = urls.slice(i, i + limit);
|
|
13295
|
-
|
|
13296
|
-
|
|
13632
|
+
batch.map((url) => this._addImageWithPending(url));
|
|
13633
|
+
const batchSettled = Promise.allSettled(batch.map((url) => this._cache.get(url)?.value ?? Promise.resolve()));
|
|
13634
|
+
await (abortPromise ? Promise.race([batchSettled, abortPromise]) : batchSettled);
|
|
13297
13635
|
settled += batch.length;
|
|
13298
13636
|
onProgress?.(settled, urls.length);
|
|
13299
13637
|
}
|
|
@@ -13336,7 +13674,10 @@ var Cache = class {
|
|
|
13336
13674
|
const timeoutMs = this._options.imageTimeout ?? 15e3;
|
|
13337
13675
|
const imageWithTimeout = this.withTimeout(this.loadImage(src), timeoutMs, `Timed out (${timeoutMs}ms) loading image`);
|
|
13338
13676
|
imageWithTimeout.catch((error) => {
|
|
13339
|
-
|
|
13677
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
13678
|
+
const message = `Failed to load image ${src.substring(0, 256)}: ${reason}`;
|
|
13679
|
+
this.context.logger.error(message);
|
|
13680
|
+
this.context.onError?.(new Error(message));
|
|
13340
13681
|
});
|
|
13341
13682
|
this.set(src, imageWithTimeout);
|
|
13342
13683
|
}
|
|
@@ -13398,18 +13739,22 @@ var Cache = class {
|
|
|
13398
13739
|
const isSameOrigin = typeof this._options.customIsSameOrigin === "function" ? await this._options.customIsSameOrigin(key, defaultIsSameOrigin) : defaultIsSameOrigin(key);
|
|
13399
13740
|
const canAttemptCors = !isSameOrigin && this._options.allowTaint === false && !isInlineImage(key) && !isBlobImage(key) && typeof this._options.proxy !== "string";
|
|
13400
13741
|
const useCORS = !isInlineImage(key) && (this._options.useCORS === true || canAttemptCors) && FEATURES.SUPPORT_CORS_IMAGES && !isSameOrigin;
|
|
13401
|
-
const useProxy = !isInlineImage(key) && !isSameOrigin && !isBlobImage(key) && typeof this._options.proxy === "string" &&
|
|
13742
|
+
const useProxy = !isInlineImage(key) && !isSameOrigin && !isBlobImage(key) && typeof this._options.proxy === "string" && !useCORS;
|
|
13402
13743
|
if (!isSameOrigin && this._options.allowTaint === false && !isInlineImage(key) && !isBlobImage(key) && !useProxy && !useCORS) return;
|
|
13403
13744
|
let src = key;
|
|
13404
13745
|
if (useProxy) src = await this.proxy(src);
|
|
13405
13746
|
this.context.logger.debug(`Added image ${key.substring(0, 256)}`);
|
|
13747
|
+
const imageConstructor = this.context.config.window.Image ?? Image;
|
|
13406
13748
|
return await new Promise((resolve, reject) => {
|
|
13407
|
-
const img = new
|
|
13749
|
+
const img = new imageConstructor();
|
|
13408
13750
|
img.onload = () => resolve(img);
|
|
13409
13751
|
img.onerror = reject;
|
|
13410
13752
|
if (isInlineBase64Image(src) || useCORS) img.crossOrigin = "anonymous";
|
|
13411
13753
|
img.src = src;
|
|
13412
|
-
if (img.complete === true)
|
|
13754
|
+
if (img.complete === true) {
|
|
13755
|
+
if (typeof img.decode === "function") img.decode().then(() => resolve(img), () => reject(/* @__PURE__ */ new Error(`Failed to decode image ${src.substring(0, 256)}`)));
|
|
13756
|
+
else setTimeout(() => resolve(img), 500);
|
|
13757
|
+
}
|
|
13413
13758
|
});
|
|
13414
13759
|
}
|
|
13415
13760
|
has(key) {
|
|
@@ -13423,23 +13768,19 @@ var Cache = class {
|
|
|
13423
13768
|
if (!proxy) throw new Error("No proxy defined");
|
|
13424
13769
|
const key = src.substring(0, 256);
|
|
13425
13770
|
return new Promise((resolve, reject) => {
|
|
13426
|
-
const responseType = FEATURES.SUPPORT_RESPONSE_TYPE ? "blob" : "text";
|
|
13427
13771
|
const xhr = new XMLHttpRequest();
|
|
13428
13772
|
xhr.onload = () => {
|
|
13429
13773
|
if (xhr.status === 200) {
|
|
13430
|
-
|
|
13431
|
-
|
|
13432
|
-
|
|
13433
|
-
|
|
13434
|
-
reader.addEventListener("error", (e) => reject(e), false);
|
|
13435
|
-
reader.readAsDataURL(xhr.response);
|
|
13436
|
-
}
|
|
13774
|
+
const reader = new FileReader();
|
|
13775
|
+
reader.addEventListener("load", () => resolve(reader.result), false);
|
|
13776
|
+
reader.addEventListener("error", (e) => reject(e), false);
|
|
13777
|
+
reader.readAsDataURL(xhr.response);
|
|
13437
13778
|
} else reject(`Failed to proxy resource ${key} with status code ${xhr.status}`);
|
|
13438
13779
|
};
|
|
13439
13780
|
xhr.onerror = reject;
|
|
13440
13781
|
const queryString = proxy.indexOf("?") > -1 ? "&" : "?";
|
|
13441
|
-
xhr.open("GET", `${proxy}${queryString}url=${encodeURIComponent(src)}&responseType
|
|
13442
|
-
|
|
13782
|
+
xhr.open("GET", `${proxy}${queryString}url=${encodeURIComponent(src)}&responseType=blob`);
|
|
13783
|
+
xhr.responseType = "blob";
|
|
13443
13784
|
if (this._options.imageTimeout) {
|
|
13444
13785
|
const timeout = this._options.imageTimeout;
|
|
13445
13786
|
xhr.timeout = timeout;
|
|
@@ -13463,27 +13804,34 @@ const isSVG = (src) => src.slice(-3).toLowerCase() === "svg" || INLINE_SVG.test(
|
|
|
13463
13804
|
* Origin Checker
|
|
13464
13805
|
*
|
|
13465
13806
|
* Provides origin checking functionality without global static state.
|
|
13466
|
-
* Each instance maintains its own
|
|
13807
|
+
* Each instance maintains its own base URI and origin reference.
|
|
13467
13808
|
*
|
|
13468
13809
|
* Replaces the static methods in CacheStorage with instance-based approach.
|
|
13469
13810
|
*/
|
|
13470
13811
|
var OriginChecker = class {
|
|
13812
|
+
baseUri;
|
|
13813
|
+
origin;
|
|
13471
13814
|
constructor(window) {
|
|
13472
13815
|
if (!window || !window.document) throw new Error("Valid window object required for OriginChecker");
|
|
13473
13816
|
if (!window.location || !window.location.href) throw new Error("Window object must have valid location");
|
|
13474
|
-
this.
|
|
13817
|
+
this.baseUri = window.location.href;
|
|
13475
13818
|
this.origin = this.getOrigin(window.location.href);
|
|
13476
13819
|
}
|
|
13477
13820
|
/**
|
|
13478
13821
|
* Get the origin (protocol + hostname + port) of a URL
|
|
13479
13822
|
*
|
|
13480
|
-
* @param url - URL to parse
|
|
13481
|
-
*
|
|
13823
|
+
* @param url - URL to parse; relative URLs resolve against the context
|
|
13824
|
+
* window's location, as the anchor element used to
|
|
13825
|
+
* @returns Origin string (e.g. "https://example.com:8080"), or an empty
|
|
13826
|
+
* string for unparseable URLs — which never matches and is
|
|
13827
|
+
* therefore treated as cross-origin
|
|
13482
13828
|
*/
|
|
13483
13829
|
getOrigin(url) {
|
|
13484
|
-
|
|
13485
|
-
|
|
13486
|
-
|
|
13830
|
+
try {
|
|
13831
|
+
return new URL(url, this.baseUri).origin;
|
|
13832
|
+
} catch (e) {
|
|
13833
|
+
return "";
|
|
13834
|
+
}
|
|
13487
13835
|
}
|
|
13488
13836
|
/**
|
|
13489
13837
|
* Check if a URL is from the same origin as the context
|
|
@@ -13506,11 +13854,15 @@ var OriginChecker = class {
|
|
|
13506
13854
|
//#endregion
|
|
13507
13855
|
//#region src/core/context.ts
|
|
13508
13856
|
var Context = class Context {
|
|
13509
|
-
static
|
|
13510
|
-
|
|
13511
|
-
|
|
13857
|
+
static instanceCount = 1;
|
|
13858
|
+
instanceName = `#${Context.instanceCount++}`;
|
|
13859
|
+
logger;
|
|
13860
|
+
cache;
|
|
13861
|
+
originChecker;
|
|
13862
|
+
config;
|
|
13863
|
+
onError;
|
|
13864
|
+
_windowBounds;
|
|
13512
13865
|
constructor(options, windowBounds, config) {
|
|
13513
|
-
this.instanceName = `#${Context.instanceCount++}`;
|
|
13514
13866
|
this.config = config;
|
|
13515
13867
|
this.logger = new Logger({
|
|
13516
13868
|
id: this.instanceName,
|
|
@@ -13526,6 +13878,18 @@ var Context = class Context {
|
|
|
13526
13878
|
return this._windowBounds;
|
|
13527
13879
|
}
|
|
13528
13880
|
/**
|
|
13881
|
+
* Document used to allocate offscreen resources (offscreen canvases,
|
|
13882
|
+
* images, measurement elements). Prefers the configured window's document
|
|
13883
|
+
* so resources live in the captured realm; falls back to the global
|
|
13884
|
+
* document, which keeps mock environments without a window document
|
|
13885
|
+
* working.
|
|
13886
|
+
*/
|
|
13887
|
+
get resourceDocument() {
|
|
13888
|
+
const windowDocument = this.config.window.document;
|
|
13889
|
+
if (windowDocument) return windowDocument;
|
|
13890
|
+
return typeof document !== "undefined" ? document : void 0;
|
|
13891
|
+
}
|
|
13892
|
+
/**
|
|
13529
13893
|
* Compensate window bounds for a page scroll that the browser performed
|
|
13530
13894
|
* underneath us. Used by the document cloner: WebKit's scroll anchoring can
|
|
13531
13895
|
* scroll the cloned iframe after `onclone`, and the offset must be applied
|
|
@@ -13597,7 +13961,8 @@ const assembleCloneOptions = (opts, config, foreignObjectRendering) => ({
|
|
|
13597
13961
|
iframeContainer: opts.iframeContainer,
|
|
13598
13962
|
inlineImages: foreignObjectRendering,
|
|
13599
13963
|
copyStyles: foreignObjectRendering,
|
|
13600
|
-
cspNonce: opts.cspNonce ?? config.cspNonce
|
|
13964
|
+
cspNonce: opts.cspNonce ?? config.cspNonce,
|
|
13965
|
+
signal: opts.signal
|
|
13601
13966
|
});
|
|
13602
13967
|
/** Assemble canvas rendering options. */
|
|
13603
13968
|
const assembleRenderOptions = (opts, backgroundColor, left, top, width, height, devicePixelRatio) => ({
|
|
@@ -13703,13 +14068,13 @@ const renderElement = async (element, opts, config) => {
|
|
|
13703
14068
|
perfMonitor.start("parse");
|
|
13704
14069
|
throwIfAborted(signal);
|
|
13705
14070
|
context.cache.startDefer();
|
|
13706
|
-
root = parseTree(context, clonedElement);
|
|
14071
|
+
root = parseTree(context, clonedElement, { normalizeDom: opts.normalizeDom });
|
|
13707
14072
|
perfMonitor.end("parse");
|
|
13708
14073
|
emitProgress(opts.onProgress, context, "parse", 50);
|
|
13709
14074
|
perfMonitor.start("preload");
|
|
13710
14075
|
await context.cache.preloadAll(10, (loaded, total) => {
|
|
13711
14076
|
emitProgress(opts.onProgress, context, "preload", 50 + Math.round(loaded / total * 10));
|
|
13712
|
-
});
|
|
14077
|
+
}, signal);
|
|
13713
14078
|
perfMonitor.end("preload");
|
|
13714
14079
|
emitProgress(opts.onProgress, context, "layout", 60);
|
|
13715
14080
|
if (backgroundColor === root.styles.backgroundColor) root.styles.backgroundColor = 0;
|