@zumer/snapdom 1.9.12-dev.0 → 1.9.12-dev.1

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/dist/snapdom.js CHANGED
@@ -1,7 +1,7 @@
1
1
 
2
2
  /*
3
3
  * snapdom
4
- * v.1.9.12-dev.0
4
+ * v.1.9.12-dev.1
5
5
  * Author Juan Martin Muda
6
6
  * License MIT
7
7
  **/
@@ -673,7 +673,10 @@
673
673
  }
674
674
  }
675
675
  function isSafari() {
676
- return /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
676
+ const ua = typeof navigator !== "undefined" && navigator.userAgent ? navigator.userAgent : "";
677
+ const isSafariUA = /^((?!chrome|android).)*safari/i.test(ua);
678
+ const isWeChatUA = /(MicroMessenger|wxwork|WeCom|WindowsWechat|MacWechat)/i.test(ua);
679
+ return isSafariUA || isWeChatUA;
677
680
  }
678
681
 
679
682
  // src/modules/styles.js
@@ -708,7 +711,7 @@
708
711
  } catch (e) {
709
712
  }
710
713
  }
711
- function snapshotComputedStyleFull(style) {
714
+ function snapshotComputedStyleFull(style, options = {}) {
712
715
  const out = {};
713
716
  const vis = style.getPropertyValue("visibility");
714
717
  for (let i = 0; i < style.length; i++) {
@@ -719,6 +722,24 @@
719
722
  }
720
723
  out[prop] = val;
721
724
  }
725
+ if (options.embedFonts) {
726
+ const EXTRA_FONT_PROPS = [
727
+ "font-feature-settings",
728
+ "font-variation-settings",
729
+ "font-kerning",
730
+ "font-variant",
731
+ "font-variant-ligatures",
732
+ "font-optical-sizing"
733
+ ];
734
+ for (const prop of EXTRA_FONT_PROPS) {
735
+ if (out[prop]) continue;
736
+ try {
737
+ const v = style.getPropertyValue(prop);
738
+ if (v) out[prop] = v;
739
+ } catch (e) {
740
+ }
741
+ }
742
+ }
722
743
  if (vis === "hidden") out.opacity = "0";
723
744
  return out;
724
745
  }
@@ -731,11 +752,11 @@
731
752
  __snapshotSig.set(snap, sig);
732
753
  return sig;
733
754
  }
734
- function getSnapshot(el, preStyle = null) {
755
+ function getSnapshot(el, preStyle = null, options = {}) {
735
756
  const rec = snapshotCache.get(el);
736
757
  if (rec && rec.epoch === __epoch) return rec.snapshot;
737
758
  const style = preStyle || getComputedStyle(el);
738
- const snap = snapshotComputedStyleFull(style);
759
+ const snap = snapshotComputedStyleFull(style, options);
739
760
  snapshotCache.set(el, { epoch: __epoch, snapshot: snap });
740
761
  return snap;
741
762
  }
@@ -791,7 +812,7 @@
791
812
  session.styleCache.set(source, getComputedStyle(source));
792
813
  }
793
814
  const pre = session.styleCache.get(source);
794
- const snap = getSnapshot(source, pre);
815
+ const snap = getSnapshot(source, pre, ctx.options);
795
816
  const sig = styleSignature(snap);
796
817
  let key = persist.snapshotKeyCache.get(sig);
797
818
  if (!key) {
@@ -1043,7 +1064,7 @@
1043
1064
  return node.cloneNode(true);
1044
1065
  }
1045
1066
  if (node.getAttribute("data-capture") === "exclude") {
1046
- if (options.excludeMode === "visuallyHide") {
1067
+ if (options.excludeMode === "hide") {
1047
1068
  const spacer = document.createElement("div");
1048
1069
  const rect = node.getBoundingClientRect();
1049
1070
  spacer.style.cssText = `display:inline-block;width:${rect.width}px;height:${rect.height}px;visibility:hidden;`;
@@ -1056,7 +1077,7 @@
1056
1077
  for (const selector of options.exclude) {
1057
1078
  try {
1058
1079
  if ((_a = node.matches) == null ? void 0 : _a.call(node, selector)) {
1059
- if (options.excludeMode === "visuallyHide") {
1080
+ if (options.excludeMode === "hide") {
1060
1081
  const spacer = document.createElement("div");
1061
1082
  const rect = node.getBoundingClientRect();
1062
1083
  spacer.style.cssText = `display:inline-block;width:${rect.width}px;height:${rect.height}px;visibility:hidden;`;
@@ -1073,7 +1094,7 @@
1073
1094
  if (typeof options.filter === "function") {
1074
1095
  try {
1075
1096
  if (!options.filter(node)) {
1076
- if (options.filterMode === "visuallyHide") {
1097
+ if (options.filterMode === "hide") {
1077
1098
  const spacer = document.createElement("div");
1078
1099
  const rect = node.getBoundingClientRect();
1079
1100
  spacer.style.cssText = `display:inline-block;width:${rect.width}px;height:${rect.height}px;visibility:hidden;`;
@@ -1969,7 +1990,186 @@
1969
1990
  });
1970
1991
  }
1971
1992
 
1993
+ // src/modules/counter.js
1994
+ function hasCounters(input) {
1995
+ return /\bcounter\s*\(|\bcounters\s*\(/.test(input || "");
1996
+ }
1997
+ function unquoteDoubleStrings(s) {
1998
+ return (s || "").replace(/"([^"]*)"/g, "$1");
1999
+ }
2000
+ function alpha(n, upper = false) {
2001
+ let s = "", x = Math.max(1, n);
2002
+ while (x > 0) {
2003
+ x--;
2004
+ s = String.fromCharCode(97 + x % 26) + s;
2005
+ x = Math.floor(x / 26);
2006
+ }
2007
+ return upper ? s.toUpperCase() : s;
2008
+ }
2009
+ function roman(n, upper = true) {
2010
+ const map = [[1e3, "M"], [900, "CM"], [500, "D"], [400, "CD"], [100, "C"], [90, "XC"], [50, "L"], [40, "XL"], [10, "X"], [9, "IX"], [5, "V"], [4, "IV"], [1, "I"]];
2011
+ let num = Math.max(1, Math.min(3999, n)), out = "";
2012
+ for (const [v, sym] of map) while (num >= v) {
2013
+ out += sym;
2014
+ num -= v;
2015
+ }
2016
+ return upper ? out : out.toLowerCase();
2017
+ }
2018
+ function formatCounter(value, style) {
2019
+ switch ((style || "decimal").toLowerCase()) {
2020
+ case "decimal":
2021
+ return String(Math.max(0, value));
2022
+ case "decimal-leading-zero":
2023
+ return (value < 10 ? "0" : "") + String(Math.max(0, value));
2024
+ case "lower-alpha":
2025
+ return alpha(value, false);
2026
+ case "upper-alpha":
2027
+ return alpha(value, true);
2028
+ case "lower-roman":
2029
+ return roman(value, false);
2030
+ case "upper-roman":
2031
+ return roman(value, true);
2032
+ default:
2033
+ return String(Math.max(0, value));
2034
+ }
2035
+ }
2036
+ function buildCounterContext(root) {
2037
+ const nodeCounters = /* @__PURE__ */ new WeakMap();
2038
+ const rootEl = root instanceof Document ? root.documentElement : root;
2039
+ const isLi = (el) => el && el.tagName === "LI";
2040
+ const countPrevLi = (li) => {
2041
+ let c = 0, p = li == null ? void 0 : li.parentElement;
2042
+ if (!p) return 0;
2043
+ for (const sib of p.children) {
2044
+ if (sib === li) break;
2045
+ if (sib.tagName === "LI") c++;
2046
+ }
2047
+ return c;
2048
+ };
2049
+ const cloneMap = (m) => {
2050
+ const out = /* @__PURE__ */ new Map();
2051
+ for (const [k, arr] of m) out.set(k, arr.slice());
2052
+ return out;
2053
+ };
2054
+ const applyTo = (baseMap, parentMap, el) => {
2055
+ var _a, _b;
2056
+ const map = cloneMap(baseMap);
2057
+ let reset;
2058
+ try {
2059
+ reset = ((_a = el.style) == null ? void 0 : _a.counterReset) || getComputedStyle(el).counterReset;
2060
+ } catch (e) {
2061
+ }
2062
+ if (reset && reset !== "none") {
2063
+ for (const part of reset.split(",")) {
2064
+ const toks = part.trim().split(/\s+/);
2065
+ const name = toks[0];
2066
+ const val = Number.isFinite(Number(toks[1])) ? Number(toks[1]) : 0;
2067
+ if (!name) continue;
2068
+ const parentStack = parentMap.get(name);
2069
+ if (parentStack && parentStack.length) {
2070
+ const s = parentStack.slice();
2071
+ s.push(val);
2072
+ map.set(name, s);
2073
+ } else {
2074
+ map.set(name, [val]);
2075
+ }
2076
+ }
2077
+ }
2078
+ let inc;
2079
+ try {
2080
+ inc = ((_b = el.style) == null ? void 0 : _b.counterIncrement) || getComputedStyle(el).counterIncrement;
2081
+ } catch (e) {
2082
+ }
2083
+ if (inc && inc !== "none") {
2084
+ for (const part of inc.split(",")) {
2085
+ const toks = part.trim().split(/\s+/);
2086
+ const name = toks[0];
2087
+ const by = Number.isFinite(Number(toks[1])) ? Number(toks[1]) : 1;
2088
+ if (!name) continue;
2089
+ const stack = map.get(name) || [];
2090
+ if (stack.length === 0) stack.push(0);
2091
+ stack[stack.length - 1] += by;
2092
+ map.set(name, stack);
2093
+ }
2094
+ }
2095
+ try {
2096
+ const cs = getComputedStyle(el);
2097
+ if (cs.display === "list-item" && isLi(el)) {
2098
+ const p = el.parentElement;
2099
+ let idx = 1;
2100
+ if (p && p.tagName === "OL") {
2101
+ const startAttr = p.getAttribute("start");
2102
+ const start = Number.isFinite(Number(startAttr)) ? Number(startAttr) : 1;
2103
+ const prev = countPrevLi(el);
2104
+ const ownAttr = el.getAttribute("value");
2105
+ idx = Number.isFinite(Number(ownAttr)) ? Number(ownAttr) : start + prev;
2106
+ } else {
2107
+ idx = 1 + countPrevLi(el);
2108
+ }
2109
+ const s = map.get("list-item") || [];
2110
+ if (s.length === 0) s.push(0);
2111
+ s[s.length - 1] = idx;
2112
+ map.set("list-item", s);
2113
+ }
2114
+ } catch (e) {
2115
+ }
2116
+ return map;
2117
+ };
2118
+ const build = (el, parentMap, carryMap) => {
2119
+ const curr = applyTo(carryMap, parentMap, el);
2120
+ nodeCounters.set(el, curr);
2121
+ let nextCarry = curr;
2122
+ for (const child of el.children) {
2123
+ const childCarry = build(child, curr, nextCarry);
2124
+ nextCarry = childCarry;
2125
+ }
2126
+ return curr;
2127
+ };
2128
+ const empty = /* @__PURE__ */ new Map();
2129
+ build(rootEl, empty, empty);
2130
+ return {
2131
+ get(node, name) {
2132
+ var _a;
2133
+ const s = (_a = nodeCounters.get(node)) == null ? void 0 : _a.get(name);
2134
+ return s && s.length ? s[s.length - 1] : 0;
2135
+ },
2136
+ getStack(node, name) {
2137
+ var _a;
2138
+ const s = (_a = nodeCounters.get(node)) == null ? void 0 : _a.get(name);
2139
+ return s ? s.slice() : [];
2140
+ }
2141
+ };
2142
+ }
2143
+ function resolveCountersInContent(raw, node, ctx) {
2144
+ if (!raw || raw === "none") return raw;
2145
+ try {
2146
+ const RX = /\b(counter|counters)\s*\(([^)]+)\)/g;
2147
+ let out = raw.replace(RX, (_, fn, args) => {
2148
+ var _a, _b, _c, _d;
2149
+ const parts = String(args).split(",").map((s) => s.trim());
2150
+ if (fn === "counter") {
2151
+ const name = (_a = parts[0]) == null ? void 0 : _a.replace(/^["']|["']$/g, "");
2152
+ const style = (parts[1] || "decimal").toLowerCase();
2153
+ const v = ctx.get(node, name);
2154
+ return formatCounter(v, style);
2155
+ } else {
2156
+ const name = (_b = parts[0]) == null ? void 0 : _b.replace(/^["']|["']$/g, "");
2157
+ const sep = (_d = (_c = parts[1]) == null ? void 0 : _c.replace(/^["']|["']$/g, "")) != null ? _d : "";
2158
+ const style = (parts[2] || "decimal").toLowerCase();
2159
+ const stack = ctx.getStack(node, name);
2160
+ if (!stack.length) return "";
2161
+ const pieces = stack.map((v) => formatCounter(v, style));
2162
+ return pieces.join(sep);
2163
+ }
2164
+ });
2165
+ return unquoteDoubleStrings(out);
2166
+ } catch (e) {
2167
+ return "- ";
2168
+ }
2169
+ }
2170
+
1972
2171
  // src/modules/pseudo.js
2172
+ var counterCtx = null;
1973
2173
  function inlinePseudoElements(source, clone, sessionCache, options) {
1974
2174
  return __async(this, null, function* () {
1975
2175
  var _a;
@@ -2008,7 +2208,11 @@
2008
2208
  continue;
2009
2209
  }
2010
2210
  const content = style.content;
2011
- const cleanContent = /counter\s*\(|counters\s*\(/.test(content) ? "- " : parseContent(content);
2211
+ let cleanContent = parseContent(content);
2212
+ if (hasCounters(content)) {
2213
+ counterCtx = buildCounterContext(source.ownerDocument || document);
2214
+ cleanContent = resolveCountersInContent(cleanContent, source, counterCtx);
2215
+ }
2012
2216
  const bg = style.backgroundImage;
2013
2217
  const bgColor = style.backgroundColor;
2014
2218
  const fontFamily = style.fontFamily;
@@ -2408,8 +2612,8 @@
2408
2612
  if (!img.height) img.height = img.naturalHeight || 100;
2409
2613
  return;
2410
2614
  }
2411
- const { defaultImageUrl } = options || {};
2412
- if (defaultImageUrl) {
2615
+ const { fallbackURL } = options || {};
2616
+ if (fallbackURL) {
2413
2617
  try {
2414
2618
  const dsW = parseInt(((_a = img.dataset) == null ? void 0 : _a.snapdomWidth) || "", 10) || 0;
2415
2619
  const dsH = parseInt(((_b = img.dataset) == null ? void 0 : _b.snapdomHeight) || "", 10) || 0;
@@ -2417,14 +2621,14 @@
2417
2621
  const attrH = parseInt(img.getAttribute("height") || "", 10) || 0;
2418
2622
  const styleW = parseFloat(((_c = img.style) == null ? void 0 : _c.width) || "") || 0;
2419
2623
  const styleH = parseFloat(((_d = img.style) == null ? void 0 : _d.height) || "") || 0;
2420
- const width = dsW || styleW || attrW || img.width || void 0;
2421
- const height = dsH || styleH || attrH || img.height || void 0;
2422
- const fallbackUrl = typeof defaultImageUrl === "function" ? yield defaultImageUrl({ width, height, src, element: img }) : defaultImageUrl;
2624
+ const fbW = dsW || styleW || attrW || img.width || void 0;
2625
+ const fbH = dsH || styleH || attrH || img.height || void 0;
2626
+ const fallbackUrl = typeof fallbackURL === "function" ? yield fallbackURL({ width: fbW, height: fbH, src, element: img }) : fallbackURL;
2423
2627
  if (fallbackUrl) {
2424
2628
  const fallbackData = yield snapFetch(fallbackUrl, { as: "dataURL", useProxy: options.useProxy });
2425
2629
  img.src = fallbackData.data;
2426
- if (!img.width && width) img.width = width;
2427
- if (!img.height && height) img.height = height;
2630
+ if (!img.width && fbW) img.width = fbW;
2631
+ if (!img.height && fbH) img.height = fbH;
2428
2632
  if (!img.width) img.width = img.naturalWidth || 100;
2429
2633
  if (!img.height) img.height = img.naturalHeight || 100;
2430
2634
  return;
@@ -2546,6 +2750,64 @@
2546
2750
  });
2547
2751
  }
2548
2752
 
2753
+ // src/modules/lineClamp.js
2754
+ function lineClamp(el) {
2755
+ var _a;
2756
+ if (!el) return () => {
2757
+ };
2758
+ const lines = getClamp(el);
2759
+ if (lines <= 0) return () => {
2760
+ };
2761
+ if (!isPlainTextContainer(el)) return () => {
2762
+ };
2763
+ const cs = getComputedStyle(el);
2764
+ const targetH = Math.round(usedLineHeightPx(cs) * lines + vpad(cs));
2765
+ const original = (_a = el.textContent) != null ? _a : "";
2766
+ const prevText = original;
2767
+ if (el.scrollHeight <= targetH + 0.5) {
2768
+ return () => {
2769
+ };
2770
+ }
2771
+ let lo = 0, hi = original.length, best = -1;
2772
+ while (lo <= hi) {
2773
+ const mid = lo + hi >> 1;
2774
+ el.textContent = original.slice(0, mid) + "\u2026";
2775
+ if (el.scrollHeight <= targetH + 0.5) {
2776
+ best = mid;
2777
+ lo = mid + 1;
2778
+ } else {
2779
+ hi = mid - 1;
2780
+ }
2781
+ }
2782
+ el.textContent = (best >= 0 ? original.slice(0, best) : "") + "\u2026";
2783
+ return () => {
2784
+ el.textContent = prevText;
2785
+ };
2786
+ }
2787
+ function getClamp(el) {
2788
+ const cs = getComputedStyle(el);
2789
+ let v = cs.getPropertyValue("-webkit-line-clamp") || cs.getPropertyValue("line-clamp");
2790
+ v = (v || "").trim();
2791
+ const n = parseInt(v, 10);
2792
+ return Number.isFinite(n) && n > 0 ? n : 0;
2793
+ }
2794
+ function usedLineHeightPx(cs) {
2795
+ const lh = (cs.lineHeight || "").trim();
2796
+ const fs = parseFloat(cs.fontSize) || 16;
2797
+ if (!lh || lh === "normal") return Math.round(fs * 1.2);
2798
+ if (lh.endsWith("px")) return parseFloat(lh);
2799
+ if (/^\d+(\.\d+)?$/.test(lh)) return Math.round(parseFloat(lh) * fs);
2800
+ if (lh.endsWith("%")) return Math.round(parseFloat(lh) / 100 * fs);
2801
+ return Math.round(fs * 1.2);
2802
+ }
2803
+ function vpad(cs) {
2804
+ return (parseFloat(cs.paddingTop) || 0) + (parseFloat(cs.paddingBottom) || 0);
2805
+ }
2806
+ function isPlainTextContainer(el) {
2807
+ if (el.childElementCount > 0) return false;
2808
+ return Array.from(el.childNodes).some((n) => n.nodeType === Node.TEXT_NODE);
2809
+ }
2810
+
2549
2811
  // src/core/capture.js
2550
2812
  function captureDOM(element, options) {
2551
2813
  return __async(this, null, function* () {
@@ -2557,7 +2819,12 @@
2557
2819
  let baseCSS = "";
2558
2820
  let dataURL;
2559
2821
  let svgString;
2560
- ({ clone, classCSS, styleCache } = yield prepareClone(element, options));
2822
+ const undoClamp = lineClamp(element);
2823
+ try {
2824
+ ({ clone, classCSS, styleCache } = yield prepareClone(element, options));
2825
+ } finally {
2826
+ undoClamp();
2827
+ }
2561
2828
  yield new Promise((resolve) => {
2562
2829
  idle(() => __async(null, null, function* () {
2563
2830
  yield inlineImages(clone, options);
@@ -2608,28 +2875,28 @@
2608
2875
  yield new Promise((resolve) => {
2609
2876
  idle(() => {
2610
2877
  var _a, _b, _c, _d, _e;
2611
- const rect = getNaturalBorderBoxSize(element);
2612
- let w = rect.width;
2613
- let h = rect.height;
2878
+ const rect = element.getBoundingClientRect();
2879
+ let w = Number(rect.width) || 0;
2880
+ let h = Number(rect.height) || 0;
2614
2881
  const hasW = Number.isFinite(options.width);
2615
2882
  const hasH = Number.isFinite(options.height);
2616
2883
  const scaleOpt = (_a = options.scale) != null ? _a : 1;
2617
2884
  const hasScale = typeof scaleOpt === "number" && scaleOpt !== 1;
2618
2885
  if (!hasScale) {
2619
- const aspect = rect.width / rect.height;
2886
+ const aspect = h > 0 ? w / h : 1;
2620
2887
  if (hasW && hasH) {
2621
- w = options.width;
2622
- h = options.height;
2888
+ w = Number(options.width);
2889
+ h = Number(options.height);
2623
2890
  } else if (hasW) {
2624
- w = options.width;
2625
- h = w / aspect;
2891
+ w = Number(options.width);
2892
+ h = w / (aspect || 1);
2626
2893
  } else if (hasH) {
2627
- h = options.height;
2628
- w = h * aspect;
2894
+ h = Number(options.height);
2895
+ w = h * (aspect || 1);
2629
2896
  }
2630
2897
  }
2631
- w = Math.max(1, Math.ceil(w));
2632
- h = Math.max(1, Math.ceil(h));
2898
+ w = Math.max(1, Math.ceil(Number.isFinite(w) ? w : 1));
2899
+ h = Math.max(1, Math.ceil(Number.isFinite(h) ? h : 1));
2633
2900
  const csEl = getComputedStyle(element);
2634
2901
  const baseTransform = csEl.transform && csEl.transform !== "none" ? csEl.transform : "";
2635
2902
  const ind = readIndividualTransforms(element);
@@ -2700,7 +2967,9 @@
2700
2967
  fo.appendChild(container);
2701
2968
  const serializer = new XMLSerializer();
2702
2969
  const foString = serializer.serializeToString(fo);
2703
- const svgHeader = `<svg xmlns="${svgNS}" width="${outW}" height="${outH}" viewBox="0 0 ${outW} ${outH}">`;
2970
+ const finalW = !hasScale && (hasW || hasH) ? w : outW;
2971
+ const finalH = !hasScale && (hasH || hasW) ? h : outH;
2972
+ const svgHeader = `<svg xmlns="${svgNS}" width="${finalW}" height="${finalH}" viewBox="0 0 ${outW} ${outH}">`;
2704
2973
  const svgFooter = "</svg>";
2705
2974
  svgString = svgHeader + foString + svgFooter;
2706
2975
  dataURL = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgString)}`;
@@ -2712,17 +2981,6 @@
2712
2981
  return dataURL;
2713
2982
  });
2714
2983
  }
2715
- function getNaturalBorderBoxSize(el) {
2716
- const cs = getComputedStyle(el);
2717
- const px = (v) => parseFloat(v) || 0;
2718
- let w = px(cs.width);
2719
- let h = px(cs.height);
2720
- if (cs.boxSizing === "content-box") {
2721
- w += px(cs.paddingLeft) + px(cs.paddingRight) + px(cs.borderLeftWidth) + px(cs.borderRightWidth);
2722
- h += px(cs.paddingTop) + px(cs.paddingBottom) + px(cs.borderTopWidth) + px(cs.borderBottomWidth);
2723
- }
2724
- return { width: w, height: h };
2725
- }
2726
2984
  function matrixFromComputed(el) {
2727
2985
  const tr = getComputedStyle(el).transform;
2728
2986
  if (!tr || tr === "none") return new DOMMatrix();
@@ -2753,31 +3011,40 @@
2753
3011
  return { minX, minY, width: maxX - minX, height: maxY - minY };
2754
3012
  }
2755
3013
  function readIndividualTransforms(el) {
2756
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
3014
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
2757
3015
  const out = { rotate: "0deg", scale: null, translate: null };
2758
- const map = (_a = el.computedStyleMap) == null ? void 0 : _a.call(el);
3016
+ const map = typeof el.computedStyleMap === "function" ? el.computedStyleMap() : null;
2759
3017
  if (map) {
2760
- const rot = map.get("rotate");
3018
+ const safeGet = (prop) => {
3019
+ try {
3020
+ if (typeof map.has === "function" && !map.has(prop)) return null;
3021
+ if (typeof map.get !== "function") return null;
3022
+ return map.get(prop);
3023
+ } catch (e) {
3024
+ return null;
3025
+ }
3026
+ };
3027
+ const rot = safeGet("rotate");
2761
3028
  if (rot) {
2762
- const ang = (_b = rot.angle) != null ? _b : rot;
2763
- if (ang && "unit" in ang) {
3029
+ const ang = (_a = rot.angle) != null ? _a : rot;
3030
+ if (ang && typeof ang === "object" && "unit" in ang) {
2764
3031
  out.rotate = ang.unit === "rad" ? ang.value * 180 / Math.PI + "deg" : ang.value + ang.unit;
2765
3032
  } else {
2766
3033
  out.rotate = String(rot);
2767
3034
  }
2768
3035
  }
2769
- const sc = map.get("scale");
3036
+ const sc = safeGet("scale");
2770
3037
  if (sc && sc.length) {
2771
- const sx = (_d = (_c = sc[0]) == null ? void 0 : _c.value) != null ? _d : 1;
2772
- const sy = (_f = (_e = sc[1]) == null ? void 0 : _e.value) != null ? _f : sx;
3038
+ const sx = (_c = (_b = sc[0]) == null ? void 0 : _b.value) != null ? _c : 1;
3039
+ const sy = (_e = (_d = sc[1]) == null ? void 0 : _d.value) != null ? _e : sx;
2773
3040
  out.scale = `${sx} ${sy}`;
2774
3041
  }
2775
- const tr = map.get("translate");
3042
+ const tr = safeGet("translate");
2776
3043
  if (tr && tr.length) {
2777
- const tx = (_h = (_g = tr[0]) == null ? void 0 : _g.value) != null ? _h : 0;
2778
- const ty = (_j = (_i = tr[1]) == null ? void 0 : _i.value) != null ? _j : 0;
2779
- const ux = (_l = (_k = tr[0]) == null ? void 0 : _k.unit) != null ? _l : "px";
2780
- const uy = (_n = (_m = tr[1]) == null ? void 0 : _m.unit) != null ? _n : "px";
3044
+ const tx = (_g = (_f = tr[0]) == null ? void 0 : _f.value) != null ? _g : 0;
3045
+ const ty = (_i = (_h = tr[1]) == null ? void 0 : _h.value) != null ? _i : 0;
3046
+ const ux = (_k = (_j = tr[0]) == null ? void 0 : _j.unit) != null ? _k : "px";
3047
+ const uy = (_m = (_l = tr[1]) == null ? void 0 : _l.unit) != null ? _m : "px";
2781
3048
  out.translate = `${tx}${ux} ${ty}${uy}`;
2782
3049
  }
2783
3050
  return out;
@@ -2858,9 +3125,9 @@
2858
3125
  scale: (_d = options.scale) != null ? _d : 1,
2859
3126
  // DOM filters
2860
3127
  exclude: (_e = options.exclude) != null ? _e : [],
2861
- excludeMode: (_f = options.excludeMode) != null ? _f : "visuallyHide",
3128
+ excludeMode: (_f = options.excludeMode) != null ? _f : "hide",
2862
3129
  filter: (_g = options.filter) != null ? _g : null,
2863
- filterMode: (_h = options.filterMode) != null ? _h : "visuallyHide",
3130
+ filterMode: (_h = options.filterMode) != null ? _h : "hide",
2864
3131
  placeholders: options.placeholders !== false,
2865
3132
  // default true
2866
3133
  // Fuentes
@@ -2868,7 +3135,7 @@
2868
3135
  iconFonts: Array.isArray(options.iconFonts) ? options.iconFonts : options.iconFonts ? [options.iconFonts] : [],
2869
3136
  localFonts: Array.isArray(options.localFonts) ? options.localFonts : [],
2870
3137
  excludeFonts: (_j = options.excludeFonts) != null ? _j : void 0,
2871
- defaultImageUrl: (_k = options.defaultImageUrl) != null ? _k : void 0,
3138
+ fallbackURL: (_k = options.fallbackURL) != null ? _k : void 0,
2872
3139
  /** Cache policy (disabled|full|auto|soft). Default: "soft" */
2873
3140
  /** @type {CachePolicy} */
2874
3141
  cache: cachePolicy,
@@ -2963,6 +3230,7 @@
2963
3230
  // src/exporters/download.js
2964
3231
  function download(url, options) {
2965
3232
  return __async(this, null, function* () {
3233
+ options.dpr = 1;
2966
3234
  if (options.format === "svg") {
2967
3235
  const blob = yield toBlob(url, __spreadProps(__spreadValues({}, options), { type: "svg" }));
2968
3236
  const objectURL = URL.createObjectURL(blob);