@burdenoff/microfe-bigconsole 2026.1103.6 → 2026.1103.7

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.
@@ -1,90 +1,70 @@
1
- import { useCallback as e, useState as t } from "react";
1
+ import { elementToCanvas as e } from "../utils/elementToCanvas.js";
2
+ import { useCallback as t, useState as n } from "react";
3
+ import { useI18n as r } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
4
+ import { toast as i } from "sonner";
2
5
  //#region src/bigconsole/hooks/useDashboardImageExport.ts
3
- function n(e, t) {
6
+ function a(e, t) {
4
7
  let n = URL.createObjectURL(e), r = document.createElement("a");
5
8
  r.href = n, r.download = t, r.click(), URL.revokeObjectURL(n);
6
9
  }
7
- function r(e) {
8
- let t = getComputedStyle(e).backgroundColor;
9
- return !t || t === "transparent" || /,\s*0\)\s*$/.test(t) ? getComputedStyle(document.documentElement).getPropertyValue("--color-bg-surface").trim() || "transparent" : t;
10
- }
11
- async function i(e) {
12
- if (typeof window < "u" && "html2canvas" in window) return await window.html2canvas(e, {
13
- backgroundColor: r(e),
14
- scale: 2,
15
- useCORS: !0
16
- });
17
- let t = document.createElement("canvas"), n = t.getContext("2d");
18
- if (!n) throw Error("Could not get canvas context");
19
- let i = e.getBoundingClientRect();
20
- t.width = i.width * 2, t.height = i.height * 2, n.scale(2, 2), n.fillStyle = r(e), n.fillRect(0, 0, i.width, i.height);
21
- let a = e.querySelectorAll("svg");
22
- for (let e of a) {
23
- let t = new XMLSerializer().serializeToString(e), r = new Blob([t], { type: "image/svg+xml;charset=utf-8" }), a = URL.createObjectURL(r);
24
- try {
25
- await new Promise((t) => {
26
- let r = new Image();
27
- r.onload = () => {
28
- let a = e.getBoundingClientRect();
29
- n.drawImage(r, a.left - i.left, a.top - i.top), t();
30
- }, r.onerror = () => t(), r.src = a;
31
- });
32
- } finally {
33
- URL.revokeObjectURL(a);
34
- }
35
- }
36
- return t;
37
- }
38
- function a(r) {
39
- let { containerRef: a, name: o = "dashboard" } = r, [s, c] = t(!1);
10
+ function o(o) {
11
+ let { containerRef: s, name: c = "dashboard" } = o, [l, u] = n(!1), { t: d } = r(), f = t(() => {
12
+ i.error(d("bigconsole.dashboards.export.failed", "Could not export the dashboard. Please try again."));
13
+ }, [d]);
40
14
  return {
41
- exportPNG: e(async (e) => {
42
- let t = a.current;
43
- if (!(!t || s)) {
44
- c(!0);
15
+ exportPNG: t(async (t) => {
16
+ let n = s.current;
17
+ if (!(!n || l)) {
18
+ u(!0);
45
19
  try {
46
- let r = await i(t), a = await new Promise((e, t) => {
20
+ let r = await e(n), i = await new Promise((e, t) => {
47
21
  r.toBlob((n) => n ? e(n) : t(/* @__PURE__ */ Error("Failed to create image blob")), "image/png");
48
- }), s = o.replace(/\s+/g, "_").toLowerCase();
49
- n(a, e || `${s}_board.png`);
22
+ }), o = c.replace(/\s+/g, "_").toLowerCase();
23
+ a(i, t || `${o}_board.png`);
24
+ } catch {
25
+ f();
50
26
  } finally {
51
- c(!1);
27
+ u(!1);
52
28
  }
53
29
  }
54
30
  }, [
55
- a,
56
- o,
57
- s
31
+ s,
32
+ c,
33
+ l,
34
+ f
58
35
  ]),
59
- exportPDF: e(async () => {
60
- let e = a.current;
61
- if (!(!e || s)) {
62
- c(!0);
36
+ exportPDF: t(async () => {
37
+ let t = s.current;
38
+ if (!(!t || l)) {
39
+ u(!0);
63
40
  try {
64
- let t = await i(e), n = t.toDataURL("image/png"), r = `${o} — board`, a = window.open("", "_blank");
41
+ let n = await e(t), r = n.toDataURL("image/png"), i = `${c} — board`, a = window.open("", "_blank");
65
42
  if (!a) {
66
43
  window.print();
67
44
  return;
68
45
  }
69
- let s = t.width >= t.height ? "landscape" : "portrait", c = a.document;
70
- c.title = r;
71
- let l = c.createElement("style");
72
- l.textContent = `@page{size:${s};margin:12mm}html,body{margin:0;padding:0}img{width:100%;height:auto;display:block}`, c.head.appendChild(l);
73
- let u = c.createElement("img");
74
- u.alt = r, u.addEventListener("load", () => {
46
+ let o = n.width >= n.height ? "landscape" : "portrait", s = a.document;
47
+ s.title = i;
48
+ let l = s.createElement("style");
49
+ l.textContent = `@page{size:${o};margin:12mm}html,body{margin:0;padding:0}img{width:100%;height:auto;display:block}`, s.head.appendChild(l);
50
+ let u = s.createElement("img");
51
+ u.alt = i, u.addEventListener("load", () => {
75
52
  a.focus(), a.print();
76
- }), u.src = n, c.body.appendChild(u);
53
+ }), u.src = r, s.body.appendChild(u);
54
+ } catch {
55
+ f();
77
56
  } finally {
78
- c(!1);
57
+ u(!1);
79
58
  }
80
59
  }
81
60
  }, [
82
- a,
83
- o,
84
- s
61
+ s,
62
+ c,
63
+ l,
64
+ f
85
65
  ]),
86
- isExporting: s
66
+ isExporting: l
87
67
  };
88
68
  }
89
69
  //#endregion
90
- export { a as default, a as useDashboardImageExport };
70
+ export { o as default, o as useDashboardImageExport };
@@ -1,75 +1,61 @@
1
- import { useCallback as e, useRef as t } from "react";
1
+ import { elementToCanvas as e } from "../utils/elementToCanvas.js";
2
+ import { useCallback as t, useRef as n } from "react";
3
+ import { useI18n as r } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
4
+ import { toast as i } from "sonner";
2
5
  //#region src/bigconsole/hooks/useWidgetExport.ts
3
- function n(e) {
6
+ function a(e) {
4
7
  if (!e.length) return "";
5
8
  let t = Object.keys(e[0]), n = [];
6
- n.push(t.map(r).join(","));
7
- for (let i of e) {
9
+ n.push(t.map(o).join(","));
10
+ for (let r of e) {
8
11
  let e = t.map((e) => {
9
- let t = i[e];
10
- return r(t);
12
+ let t = r[e];
13
+ return o(t);
11
14
  });
12
15
  n.push(e.join(","));
13
16
  }
14
17
  return n.join("\n");
15
18
  }
16
- function r(e) {
19
+ function o(e) {
17
20
  if (e == null) return "";
18
21
  let t = String(e);
19
22
  return t.includes(",") || t.includes("\"") || t.includes("\n") || t.includes("\r") ? `"${t.replace(/"/g, "\"\"")}"` : t;
20
23
  }
21
- function i(e, t, n) {
24
+ function s(e, t, n) {
22
25
  let r = e instanceof Blob ? e : new Blob([e], { type: n }), i = URL.createObjectURL(r), a = document.createElement("a");
23
26
  a.href = i, a.download = t, document.body.appendChild(a), a.click(), document.body.removeChild(a), setTimeout(() => URL.revokeObjectURL(i), 100);
24
27
  }
25
- async function a(e) {
26
- if (typeof window < "u" && "html2canvas" in window) return await window.html2canvas(e, {
27
- backgroundColor: null,
28
- scale: 2,
29
- logging: !1,
30
- useCORS: !0
31
- });
32
- let t = document.createElement("canvas"), n = t.getContext("2d");
33
- if (!n) throw Error("Could not get canvas context");
34
- let r = e.getBoundingClientRect();
35
- t.width = r.width * 2, t.height = r.height * 2, n.scale(2, 2);
36
- let i = e.querySelectorAll("svg");
37
- if (i.length > 0) for (let e of i) {
38
- let t = new XMLSerializer().serializeToString(e), i = new Blob([t], { type: "image/svg+xml;charset=utf-8" }), a = URL.createObjectURL(i), o = new Image();
39
- await new Promise((t, i) => {
40
- o.onload = () => {
41
- let i = e.getBoundingClientRect(), s = i.left - r.left, c = i.top - r.top;
42
- n.drawImage(o, s, c), URL.revokeObjectURL(a), t();
43
- }, o.onerror = i, o.src = a;
44
- });
45
- }
46
- return n.globalCompositeOperation = "destination-over", n.fillStyle = getComputedStyle(e).backgroundColor || "#ffffff", n.fillRect(0, 0, t.width / 2, t.height / 2), t;
47
- }
48
- function o(r, o = {}) {
49
- let { data: s, containerRef: c } = o, l = t(!1);
28
+ function c(o, c = {}) {
29
+ let { data: l, containerRef: u } = c, d = n(!1), { t: f } = r();
50
30
  return {
51
- exportCSV: e((e) => {
52
- if (!s?.length) return;
53
- let t = n(s), a = `${r.title.replace(/\s+/g, "_").toLowerCase()}_${Date.now()}.csv`;
54
- i(t, e || a, "text/csv;charset=utf-8");
55
- }, [s, r.title]),
56
- exportPNG: e(async (e) => {
57
- if (c?.current && !l.current) {
58
- l.current = !0;
31
+ exportCSV: t((e) => {
32
+ if (!l?.length) return;
33
+ let t = a(l), n = `${o.title.replace(/\s+/g, "_").toLowerCase()}_${Date.now()}.csv`;
34
+ s(t, e || n, "text/csv;charset=utf-8");
35
+ }, [l, o.title]),
36
+ exportPNG: t(async (t) => {
37
+ if (u?.current && !d.current) {
38
+ d.current = !0;
59
39
  try {
60
- let t = await a(c.current), n = await new Promise((e, n) => {
61
- t.toBlob((t) => {
62
- t ? e(t) : n(/* @__PURE__ */ Error("Failed to create image blob"));
40
+ let n = await e(u.current), r = await new Promise((e, t) => {
41
+ n.toBlob((n) => {
42
+ n ? e(n) : t(/* @__PURE__ */ Error("Failed to create image blob"));
63
43
  }, "image/png");
64
- }), o = `${r.title.replace(/\s+/g, "_").toLowerCase()}_${Date.now()}.png`;
65
- i(n, e || o, "image/png");
66
- } catch {} finally {
67
- l.current = !1;
44
+ }), i = `${o.title.replace(/\s+/g, "_").toLowerCase()}_${Date.now()}.png`;
45
+ s(r, t || i, "image/png");
46
+ } catch {
47
+ i.error(f("bigconsole.widget.export.failed", "Could not export the widget image. Please try again."));
48
+ } finally {
49
+ d.current = !1;
68
50
  }
69
51
  }
70
- }, [c, r.title]),
71
- isExporting: l.current
52
+ }, [
53
+ u,
54
+ o.title,
55
+ f
56
+ ]),
57
+ isExporting: d.current
72
58
  };
73
59
  }
74
60
  //#endregion
75
- export { o as default, o as useWidgetExport };
61
+ export { c as default, c as useWidgetExport };
@@ -0,0 +1,9 @@
1
+ /** Export resolution multiplier, so text stays sharp when the image is zoomed or printed. */
2
+ export declare const EXPORT_PIXEL_RATIO = 2;
3
+ /**
4
+ * A concrete background fill for the export. Prefers the element's own computed
5
+ * background, then the resolved `--color-bg-surface` theme token, then none (a
6
+ * transparent image), so no colour literal is needed.
7
+ */
8
+ export declare function resolveExportBackground(element: HTMLElement): string | undefined;
9
+ export declare function elementToCanvas(element: HTMLElement): Promise<HTMLCanvasElement>;
@@ -0,0 +1,16 @@
1
+ import { toCanvas as e } from "../../node_modules/html-to-image/es/index.js";
2
+ //#region src/bigconsole/utils/elementToCanvas.ts
3
+ var t = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
4
+ function n(e) {
5
+ let t = getComputedStyle(e).backgroundColor;
6
+ return !t || t === "transparent" || /,\s*0\)\s*$/.test(t) ? getComputedStyle(document.documentElement).getPropertyValue("--color-bg-surface").trim() || void 0 : t;
7
+ }
8
+ async function r(r) {
9
+ return e(r, {
10
+ pixelRatio: 2,
11
+ backgroundColor: n(r),
12
+ imagePlaceholder: t
13
+ });
14
+ }
15
+ //#endregion
16
+ export { r as elementToCanvas, n as resolveExportBackground };
@@ -0,0 +1,11 @@
1
+ //#region node_modules/html-to-image/es/apply-style.js
2
+ function e(e, t) {
3
+ let { style: n } = e;
4
+ t.backgroundColor && (n.backgroundColor = t.backgroundColor), t.width && (n.width = `${t.width}px`), t.height && (n.height = `${t.height}px`);
5
+ let r = t.style;
6
+ return r != null && Object.keys(r).forEach((e) => {
7
+ n[e] = r[e];
8
+ }), e;
9
+ }
10
+ //#endregion
11
+ export { e as applyStyle };
@@ -0,0 +1,82 @@
1
+ import { createImage as e, getStyleProperties as t, isInstanceOfElement as n, toArray as r } from "./util.js";
2
+ import { clonePseudoElements as i } from "./clone-pseudos.js";
3
+ import { getMimeType as a } from "./mimes.js";
4
+ import { resourceToDataURL as o } from "./dataurl.js";
5
+ //#region node_modules/html-to-image/es/clone-node.js
6
+ async function s(t) {
7
+ let n = t.toDataURL();
8
+ return n === "data:," ? t.cloneNode(!1) : e(n);
9
+ }
10
+ async function c(t, n) {
11
+ if (t.currentSrc) {
12
+ let n = document.createElement("canvas"), r = n.getContext("2d");
13
+ return n.width = t.clientWidth, n.height = t.clientHeight, r?.drawImage(t, 0, 0, n.width, n.height), e(n.toDataURL());
14
+ }
15
+ let r = t.poster;
16
+ return e(await o(r, a(r), n));
17
+ }
18
+ async function l(e, t) {
19
+ try {
20
+ if (e?.contentDocument?.body) return await y(e.contentDocument.body, t, !0);
21
+ } catch {}
22
+ return e.cloneNode(!1);
23
+ }
24
+ async function u(e, t) {
25
+ return n(e, HTMLCanvasElement) ? s(e) : n(e, HTMLVideoElement) ? c(e, t) : n(e, HTMLIFrameElement) ? l(e, t) : e.cloneNode(f(e));
26
+ }
27
+ var d = (e) => e.tagName != null && e.tagName.toUpperCase() === "SLOT", f = (e) => e.tagName != null && e.tagName.toUpperCase() === "SVG";
28
+ async function p(e, t, i) {
29
+ if (f(t)) return t;
30
+ let a = [];
31
+ return a = d(e) && e.assignedNodes ? r(e.assignedNodes()) : n(e, HTMLIFrameElement) && e.contentDocument?.body ? r(e.contentDocument.body.childNodes) : r((e.shadowRoot ?? e).childNodes), a.length === 0 || n(e, HTMLVideoElement) || await a.reduce((e, n) => e.then(() => y(n, i)).then((e) => {
32
+ e && t.appendChild(e);
33
+ }), Promise.resolve()), t;
34
+ }
35
+ function m(e, r, i) {
36
+ let a = r.style;
37
+ if (!a) return;
38
+ let o = window.getComputedStyle(e);
39
+ o.cssText ? (a.cssText = o.cssText, a.transformOrigin = o.transformOrigin) : t(i).forEach((t) => {
40
+ let i = o.getPropertyValue(t);
41
+ t === "font-size" && i.endsWith("px") && (i = `${Math.floor(parseFloat(i.substring(0, i.length - 2))) - .1}px`), n(e, HTMLIFrameElement) && t === "display" && i === "inline" && (i = "block"), t === "d" && r.getAttribute("d") && (i = `path(${r.getAttribute("d")})`), a.setProperty(t, i, o.getPropertyPriority(t));
42
+ });
43
+ }
44
+ function h(e, t) {
45
+ n(e, HTMLTextAreaElement) && (t.innerHTML = e.value), n(e, HTMLInputElement) && t.setAttribute("value", e.value);
46
+ }
47
+ function g(e, t) {
48
+ if (n(e, HTMLSelectElement)) {
49
+ let n = t, r = Array.from(n.children).find((t) => e.value === t.getAttribute("value"));
50
+ r && r.setAttribute("selected", "");
51
+ }
52
+ }
53
+ function _(e, t, r) {
54
+ return n(t, Element) && (m(e, t, r), i(e, t, r), h(e, t), g(e, t)), t;
55
+ }
56
+ async function v(e, t) {
57
+ let n = e.querySelectorAll ? e.querySelectorAll("use") : [];
58
+ if (n.length === 0) return e;
59
+ let r = {};
60
+ for (let i = 0; i < n.length; i++) {
61
+ let a = n[i].getAttribute("xlink:href");
62
+ if (a) {
63
+ let n = e.querySelector(a), i = document.querySelector(a);
64
+ !n && i && !r[a] && (r[a] = await y(i, t, !0));
65
+ }
66
+ }
67
+ let i = Object.values(r);
68
+ if (i.length) {
69
+ let t = "http://www.w3.org/1999/xhtml", n = document.createElementNS(t, "svg");
70
+ n.setAttribute("xmlns", t), n.style.position = "absolute", n.style.width = "0", n.style.height = "0", n.style.overflow = "hidden", n.style.display = "none";
71
+ let r = document.createElementNS(t, "defs");
72
+ n.appendChild(r);
73
+ for (let e = 0; e < i.length; e++) r.appendChild(i[e]);
74
+ e.appendChild(n);
75
+ }
76
+ return e;
77
+ }
78
+ async function y(e, t, n) {
79
+ return !n && t.filter && !t.filter(e) ? null : Promise.resolve(e).then((e) => u(e, t)).then((n) => p(e, n, t)).then((n) => _(e, n, t)).then((e) => v(e, t));
80
+ }
81
+ //#endregion
82
+ export { y as cloneNode };
@@ -0,0 +1,30 @@
1
+ import { getStyleProperties as e, uuid as t } from "./util.js";
2
+ //#region node_modules/html-to-image/es/clone-pseudos.js
3
+ function n(e) {
4
+ let t = e.getPropertyValue("content");
5
+ return `${e.cssText} content: '${t.replace(/'|"/g, "")}';`;
6
+ }
7
+ function r(t, n) {
8
+ return e(n).map((e) => `${e}: ${t.getPropertyValue(e)}${t.getPropertyPriority(e) ? " !important" : ""};`).join(" ");
9
+ }
10
+ function i(e, t, i, a) {
11
+ let o = `.${e}:${t}`, s = i.cssText ? n(i) : r(i, a);
12
+ return document.createTextNode(`${o}{${s}}`);
13
+ }
14
+ function a(e, n, r, a) {
15
+ let o = window.getComputedStyle(e, r), s = o.getPropertyValue("content");
16
+ if (s === "" || s === "none") return;
17
+ let c = t();
18
+ try {
19
+ n.className = `${n.className} ${c}`;
20
+ } catch {
21
+ return;
22
+ }
23
+ let l = document.createElement("style");
24
+ l.appendChild(i(c, r, o, a)), n.appendChild(l);
25
+ }
26
+ function o(e, t, n) {
27
+ a(e, t, ":before", n), a(e, t, ":after", n);
28
+ }
29
+ //#endregion
30
+ export { o as clonePseudoElements };
@@ -0,0 +1,49 @@
1
+ //#region node_modules/html-to-image/es/dataurl.js
2
+ function e(e) {
3
+ return e.split(/,/)[1];
4
+ }
5
+ function t(e) {
6
+ return e.search(/^(data:)/) !== -1;
7
+ }
8
+ function n(e, t) {
9
+ return `data:${t};base64,${e}`;
10
+ }
11
+ async function r(e, t, n) {
12
+ let r = await fetch(e, t);
13
+ if (r.status === 404) throw Error(`Resource "${r.url}" not found`);
14
+ let i = await r.blob();
15
+ return new Promise((e, t) => {
16
+ let a = new FileReader();
17
+ a.onerror = t, a.onloadend = () => {
18
+ try {
19
+ e(n({
20
+ res: r,
21
+ result: a.result
22
+ }));
23
+ } catch (e) {
24
+ t(e);
25
+ }
26
+ }, a.readAsDataURL(i);
27
+ });
28
+ }
29
+ var i = {};
30
+ function a(e, t, n) {
31
+ let r = e.replace(/\?.*/, "");
32
+ return n && (r = e), /ttf|otf|eot|woff2?/i.test(r) && (r = r.replace(/.*\//, "")), t ? `[${t}]${r}` : r;
33
+ }
34
+ async function o(t, o, s) {
35
+ let c = a(t, o, s.includeQueryParams);
36
+ if (i[c] != null) return i[c];
37
+ s.cacheBust && (t += (/\?/.test(t) ? "&" : "?") + (/* @__PURE__ */ new Date()).getTime());
38
+ let l;
39
+ try {
40
+ l = n(await r(t, s.fetchRequestInit, ({ res: t, result: n }) => (o ||= t.headers.get("Content-Type") || "", e(n))), o);
41
+ } catch (e) {
42
+ l = s.imagePlaceholder || "";
43
+ let n = `Failed to fetch resource: ${t}`;
44
+ e && (n = typeof e == "string" ? e : e.message), n && console.warn(n);
45
+ }
46
+ return i[c] = l, l;
47
+ }
48
+ //#endregion
49
+ export { r as fetchAsDataURL, t as isDataUrl, n as makeDataUrl, o as resourceToDataURL };
@@ -0,0 +1,41 @@
1
+ import { isInstanceOfElement as e, toArray as t } from "./util.js";
2
+ import { getMimeType as n } from "./mimes.js";
3
+ import { isDataUrl as r, resourceToDataURL as i } from "./dataurl.js";
4
+ import { embedResources as a } from "./embed-resources.js";
5
+ //#region node_modules/html-to-image/es/embed-images.js
6
+ async function o(e, t, n) {
7
+ let r = t.style?.getPropertyValue(e);
8
+ if (r) {
9
+ let i = await a(r, null, n);
10
+ return t.style.setProperty(e, i, t.style.getPropertyPriority(e)), !0;
11
+ }
12
+ return !1;
13
+ }
14
+ async function s(e, t) {
15
+ await o("background", e, t) || await o("background-image", e, t), await o("mask", e, t) || await o("-webkit-mask", e, t) || await o("mask-image", e, t) || await o("-webkit-mask-image", e, t);
16
+ }
17
+ async function c(t, a) {
18
+ let o = e(t, HTMLImageElement);
19
+ if (!(o && !r(t.src)) && !(e(t, SVGImageElement) && !r(t.href.baseVal))) return;
20
+ let s = o ? t.src : t.href.baseVal, c = await i(s, n(s), a);
21
+ await new Promise((e, n) => {
22
+ t.onload = e, t.onerror = a.onImageErrorHandler ? (...t) => {
23
+ try {
24
+ e(a.onImageErrorHandler(...t));
25
+ } catch (e) {
26
+ n(e);
27
+ }
28
+ } : n;
29
+ let r = t;
30
+ r.decode &&= e, r.loading === "lazy" && (r.loading = "eager"), o ? (t.srcset = "", t.src = c) : t.href.baseVal = c;
31
+ });
32
+ }
33
+ async function l(e, n) {
34
+ let r = t(e.childNodes).map((e) => u(e, n));
35
+ await Promise.all(r).then(() => e);
36
+ }
37
+ async function u(t, n) {
38
+ e(t, Element) && (await s(t, n), await c(t, n), await l(t, n));
39
+ }
40
+ //#endregion
41
+ export { u as embedImages };
@@ -0,0 +1,39 @@
1
+ import { resolveUrl as e } from "./util.js";
2
+ import { getMimeType as t } from "./mimes.js";
3
+ import { isDataUrl as n, makeDataUrl as r, resourceToDataURL as i } from "./dataurl.js";
4
+ //#region node_modules/html-to-image/es/embed-resources.js
5
+ var a = /url\((['"]?)([^'"]+?)\1\)/g, o = /url\([^)]+\)\s*format\((["']?)([^"']+)\1\)/g, s = /src:\s*(?:url\([^)]+\)\s*format\([^)]+\)[,;]\s*)+/g;
6
+ function c(e) {
7
+ let t = e.replace(/([.*+?^${}()|\[\]\/\\])/g, "\\$1");
8
+ return RegExp(`(url\\(['"]?)(${t})(['"]?\\))`, "g");
9
+ }
10
+ function l(e) {
11
+ let t = [];
12
+ return e.replace(a, (e, n, r) => (t.push(r), e)), t.filter((e) => !n(e));
13
+ }
14
+ async function u(n, a, o, s, l) {
15
+ try {
16
+ let u = o ? e(a, o) : a, d = t(a), f;
17
+ return f = l ? r(await l(u), d) : await i(u, d, s), n.replace(c(a), `$1${f}$3`);
18
+ } catch {}
19
+ return n;
20
+ }
21
+ function d(e, { preferredFontFormat: t }) {
22
+ return t ? e.replace(s, (e) => {
23
+ for (;;) {
24
+ let [n, , r] = o.exec(e) || [];
25
+ if (!r) return "";
26
+ if (r === t) return `src: ${n};`;
27
+ }
28
+ }) : e;
29
+ }
30
+ function f(e) {
31
+ return e.search(a) !== -1;
32
+ }
33
+ async function p(e, t, n) {
34
+ if (!f(e)) return e;
35
+ let r = d(e, n);
36
+ return l(r).reduce((e, r) => e.then((e) => u(e, r, t, n)), Promise.resolve(r));
37
+ }
38
+ //#endregion
39
+ export { u as embed, p as embedResources, l as parseURLs, f as shouldEmbed };
@@ -0,0 +1,115 @@
1
+ import { toArray as e } from "./util.js";
2
+ import { fetchAsDataURL as t } from "./dataurl.js";
3
+ import { embedResources as n, shouldEmbed as r } from "./embed-resources.js";
4
+ //#region node_modules/html-to-image/es/embed-webfonts.js
5
+ var i = {};
6
+ async function a(e) {
7
+ let t = i[e];
8
+ return t ?? (t = {
9
+ url: e,
10
+ cssText: await (await fetch(e)).text()
11
+ }, i[e] = t, t);
12
+ }
13
+ async function o(e, n) {
14
+ let r = e.cssText, i = /url\(["']?([^"')]+)["']?\)/g, a = (r.match(/url\([^)]+\)/g) || []).map(async (a) => {
15
+ let o = a.replace(i, "$1");
16
+ return o.startsWith("https://") || (o = new URL(o, e.url).href), t(o, n.fetchRequestInit, ({ result: e }) => (r = r.replace(a, `url(${e})`), [a, e]));
17
+ });
18
+ return Promise.all(a).then(() => r);
19
+ }
20
+ function s(e) {
21
+ if (e == null) return [];
22
+ let t = [], n = e.replace(/(\/\*[\s\S]*?\*\/)/gi, ""), r = /* @__PURE__ */ RegExp("((@.*?keyframes [\\s\\S]*?){([\\s\\S]*?}\\s*?)})", "gi");
23
+ for (;;) {
24
+ let e = r.exec(n);
25
+ if (e === null) break;
26
+ t.push(e[0]);
27
+ }
28
+ n = n.replace(r, "");
29
+ let i = /@import[\s\S]*?url\([^)]*\)[\s\S]*?;/gi, a = /* @__PURE__ */ RegExp("((\\s*?(?:\\/\\*[\\s\\S]*?\\*\\/)?\\s*?@media[\\s\\S]*?){([\\s\\S]*?)}\\s*?})|(([\\s\\S]*?){([\\s\\S]*?)})", "gi");
30
+ for (;;) {
31
+ let e = i.exec(n);
32
+ if (e === null) {
33
+ if (e = a.exec(n), e === null) break;
34
+ i.lastIndex = a.lastIndex;
35
+ } else a.lastIndex = i.lastIndex;
36
+ t.push(e[0]);
37
+ }
38
+ return t;
39
+ }
40
+ async function c(t, n) {
41
+ let r = [], i = [];
42
+ return t.forEach((r) => {
43
+ if ("cssRules" in r) try {
44
+ e(r.cssRules || []).forEach((e, t) => {
45
+ if (e.type === CSSRule.IMPORT_RULE) {
46
+ let c = t + 1, l = e.href, u = a(l).then((e) => o(e, n)).then((e) => s(e).forEach((e) => {
47
+ try {
48
+ r.insertRule(e, e.startsWith("@import") ? c += 1 : r.cssRules.length);
49
+ } catch (t) {
50
+ console.error("Error inserting rule from remote css", {
51
+ rule: e,
52
+ error: t
53
+ });
54
+ }
55
+ })).catch((e) => {
56
+ console.error("Error loading remote css", e.toString());
57
+ });
58
+ i.push(u);
59
+ }
60
+ });
61
+ } catch (e) {
62
+ let c = t.find((e) => e.href == null) || document.styleSheets[0];
63
+ r.href != null && i.push(a(r.href).then((e) => o(e, n)).then((e) => s(e).forEach((e) => {
64
+ c.insertRule(e, c.cssRules.length);
65
+ })).catch((e) => {
66
+ console.error("Error loading remote stylesheet", e);
67
+ })), console.error("Error inlining remote css file", e);
68
+ }
69
+ }), Promise.all(i).then(() => (t.forEach((t) => {
70
+ if ("cssRules" in t) try {
71
+ e(t.cssRules || []).forEach((e) => {
72
+ r.push(e);
73
+ });
74
+ } catch (e) {
75
+ console.error(`Error while reading CSS rules from ${t.href}`, e);
76
+ }
77
+ }), r));
78
+ }
79
+ function l(e) {
80
+ return e.filter((e) => e.type === CSSRule.FONT_FACE_RULE).filter((e) => r(e.style.getPropertyValue("src")));
81
+ }
82
+ async function u(t, n) {
83
+ if (t.ownerDocument == null) throw Error("Provided element is not within a Document");
84
+ return l(await c(e(t.ownerDocument.styleSheets), n));
85
+ }
86
+ function d(e) {
87
+ return e.trim().replace(/["']/g, "");
88
+ }
89
+ function f(e) {
90
+ let t = /* @__PURE__ */ new Set();
91
+ function n(e) {
92
+ (e.style.fontFamily || getComputedStyle(e).fontFamily).split(",").forEach((e) => {
93
+ t.add(d(e));
94
+ }), Array.from(e.children).forEach((e) => {
95
+ e instanceof HTMLElement && n(e);
96
+ });
97
+ }
98
+ return n(e), t;
99
+ }
100
+ async function p(e, t) {
101
+ let r = await u(e, t), i = f(e);
102
+ return (await Promise.all(r.filter((e) => i.has(d(e.style.fontFamily))).map((e) => {
103
+ let r = e.parentStyleSheet ? e.parentStyleSheet.href : null;
104
+ return n(e.cssText, r, t);
105
+ }))).join("\n");
106
+ }
107
+ async function m(e, t) {
108
+ let n = t.fontEmbedCSS == null ? t.skipFonts ? null : await p(e, t) : t.fontEmbedCSS;
109
+ if (n) {
110
+ let t = document.createElement("style"), r = document.createTextNode(n);
111
+ t.appendChild(r), e.firstChild ? e.insertBefore(t, e.firstChild) : e.appendChild(t);
112
+ }
113
+ }
114
+ //#endregion
115
+ export { m as embedWebFonts, p as getWebFontCSS };
@@ -0,0 +1,16 @@
1
+ import { checkCanvasDimensions as e, createImage as t, getImageSize as n, getPixelRatio as r, nodeToDataURL as i } from "./util.js";
2
+ import { cloneNode as a } from "./clone-node.js";
3
+ import { embedImages as o } from "./embed-images.js";
4
+ import { applyStyle as s } from "./apply-style.js";
5
+ import { embedWebFonts as c } from "./embed-webfonts.js";
6
+ //#region node_modules/html-to-image/es/index.js
7
+ async function l(e, t = {}) {
8
+ let { width: r, height: l } = n(e, t), u = await a(e, t, !0);
9
+ return await c(u, t), await o(u, t), s(u, t), await i(u, r, l);
10
+ }
11
+ async function u(i, a = {}) {
12
+ let { width: o, height: s } = n(i, a), c = await t(await l(i, a)), u = document.createElement("canvas"), d = u.getContext("2d"), f = a.pixelRatio || r(), p = a.canvasWidth || o, m = a.canvasHeight || s;
13
+ return u.width = p * f, u.height = m * f, a.skipAutoScale || e(u), u.style.width = `${p}`, u.style.height = `${m}`, a.backgroundColor && (d.fillStyle = a.backgroundColor, d.fillRect(0, 0, u.width, u.height)), d.drawImage(c, 0, 0, u.width, u.height), u;
14
+ }
15
+ //#endregion
16
+ export { u as toCanvas, l as toSvg };
@@ -0,0 +1,23 @@
1
+ //#region node_modules/html-to-image/es/mimes.js
2
+ var e = "application/font-woff", t = "image/jpeg", n = {
3
+ woff: e,
4
+ woff2: e,
5
+ ttf: "application/font-truetype",
6
+ eot: "application/vnd.ms-fontobject",
7
+ png: "image/png",
8
+ jpg: t,
9
+ jpeg: t,
10
+ gif: "image/gif",
11
+ tiff: "image/tiff",
12
+ svg: "image/svg+xml",
13
+ webp: "image/webp"
14
+ };
15
+ function r(e) {
16
+ let t = /\.([^./]*?)$/g.exec(e);
17
+ return t ? t[1] : "";
18
+ }
19
+ function i(e) {
20
+ return n[r(e).toLowerCase()] || "";
21
+ }
22
+ //#endregion
23
+ export { i as getMimeType };
@@ -0,0 +1,75 @@
1
+ //#region node_modules/html-to-image/es/util.js
2
+ function e(e, t) {
3
+ if (e.match(/^[a-z]+:\/\//i)) return e;
4
+ if (e.match(/^\/\//)) return window.location.protocol + e;
5
+ if (e.match(/^[a-z]+:/i)) return e;
6
+ let n = document.implementation.createHTMLDocument(), r = n.createElement("base"), i = n.createElement("a");
7
+ return n.head.appendChild(r), n.body.appendChild(i), t && (r.href = t), i.href = e, i.href;
8
+ }
9
+ var t = (() => {
10
+ let e = 0, t = () => `0000${(Math.random() * 36 ** 4 << 0).toString(36)}`.slice(-4);
11
+ return () => (e += 1, `u${t()}${e}`);
12
+ })();
13
+ function n(e) {
14
+ let t = [];
15
+ for (let n = 0, r = e.length; n < r; n++) t.push(e[n]);
16
+ return t;
17
+ }
18
+ var r = null;
19
+ function i(e = {}) {
20
+ return r || (e.includeStyleProperties ? (r = e.includeStyleProperties, r) : (r = n(window.getComputedStyle(document.documentElement)), r));
21
+ }
22
+ function a(e, t) {
23
+ let n = (e.ownerDocument.defaultView || window).getComputedStyle(e).getPropertyValue(t);
24
+ return n ? parseFloat(n.replace("px", "")) : 0;
25
+ }
26
+ function o(e) {
27
+ let t = a(e, "border-left-width"), n = a(e, "border-right-width");
28
+ return e.clientWidth + t + n;
29
+ }
30
+ function s(e) {
31
+ let t = a(e, "border-top-width"), n = a(e, "border-bottom-width");
32
+ return e.clientHeight + t + n;
33
+ }
34
+ function c(e, t = {}) {
35
+ return {
36
+ width: t.width || o(e),
37
+ height: t.height || s(e)
38
+ };
39
+ }
40
+ function l() {
41
+ let e, t;
42
+ try {
43
+ t = process;
44
+ } catch {}
45
+ let n = t && t.env ? t.env.devicePixelRatio : null;
46
+ return n && (e = parseInt(n, 10), Number.isNaN(e) && (e = 1)), e || window.devicePixelRatio || 1;
47
+ }
48
+ var u = 16384;
49
+ function d(e) {
50
+ (e.width > u || e.height > u) && (e.width > u && e.height > u ? e.width > e.height ? (e.height *= u / e.width, e.width = u) : (e.width *= u / e.height, e.height = u) : e.width > u ? (e.height *= u / e.width, e.width = u) : (e.width *= u / e.height, e.height = u));
51
+ }
52
+ function f(e) {
53
+ return new Promise((t, n) => {
54
+ let r = new Image();
55
+ r.onload = () => {
56
+ r.decode().then(() => {
57
+ requestAnimationFrame(() => t(r));
58
+ });
59
+ }, r.onerror = n, r.crossOrigin = "anonymous", r.decoding = "async", r.src = e;
60
+ });
61
+ }
62
+ async function p(e) {
63
+ return Promise.resolve().then(() => new XMLSerializer().serializeToString(e)).then(encodeURIComponent).then((e) => `data:image/svg+xml;charset=utf-8,${e}`);
64
+ }
65
+ async function m(e, t, n) {
66
+ let r = "http://www.w3.org/2000/svg", i = document.createElementNS(r, "svg"), a = document.createElementNS(r, "foreignObject");
67
+ return i.setAttribute("width", `${t}`), i.setAttribute("height", `${n}`), i.setAttribute("viewBox", `0 0 ${t} ${n}`), a.setAttribute("width", "100%"), a.setAttribute("height", "100%"), a.setAttribute("x", "0"), a.setAttribute("y", "0"), a.setAttribute("externalResourcesRequired", "true"), i.appendChild(a), a.appendChild(e), p(i);
68
+ }
69
+ var h = (e, t) => {
70
+ if (e instanceof t) return !0;
71
+ let n = Object.getPrototypeOf(e);
72
+ return n === null ? !1 : n.constructor.name === t.name || h(n, t);
73
+ };
74
+ //#endregion
75
+ export { d as checkCanvasDimensions, f as createImage, c as getImageSize, l as getPixelRatio, i as getStyleProperties, h as isInstanceOfElement, m as nodeToDataURL, e as resolveUrl, p as svgToDataURL, n as toArray, t as uuid };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/microfe-bigconsole",
3
- "version": "2026.1103.6",
3
+ "version": "2026.1103.7",
4
4
  "description": "BigConsole - AI-powered analytics and dashboard platform",
5
5
  "type": "module",
6
6
  "files": [
@@ -51,7 +51,8 @@
51
51
  "verify:dependency-mitigations": "bun test tests/dependency-mitigations.test.ts"
52
52
  },
53
53
  "dependencies": {
54
- "dompurify": "^3.4.17"
54
+ "dompurify": "^3.4.17",
55
+ "html-to-image": "1.11.13"
55
56
  },
56
57
  "peerDependencies": {
57
58
  "@apollo/client": "^4.2.0",