@zumer/snapdom 1.9.14 → 2.0.0-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.14
4
+ * v.2.0.0-dev.1
5
5
  * Author Juan Martin Muda
6
6
  * License MIT
7
7
  **/
@@ -13,6 +13,7 @@
13
13
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
14
14
  var __hasOwnProp = Object.prototype.hasOwnProperty;
15
15
  var __propIsEnum = Object.prototype.propertyIsEnumerable;
16
+ var __pow = Math.pow;
16
17
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
17
18
  var __spreadValues = (a, b) => {
18
19
  for (var prop in b || (b = {}))
@@ -63,6 +64,7 @@
63
64
  }
64
65
  };
65
66
  function applyCachePolicy(policy = "soft") {
67
+ cache.session.__counterEpoch = (cache.session.__counterEpoch || 0) + 1;
66
68
  switch (policy) {
67
69
  case "auto": {
68
70
  cache.session.styleMap = /* @__PURE__ */ new Map();
@@ -859,6 +861,27 @@
859
861
  }
860
862
 
861
863
  // src/modules/CSSVar.js
864
+ var KEY_PROPS = ["fill", "stroke", "color", "background-color", "stop-color"];
865
+ var __BASELINE_CACHE = /* @__PURE__ */ new Map();
866
+ function getBaselineComputed(tagName, ns) {
867
+ const key = ns + "::" + tagName.toLowerCase();
868
+ let entry = __BASELINE_CACHE.get(key);
869
+ if (entry) return entry;
870
+ const doc = document;
871
+ const el = ns === "http://www.w3.org/2000/svg" ? doc.createElementNS(ns, tagName) : doc.createElement(tagName);
872
+ const holder = doc.createElement("div");
873
+ holder.style.cssText = "position:absolute;left:-99999px;top:-99999px;contain:strict;display:block;";
874
+ holder.appendChild(el);
875
+ doc.documentElement.appendChild(holder);
876
+ const cs = getComputedStyle(el);
877
+ const base = {};
878
+ for (const p of KEY_PROPS) {
879
+ base[p] = cs.getPropertyValue(p) || "";
880
+ }
881
+ holder.remove();
882
+ __BASELINE_CACHE.set(key, base);
883
+ return base;
884
+ }
862
885
  function resolveCSSVars(sourceEl, cloneEl) {
863
886
  var _a, _b, _c;
864
887
  if (!(sourceEl instanceof Element) || !(cloneEl instanceof Element)) return;
@@ -874,42 +897,62 @@
874
897
  }
875
898
  }
876
899
  }
877
- if (!hasVar) return;
878
- let cs;
879
- try {
880
- cs = getComputedStyle(sourceEl);
881
- } catch (e) {
882
- return;
900
+ let cs = null;
901
+ if (hasVar) {
902
+ try {
903
+ cs = getComputedStyle(sourceEl);
904
+ } catch (e) {
905
+ }
883
906
  }
884
- const author = sourceEl.style;
885
- if (author && author.length) {
886
- for (let i = 0; i < author.length; i++) {
887
- const prop = author[i];
888
- const val = author.getPropertyValue(prop);
889
- if (!val || !val.includes("var(")) continue;
890
- const resolved = cs.getPropertyValue(prop);
891
- if (resolved) {
892
- try {
893
- cloneEl.style.setProperty(prop, resolved.trim(), author.getPropertyPriority(prop));
894
- } catch (e) {
907
+ if (hasVar) {
908
+ const author = sourceEl.style;
909
+ if (author && author.length) {
910
+ for (let i = 0; i < author.length; i++) {
911
+ const prop = author[i];
912
+ const val = author.getPropertyValue(prop);
913
+ if (!val || !val.includes("var(")) continue;
914
+ const resolved = cs && cs.getPropertyValue(prop);
915
+ if (resolved) {
916
+ try {
917
+ cloneEl.style.setProperty(prop, resolved.trim(), author.getPropertyPriority(prop));
918
+ } catch (e) {
919
+ }
895
920
  }
896
921
  }
897
922
  }
898
923
  }
899
- if ((_c = sourceEl.attributes) == null ? void 0 : _c.length) {
924
+ if (hasVar && ((_c = sourceEl.attributes) == null ? void 0 : _c.length)) {
900
925
  const attrs = sourceEl.attributes;
901
926
  for (let i = 0; i < attrs.length; i++) {
902
927
  const a = attrs[i];
903
928
  if (!a || typeof a.value !== "string" || !a.value.includes("var(")) continue;
904
929
  const propName = a.name;
905
- let resolved = "";
930
+ const resolved = cs && cs.getPropertyValue(propName);
931
+ if (resolved) {
932
+ try {
933
+ cloneEl.style.setProperty(propName, resolved.trim());
934
+ } catch (e) {
935
+ }
936
+ }
937
+ }
938
+ }
939
+ if (!hasVar) {
940
+ if (!cs) {
906
941
  try {
907
- resolved = cs.getPropertyValue(propName);
942
+ cs = getComputedStyle(sourceEl);
908
943
  } catch (e) {
944
+ cs = null;
909
945
  }
910
- if (resolved) {
946
+ }
947
+ if (!cs) return;
948
+ const ns = sourceEl.namespaceURI || "html";
949
+ const base = getBaselineComputed(sourceEl.tagName, ns);
950
+ for (const prop of KEY_PROPS) {
951
+ const v = cs.getPropertyValue(prop) || "";
952
+ const b = base[prop] || "";
953
+ if (v && v !== b) {
911
954
  try {
912
- cloneEl.style.setProperty(propName, resolved.trim());
955
+ cloneEl.style.setProperty(prop, v.trim());
913
956
  } catch (e) {
914
957
  }
915
958
  }
@@ -1239,11 +1282,50 @@
1239
1282
  return clone2;
1240
1283
  }
1241
1284
  if (node.tagName === "CANVAS") {
1242
- const dataURL = node.toDataURL();
1285
+ let url = "";
1286
+ try {
1287
+ const ctx = node.getContext("2d", { willReadFrequently: true });
1288
+ try {
1289
+ ctx && ctx.getImageData(0, 0, 1, 1);
1290
+ } catch (e) {
1291
+ }
1292
+ yield new Promise((r) => requestAnimationFrame(r));
1293
+ url = node.toDataURL("image/png");
1294
+ if (!url || url === "data:,") {
1295
+ try {
1296
+ ctx && ctx.getImageData(0, 0, 1, 1);
1297
+ } catch (e) {
1298
+ }
1299
+ yield new Promise((r) => requestAnimationFrame(r));
1300
+ url = node.toDataURL("image/png");
1301
+ if (!url || url === "data:,") {
1302
+ const scratch = document.createElement("canvas");
1303
+ scratch.width = node.width;
1304
+ scratch.height = node.height;
1305
+ const sctx = scratch.getContext("2d");
1306
+ if (sctx) {
1307
+ sctx.drawImage(node, 0, 0);
1308
+ url = scratch.toDataURL("image/png");
1309
+ }
1310
+ }
1311
+ }
1312
+ } catch (e) {
1313
+ }
1243
1314
  const img = document.createElement("img");
1244
- img.src = dataURL;
1315
+ try {
1316
+ img.decoding = "sync";
1317
+ img.loading = "eager";
1318
+ } catch (e) {
1319
+ }
1320
+ if (url) img.src = url;
1245
1321
  img.width = node.width;
1246
1322
  img.height = node.height;
1323
+ try {
1324
+ const cs = getComputedStyle(node);
1325
+ if (cs.width) img.style.width = cs.width;
1326
+ if (cs.height) img.style.height = cs.height;
1327
+ } catch (e) {
1328
+ }
1247
1329
  sessionCache.nodeMap.set(img, node);
1248
1330
  inlineAllStyles(node, img, sessionCache, options);
1249
1331
  return img;
@@ -1422,6 +1504,130 @@
1422
1504
  if (/icon/i.test(text) || /glyph/i.test(text) || /symbols/i.test(text) || /feather/i.test(text) || /fontawesome/i.test(text)) return true;
1423
1505
  return false;
1424
1506
  }
1507
+ function isMaterialFamily(family = "") {
1508
+ const s = String(family).toLowerCase();
1509
+ return /\bmaterial\s*icons\b/.test(s) || /\bmaterial\s*symbols\b/.test(s);
1510
+ }
1511
+ function ensureMaterialFontsReady(family = "Material Icons", px = 24) {
1512
+ return __async(this, null, function* () {
1513
+ try {
1514
+ yield Promise.all([
1515
+ document.fonts.load(`400 ${px}px "${family.replace(/["']/g, "")}"`),
1516
+ document.fonts.ready
1517
+ ]);
1518
+ } catch (e) {
1519
+ }
1520
+ });
1521
+ }
1522
+ function resolvePaintColor(cs) {
1523
+ var _a, _b;
1524
+ let fill = ((_a = cs.getPropertyValue("-webkit-text-fill-color")) == null ? void 0 : _a.trim()) || "";
1525
+ const isTransparent = /rgba?\(\s*0\s*,\s*0\s*,\s*0\s*,\s*0\s*\)/i.test(fill);
1526
+ if (fill && !isTransparent && fill.toLowerCase() !== "currentcolor") {
1527
+ return fill;
1528
+ }
1529
+ const c = (_b = cs.color) == null ? void 0 : _b.trim();
1530
+ return c && c !== "inherit" ? c : "#000";
1531
+ }
1532
+ function materialIconToImage(_0) {
1533
+ return __async(this, arguments, function* (ligatureText, {
1534
+ family = "Material Icons",
1535
+ weight = "normal",
1536
+ fontSize = 32,
1537
+ color = "#000",
1538
+ variation = ""
1539
+ } = {}) {
1540
+ const fam = String(family || "").replace(/^['"]+|['"]+$/g, "");
1541
+ const dpr = window.devicePixelRatio || 1;
1542
+ yield ensureMaterialFontsReady(fam, fontSize);
1543
+ const span = document.createElement("span");
1544
+ span.textContent = ligatureText;
1545
+ span.style.position = "absolute";
1546
+ span.style.visibility = "hidden";
1547
+ span.style.left = "-99999px";
1548
+ span.style.whiteSpace = "nowrap";
1549
+ span.style.fontFamily = `"${fam}"`;
1550
+ span.style.fontWeight = String(weight || "normal");
1551
+ span.style.fontSize = `${fontSize}px`;
1552
+ span.style.lineHeight = "1";
1553
+ span.style.margin = "0";
1554
+ span.style.padding = "0";
1555
+ span.style.fontFeatureSettings = "'liga' 1";
1556
+ span.style.fontVariantLigatures = "normal";
1557
+ if (variation) span.style.fontVariationSettings = variation;
1558
+ span.style.color = color;
1559
+ document.body.appendChild(span);
1560
+ const rect = span.getBoundingClientRect();
1561
+ const width = Math.max(1, Math.ceil(rect.width));
1562
+ const height = Math.max(1, Math.ceil(rect.height));
1563
+ document.body.removeChild(span);
1564
+ const canvas = document.createElement("canvas");
1565
+ canvas.width = width * dpr;
1566
+ canvas.height = height * dpr;
1567
+ const ctx = canvas.getContext("2d");
1568
+ ctx.scale(dpr, dpr);
1569
+ ctx.font = `${weight ? `${weight} ` : ""}${fontSize}px "${fam}"`;
1570
+ ctx.textAlign = "left";
1571
+ ctx.textBaseline = "top";
1572
+ ctx.fillStyle = color;
1573
+ try {
1574
+ ctx.fontKerning = "normal";
1575
+ } catch (e) {
1576
+ }
1577
+ ctx.fillText(ligatureText, 0, 0);
1578
+ return {
1579
+ dataUrl: canvas.toDataURL(),
1580
+ width,
1581
+ height
1582
+ };
1583
+ });
1584
+ }
1585
+ function ligatureIconToImage(cloneRoot, sourceRoot) {
1586
+ return __async(this, null, function* () {
1587
+ if (!(cloneRoot instanceof Element)) return 0;
1588
+ const selector = '.material-icons, [class*="material-symbols"]';
1589
+ const cloneNodes = Array.from(
1590
+ cloneRoot.querySelectorAll(selector)
1591
+ ).filter((n) => n && n.textContent && n.textContent.trim());
1592
+ if (cloneNodes.length === 0) return 0;
1593
+ const sourceNodes = sourceRoot instanceof Element ? Array.from(sourceRoot.querySelectorAll(selector)).filter((n) => n && n.textContent && n.textContent.trim()) : [];
1594
+ let replaced = 0;
1595
+ for (let i = 0; i < cloneNodes.length; i++) {
1596
+ const el = cloneNodes[i];
1597
+ const src = sourceNodes[i] || null;
1598
+ try {
1599
+ const csSrc = src ? getComputedStyle(src) : getComputedStyle(el);
1600
+ const family = csSrc.fontFamily || "Material Icons";
1601
+ if (!isMaterialFamily(family)) continue;
1602
+ const text = (src || el).textContent.trim();
1603
+ if (!text) continue;
1604
+ const size = parseInt(csSrc.fontSize, 10) || 24;
1605
+ const weight = csSrc.fontWeight && csSrc.fontWeight !== "normal" ? csSrc.fontWeight : "normal";
1606
+ const color = resolvePaintColor(csSrc);
1607
+ const variation = csSrc.fontVariationSettings && csSrc.fontVariationSettings !== "normal" ? csSrc.fontVariationSettings : "";
1608
+ const { dataUrl, width, height } = yield materialIconToImage(text, {
1609
+ family,
1610
+ weight,
1611
+ fontSize: size,
1612
+ color,
1613
+ variation
1614
+ });
1615
+ el.textContent = "";
1616
+ const img = el.ownerDocument.createElement("img");
1617
+ img.src = dataUrl;
1618
+ img.alt = text;
1619
+ img.style.height = `${size}px`;
1620
+ img.style.width = `${Math.max(1, Math.round(width / height * size))}px`;
1621
+ img.style.objectFit = "contain";
1622
+ img.style.verticalAlign = getComputedStyle(el).verticalAlign || "baseline";
1623
+ el.appendChild(img);
1624
+ replaced++;
1625
+ } catch (e) {
1626
+ }
1627
+ }
1628
+ return replaced;
1629
+ });
1630
+ }
1425
1631
 
1426
1632
  // src/modules/fonts.js
1427
1633
  function iconToImage(unicodeChar, fontFamily, fontWeight, fontSize = 32, color = "#000") {
@@ -2254,6 +2460,11 @@ ${imported}
2254
2460
  }
2255
2461
  }
2256
2462
  function buildCounterContext(root) {
2463
+ const getEpoch = () => {
2464
+ var _a, _b, _c;
2465
+ return (_c = (_b = (_a = cache) == null ? void 0 : _a.session) == null ? void 0 : _b.__counterEpoch) != null ? _c : 0;
2466
+ };
2467
+ let run = getEpoch();
2257
2468
  const nodeCounters = /* @__PURE__ */ new WeakMap();
2258
2469
  const rootEl = root instanceof Document ? root.documentElement : root;
2259
2470
  const isLi = (el) => el && el.tagName === "LI";
@@ -2347,6 +2558,14 @@ ${imported}
2347
2558
  };
2348
2559
  const empty = /* @__PURE__ */ new Map();
2349
2560
  build(rootEl, empty, empty);
2561
+ function ensureFresh() {
2562
+ const now = getEpoch();
2563
+ if (now !== run) {
2564
+ run = now;
2565
+ const empty2 = /* @__PURE__ */ new Map();
2566
+ build(rootEl, empty2, empty2);
2567
+ }
2568
+ }
2350
2569
  return {
2351
2570
  /**
2352
2571
  * Get top value for counter name at given node.
@@ -2355,6 +2574,7 @@ ${imported}
2355
2574
  */
2356
2575
  get(node, name) {
2357
2576
  var _a;
2577
+ ensureFresh();
2358
2578
  const s = (_a = nodeCounters.get(node)) == null ? void 0 : _a.get(name);
2359
2579
  return s && s.length ? s[s.length - 1] : 0;
2360
2580
  },
@@ -2365,6 +2585,7 @@ ${imported}
2365
2585
  */
2366
2586
  getStack(node, name) {
2367
2587
  var _a;
2588
+ ensureFresh();
2368
2589
  const s = (_a = nodeCounters.get(node)) == null ? void 0 : _a.get(name);
2369
2590
  return s ? s.slice() : [];
2370
2591
  }
@@ -2399,8 +2620,8 @@ ${imported}
2399
2620
  }
2400
2621
 
2401
2622
  // src/modules/pseudo.js
2402
- var counterCtx = null;
2403
2623
  var __siblingCounters = /* @__PURE__ */ new WeakMap();
2624
+ var __pseudoEpoch = -1;
2404
2625
  function unquoteDoubleStrings2(s) {
2405
2626
  return (s || "").replace(/"([^"]*)"/g, "$1");
2406
2627
  }
@@ -2497,14 +2718,21 @@ ${imported}
2497
2718
  }
2498
2719
  function inlinePseudoElements(source, clone, sessionCache, options) {
2499
2720
  return __async(this, null, function* () {
2500
- var _a;
2721
+ var _a, _b, _c, _d;
2501
2722
  if (!(source instanceof Element) || !(clone instanceof Element)) return;
2502
- if (!counterCtx) {
2723
+ const epoch = (_c = (_b = (_a = cache) == null ? void 0 : _a.session) == null ? void 0 : _b.__counterEpoch) != null ? _c : 0;
2724
+ if (__pseudoEpoch !== epoch) {
2725
+ __siblingCounters = /* @__PURE__ */ new WeakMap();
2726
+ if (sessionCache) sessionCache.__counterCtx = null;
2727
+ __pseudoEpoch = epoch;
2728
+ }
2729
+ if (!sessionCache.__counterCtx) {
2503
2730
  try {
2504
- counterCtx = buildCounterContext(source.ownerDocument || document);
2731
+ sessionCache.__counterCtx = buildCounterContext(source.ownerDocument || document);
2505
2732
  } catch (e) {
2506
2733
  }
2507
2734
  }
2735
+ const counterCtx = sessionCache.__counterCtx;
2508
2736
  for (const pseudo of ["::before", "::after", "::first-letter"]) {
2509
2737
  try {
2510
2738
  const style = getStyle(source, pseudo);
@@ -2572,7 +2800,8 @@ ${imported}
2572
2800
  }
2573
2801
  const pseudoEl = document.createElement("span");
2574
2802
  pseudoEl.dataset.snapdomPseudo = pseudo;
2575
- pseudoEl.style.verticalAlign = "middle";
2803
+ pseudoEl.style.display = "inline";
2804
+ pseudoEl.style.verticalAlign = "baseline";
2576
2805
  pseudoEl.style.pointerEvents = "none";
2577
2806
  const snapshot = snapshotComputedStyle(style);
2578
2807
  const key = getStyleKey(snapshot, "span");
@@ -2600,9 +2829,23 @@ ${imported}
2600
2829
  } else if (!isIconFont22 && hasExplicitContent) {
2601
2830
  pseudoEl.textContent = cleanContent;
2602
2831
  }
2603
- pseudoEl.style.background = "none";
2604
- if ("mask" in pseudoEl.style) {
2605
- pseudoEl.style.mask = "none";
2832
+ pseudoEl.style.backgroundImage = "none";
2833
+ if ("maskImage" in pseudoEl.style) pseudoEl.style.maskImage = "none";
2834
+ if ("webkitMaskImage" in pseudoEl.style) pseudoEl.style.webkitMaskImage = "none";
2835
+ try {
2836
+ pseudoEl.style.backgroundRepeat = style.backgroundRepeat;
2837
+ pseudoEl.style.backgroundSize = style.backgroundSize;
2838
+ if (style.backgroundPositionX && style.backgroundPositionY) {
2839
+ pseudoEl.style.backgroundPositionX = style.backgroundPositionX;
2840
+ pseudoEl.style.backgroundPositionY = style.backgroundPositionY;
2841
+ } else {
2842
+ pseudoEl.style.backgroundPosition = style.backgroundPosition;
2843
+ }
2844
+ pseudoEl.style.backgroundOrigin = style.backgroundOrigin;
2845
+ pseudoEl.style.backgroundClip = style.backgroundClip;
2846
+ pseudoEl.style.backgroundAttachment = style.backgroundAttachment;
2847
+ pseudoEl.style.backgroundBlendMode = style.backgroundBlendMode;
2848
+ } catch (e) {
2606
2849
  }
2607
2850
  if (hasBg) {
2608
2851
  try {
@@ -2614,7 +2857,7 @@ ${imported}
2614
2857
  }
2615
2858
  }
2616
2859
  if (hasBgColor) pseudoEl.style.backgroundColor = bgColor;
2617
- const hasContent2 = pseudoEl.childNodes.length > 0 || ((_a = pseudoEl.textContent) == null ? void 0 : _a.trim()) !== "";
2860
+ const hasContent2 = pseudoEl.childNodes.length > 0 || ((_d = pseudoEl.textContent) == null ? void 0 : _d.trim()) !== "";
2618
2861
  const hasVisibleBox = hasContent2 || hasBg || hasBgColor || hasBorder || hasTransform;
2619
2862
  if (incs && incs.length && source.parentElement) {
2620
2863
  const map = __siblingCounters.get(source.parentElement) || /* @__PURE__ */ new Map();
@@ -2646,53 +2889,114 @@ ${imported}
2646
2889
  }
2647
2890
 
2648
2891
  // src/modules/svgDefs.js
2649
- function inlineExternalDefsAndSymbols(rootElement) {
2650
- if (!rootElement) return;
2651
- const usedIds = /* @__PURE__ */ new Set();
2652
- rootElement.querySelectorAll("use").forEach((use) => {
2653
- const href = use.getAttribute("xlink:href") || use.getAttribute("href");
2654
- if (href && href.startsWith("#")) {
2655
- usedIds.add(href.slice(1));
2892
+ function inlineExternalDefsAndSymbols(element, lookupRoot) {
2893
+ var _a, _b, _c, _d;
2894
+ if (!element || !(element instanceof Element)) return;
2895
+ const doc = element.ownerDocument || document;
2896
+ const searchRoot = lookupRoot || doc;
2897
+ const svgRoots = element instanceof SVGSVGElement ? [element] : Array.from(element.querySelectorAll("svg"));
2898
+ if (svgRoots.length === 0) return;
2899
+ const URL_ID_RE = /url\(\s*#([^)]+)\)/g;
2900
+ const URL_ATTRS = [
2901
+ "fill",
2902
+ "stroke",
2903
+ "filter",
2904
+ "clip-path",
2905
+ "mask",
2906
+ "marker",
2907
+ "marker-start",
2908
+ "marker-mid",
2909
+ "marker-end"
2910
+ ];
2911
+ const cssEscape = (s) => window.CSS && CSS.escape ? CSS.escape(s) : s.replace(/[^a-zA-Z0-9_-]/g, "\\$&");
2912
+ const globalExistingIds = new Set(
2913
+ Array.from(element.querySelectorAll("[id]")).map((n) => n.id)
2914
+ );
2915
+ const neededIds = /* @__PURE__ */ new Set();
2916
+ let sawAnyReference = false;
2917
+ const addUrlIdsFromValue = (val) => {
2918
+ if (!val) return;
2919
+ URL_ID_RE.lastIndex = 0;
2920
+ let m;
2921
+ while (m = URL_ID_RE.exec(val)) {
2922
+ sawAnyReference = true;
2923
+ const id = (m[1] || "").trim();
2924
+ if (id && !globalExistingIds.has(id)) neededIds.add(id);
2656
2925
  }
2657
- });
2658
- if (!usedIds.size) return;
2659
- const allGlobal = Array.from(document.querySelectorAll("svg > symbol, svg > defs"));
2660
- const globalSymbols = allGlobal.filter((el) => el.tagName.toLowerCase() === "symbol");
2661
- const globalDefs = allGlobal.filter((el) => el.tagName.toLowerCase() === "defs");
2662
- let container = rootElement.querySelector("svg.inline-defs-container");
2663
- if (!container) {
2664
- container = document.createElementNS("http://www.w3.org/2000/svg", "svg");
2665
- container.setAttribute("aria-hidden", "true");
2666
- container.setAttribute("style", "position: absolute; width: 0; height: 0; overflow: hidden;");
2667
- container.classList.add("inline-defs-container");
2668
- rootElement.insertBefore(container, rootElement.firstChild);
2669
- }
2670
- const existingIds = /* @__PURE__ */ new Set();
2671
- rootElement.querySelectorAll("symbol[id], defs > *[id]").forEach((el) => {
2672
- existingIds.add(el.id);
2673
- });
2674
- usedIds.forEach((id) => {
2675
- if (existingIds.has(id)) return;
2676
- const symbol = globalSymbols.find((sym) => sym.id === id);
2677
- if (symbol) {
2678
- container.appendChild(symbol.cloneNode(true));
2679
- existingIds.add(id);
2680
- return;
2926
+ };
2927
+ const collectReferencesInSvg = (rootSvg) => {
2928
+ const uses = rootSvg.querySelectorAll('use[href^="#"], use[xlink\\:href^="#"]');
2929
+ for (const u of uses) {
2930
+ const href = u.getAttribute("href") || u.getAttribute("xlink:href");
2931
+ if (!href || !href.startsWith("#")) continue;
2932
+ sawAnyReference = true;
2933
+ const id = href.slice(1).trim();
2934
+ if (id && !globalExistingIds.has(id)) neededIds.add(id);
2935
+ }
2936
+ let query = '*[style*="url("],*[fill^="url("], *[stroke^="url("],*[filter^="url("], *[clip-path^="url("],*[mask^="url("],*[marker^="url("], *[marker-start^="url("],*[marker-mid^="url("], *[marker-end^="url("]';
2937
+ const candidates = rootSvg.querySelectorAll(query);
2938
+ for (const el of candidates) {
2939
+ addUrlIdsFromValue(el.getAttribute("style") || "");
2940
+ for (const a of URL_ATTRS) addUrlIdsFromValue(el.getAttribute(a));
2681
2941
  }
2682
- for (const defs of globalDefs) {
2683
- const defEl = defs.querySelector(`#${CSS.escape(id)}`);
2684
- if (defEl) {
2685
- let defsContainer = container.querySelector("defs");
2686
- if (!defsContainer) {
2687
- defsContainer = document.createElementNS("http://www.w3.org/2000/svg", "defs");
2688
- container.appendChild(defsContainer);
2689
- }
2690
- defsContainer.appendChild(defEl.cloneNode(true));
2691
- existingIds.add(id);
2692
- break;
2942
+ };
2943
+ for (const svg of svgRoots) collectReferencesInSvg(svg);
2944
+ if (!sawAnyReference) return;
2945
+ let defsHost = element.querySelector("svg.inline-defs-container");
2946
+ if (!defsHost) {
2947
+ defsHost = doc.createElementNS("http://www.w3.org/2000/svg", "svg");
2948
+ defsHost.classList.add("inline-defs-container");
2949
+ defsHost.setAttribute("aria-hidden", "true");
2950
+ defsHost.setAttribute("style", "position:absolute;width:0;height:0;overflow:hidden");
2951
+ element.insertBefore(defsHost, element.firstChild || null);
2952
+ }
2953
+ let localDefs = defsHost.querySelector("defs") || null;
2954
+ const findGlobalById = (id) => {
2955
+ if (!id) return null;
2956
+ if (globalExistingIds.has(id)) return null;
2957
+ const esc = cssEscape(id);
2958
+ const tryFind = (sel) => {
2959
+ const el = searchRoot.querySelector(sel);
2960
+ return el && !element.contains(el) ? el : null;
2961
+ };
2962
+ return tryFind(`svg defs > *#${esc}`) || tryFind(`svg > symbol#${esc}`) || tryFind(`*#${esc}`);
2963
+ };
2964
+ if (!neededIds.size) return;
2965
+ const queued = new Set(neededIds);
2966
+ const inlined = /* @__PURE__ */ new Set();
2967
+ while (queued.size) {
2968
+ const id = queued.values().next().value;
2969
+ queued.delete(id);
2970
+ if (!id || globalExistingIds.has(id) || inlined.has(id)) continue;
2971
+ const source = findGlobalById(id);
2972
+ if (!source) {
2973
+ inlined.add(id);
2974
+ continue;
2975
+ }
2976
+ if (!localDefs) {
2977
+ localDefs = doc.createElementNS("http://www.w3.org/2000/svg", "defs");
2978
+ defsHost.appendChild(localDefs);
2979
+ }
2980
+ const clone = source.cloneNode(true);
2981
+ if (!clone.id) clone.setAttribute("id", id);
2982
+ localDefs.appendChild(clone);
2983
+ inlined.add(id);
2984
+ globalExistingIds.add(id);
2985
+ const walk = [clone, ...clone.querySelectorAll("*")];
2986
+ for (const node of walk) {
2987
+ const h = ((_a = node.getAttribute) == null ? void 0 : _a.call(node, "href")) || ((_b = node.getAttribute) == null ? void 0 : _b.call(node, "xlink:href"));
2988
+ if (h && h.startsWith("#")) {
2989
+ const ref = h.slice(1).trim();
2990
+ if (ref && !globalExistingIds.has(ref) && !inlined.has(ref)) queued.add(ref);
2991
+ }
2992
+ const style = ((_c = node.getAttribute) == null ? void 0 : _c.call(node, "style")) || "";
2993
+ if (style) addUrlIdsFromValue(style);
2994
+ for (const a of URL_ATTRS) {
2995
+ const v = (_d = node.getAttribute) == null ? void 0 : _d.call(node, a);
2996
+ if (v) addUrlIdsFromValue(v);
2693
2997
  }
2694
2998
  }
2695
- });
2999
+ }
2696
3000
  }
2697
3001
 
2698
3002
  // src/modules/changeCSS.js
@@ -3155,6 +3459,17 @@ ${imported}
3155
3459
  "-webkit-mask-position-x",
3156
3460
  "-webkit-mask-position-y"
3157
3461
  ];
3462
+ const BG_LAYOUT_PROPS = [
3463
+ "background-position",
3464
+ "background-position-x",
3465
+ "background-position-y",
3466
+ "background-size",
3467
+ "background-repeat",
3468
+ "background-origin",
3469
+ "background-clip",
3470
+ "background-attachment",
3471
+ "background-blend-mode"
3472
+ ];
3158
3473
  const BORDER_AUX_PROPS = [
3159
3474
  "border-image-slice",
3160
3475
  "border-image-width",
@@ -3170,6 +3485,11 @@ ${imported}
3170
3485
  const bis = style.getPropertyValue("border-image-source");
3171
3486
  return bi && bi !== "none" || bis && bis !== "none";
3172
3487
  })();
3488
+ for (const prop of BG_LAYOUT_PROPS) {
3489
+ const v = style.getPropertyValue(prop);
3490
+ if (!v) continue;
3491
+ cloneNode.style.setProperty(prop, v);
3492
+ }
3173
3493
  for (const prop of URL_PROPS) {
3174
3494
  const val = style.getPropertyValue(prop);
3175
3495
  if (!val || val === "none") continue;
@@ -3194,7 +3514,7 @@ ${imported}
3194
3514
  }
3195
3515
  }
3196
3516
  const sChildren = Array.from(srcNode.children);
3197
- const cChildren = Array.from(cloneNode.children);
3517
+ const cChildren = Array.from(cloneNode.children).filter((el) => !(el.dataset && el.dataset.snapdomPseudo));
3198
3518
  for (let i = 0; i < Math.min(sChildren.length, cChildren.length); i++) {
3199
3519
  queue.push([sChildren[i], cChildren[i]]);
3200
3520
  }
@@ -3260,6 +3580,85 @@ ${imported}
3260
3580
  return Array.from(el.childNodes).some((n) => n.nodeType === Node.TEXT_NODE);
3261
3581
  }
3262
3582
 
3583
+ // src/core/plugins.js
3584
+ var __plugins = [];
3585
+ function normalizePlugin(spec) {
3586
+ if (!spec) return null;
3587
+ if (Array.isArray(spec)) {
3588
+ const [factory, options] = spec;
3589
+ return typeof factory === "function" ? factory(options) : factory;
3590
+ }
3591
+ if (typeof spec === "object" && "plugin" in spec) {
3592
+ const { plugin, options } = spec;
3593
+ return typeof plugin === "function" ? plugin(options) : plugin;
3594
+ }
3595
+ if (typeof spec === "function") return spec();
3596
+ return spec;
3597
+ }
3598
+ function registerPlugins(...defs) {
3599
+ const flat = defs.flat();
3600
+ for (const d of flat) {
3601
+ const inst = normalizePlugin(d);
3602
+ if (!inst) continue;
3603
+ if (!__plugins.some((p) => p && p.name && inst.name && p.name === inst.name)) {
3604
+ __plugins.push(inst);
3605
+ }
3606
+ }
3607
+ }
3608
+ function getContextPlugins(context) {
3609
+ const arr = context && Array.isArray(context.plugins) ? context.plugins : __plugins;
3610
+ return arr || __plugins;
3611
+ }
3612
+ function runHook(name, context, payload) {
3613
+ return __async(this, null, function* () {
3614
+ let acc = payload;
3615
+ const list = getContextPlugins(context);
3616
+ for (const p of list) {
3617
+ const fn = p && typeof p[name] === "function" ? p[name] : null;
3618
+ if (!fn) continue;
3619
+ const out = yield fn(context, acc);
3620
+ if (typeof out !== "undefined") acc = out;
3621
+ }
3622
+ return acc;
3623
+ });
3624
+ }
3625
+ function runAll(name, context, payload) {
3626
+ return __async(this, null, function* () {
3627
+ const outs = [];
3628
+ const list = getContextPlugins(context);
3629
+ for (const p of list) {
3630
+ const fn = p && typeof p[name] === "function" ? p[name] : null;
3631
+ if (!fn) continue;
3632
+ const out = yield fn(context, payload);
3633
+ if (typeof out !== "undefined") outs.push(out);
3634
+ }
3635
+ return outs;
3636
+ });
3637
+ }
3638
+ function mergePlugins(localDefs) {
3639
+ const out = [];
3640
+ if (Array.isArray(localDefs)) {
3641
+ for (const d of localDefs) {
3642
+ const inst = normalizePlugin(d);
3643
+ if (!inst || !inst.name) continue;
3644
+ const i = out.findIndex((x) => x && x.name === inst.name);
3645
+ if (i >= 0) out.splice(i, 1);
3646
+ out.push(inst);
3647
+ }
3648
+ }
3649
+ for (const g of __plugins) {
3650
+ if (g && g.name && !out.some((x) => x.name === g.name)) {
3651
+ out.push(g);
3652
+ }
3653
+ }
3654
+ return Object.freeze(out);
3655
+ }
3656
+ function attachSessionPlugins(context, localDefs, force = false) {
3657
+ if (!context || context.plugins && !force) return context;
3658
+ context.plugins = mergePlugins(localDefs);
3659
+ return context;
3660
+ }
3661
+
3263
3662
  // src/core/capture.js
3264
3663
  function stripRootShadows(originalEl, cloneRoot) {
3265
3664
  if (!originalEl || !cloneRoot || !cloneRoot.style) return;
@@ -3288,43 +3687,52 @@ ${imported}
3288
3687
  if (!element) throw new Error("Element cannot be null or undefined");
3289
3688
  applyCachePolicy(options.cache);
3290
3689
  const fast = options.fast;
3291
- const straighten = !!options.straighten;
3292
- const noShadows = !!options.noShadows;
3690
+ const outerTransforms = options.outerTransforms !== false;
3691
+ const outerShadows = !!options.outerShadows;
3692
+ let state = { element, options, plugins: options.plugins };
3293
3693
  let clone, classCSS, styleCache;
3294
3694
  let fontsCSS = "";
3295
3695
  let baseCSS = "";
3296
3696
  let dataURL;
3297
3697
  let svgString;
3298
3698
  let rootTransform2D = null;
3299
- const undoClamp = lineClamp(element);
3699
+ yield runHook("beforeSnap", state);
3700
+ yield runHook("beforeClone", state);
3701
+ const undoClamp = lineClamp(state.element);
3300
3702
  try {
3301
- ({ clone, classCSS, styleCache } = yield prepareClone(element, options));
3302
- if (straighten && clone) {
3303
- rootTransform2D = normalizeRootTransforms(element, clone);
3703
+ ({ clone, classCSS, styleCache } = yield prepareClone(state.element, state.options));
3704
+ if (!outerTransforms && clone) {
3705
+ rootTransform2D = normalizeRootTransforms(state.element, clone);
3304
3706
  }
3305
- if (noShadows && clone) {
3306
- stripRootShadows(element, clone);
3707
+ if (!outerShadows && clone) {
3708
+ stripRootShadows(state.element, clone);
3307
3709
  }
3308
3710
  } finally {
3309
3711
  undoClamp();
3310
3712
  }
3713
+ state = __spreadValues({ clone, classCSS, styleCache }, state);
3714
+ yield runHook("afterClone", state);
3715
+ try {
3716
+ yield ligatureIconToImage(state.clone, state.element);
3717
+ } catch (e) {
3718
+ }
3311
3719
  yield new Promise((resolve) => {
3312
3720
  idle(() => __async(null, null, function* () {
3313
- yield inlineImages(clone, options);
3721
+ yield inlineImages(state.clone, state.options);
3314
3722
  resolve();
3315
3723
  }), { fast });
3316
3724
  });
3317
3725
  yield new Promise((resolve) => {
3318
3726
  idle(() => __async(null, null, function* () {
3319
- yield inlineBackgroundImages(element, clone, styleCache, options);
3727
+ yield inlineBackgroundImages(state.element, state.clone, state.styleCache, state.options);
3320
3728
  resolve();
3321
3729
  }), { fast });
3322
3730
  });
3323
3731
  if (options.embedFonts) {
3324
3732
  yield new Promise((resolve) => {
3325
3733
  idle(() => __async(null, null, function* () {
3326
- const required = collectUsedFontVariants(element);
3327
- const usedCodepoints = collectUsedCodepoints(element);
3734
+ const required = collectUsedFontVariants(state.element);
3735
+ const usedCodepoints = collectUsedCodepoints(state.element);
3328
3736
  if (isSafari()) {
3329
3737
  const families = new Set(
3330
3738
  Array.from(required).map((k) => String(k).split("__")[0]).filter(Boolean)
@@ -3335,14 +3743,14 @@ ${imported}
3335
3743
  required,
3336
3744
  usedCodepoints,
3337
3745
  preCached: false,
3338
- exclude: options.excludeFonts,
3339
- useProxy: options.useProxy
3746
+ exclude: state.options.excludeFonts,
3747
+ useProxy: state.options.useProxy
3340
3748
  });
3341
3749
  resolve();
3342
3750
  }), { fast });
3343
3751
  });
3344
3752
  }
3345
- const usedTags = collectUsedTagNames(clone).sort();
3753
+ const usedTags = collectUsedTagNames(state.clone).sort();
3346
3754
  const tagKey = usedTags.join(",");
3347
3755
  if (cache.baseStyle.has(tagKey)) {
3348
3756
  baseCSS = cache.baseStyle.get(tagKey);
@@ -3355,70 +3763,57 @@ ${imported}
3355
3763
  }, { fast });
3356
3764
  });
3357
3765
  }
3766
+ state = __spreadValues({ fontsCSS, baseCSS }, state);
3767
+ yield runHook("beforeRender", state);
3358
3768
  yield new Promise((resolve) => {
3359
3769
  idle(() => {
3360
- const csEl = getComputedStyle(element);
3361
- function parseFilterDropShadows(cs) {
3362
- var _a;
3363
- const raw = `${cs.filter || ""} ${cs.webkitFilter || ""}`.trim();
3364
- if (!raw || raw === "none") {
3365
- return { bleed: { top: 0, right: 0, bottom: 0, left: 0 }, has: false };
3366
- }
3367
- const tokens = raw.match(/drop-shadow\((?:[^()]|\([^()]*\))*\)/gi) || [];
3368
- let t = 0, r = 0, b = 0, l = 0;
3369
- let found = false;
3370
- for (const tok of tokens) {
3371
- found = true;
3372
- const nums = ((_a = tok.match(/-?\d+(?:\.\d+)?px/gi)) == null ? void 0 : _a.map((v) => parseFloat(v))) || [];
3373
- const [ox = 0, oy = 0, blur = 0] = nums;
3374
- const extX = Math.abs(ox) + blur;
3375
- const extY = Math.abs(oy) + blur;
3376
- r = Math.max(r, extX + Math.max(ox, 0));
3377
- l = Math.max(l, extX + Math.max(-ox, 0));
3378
- b = Math.max(b, extY + Math.max(oy, 0));
3379
- t = Math.max(t, extY + Math.max(-oy, 0));
3380
- }
3381
- return { bleed: { top: Math.ceil(t), right: Math.ceil(r), bottom: Math.ceil(b), left: Math.ceil(l) }, has: found };
3382
- }
3383
- const rect = element.getBoundingClientRect();
3384
- const w0 = Math.max(1, Math.ceil(element.offsetWidth || parseFloat(csEl.width) || rect.width || 1));
3385
- const h0 = Math.max(1, Math.ceil(element.offsetHeight || parseFloat(csEl.height) || rect.height || 1));
3770
+ const csEl = getComputedStyle(state.element);
3771
+ const rect = state.element.getBoundingClientRect();
3772
+ const w0 = Math.max(1, limitDecimals(state.element.offsetWidth || parseFloat(csEl.width) || rect.width || 1));
3773
+ const h0 = Math.max(1, limitDecimals(state.element.offsetHeight || parseFloat(csEl.height) || rect.height || 1));
3386
3774
  const coerceNum = (v, def = NaN) => {
3387
3775
  const n = typeof v === "string" ? parseFloat(v) : v;
3388
3776
  return Number.isFinite(n) ? n : def;
3389
3777
  };
3390
- const optW = coerceNum(options.width);
3391
- const optH = coerceNum(options.height);
3778
+ const optW = coerceNum(state.options.width);
3779
+ const optH = coerceNum(state.options.height);
3392
3780
  let w = w0, h = h0;
3393
3781
  const hasW = Number.isFinite(optW);
3394
3782
  const hasH = Number.isFinite(optH);
3395
3783
  const aspect0 = h0 > 0 ? w0 / h0 : 1;
3396
3784
  if (hasW && hasH) {
3397
- w = Math.max(1, Math.ceil(optW));
3398
- h = Math.max(1, Math.ceil(optH));
3785
+ w = Math.max(1, limitDecimals(optW));
3786
+ h = Math.max(1, limitDecimals(optH));
3399
3787
  } else if (hasW) {
3400
- w = Math.max(1, Math.ceil(optW));
3401
- h = Math.max(1, Math.ceil(w / (aspect0 || 1)));
3788
+ w = Math.max(1, limitDecimals(optW));
3789
+ h = Math.max(1, limitDecimals(w / (aspect0 || 1)));
3402
3790
  } else if (hasH) {
3403
- h = Math.max(1, Math.ceil(optH));
3404
- w = Math.max(1, Math.ceil(h * (aspect0 || 1)));
3791
+ h = Math.max(1, limitDecimals(optH));
3792
+ w = Math.max(1, limitDecimals(h * (aspect0 || 1)));
3405
3793
  } else {
3406
3794
  w = w0;
3407
3795
  h = h0;
3408
3796
  }
3409
3797
  let minX = 0, minY = 0, maxX = w0, maxY = h0;
3410
- if (straighten && rootTransform2D && Number.isFinite(rootTransform2D.a)) {
3411
- const M2 = { a: rootTransform2D.a, b: rootTransform2D.b || 0, c: rootTransform2D.c || 0, d: rootTransform2D.d || 1, e: 0, f: 0 };
3798
+ if (!outerTransforms && rootTransform2D && Number.isFinite(rootTransform2D.a)) {
3799
+ const M2 = {
3800
+ a: rootTransform2D.a,
3801
+ b: rootTransform2D.b || 0,
3802
+ c: rootTransform2D.c || 0,
3803
+ d: rootTransform2D.d || 1,
3804
+ e: 0,
3805
+ f: 0
3806
+ };
3412
3807
  const bb2 = bboxWithOriginFull(w0, h0, M2, 0, 0);
3413
- minX = bb2.minX;
3414
- minY = bb2.minY;
3415
- maxX = bb2.maxX;
3416
- maxY = bb2.maxY;
3808
+ minX = limitDecimals(bb2.minX);
3809
+ minY = limitDecimals(bb2.minY);
3810
+ maxX = limitDecimals(bb2.maxX);
3811
+ maxY = limitDecimals(bb2.maxY);
3417
3812
  } else {
3418
- const useTFBBox = !straighten && hasTFBBox(element);
3813
+ const useTFBBox = outerTransforms && hasTFBBox(state.element);
3419
3814
  if (useTFBBox) {
3420
3815
  const baseTransform2 = csEl.transform && csEl.transform !== "none" ? csEl.transform : "";
3421
- const ind2 = readIndividualTransforms(element);
3816
+ const ind2 = readIndividualTransforms(state.element);
3422
3817
  const TOTAL = readTotalTransformMatrix({
3423
3818
  baseTransform: baseTransform2,
3424
3819
  rotate: ind2.rotate || "0deg",
@@ -3428,73 +3823,108 @@ ${imported}
3428
3823
  const { ox: ox2, oy: oy2 } = parseTransformOriginPx(csEl, w0, h0);
3429
3824
  const M = TOTAL.is2D ? TOTAL : new DOMMatrix(TOTAL.toString());
3430
3825
  const bb = bboxWithOriginFull(w0, h0, M, ox2, oy2);
3431
- minX = bb.minX;
3432
- minY = bb.minY;
3433
- maxX = bb.maxX;
3434
- maxY = bb.maxY;
3826
+ minX = limitDecimals(bb.minX);
3827
+ minY = limitDecimals(bb.minY);
3828
+ maxX = limitDecimals(bb.maxX);
3829
+ maxY = limitDecimals(bb.maxY);
3435
3830
  }
3436
3831
  }
3437
3832
  const bleedShadow = parseBoxShadow(csEl);
3438
3833
  const bleedBlur = parseFilterBlur(csEl);
3439
3834
  const bleedOutline = parseOutline(csEl);
3440
3835
  const drop = parseFilterDropShadows(csEl);
3441
- const bleed = noShadows ? { top: 0, right: 0, bottom: 0, left: 0 } : {
3442
- top: bleedShadow.top + bleedBlur.top + bleedOutline.top + drop.bleed.top,
3443
- right: bleedShadow.right + bleedBlur.right + bleedOutline.right + drop.bleed.right,
3444
- bottom: bleedShadow.bottom + bleedBlur.bottom + bleedOutline.bottom + drop.bleed.bottom,
3445
- left: bleedShadow.left + bleedBlur.left + bleedOutline.left + drop.bleed.left
3836
+ const bleed = !outerShadows ? { top: 0, right: 0, bottom: 0, left: 0 } : {
3837
+ top: limitDecimals(bleedShadow.top + bleedBlur.top + bleedOutline.top + drop.bleed.top),
3838
+ right: limitDecimals(bleedShadow.right + bleedBlur.right + bleedOutline.right + drop.bleed.right),
3839
+ bottom: limitDecimals(bleedShadow.bottom + bleedBlur.bottom + bleedOutline.bottom + drop.bleed.bottom),
3840
+ left: limitDecimals(bleedShadow.left + bleedBlur.left + bleedOutline.left + drop.bleed.left)
3446
3841
  };
3447
- minX -= bleed.left;
3448
- minY -= bleed.top;
3449
- maxX += bleed.right;
3450
- maxY += bleed.bottom;
3451
- const vbW0 = Math.max(1, Math.ceil(maxX - minX));
3452
- const vbH0 = Math.max(1, Math.ceil(maxY - minY));
3453
- const outW = Math.max(1, Math.round(vbW0 * (hasW || hasH ? w / w0 : 1)));
3454
- const outH = Math.max(1, Math.round(vbH0 * (hasH || hasW ? h / h0 : 1)));
3842
+ minX = limitDecimals(minX - bleed.left);
3843
+ minY = limitDecimals(minY - bleed.top);
3844
+ maxX = limitDecimals(maxX + bleed.right);
3845
+ maxY = limitDecimals(maxY + bleed.bottom);
3846
+ const vbW0 = Math.max(1, limitDecimals(maxX - minX));
3847
+ const vbH0 = Math.max(1, limitDecimals(maxY - minY));
3848
+ const scaleW = hasW || hasH ? limitDecimals(w / w0) : 1;
3849
+ const scaleH = hasH || hasW ? limitDecimals(h / h0) : 1;
3850
+ const outW = Math.max(1, limitDecimals(vbW0 * scaleW));
3851
+ const outH = Math.max(1, limitDecimals(vbH0 * scaleH));
3455
3852
  const svgNS = "http://www.w3.org/2000/svg";
3456
3853
  const basePad = isSafari() ? 1 : 0;
3457
- const extraPad = straighten ? 1 : 0;
3458
- const pad = basePad + extraPad;
3854
+ const extraPad = !outerTransforms ? 1 : 0;
3855
+ const pad = limitDecimals(basePad + extraPad);
3459
3856
  const fo = document.createElementNS(svgNS, "foreignObject");
3460
- const vbMinX = Math.floor(minX);
3461
- const vbMinY = Math.floor(minY);
3462
- fo.setAttribute("x", String(-(vbMinX - pad)));
3463
- fo.setAttribute("y", String(-(vbMinY - pad)));
3464
- fo.setAttribute("width", String(Math.ceil(w0 + pad * 2)));
3465
- fo.setAttribute("height", String(Math.ceil(h0 + pad * 2)));
3857
+ const vbMinX = limitDecimals(minX);
3858
+ const vbMinY = limitDecimals(minY);
3859
+ fo.setAttribute("x", String(limitDecimals(-(vbMinX - pad))));
3860
+ fo.setAttribute("y", String(limitDecimals(-(vbMinY - pad))));
3861
+ fo.setAttribute("width", String(limitDecimals(w0 + pad * 2)));
3862
+ fo.setAttribute("height", String(limitDecimals(h0 + pad * 2)));
3466
3863
  fo.style.overflow = "visible";
3467
3864
  const styleTag = document.createElement("style");
3468
- styleTag.textContent = baseCSS + fontsCSS + "svg{overflow:visible;} foreignObject{overflow:visible;}" + classCSS;
3865
+ styleTag.textContent = state.baseCSS + state.fontsCSS + "svg{overflow:visible;} foreignObject{overflow:visible;}" + state.classCSS;
3469
3866
  fo.appendChild(styleTag);
3470
3867
  const container = document.createElement("div");
3471
3868
  container.setAttribute("xmlns", "http://www.w3.org/1999/xhtml");
3472
- container.style.width = `${w0}px`;
3473
- container.style.height = `${h0}px`;
3869
+ container.style.width = `${limitDecimals(w0)}px`;
3870
+ container.style.height = `${limitDecimals(h0)}px`;
3474
3871
  container.style.overflow = "visible";
3475
- clone.setAttribute("xmlns", "http://www.w3.org/1999/xhtml");
3476
- container.appendChild(clone);
3872
+ state.clone.setAttribute("xmlns", "http://www.w3.org/1999/xhtml");
3873
+ container.appendChild(state.clone);
3477
3874
  fo.appendChild(container);
3478
3875
  const serializer = new XMLSerializer();
3479
3876
  const foString = serializer.serializeToString(fo);
3480
- const vbW = vbW0 + pad * 2;
3481
- const vbH = vbH0 + pad * 2;
3877
+ const vbW = limitDecimals(vbW0 + pad * 2);
3878
+ const vbH = limitDecimals(vbH0 + pad * 2);
3482
3879
  const wantsSize = hasW || hasH;
3483
3880
  options.meta = { w0, h0, vbW, vbH, targetW: w, targetH: h };
3484
- const svgOutW = isSafari() && wantsSize ? vbW : outW + pad * 2;
3485
- const svgOutH = isSafari() && wantsSize ? vbH : outH + pad * 2;
3881
+ const svgOutW = isSafari() && wantsSize ? vbW : limitDecimals(outW + pad * 2);
3882
+ const svgOutH = isSafari() && wantsSize ? vbH : limitDecimals(outH + pad * 2);
3486
3883
  const svgHeader = `<svg xmlns="${svgNS}" width="${svgOutW}" height="${svgOutH}" viewBox="0 0 ${vbW} ${vbH}">`;
3487
3884
  const svgFooter = "</svg>";
3488
3885
  svgString = svgHeader + foString + svgFooter;
3489
3886
  dataURL = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgString)}`;
3887
+ state = __spreadValues({ svgString, dataURL }, state);
3490
3888
  resolve();
3491
3889
  }, { fast });
3492
3890
  });
3891
+ yield runHook("afterRender", state);
3493
3892
  const sandbox = document.getElementById("snapdom-sandbox");
3494
3893
  if (sandbox && sandbox.style.position === "absolute") sandbox.remove();
3495
- return dataURL;
3894
+ return state.dataURL;
3496
3895
  });
3497
3896
  }
3897
+ var limitDecimals = (v, n = 3) => Number.isFinite(v) ? Math.round(v * __pow(10, n)) / __pow(10, n) : v;
3898
+ function parseFilterDropShadows(cs) {
3899
+ var _a;
3900
+ const raw = `${cs.filter || ""} ${cs.webkitFilter || ""}`.trim();
3901
+ if (!raw || raw === "none") {
3902
+ return { bleed: { top: 0, right: 0, bottom: 0, left: 0 }, has: false };
3903
+ }
3904
+ const tokens = raw.match(/drop-shadow\((?:[^()]|\([^()]*\))*\)/gi) || [];
3905
+ let t = 0, r = 0, b = 0, l = 0;
3906
+ let found = false;
3907
+ for (const tok of tokens) {
3908
+ found = true;
3909
+ const nums = ((_a = tok.match(/-?\d+(?:\.\d+)?px/gi)) == null ? void 0 : _a.map((v) => parseFloat(v))) || [];
3910
+ const [ox = 0, oy = 0, blur = 0] = nums;
3911
+ const extX = Math.abs(ox) + blur;
3912
+ const extY = Math.abs(oy) + blur;
3913
+ r = Math.max(r, extX + Math.max(ox, 0));
3914
+ l = Math.max(l, extX + Math.max(-ox, 0));
3915
+ b = Math.max(b, extY + Math.max(oy, 0));
3916
+ t = Math.max(t, extY + Math.max(-oy, 0));
3917
+ }
3918
+ return {
3919
+ bleed: {
3920
+ top: limitDecimals(t),
3921
+ right: limitDecimals(r),
3922
+ bottom: limitDecimals(b),
3923
+ left: limitDecimals(l)
3924
+ },
3925
+ has: found
3926
+ };
3927
+ }
3498
3928
  function normalizeRootTransforms(originalEl, cloneRoot) {
3499
3929
  if (!originalEl || !cloneRoot || !cloneRoot.style) return null;
3500
3930
  const cs = getComputedStyle(originalEl);
@@ -3747,7 +4177,8 @@ ${imported}
3747
4177
  }
3748
4178
  function createContext(options = {}) {
3749
4179
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t;
3750
- const resolvedFormat = (_a = options.format) != null ? _a : "png";
4180
+ let resolvedFormat = (_a = options.format) != null ? _a : "png";
4181
+ if (resolvedFormat === "jpg") resolvedFormat = "jpeg";
3751
4182
  const cachePolicy = normalizeCachePolicy(options.cache);
3752
4183
  return {
3753
4184
  // Debug & perf
@@ -3779,11 +4210,11 @@ ${imported}
3779
4210
  type: (_n = options.type) != null ? _n : "svg",
3780
4211
  quality: (_o = options.quality) != null ? _o : 0.92,
3781
4212
  dpr: (_p = options.dpr) != null ? _p : window.devicePixelRatio || 1,
3782
- backgroundColor: (_q = options.backgroundColor) != null ? _q : ["jpg", "jpeg", "webp"].includes(resolvedFormat) ? "#ffffff" : null,
4213
+ backgroundColor: (_q = options.backgroundColor) != null ? _q : ["jpeg", "webp"].includes(resolvedFormat) ? "#ffffff" : null,
3783
4214
  filename: (_r = options.filename) != null ? _r : "snapDOM",
3784
4215
  // NEW flags (user-friendly)
3785
- straighten: (_s = options.straighten) != null ? _s : false,
3786
- noShadows: (_t = options.noShadows) != null ? _t : false
4216
+ outerTransforms: (_s = options.outerTransforms) != null ? _s : true,
4217
+ outerShadows: (_t = options.outerShadows) != null ? _t : false
3787
4218
  // Plugins (reservado)
3788
4219
  // plugins: normalizePlugins(...),
3789
4220
  };
@@ -3911,20 +4342,20 @@ ${imported}
3911
4342
  } else if (hasW) {
3912
4343
  const k = optW / Math.max(1, refW);
3913
4344
  outW = optW;
3914
- outH = Math.round(refH * k);
4345
+ outH = refH * k;
3915
4346
  } else if (hasH) {
3916
4347
  const k = optH / Math.max(1, refH);
3917
4348
  outH = optH;
3918
- outW = Math.round(refW * k);
4349
+ outW = refW * k;
3919
4350
  } else {
3920
4351
  outW = natW;
3921
4352
  outH = natH;
3922
4353
  }
3923
- outW = Math.round(outW * scale);
3924
- outH = Math.round(outH * scale);
4354
+ outW = outW * scale;
4355
+ outH = outH * scale;
3925
4356
  const canvas = document.createElement("canvas");
3926
- canvas.width = Math.ceil(outW * dpr);
3927
- canvas.height = Math.ceil(outH * dpr);
4357
+ canvas.width = outW * dpr;
4358
+ canvas.height = outH * dpr;
3928
4359
  canvas.style.width = `${outW}px`;
3929
4360
  canvas.style.height = `${outH}px`;
3930
4361
  const ctx = canvas.getContext("2d");
@@ -4042,17 +4473,23 @@ ${imported}
4042
4473
  }
4043
4474
 
4044
4475
  // src/api/snapdom.js
4476
+ snapdom.plugins = (...defs) => {
4477
+ registerPlugins(...defs);
4478
+ return snapdom;
4479
+ };
4045
4480
  var INTERNAL_TOKEN = Symbol("snapdom.internal");
4481
+ var INTERNAL_EXPORT_TOKEN = Symbol("snapdom.internal.silent");
4046
4482
  var _safariWarmup = false;
4047
4483
  function snapdom(element, userOptions) {
4048
4484
  return __async(this, null, function* () {
4049
4485
  if (!element) throw new Error("Element cannot be null or undefined");
4050
4486
  const context = createContext(userOptions);
4487
+ attachSessionPlugins(context, userOptions && userOptions.plugins);
4051
4488
  if (isSafari() && (context.embedFonts === true || hasBackgroundOrMask(element))) {
4052
4489
  for (let i = 0; i < 3; i++) {
4053
4490
  try {
4054
4491
  yield safariWarmup(element, userOptions);
4055
- console.log("Iteraci\xF3n n\xFAmero:", i);
4492
+ console.log("safariWarmup:", i);
4056
4493
  _safariWarmup = false;
4057
4494
  } catch (e) {
4058
4495
  }
@@ -4068,31 +4505,108 @@ ${imported}
4068
4505
  return snapdom.capture(element, context, INTERNAL_TOKEN);
4069
4506
  });
4070
4507
  }
4508
+ snapdom.plugins = (...defs) => {
4509
+ registerPlugins(...defs);
4510
+ return snapdom;
4511
+ };
4071
4512
  snapdom.capture = (el, context, _token) => __async(null, null, function* () {
4072
4513
  if (_token !== INTERNAL_TOKEN) throw new Error("[snapdom.capture] is internal. Use snapdom(...) instead.");
4073
4514
  const url = yield captureDOM(el, context);
4074
- const ensureContext = (opts) => __spreadValues(__spreadValues({}, context), opts || {});
4075
- const withFormat = (format) => (opts) => {
4076
- const next = ensureContext(__spreadProps(__spreadValues({}, opts || {}), { format }));
4077
- const wantsJpeg = format === "jpeg" || format === "jpg";
4078
- const noBg = next.backgroundColor == null || next.backgroundColor === "transparent";
4079
- if (wantsJpeg && noBg) {
4080
- next.backgroundColor = "#ffffff";
4081
- }
4082
- return rasterize(url, next);
4515
+ const coreExports = {
4516
+ img: (ctx, opts) => __async(null, null, function* () {
4517
+ return toImg(url, __spreadValues(__spreadValues({}, ctx), opts || {}));
4518
+ }),
4519
+ svg: (ctx, opts) => __async(null, null, function* () {
4520
+ return toImg(url, __spreadValues(__spreadValues({}, ctx), opts || {}));
4521
+ }),
4522
+ canvas: (ctx, opts) => __async(null, null, function* () {
4523
+ return toCanvas(url, __spreadValues(__spreadValues({}, ctx), opts || {}));
4524
+ }),
4525
+ blob: (ctx, opts) => __async(null, null, function* () {
4526
+ return toBlob(url, __spreadValues(__spreadValues({}, ctx), opts || {}));
4527
+ }),
4528
+ png: (ctx, opts) => __async(null, null, function* () {
4529
+ return rasterize(url, __spreadProps(__spreadValues(__spreadValues({}, ctx), opts || {}), { format: "png" }));
4530
+ }),
4531
+ jpeg: (ctx, opts) => __async(null, null, function* () {
4532
+ return rasterize(url, __spreadProps(__spreadValues(__spreadValues({}, ctx), opts || {}), { format: "jpeg" }));
4533
+ }),
4534
+ webp: (ctx, opts) => __async(null, null, function* () {
4535
+ return rasterize(url, __spreadProps(__spreadValues(__spreadValues({}, ctx), opts || {}), { format: "webp" }));
4536
+ }),
4537
+ download: (ctx, opts) => __async(null, null, function* () {
4538
+ return download(url, __spreadValues(__spreadValues({}, ctx), opts || {}));
4539
+ })
4083
4540
  };
4084
- return {
4541
+ const _pluginExports = {
4542
+ svg: (opts) => toImg(url, __spreadProps(__spreadValues(__spreadValues({}, context), opts || {}), { [INTERNAL_EXPORT_TOKEN]: true })),
4543
+ canvas: (opts) => toCanvas(url, __spreadProps(__spreadValues(__spreadValues({}, context), opts || {}), { [INTERNAL_EXPORT_TOKEN]: true })),
4544
+ png: (opts) => rasterize(url, __spreadProps(__spreadValues(__spreadValues({}, context), opts || {}), { format: "png", [INTERNAL_EXPORT_TOKEN]: true })),
4545
+ jpeg: (opts) => rasterize(url, __spreadProps(__spreadValues(__spreadValues({}, context), opts || {}), { format: "jpeg", [INTERNAL_EXPORT_TOKEN]: true })),
4546
+ jpg: (opts) => rasterize(url, __spreadProps(__spreadValues(__spreadValues({}, context), opts || {}), { format: "jpeg", [INTERNAL_EXPORT_TOKEN]: true })),
4547
+ webp: (opts) => rasterize(url, __spreadProps(__spreadValues(__spreadValues({}, context), opts || {}), { format: "webp", [INTERNAL_EXPORT_TOKEN]: true })),
4548
+ blob: (opts) => toBlob(url, __spreadProps(__spreadValues(__spreadValues({}, context), opts || {}), { [INTERNAL_EXPORT_TOKEN]: true })),
4549
+ img: (opts) => toImg(url, __spreadProps(__spreadValues(__spreadValues({}, context), opts || {}), { [INTERNAL_EXPORT_TOKEN]: true }))
4550
+ };
4551
+ const _defineCtx = __spreadProps(__spreadValues({}, context), { export: { url }, exports: _pluginExports });
4552
+ const providedMaps = yield runAll("defineExports", _defineCtx);
4553
+ const provided = Object.assign({}, ...providedMaps.filter((x) => x && typeof x === "object"));
4554
+ const exportsMap = __spreadValues(__spreadValues({}, coreExports), provided);
4555
+ if (exportsMap.jpeg && !exportsMap.jpg) {
4556
+ exportsMap.jpg = (ctx, opts) => exportsMap.jpeg(ctx, opts);
4557
+ }
4558
+ function normalizeExportOptions(type, opts) {
4559
+ const next = __spreadValues(__spreadValues({}, context), opts || {});
4560
+ if (type === "jpeg" || type === "jpg") {
4561
+ const noBg = next.backgroundColor == null || next.backgroundColor === "transparent";
4562
+ if (noBg) next.backgroundColor = "#ffffff";
4563
+ }
4564
+ return next;
4565
+ }
4566
+ let afterSnapFired = false;
4567
+ let _exportQueue = Promise.resolve();
4568
+ function runExport(type, opts) {
4569
+ return __async(this, null, function* () {
4570
+ const job = () => __async(null, null, function* () {
4571
+ const work = exportsMap[type];
4572
+ if (!work) throw new Error(`[snapdom] Unknown export type: ${type}`);
4573
+ const nextOpts = normalizeExportOptions(type, opts);
4574
+ const ctx = __spreadProps(__spreadValues({}, context), { export: { type, options: nextOpts, url } });
4575
+ yield runHook("beforeExport", ctx);
4576
+ const result2 = yield work(ctx, nextOpts);
4577
+ yield runHook("afterExport", ctx, result2);
4578
+ if (!afterSnapFired) {
4579
+ afterSnapFired = true;
4580
+ yield runHook("afterSnap", context);
4581
+ }
4582
+ return result2;
4583
+ });
4584
+ return _exportQueue = _exportQueue.then(job);
4585
+ });
4586
+ }
4587
+ const result = {
4085
4588
  url,
4086
4589
  toRaw: () => url,
4087
- toImg: (opts) => toImg(url, ensureContext(opts)),
4088
- toSvg: (opts) => toImg(url, ensureContext(opts)),
4089
- toCanvas: (opts) => toCanvas(url, ensureContext(opts)),
4090
- toBlob: (opts) => toBlob(url, ensureContext(opts)),
4091
- toPng: withFormat("png"),
4092
- toJpg: withFormat("jpeg"),
4093
- toWebp: withFormat("webp"),
4094
- download: (opts) => download(url, ensureContext(opts))
4590
+ to: (type, opts) => runExport(type, opts),
4591
+ // Métodos “clásicos” que los tests esperan:
4592
+ toImg: (opts) => runExport("img", opts),
4593
+ toSvg: (opts) => runExport("svg", opts),
4594
+ toCanvas: (opts) => runExport("canvas", opts),
4595
+ toBlob: (opts) => runExport("blob", opts),
4596
+ toPng: (opts) => runExport("png", opts),
4597
+ toJpg: (opts) => runExport("jpg", opts),
4598
+ // ← alias requerido por los tests
4599
+ toWebp: (opts) => runExport("webp", opts),
4600
+ download: (opts) => runExport("download", opts)
4601
+ // ← método directo (no toDownload)
4095
4602
  };
4603
+ for (const key of Object.keys(exportsMap)) {
4604
+ const helper = "to" + key.charAt(0).toUpperCase() + key.slice(1);
4605
+ if (!result[helper]) {
4606
+ result[helper] = (opts) => runExport(key, opts);
4607
+ }
4608
+ }
4609
+ return result;
4096
4610
  });
4097
4611
  snapdom.toRaw = (el, options) => snapdom(el, options).then((result) => result.toRaw());
4098
4612
  snapdom.toImg = (el, options) => snapdom(el, options).then((result) => result.toImg());
@@ -4115,30 +4629,47 @@ ${imported}
4115
4629
  try {
4116
4630
  url = yield captureDOM(element, preflight);
4117
4631
  } catch (e) {
4118
- return;
4119
4632
  }
4120
- yield new Promise((resolve) => {
4121
- const img = new Image();
4122
- img.decoding = "sync";
4123
- img.loading = "eager";
4124
- img.style.position = "fixed";
4125
- img.style.left = 0;
4126
- img.style.top = 0;
4127
- img.style.width = "10px";
4128
- img.style.height = "10px";
4129
- img.style.opacity = "0.01";
4130
- img.style.transform = "translateZ(10px)";
4131
- img.style.willChange = "transform,opacity;";
4132
- img.src = url;
4133
- const cleanup = () => __async(null, null, function* () {
4134
- yield new Promise((r) => setTimeout(r, 100));
4135
- if (img && img.parentNode) img.parentNode.removeChild(img);
4136
- _safariWarmup = true;
4137
- resolve();
4633
+ yield new Promise((r) => requestAnimationFrame(() => requestAnimationFrame(r)));
4634
+ if (url) {
4635
+ yield new Promise((resolve) => {
4636
+ const img = new Image();
4637
+ try {
4638
+ img.decoding = "sync";
4639
+ img.loading = "eager";
4640
+ } catch (e) {
4641
+ }
4642
+ img.style.cssText = "position:fixed;left:0px;top:0px;width:10px;height:10px;opacity:0.01;pointer-events:none;";
4643
+ img.src = url;
4644
+ document.body.appendChild(img);
4645
+ (() => __async(null, null, function* () {
4646
+ try {
4647
+ if (typeof img.decode === "function") yield img.decode();
4648
+ } catch (e) {
4649
+ }
4650
+ const start = performance.now();
4651
+ while (!(img.complete && img.naturalWidth > 0) && performance.now() - start < 900) {
4652
+ yield new Promise((r) => setTimeout(r, 50));
4653
+ }
4654
+ yield new Promise((r) => requestAnimationFrame(r));
4655
+ try {
4656
+ img.remove();
4657
+ } catch (e) {
4658
+ }
4659
+ resolve();
4660
+ }))();
4138
4661
  });
4139
- document.body.appendChild(img);
4140
- cleanup();
4662
+ }
4663
+ element.querySelectorAll("canvas").forEach((c) => {
4664
+ try {
4665
+ const ctx = c.getContext("2d", { willReadFrequently: true });
4666
+ if (ctx) {
4667
+ ctx.getImageData(0, 0, 1, 1);
4668
+ }
4669
+ } catch (e) {
4670
+ }
4141
4671
  });
4672
+ _safariWarmup = true;
4142
4673
  });
4143
4674
  }
4144
4675
  function hasBackgroundOrMask(el) {
@@ -4152,6 +4683,7 @@ ${imported}
4152
4683
  const bg = cs.backgroundImage && cs.backgroundImage !== "none";
4153
4684
  const mask = cs.maskImage && cs.maskImage !== "none" || cs.webkitMaskImage && cs.webkitMaskImage !== "none";
4154
4685
  if (bg || mask) return true;
4686
+ if (node.tagName === "CANVAS") return true;
4155
4687
  }
4156
4688
  return false;
4157
4689
  }
@@ -4159,7 +4691,7 @@ ${imported}
4159
4691
  // src/api/preCache.js
4160
4692
  function preCache() {
4161
4693
  return __async(this, arguments, function* (root = document, options = {}) {
4162
- var _a, _b, _c, _d;
4694
+ var _a, _b, _c, _d, _e, _f;
4163
4695
  const {
4164
4696
  embedFonts = true,
4165
4697
  useProxy = ""
@@ -4179,6 +4711,7 @@ ${imported}
4179
4711
  cache.session.styleCache = /* @__PURE__ */ new WeakMap();
4180
4712
  }
4181
4713
  cache.image = cache.image || /* @__PURE__ */ new Map();
4714
+ cache.background = cache.background || /* @__PURE__ */ new Map();
4182
4715
  try {
4183
4716
  yield inlineBackgroundImages(
4184
4717
  root,
@@ -4191,7 +4724,13 @@ ${imported}
4191
4724
  }
4192
4725
  let imgEls = [], allEls = [];
4193
4726
  try {
4194
- if (root == null ? void 0 : root.querySelectorAll) {
4727
+ if (root && root.nodeType === 1) {
4728
+ const descendants = root.querySelectorAll ? Array.from(root.querySelectorAll("*")) : [];
4729
+ allEls = [root, ...descendants];
4730
+ imgEls = [];
4731
+ if (root.tagName === "IMG" && root.getAttribute("src")) imgEls.push(root);
4732
+ imgEls.push(...Array.from(((_d = root.querySelectorAll) == null ? void 0 : _d.call(root, "img[src]")) || []));
4733
+ } else if (root == null ? void 0 : root.querySelectorAll) {
4195
4734
  imgEls = Array.from(root.querySelectorAll("img[src]"));
4196
4735
  allEls = Array.from(root.querySelectorAll("*"));
4197
4736
  }
@@ -4215,17 +4754,18 @@ ${imported}
4215
4754
  for (const el of allEls) {
4216
4755
  let bg = "";
4217
4756
  try {
4218
- bg = getStyle(el).backgroundImage;
4757
+ bg = ((_e = el == null ? void 0 : el.style) == null ? void 0 : _e.backgroundImage) || "";
4758
+ if (!bg || bg === "none") {
4759
+ bg = getStyle(el).backgroundImage;
4760
+ }
4219
4761
  } catch (e) {
4220
4762
  }
4221
4763
  if (bg && bg !== "none") {
4222
- const parts = splitBackgroundImage(bg);
4223
- for (const entry of parts) {
4224
- if (entry.startsWith("url(")) {
4225
- const p = Promise.resolve().then(() => inlineSingleBackgroundEntry(entry, __spreadProps(__spreadValues({}, options), { useProxy }))).catch(() => {
4226
- });
4227
- promises.push(p);
4228
- }
4764
+ const urlEntries = bg.match(/url\((?:[^()"']+|"(?:[^"]*)"|'(?:[^']*)')\)/gi) || [];
4765
+ for (const entry of urlEntries) {
4766
+ const p = Promise.resolve().then(() => inlineSingleBackgroundEntry(entry, __spreadProps(__spreadValues({}, options), { useProxy }))).catch(() => {
4767
+ });
4768
+ promises.push(p);
4229
4769
  }
4230
4770
  }
4231
4771
  }
@@ -4245,7 +4785,7 @@ ${imported}
4245
4785
  usedCodepoints,
4246
4786
  exclude: options.excludeFonts,
4247
4787
  localFonts: options.localFonts,
4248
- useProxy: (_d = options.useProxy) != null ? _d : useProxy
4788
+ useProxy: (_f = options.useProxy) != null ? _f : useProxy
4249
4789
  });
4250
4790
  } catch (e) {
4251
4791
  }