@d3plus/export 3.0.16 → 3.1.0

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.
@@ -4,50 +4,54 @@
4
4
  Copyright (c) 2026 D3plus - https://d3plus.org
5
5
  @license MIT
6
6
  */
7
- (e=>{"function"==typeof define&&define.amd?define(e):e()})(function(){if("undefined"!=typeof window){try{if("undefined"==typeof SVGElement||Boolean(SVGElement.prototype.innerHTML))return}catch(e){return}function n(e){switch(e.nodeType){case 1:var t=e,r="";return r+="<"+t.tagName,t.hasAttributes()&&[].forEach.call(t.attributes,function(e){r+=" "+e.name+'="'+e.value+'"'}),r+=">",t.hasChildNodes()&&[].forEach.call(t.childNodes,function(e){r+=n(e)}),r+="</"+t.tagName+">";case 3:return e.textContent.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");case 8:return"\x3c!--"+e.nodeValue+"--\x3e"}}Object.defineProperty(SVGElement.prototype,"innerHTML",{get:function(){var t="";return[].forEach.call(this.childNodes,function(e){t+=n(e)}),t},set:function(e){for(;this.firstChild;)this.removeChild(this.firstChild);try{var t=new DOMParser,r=(t.async=!1,"<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>"+e+"</svg>"),n=t.parseFromString(r,"text/xml").documentElement;[].forEach.call(n.childNodes,function(e){this.appendChild(this.ownerDocument.importNode(e,!0))}.bind(this))}catch(e){throw new Error("Error parsing markup string")}}}),Object.defineProperty(SVGElement.prototype,"innerSVG",{get:function(){return this.innerHTML},set:function(e){this.innerHTML=e}})}}),((e,t)=>{"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define("@d3plus/export",["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).d3plus={})})(this,function(e){let i=(()=>{
7
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define("@d3plus/export",["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).d3plus={})}(this,function(e){const t=(()=>{
8
8
  // generate uuid for className of pseudo elements.
9
9
  // We should not use GUIDs, otherwise pseudo elements sometimes cannot be captured.
10
10
  let e=0;
11
11
  // ref: http://stackoverflow.com/a/6248722/2519373
12
- return()=>(e+=1,"u"+// eslint-disable-next-line no-bitwise
13
- ("0000"+(Math.random()*36**4<<0).toString(36)).slice(-4)+e)})();function s(r){var n=[];for(let e=0,t=r.length;e<t;e++)n.push(r[e]);return n}let t=null;function c(e={}){if(!t){if(e.includeStyleProperties)return t=e.includeStyleProperties;t=s(window.getComputedStyle(document.documentElement))}return t}function o(e,t){e=(e.ownerDocument.defaultView||window).getComputedStyle(e).getPropertyValue(t);return e?parseFloat(e.replace("px","")):0}function l(e,t={}){var r,n,a;return{width:t.width||(n=o(r=e,"border-left-width"),a=o(r,"border-right-width"),r.clientWidth+n+a),height:t.height||(n=o(r=e,"border-top-width"),a=o(r,"border-bottom-width"),r.clientHeight+n+a)}}
12
+ return()=>(e+=1,`u${// eslint-disable-next-line no-bitwise
13
+ `0000${(Math.random()*36**4|0).toString(36)}`.slice(-4)}${e}`)})();function n(e){const t=[];for(let n=0,r=e.length;n<r;n++)t.push(e[n]);return t}let r=null;function o(e={}){return r||(e.includeStyleProperties?(r=e.includeStyleProperties,r):(r=n(window.getComputedStyle(document.documentElement)),r))}function i(e,t){const n=(e.ownerDocument.defaultView||window).getComputedStyle(e).getPropertyValue(t);return n?parseFloat(n.replace("px","")):0}function a(e,t={}){return{width:t.width||function(e){const t=i(e,"border-left-width"),n=i(e,"border-right-width");return e.clientWidth+t+n}(e),height:t.height||function(e){const t=i(e,"border-top-width"),n=i(e,"border-bottom-width");return e.clientHeight+t+n}(e)}}
14
14
  // @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas#maximum_canvas_size
15
- let u=16384;function d(n){return new Promise((e,t)=>{let r=new Image;r.onload=()=>{r.decode().then(()=>{requestAnimationFrame(()=>e(r))})},r.onerror=t,r.crossOrigin="anonymous",r.decoding="async",r.src=n})}async function h(e,t,r){var n="http://www.w3.org/2000/svg",a=document.createElementNS(n,"svg"),n=document.createElementNS(n,"foreignObject");return a.setAttribute("width",""+t),a.setAttribute("height",""+r),a.setAttribute("viewBox",`0 0 ${t} `+r),n.setAttribute("width","100%"),n.setAttribute("height","100%"),n.setAttribute("x","0"),n.setAttribute("y","0"),n.setAttribute("externalResourcesRequired","true"),a.appendChild(n),n.appendChild(e),(async e=>Promise.resolve().then(()=>(new XMLSerializer).serializeToString(e)).then(encodeURIComponent).then(e=>"data:image/svg+xml;charset=utf-8,"+e))(a)}let f=(e,t)=>e instanceof t||null!==(e=Object.getPrototypeOf(e))&&(e.constructor.name===t.name||f(e,t));function p(e,t,r,n){var a,o,e=`.${e}:`+t,t=r.cssText?(o=(t=r).getPropertyValue("content"),`${t.cssText} content: '${o.replace(/'|"/g,"")}';`):(a=r,c(n).map(e=>e+`: ${a.getPropertyValue(e)}${a.getPropertyPriority(e)?" !important":""};`).join(" "));return document.createTextNode(e+`{${t}}`)}function m(e,t,r,n){var e=window.getComputedStyle(e,r),a=e.getPropertyValue("content");if(""!==a&&"none"!==a){a=i();try{t.className=t.className+" "+a}catch(e){return}var o=document.createElement("style");o.appendChild(p(a,r,e,n)),t.appendChild(o)}}var r="application/font-woff",n="image/jpeg";let a={woff:r,woff2:r,ttf:"application/font-truetype",eot:"application/vnd.ms-fontobject",png:"image/png",jpg:n,jpeg:n,gif:"image/gif",tiff:"image/tiff",svg:"image/svg+xml",webp:"image/webp"};function g(e){e=((e=/\.([^./]*?)$/g.exec(e=e))?e[1]:"").toLowerCase();return a[e]||""}function w(e){return-1!==e.search(/^(data:)/)}async function y(e,t,n){let a=await fetch(e,t);if(404===a.status)throw new Error(`Resource "${a.url}" not found`);let o=await a.blob();return new Promise((e,t)=>{let r=new FileReader;r.onerror=t,r.onloadend=()=>{try{e(n({res:a,result:r.result}))}catch(e){t(e)}},r.readAsDataURL(o)})}let v={};async function b(r,n,a){var e=((e,t,r)=>{let n=e.replace(/\?.*/,"");return r&&(n=e),
15
+ const c=16384;function s(e){return new Promise((t,n)=>{const r=new Image;r.onload=()=>{r.decode().then(()=>{requestAnimationFrame(()=>t(r))})},r.onerror=n,r.crossOrigin="anonymous",r.decoding="async",r.src=e})}async function l(e,t,n){const r="http://www.w3.org/2000/svg",o=document.createElementNS(r,"svg"),i=document.createElementNS(r,"foreignObject");return o.setAttribute("width",`${t}`),o.setAttribute("height",`${n}`),o.setAttribute("viewBox",`0 0 ${t} ${n}`),i.setAttribute("width","100%"),i.setAttribute("height","100%"),i.setAttribute("x","0"),i.setAttribute("y","0"),i.setAttribute("externalResourcesRequired","true"),o.appendChild(i),i.appendChild(e),async function(e){return Promise.resolve().then(()=>(new XMLSerializer).serializeToString(e)).then(encodeURIComponent).then(e=>`data:image/svg+xml;charset=utf-8,${e}`)}(o)}const u=(e,t)=>{if(e instanceof t)return!0;const n=Object.getPrototypeOf(e);return null!==n&&(n.constructor.name===t.name||u(n,t))};function d(e,t,n,r){const i=`.${e}:${t}`,a=n.cssText?function(e){const t=e.getPropertyValue("content");return`${e.cssText} content: '${t.replace(/'|"/g,"")}';`}(n):function(e,t){return o(t).map(t=>`${t}: ${e.getPropertyValue(t)}${e.getPropertyPriority(t)?" !important":""};`).join(" ")}(n,r);return document.createTextNode(`${i}{${a}}`)}function f(e,n,r,o){const i=window.getComputedStyle(e,r),a=i.getPropertyValue("content");if(""===a||"none"===a)return;const c=t();try{n.className=`${n.className} ${c}`}catch(e){return}const s=document.createElement("style");s.appendChild(d(c,r,i,o)),n.appendChild(s)}const h="application/font-woff",p="image/jpeg",m={woff:h,woff2:h,ttf:"application/font-truetype",eot:"application/vnd.ms-fontobject",png:"image/png",jpg:p,jpeg:p,gif:"image/gif",tiff:"image/tiff",svg:"image/svg+xml",webp:"image/webp"};function g(e){const t=function(e){const t=/\.([^./]*?)$/g.exec(e);return t?t[1]:""}(e).toLowerCase();return m[t]||""}function w(e){return-1!==e.search(/^(data:)/)}async function y(e,t,n){const r=await fetch(e,t);if(404===r.status)throw new Error(`Resource "${r.url}" not found`);const o=await r.blob();return new Promise((e,t)=>{const i=new FileReader;i.onerror=t,i.onloadend=()=>{try{e(n({res:r,result:i.result}))}catch(e){t(e)}},i.readAsDataURL(o)})}const b={};async function v(e,t,n){const r=function(e,t,n){let r=e.replace(/\?.*/,"");return n&&(r=e),
16
16
  // font resource
17
- /ttf|otf|eot|woff2?/i.test(n)&&(n=n.replace(/.*\//,"")),t?`[${t}]`+n:n})(r,n,a.includeQueryParams);if(null!=v[e])return v[e];
17
+ /ttf|otf|eot|woff2?/i.test(r)&&(r=r.replace(/.*\//,"")),t?`[${t}]${r}`:r}(e,t,n.includeQueryParams);if(null!=b[r])return b[r];
18
18
  // ref: https://developer.mozilla.org/en/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest#Bypassing_the_cache
19
- a.cacheBust&&(
19
+ let o;n.cacheBust&&(
20
20
  // eslint-disable-next-line no-param-reassign
21
- r+=(/\?/.test(r)?"&":"?")+(new Date).getTime());let o;try{var t=await y(r,a.fetchRequestInit,({res:e,result:t})=>(n=n||e.headers.get("Content-Type")||"",t.split(/,/)[1]));o=`data:${n};base64,`+t}catch(e){o=a.imagePlaceholder||"";let t="Failed to fetch resource: "+r;(t=e?"string"==typeof e?e:e.message:t)&&console.warn(t)}return v[e]=o}async function E(e,t){return f(e,HTMLCanvasElement)?(async e=>{var t=e.toDataURL();return"data:,"===t?e.cloneNode(!1):d(t)})(e):f(e,HTMLVideoElement)?(async(t,e)=>{if(t.currentSrc){var r=document.createElement("canvas"),n=r.getContext("2d");r.width=t.clientWidth,r.height=t.clientHeight,null!=n&&n.drawImage(t,0,0,r.width,r.height);let e=r.toDataURL();return d(e)}let a=await b(n=t.poster,g(n),e);return d(a)})(e,t):f(e,HTMLIFrameElement)?(async(e,t)=>{var r;try{if(null!=(r=null==e?void 0:e.contentDocument)&&r.body)return await x(e.contentDocument.body,t,!0)}catch(e){
21
+ e+=(/\?/.test(e)?"&":"?")+(new Date).getTime());try{const r=await y(e,n.fetchRequestInit,({res:e,result:n})=>(t||(
22
+ // eslint-disable-next-line no-param-reassign
23
+ t=e.headers.get("Content-Type")||""),function(e){return e.split(/,/)[1]}(n)));o=function(e,t){return`data:${t};base64,${e}`}(r,t)}catch(t){o=n.imagePlaceholder||"";let r=`Failed to fetch resource: ${e}`;t&&(r="string"==typeof t?t:t.message),r&&console.warn(r)}return b[r]=o,o}async function S(e,t){return u(e,HTMLCanvasElement)?async function(e){const t=e.toDataURL();return"data:,"===t?e.cloneNode(!1):s(t)}(e):u(e,HTMLVideoElement)?async function(e,t){if(e.currentSrc){const t=document.createElement("canvas"),n=t.getContext("2d");return t.width=e.clientWidth,t.height=e.clientHeight,null==n||n.drawImage(e,0,0,t.width,t.height),s(t.toDataURL())}const n=e.poster,r=g(n);return s(await v(n,r,t))}(e,t):u(e,HTMLIFrameElement)?async function(e,t){var n;try{if(null===(n=null==e?void 0:e.contentDocument)||void 0===n?void 0:n.body)return await C(e.contentDocument.body,t,!0)}catch(e){
22
24
  // Failed to clone iframe
23
- }return e.cloneNode(!1)})(e,t):e.cloneNode(S(e))}let D=e=>null!=e.tagName&&"SLOT"===e.tagName.toUpperCase(),S=e=>null!=e.tagName&&"SVG"===e.tagName.toUpperCase();function V(e,t,r){if(f(t,Element)){{var o=e;var i=t;var l=r;let a=i.style;if(a){let n=window.getComputedStyle(o);n.cssText?(a.cssText=n.cssText,a.transformOrigin=n.transformOrigin):c(l).forEach(e=>{let t=n.getPropertyValue(e);var r;"font-size"===e&&t.endsWith("px")&&(r=Math.floor(parseFloat(t.substring(0,t.length-2)))-.1,t=r+"px"),f(o,HTMLIFrameElement)&&"display"===e&&"inline"===t&&(t="block"),"d"===e&&i.getAttribute("d")&&(t=`path(${i.getAttribute("d")})`),a.setProperty(e,t,n.getPropertyPriority(e))})}}m(l=e,a=t,":before",r=r),m(l,a,":after",r),l=e,a=t,f(l,HTMLTextAreaElement)&&(a.innerHTML=l.value),f(l,HTMLInputElement)&&a.setAttribute("value",l.value),n=e,r=t,f(n,HTMLSelectElement)&&(r=Array.from(r.children).find(e=>n.value===e.getAttribute("value")))&&r.setAttribute("selected","")}var n,a;return t}async function x(t,r,e){return e||!r.filter||r.filter(t)?Promise.resolve(t).then(e=>E(e,r)).then(e=>(async(t,r,n)=>{var a;if(!S(r)){let e=[];0===(e=D(t)&&t.assignedNodes?s(t.assignedNodes()):f(t,HTMLIFrameElement)&&null!=(a=t.contentDocument)&&a.body?s(t.contentDocument.body.childNodes):s((null!=(a=t.shadowRoot)?a:t).childNodes)).length||f(t,HTMLVideoElement)||await e.reduce((e,t)=>e.then(()=>x(t,n)).then(e=>{e&&r.appendChild(e)}),Promise.resolve())}return r})(t,e,r)).then(e=>V(t,e,r)).then(e=>(async(t,r)=>{var n=t.querySelectorAll?t.querySelectorAll("use"):[];if(0!==n.length){var a={};for(let e=0;e<n.length;e++){var o,i,l=n[e].getAttribute("xlink:href");l&&(o=t.querySelector(l),i=document.querySelector(l),o||!i||a[l]||(
25
+ }return e.cloneNode(!1)}(e,t):e.cloneNode(x(e))}const E=e=>null!=e.tagName&&"SLOT"===e.tagName.toUpperCase(),x=e=>null!=e.tagName&&"SVG"===e.tagName.toUpperCase();function $(e,t,n){return u(t,Element)&&(function(e,t,n){const r=t.style;if(!r)return;const i=window.getComputedStyle(e);i.cssText?(r.cssText=i.cssText,r.transformOrigin=i.transformOrigin):o(n).forEach(n=>{let o=i.getPropertyValue(n);if("font-size"===n&&o.endsWith("px")){const e=Math.floor(parseFloat(o.substring(0,o.length-2)))-.1;o=`${e}px`}u(e,HTMLIFrameElement)&&"display"===n&&"inline"===o&&(o="block"),"d"===n&&t.getAttribute("d")&&(o=`path(${t.getAttribute("d")})`),r.setProperty(n,o,i.getPropertyPriority(n))})}(e,t,n),function(e,t,n){f(e,t,":before",n),f(e,t,":after",n)}(e,t,n),function(e,t){u(e,HTMLTextAreaElement)&&(t.innerHTML=e.value),u(e,HTMLInputElement)&&t.setAttribute("value",e.value)}(e,t),function(e,t){if(u(e,HTMLSelectElement)){const n=t,r=Array.from(n.children).find(t=>e.value===t.getAttribute("value"));r&&r.setAttribute("selected","")}}(e,t)),t}async function C(e,t,r){return r||!t.filter||t.filter(e)?Promise.resolve(e).then(e=>S(e,t)).then(r=>async function(e,t,r){var o,i;if(x(t))return t;let a=[];return a=E(e)&&e.assignedNodes?n(e.assignedNodes()):u(e,HTMLIFrameElement)&&(null===(o=e.contentDocument)||void 0===o?void 0:o.body)?n(e.contentDocument.body.childNodes):n((null!==(i=e.shadowRoot)&&void 0!==i?i:e).childNodes),0===a.length||u(e,HTMLVideoElement)||await a.reduce((e,n)=>e.then(()=>C(n,r)).then(e=>{e&&t.appendChild(e)}),Promise.resolve()),t}(e,r,t)).then(n=>$(e,n,t)).then(e=>async function(e,t){const n=e.querySelectorAll?e.querySelectorAll("use"):[];if(0===n.length)return e;const r={};for(let o=0;o<n.length;o++){const i=n[o].getAttribute("xlink:href");if(i){const n=e.querySelector(i),o=document.querySelector(i);n||!o||r[i]||(
24
26
  // eslint-disable-next-line no-await-in-loop
25
- a[l]=await x(i,r,!0)))}var s=Object.values(a);if(s.length){var e="http://www.w3.org/1999/xhtml",c=document.createElementNS(e,"svg"),u=(c.setAttribute("xmlns",e),c.style.position="absolute",c.style.width="0",c.style.height="0",c.style.overflow="hidden",c.style.display="none",document.createElementNS(e,"defs"));c.appendChild(u);for(let e=0;e<s.length;e++)u.appendChild(s[e]);t.appendChild(c)}}return t})(e,r)):null}let C=/url\((['"]?)([^'"]+?)\1\)/g,$=/url\([^)]+\)\s*format\((["']?)([^"']+)\1\)/g,F=/src:\s*(?:url\([^)]+\)\s*format\([^)]+\)[,;]\s*)+/g;async function j(t,r,n,a,o){try{var i=n?(u=n,
27
+ r[i]=await C(o,t,!0))}}const o=Object.values(r);if(o.length){const t="http://www.w3.org/1999/xhtml",n=document.createElementNS(t,"svg");n.setAttribute("xmlns",t),n.style.position="absolute",n.style.width="0",n.style.height="0",n.style.overflow="hidden",n.style.display="none";const r=document.createElementNS(t,"defs");n.appendChild(r);for(let e=0;e<o.length;e++)r.appendChild(o[e]);e.appendChild(n)}return e}(e,t)):null}const R=/url\((['"]?)([^'"]+?)\1\)/g,T=/url\([^)]+\)\s*format\((["']?)([^"']+)\1\)/g,P=/src:\s*(?:url\([^)]+\)\s*format\([^)]+\)[,;]\s*)+/g;async function N(e,t,n,r,o){try{const i=n?function(e,t){
26
28
  // url is absolute already
27
- (c=r).match(/^[a-z]+:\/\//i)?c:
29
+ if(e.match(/^[a-z]+:\/\//i))return e;
28
30
  // url is absolute already, without protocol
29
- c.match(/^\/\//)?window.location.protocol+c:
31
+ if(e.match(/^\/\//))return window.location.protocol+e;
30
32
  // dataURI, mailto:, tel:, etc.
31
- c.match(/^[a-z]+:/i)?c:(h=(d=document.implementation.createHTMLDocument()).createElement("base"),f=d.createElement("a"),d.head.appendChild(h),d.body.appendChild(f),u&&(h.href=u),f.href=c,f.href)):r,l=g(r);let e;return o||(e=await b(i,l,a)),t.replace((s=(s=r).replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1"),new RegExp(`(url\\(['"]?)(${s})(['"]?\\))`,"g")),`$1${e}$3`)}catch(e){
33
+ if(e.match(/^[a-z]+:/i))return e;const n=document.implementation.createHTMLDocument(),r=n.createElement("base"),o=n.createElement("a");return n.head.appendChild(r),n.body.appendChild(o),t&&(r.href=t),o.href=e,o.href}(t,n):t,a=g(t);let c;return o||(c=await v(i,a,r)),e.replace(function(e){
34
+ // eslint-disable-next-line no-useless-escape
35
+ const t=e.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1");return new RegExp(`(url\\(['"]?)(${t})(['"]?\\))`,"g")}(t),`$1${c}$3`)}catch(e){
32
36
  // pass
33
- }var s,c,u,d,h,f;return t}function T(e){return-1!==e.search(C)}async function R(e,r,n){var t,a;return T(e)?([t,a]=[e,n.preferredFontFormat],(e=>{let n=[];return e.replace(C,(e,t,r)=>(n.push(r),e)),n.filter(e=>!w(e))})(t=a?t.replace(F,e=>{
37
+ }return e}function A(e){return-1!==e.search(R)}async function L(e,t,n){if(!A(e))return e;const r=function(e,{preferredFontFormat:t}){return t?e.replace(P,e=>{
34
38
  // eslint-disable-next-line no-constant-condition
35
- for(;;){var[t,,r]=$.exec(e)||[];if(!r)return"";if(r===a)return`src: ${t};`}}):t).reduce((e,t)=>e.then(e=>j(e,t,r,n)),Promise.resolve(t))):e}async function N(e,t,r){var n=null==(n=t.style)?void 0:n.getPropertyValue(e);return!!n&&(n=await R(n,null,r),t.style.setProperty(e,n,t.style.getPropertyPriority(e)),!0)}async function P(e,t){if(f(e,Element)){await N("background",l=e,a=t)||await N("background-image",l,a),await!(await N("mask",l,a)||await N("-webkit-mask",l,a)||await N("mask-image",l,a)||await N("-webkit-mask-image",l,a));{var o=e;var i=t;let a=f(o,HTMLImageElement);if(a&&!w(o.src)||f(o,SVGImageElement)&&!w(o.href.baseVal)){l=a?o.src:o.href.baseVal;let n=await b(l,g(l),i);await new Promise((t,r)=>{o.onload=t,o.onerror=i.onImageErrorHandler?(...e)=>{try{t(i.onImageErrorHandler(...e))}catch(e){r(e)}}:r;var e=o;e.decode&&(e.decode=t),"lazy"===e.loading&&(e.loading="eager"),a?(o.srcset="",o.src=n):o.href.baseVal=n})}}await 0,n=t,a=s((r=e).childNodes).map(e=>P(e,n)),await Promise.all(a).then(()=>r)}var r,n,l,a}let L={};async function k(e){var t=L[e];return null==t&&(t={url:e,cssText:await(await fetch(e)).text()},L[e]=t),t}async function A(r,n){let a=r.cssText,o=/url\(["']?([^"')]+)["']?\)/g;var e=(a.match(/url\([^)]+\)/g)||[]).map(async t=>{let e=t.replace(o,"$1");return y(e=e.startsWith("https://")?e:new URL(e,r.url).href,n.fetchRequestInit,({result:e})=>(a=a.replace(t,`url(${e})`),[t,e]))});return Promise.all(e).then(()=>a)}function I(e){if(null==e)return[];var t=[];
39
+ for(;;){const[n,,r]=T.exec(e)||[];if(!r)return"";if(r===t)return`src: ${n};`}}):e}(e,n),o=function(e){const t=[];return e.replace(R,(e,n,r)=>(t.push(r),e)),t.filter(e=>!w(e))}(r);return o.reduce((e,r)=>e.then(e=>N(e,r,t,n)),Promise.resolve(r))}async function k(e,t,n){var r;const o=null===(r=t.style)||void 0===r?void 0:r.getPropertyValue(e);if(o){const r=await L(o,null,n);return t.style.setProperty(e,r,t.style.getPropertyPriority(e)),!0}return!1}async function I(e,t){u(e,Element)&&(await async function(e,t){await k("background",e,t)||await k("background-image",e,t),await k("mask",e,t)||await k("-webkit-mask",e,t)||await k("mask-image",e,t)||await k("-webkit-mask-image",e,t)}(e,t),await async function(e,t){const n=u(e,HTMLImageElement);if((!n||w(e.src))&&(!u(e,SVGImageElement)||w(e.href.baseVal)))return;const r=n?e.src:e.href.baseVal,o=await v(r,g(r),t);await new Promise((r,i)=>{e.onload=r,e.onerror=t.onImageErrorHandler?(...e)=>{try{r(t.onImageErrorHandler(...e))}catch(e){i(e)}}:i;const a=e;a.decode&&(a.decode=r),"lazy"===a.loading&&(a.loading="eager"),n?(e.srcset="",e.src=o):e.href.baseVal=o})}(e,t),await async function(e,t){const r=n(e.childNodes).map(e=>I(e,t));await Promise.all(r).then(()=>e)}(e,t))}const O={};async function M(e){let t=O[e];if(null!=t)return t;const n=await fetch(e);return t={url:e,cssText:await n.text()},O[e]=t,t}async function H(e,t){let n=e.cssText;const r=/url\(["']?([^"')]+)["']?\)/g,o=(n.match(/url\([^)]+\)/g)||[]).map(async o=>{let i=o.replace(r,"$1");return i.startsWith("https://")||(i=new URL(i,e.url).href),y(i,t.fetchRequestInit,({result:e})=>(n=n.replace(o,`url(${e})`),[o,e]))});return Promise.all(o).then(()=>n)}function D(e){if(null==e)return[];const t=[];
36
40
  // strip out comments
37
- let r=e.replace(/(\/\*[\s\S]*?\*\/)/gi,"");
41
+ let n=e.replace(/(\/\*[\s\S]*?\*\/)/gi,"");
38
42
  // eslint-disable-next-line prefer-regex-literals
43
+ const r=new RegExp("((@.*?keyframes [\\s\\S]*?){([\\s\\S]*?}\\s*?)})","gi");
39
44
  // eslint-disable-next-line no-constant-condition
40
- for(var n=new RegExp("((@.*?keyframes [\\s\\S]*?){([\\s\\S]*?}\\s*?)})","gi");;){var a=n.exec(r);if(null===a)break;t.push(a[0])}r=r.replace(n,"");
41
- // eslint-disable-next-line no-constant-condition
42
- for(var o=/@import[\s\S]*?url\([^)]*\)[\s\S]*?;/gi,i=new RegExp("((\\s*?(?:\\/\\*[\\s\\S]*?\\*\\/)?\\s*?@media[\\s\\S]*?){([\\s\\S]*?)}\\s*?})|(([\\s\\S]*?){([\\s\\S]*?)})","gi")
45
+ for(;;){const e=r.exec(n);if(null===e)break;t.push(e[0])}n=n.replace(r,"");const o=/@import[\s\S]*?url\([^)]*\)[\s\S]*?;/gi,i=new RegExp("((\\s*?(?:\\/\\*[\\s\\S]*?\\*\\/)?\\s*?@media[\\s\\S]*?){([\\s\\S]*?)}\\s*?})|(([\\s\\S]*?){([\\s\\S]*?)})","gi");
43
46
  // to match css & media queries together
44
- ;;){let e=o.exec(r);if(null===e){if(null===(e=i.exec(r)))break;o.lastIndex=i.lastIndex}else i.lastIndex=o.lastIndex;t.push(e[0])}return t}async function U(e,t){if(null==e.ownerDocument)throw new Error("Provided element is not within a Document");return(await(async(r,a)=>{let n=[],o=[];
47
+ // eslint-disable-next-line no-constant-condition
48
+ for(;;){let e=o.exec(n);if(null===e){if(e=i.exec(n),null===e)break;o.lastIndex=i.lastIndex}else i.lastIndex=o.lastIndex;t.push(e[0])}return t}async function F(e,t){if(null==e.ownerDocument)throw new Error("Provided element is not within a Document");const r=n(e.ownerDocument.styleSheets),o=await async function(e,t){const r=[],o=[];
45
49
  // First loop inlines imports
46
- return r.forEach(n=>{if("cssRules"in n)try{s(n.cssRules||[]).forEach((e,t)=>{if(e.type===CSSRule.IMPORT_RULE){let r=t+1;t=k(e.href).then(e=>A(e,a)).then(e=>I(e).forEach(t=>{try{n.insertRule(t,t.startsWith("@import")?r+=1:n.cssRules.length)}catch(e){console.error("Error inserting rule from remote css",{rule:t,error:e})}})).catch(e=>{console.error("Error loading remote css",e.toString())});o.push(t)}})}catch(e){let t=r.find(e=>null==e.href)||document.styleSheets[0];null!=n.href&&o.push(k(n.href).then(e=>A(e,a)).then(e=>I(e).forEach(e=>{t.insertRule(e,t.cssRules.length)})).catch(e=>{console.error("Error loading remote stylesheet",e)})),console.error("Error inlining remote css file",e)}}),Promise.all(o).then(()=>(
50
+ return e.forEach(r=>{if("cssRules"in r)try{n(r.cssRules||[]).forEach((e,n)=>{if(e.type===CSSRule.IMPORT_RULE){let i=n+1;const a=M(e.href).then(e=>H(e,t)).then(e=>D(e).forEach(e=>{try{r.insertRule(e,e.startsWith("@import")?i+=1:r.cssRules.length)}catch(t){console.error("Error inserting rule from remote css",{rule:e,error:t})}})).catch(e=>{console.error("Error loading remote css",e.toString())});o.push(a)}})}catch(n){const i=e.find(e=>null==e.href)||document.styleSheets[0];null!=r.href&&o.push(M(r.href).then(e=>H(e,t)).then(e=>D(e).forEach(e=>{i.insertRule(e,i.cssRules.length)})).catch(e=>{console.error("Error loading remote stylesheet",e)})),console.error("Error inlining remote css file",n)}}),Promise.all(o).then(()=>(
47
51
  // Second loop parses rules
48
- r.forEach(t=>{if("cssRules"in t)try{s(t.cssRules||[]).forEach(e=>{n.push(e)})}catch(e){console.error("Error while reading CSS rules from "+t.href,e)}}),n))})(s(e.ownerDocument.styleSheets),t)).filter(e=>e.type===CSSRule.FONT_FACE_RULE).filter(e=>T(e.style.getPropertyValue("src")))}function O(e){return e.trim().replace(/["']/g,"")}function q(e){let r=new Set;return function t(e){(e.style.fontFamily||getComputedStyle(e).fontFamily).split(",").forEach(e=>{r.add(O(e))}),Array.from(e.children).forEach(e=>{e instanceof HTMLElement&&t(e)})}(e),r}async function B(e,t){var r,t=null!=t.fontEmbedCSS?t.fontEmbedCSS:t.skipFonts?null:await(async(e,r)=>{var t=await U(e,r);let n=q(e);return(await Promise.all(t.filter(e=>n.has(O(e.style.fontFamily))).map(e=>{var t=e.parentStyleSheet?e.parentStyleSheet.href:null;return R(e.cssText,t,r)}))).join("\n")})(e,t);t&&(r=document.createElement("style"),t=document.createTextNode(t),r.appendChild(t),e.firstChild?e.insertBefore(r,e.firstChild):e.appendChild(r))}async function M(e,n={}){var{width:t,height:r}=l(e,n),e=await x(e,n,!0);await B(e,n),await P(e,n);{var a=e;let t=a.style,r=(n.backgroundColor&&(t.backgroundColor=n.backgroundColor),n.width&&(t.width=n.width+"px"),n.height&&(t.height=n.height+"px"),n.style);null!=r&&Object.keys(r).forEach(e=>{t[e]=r[e]})}return await h(e,t,r)}async function G(e,t={}){var{width:r,height:n}=l(e,t),e=await d(await M(e,t)),a=document.createElement("canvas"),o=a.getContext("2d"),i=t.pixelRatio||(()=>{let e,t;try{t=process}catch(e){
52
+ e.forEach(e=>{if("cssRules"in e)try{n(e.cssRules||[]).forEach(e=>{r.push(e)})}catch(t){console.error(`Error while reading CSS rules from ${e.href}`,t)}}),r))}(r,t);return function(e){return e.filter(e=>e.type===CSSRule.FONT_FACE_RULE).filter(e=>A(e.style.getPropertyValue("src")))}(o)}function U(e){return e.trim().replace(/["']/g,"")}async function j(e,t){const n=await F(e,t),r=function(e){const t=new Set;return function e(n){(n.style.fontFamily||getComputedStyle(n).fontFamily).split(",").forEach(e=>{t.add(U(e))}),Array.from(n.children).forEach(t=>{t instanceof HTMLElement&&e(t)})}(e),t}(e);return(await Promise.all(n.filter(e=>r.has(U(e.style.fontFamily))).map(e=>{const n=e.parentStyleSheet?e.parentStyleSheet.href:null;return L(e.cssText,n,t)}))).join("\n")}async function V(e,t={}){const{width:n,height:r}=a(e,t),o=await C(e,t,!0);await async function(e,t){const n=null!=t.fontEmbedCSS?t.fontEmbedCSS:t.skipFonts?null:await j(e,t);if(n){const t=document.createElement("style"),r=document.createTextNode(n);t.appendChild(r),e.firstChild?e.insertBefore(t,e.firstChild):e.appendChild(t)}}(o,t),await I(o,t),function(e,t){const{style:n}=e;t.backgroundColor&&(n.backgroundColor=t.backgroundColor),t.width&&(n.width=`${t.width}px`),t.height&&(n.height=`${t.height}px`);const r=t.style;null!=r&&Object.keys(r).forEach(e=>{n[e]=r[e]})}(o,t);return await l(o,n,r)}async function q(e,t={}){const{width:n,height:r}=a(e,t),o=await V(e,t),i=await s(o),l=document.createElement("canvas"),u=l.getContext("2d"),d=t.pixelRatio||function(){let e,t;try{t=process}catch(e){
49
53
  // pass
50
- }var r=t&&t.env?t.env.devicePixelRatio:null;return(e=r&&(e=parseInt(r,10),Number.isNaN(e))?1:e)||window.devicePixelRatio||1})(),r=t.canvasWidth||r,n=t.canvasHeight||n;return a.width=r*i,a.height=n*i,t.skipAutoScale||((i=a).width>u||i.height>u)&&(i.width>u&&i.height>u?i.width>i.height?(i.height*=u/i.width,i.width=u):(i.width*=u/i.height,i.height=u):i.width>u?(i.height*=u/i.width,i.width=u):(i.width*=u/i.height,i.height=u)),a.style.width=""+r,a.style.height=""+n,t.backgroundColor&&(o.fillStyle=t.backgroundColor,o.fillRect(0,0,a.width,a.height)),o.drawImage(e,0,0,a.width,a.height),a}async function W(e,t={}){var a,o,e=await G(e,t);return o={},await((a=e).toBlob?new Promise(e=>{a.toBlob(e,o.type||"image/png",o.quality||1)}):new Promise(e=>{var t=window.atob(a.toDataURL(o.type||void 0,o.quality||void 0).split(",")[1]),r=t.length,n=new Uint8Array(r);for(let e=0;e<r;e+=1)n[e]=t.charCodeAt(e);e(new Blob([n],{type:o.type||"image/png"}))}))}r={exports:{}};
54
+ }const n=t&&t.env?t.env.devicePixelRatio:null;return n&&(e=parseInt(n,10),Number.isNaN(e)&&(e=1)),e||window.devicePixelRatio||1}(),f=t.canvasWidth||n,h=t.canvasHeight||r;return l.width=f*d,l.height=h*d,t.skipAutoScale||function(e){(e.width>c||e.height>c)&&(e.width>c&&e.height>c?e.width>e.height?(e.height*=c/e.width,e.width=c):(e.width*=c/e.height,e.height=c):e.width>c?(e.height*=c/e.width,e.width=c):(e.width*=c/e.height,e.height=c))}(l),l.style.width=`${f}`,l.style.height=`${h}`,t.backgroundColor&&(u.fillStyle=t.backgroundColor,u.fillRect(0,0,l.width,l.height)),u.drawImage(i,0,0,l.width,l.height),l}async function B(e,t={}){const n=await q(e,t),r=await function(e,t={}){return e.toBlob?new Promise(n=>{e.toBlob(n,t.type?t.type:"image/png",t.quality?t.quality:1)}):new Promise(n=>{const r=window.atob(e.toDataURL(t.type?t.type:void 0,t.quality?t.quality:void 0).split(",")[1]),o=r.length,i=new Uint8Array(o);for(let e=0;e<o;e+=1)i[e]=r.charCodeAt(e);n(new Blob([i],{type:t.type?t.type:"image/png"}))})}(n);return r}var W,z={exports:{}},_=z.exports;
51
55
  /* FileSaver.js
52
56
  * A saveAs() FileSaver implementation.
53
57
  * 1.3.2
@@ -56,35 +60,37 @@ r.forEach(t=>{if("cssRules"in t)try{s(t.cssRules||[]).forEach(e=>{n.push(e)})}ca
56
60
  * By Eli Grey, http://eligrey.com
57
61
  * License: MIT
58
62
  * See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md
59
- */H||(H=1,n=r,H=(l=>{
63
+ */var G=(W||(W=1,function(e){
64
+ /*global self */ /*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */ /*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */var t=t||function(e){
60
65
  // IE <10 is explicitly unsupported
61
- var s,c,u,d,h,f,o,p,t,m,g,w,n,e;if(!(void 0===l||"undefined"!=typeof navigator&&/MSIE [1-9]\./.test(navigator.userAgent)))
62
- // IE 10+ (native saveAs)
63
- return e=l.document,s=function(){return l.URL||l.webkitURL||l},c=e.createElementNS("http://www.w3.org/1999/xhtml","a"),u="download"in c,d=function(e){var t=new MouseEvent("click");e.dispatchEvent(t)},h=/constructor/i.test(l.HTMLElement)||l.safari,f=/CriOS\/[\d]+/.test(navigator.userAgent),o=function(e){(l.setImmediate||l.setTimeout)(function(){throw e},0)},p="application/octet-stream",t=4e4,m=function(e){setTimeout(function(){"string"==typeof e?s().revokeObjectURL(e):e.remove()},t)},g=function(e,t,r){for(var n=(t=[].concat(t)).length;n--;){var a=e["on"+t[n]];if("function"==typeof a)try{a.call(e,r||e)}catch(e){o(e)}}},w=function(e){
66
+ if(!(void 0===e||"undefined"!=typeof navigator&&/MSIE [1-9]\./.test(navigator.userAgent))){var t=e.document,n=function(){return e.URL||e.webkitURL||e},r=t.createElementNS("http://www.w3.org/1999/xhtml","a"),o="download"in r,i=/constructor/i.test(e.HTMLElement)||e.safari,a=/CriOS\/[\d]+/.test(navigator.userAgent),c=function(t){(e.setImmediate||e.setTimeout)(function(){throw t},0)},s=function(e){setTimeout(function(){"string"==typeof e?n().revokeObjectURL(e):e.remove()},4e4)},l=function(e){
64
67
  // prepend BOM for UTF-8 XML and text/* types (including HTML)
65
68
  // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF
66
- return/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(e.type)?new Blob([String.fromCharCode(65279),e],{type:e.type}):e},e=(n=function(e,t,r){r||(e=w(e));
69
+ return/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(e.type)?new Blob([String.fromCharCode(65279),e],{type:e.type}):e},u=function(t,u,d){d||(t=l(t));
67
70
  // First try a.download, then web filesystem, then object URLs
68
- var n,a,o=this,r=e.type===p,i=function(){g(o,"writestart progress write writeend".split(" "))};o.readyState=o.INIT,u?(n=s().createObjectURL(e),setTimeout(function(){c.href=n,c.download=t,d(c),i(),m(n),o.readyState=o.DONE})):(f||r&&h)&&l.FileReader?((a=new FileReader).onloadend=function(){var e=f?a.result:a.result.replace(/^data:[^;]*;/,"data:attachment/file;");l.open(e,"_blank")||(l.location.href=e),// release reference before dispatching
69
- o.readyState=o.DONE,i()},a.readAsDataURL(e),o.readyState=o.INIT):(
71
+ var f,h=this,p="application/octet-stream"===t.type,m=function(){!function(e,t,n){for(var r=(t=[].concat(t)).length;r--;){var o=e["on"+t[r]];if("function"==typeof o)try{o.call(e,n||e)}catch(e){c(e)}}}(h,"writestart progress write writeend".split(" "))};if(h.readyState=h.INIT,o)return f=n().createObjectURL(t),void setTimeout(function(){var e,t;r.href=f,r.download=u,e=r,t=new MouseEvent("click"),e.dispatchEvent(t),m(),s(f),h.readyState=h.DONE});!function(){if((a||p&&i)&&e.FileReader){
72
+ // Safari doesn't allow downloading of blob urls
73
+ var r=new FileReader;return r.onloadend=function(){var t=a?r.result:r.result.replace(/^data:[^;]*;/,"data:attachment/file;");e.open(t,"_blank")||(e.location.href=t),t=void 0,// release reference before dispatching
74
+ h.readyState=h.DONE,m()},r.readAsDataURL(t),void(h.readyState=h.INIT)}
70
75
  // don't create more object URLs than needed
71
- n=n||s().createObjectURL(e),!r&&l.open(n,"_blank")||(
76
+ f||(f=n().createObjectURL(t)),p?e.location.href=f:e.open(f,"_blank")||(
72
77
  // Apple does not allow window.open, see https://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/WorkingwithWindowsandTabs/WorkingwithWindowsandTabs.html
73
- l.location.href=n),o.readyState=o.DONE,i(),m(n))}).prototype,"undefined"!=typeof navigator&&navigator.msSaveOrOpenBlob?function(e,t,r){return t=t||e.name||"download",r||(e=w(e)),navigator.msSaveOrOpenBlob(e,t)}:(e.abort=function(){},e.readyState=e.INIT=0,e.WRITING=1,e.DONE=2,e.error=e.onwritestart=e.onprogress=e.onwrite=e.onabort=e.onerror=e.onwriteend=null,function(e,t,r){return new n(e,t||e.name||"download",r)})})("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||r.exports.content),
78
+ e.location.href=f),h.readyState=h.DONE,m(),s(f)}()},d=u.prototype;
79
+ // IE 10+ (native saveAs)
80
+ return"undefined"!=typeof navigator&&navigator.msSaveOrOpenBlob?function(e,t,n){return t=t||e.name||"download",n||(e=l(e)),navigator.msSaveOrOpenBlob(e,t)}:(d.abort=function(){},d.readyState=d.INIT=0,d.WRITING=1,d.DONE=2,d.error=d.onwritestart=d.onprogress=d.onwrite=d.onabort=d.onerror=d.onwriteend=null,function(e,t,n){return new u(e,t||e.name||"download",n)})}}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||_.content);
74
81
  // `self` is undefined in Firefox for Android content script context
75
82
  // while `this` is nsIContentFrameMessageManager
76
83
  // with an attribute `content` that corresponds to the window
77
- n.exports&&(n.exports.saveAs=H));var H,z=r.exports;let _={filename:"download",type:"png"};
84
+ e.exports&&(e.exports.saveAs=t)}(z)),z.exports);const X={filename:"download",type:"png"};
78
85
  /**
79
- @function saveElement
80
- @desc Downloads an HTML Element as a bitmap PNG image.
81
- @param {HTMLElement} elem A single element to be saved to one file.
82
- @param {Object} [options] Additional options to specify.
83
- @param {String} [options.filename = "download"] Filename for the downloaded file, without the extension.
84
- @param {String} [options.type = "png"] File type of the saved document. Accepted values are `"png"` and `"jpg"`.
85
- @param {Function} [options.callback] Function to be invoked after saving is complete.
86
- @param {Object} [renderOptions] Custom options to be passed to the html-to-image function.
87
- */e.saveElement=function(e,t={},r={}){function n(e){z.saveAs(e,t.filename+"."+t.type),t.callback&&t.callback()}e&&(t=Object.assign({},_,t),
86
+ Downloads an HTML Element as a bitmap PNG image.
87
+ @param elem The DOM element or d3 selection to export.
88
+ @param options Additional options to specify.
89
+ @param options .filename = "download"] Filename for the downloaded file, without the extension.
90
+ @param options .type = "png"] File type of the saved document. Accepted values are `"png"` and `"jpg"`.
91
+ @param options .callback] Function to be invoked after saving is complete.
92
+ @param renderOptions Custom options to be passed to the html-to-image function.
93
+ */e.saveElement=function(e,t={},n={}){if(!e)return;const r=Object.assign({},X,t),o=Object.assign({backgroundColor:n.background},n);
88
94
  // rename renderOptions.background to backgroundColor for backwards compatibility
89
- r=Object.assign({backgroundColor:r.background},r),"svg"===t.type?M(e,r).then(e=>{let t=new XMLHttpRequest;t.open("GET",e),t.responseType="blob",t.onload=()=>n(t.response),t.send()}):W(e,r).then(n))}});
95
+ function i(e){G.saveAs(e,`${r.filename}.${r.type}`),r.callback&&r.callback()}"svg"===r.type?V(e,o).then(e=>{const t=new XMLHttpRequest;t.open("GET",e),t.responseType="blob",t.onload=()=>i(t.response),t.send()}):B(e,o).then(e=>{e&&i(e)})}});
90
96
  //# sourceMappingURL=d3plus-export.full.js.map
@@ -4,110 +4,6 @@
4
4
  Copyright (c) 2026 D3plus - https://d3plus.org
5
5
  @license MIT
6
6
  */
7
-
8
- (function (factory) {
9
- typeof define === 'function' && define.amd ? define(factory) :
10
- factory();
11
- })((function () { 'use strict';
12
-
13
- if (typeof window !== "undefined") {
14
- (function () {
15
- try {
16
- if (typeof SVGElement === 'undefined' || Boolean(SVGElement.prototype.innerHTML)) {
17
- return;
18
- }
19
- } catch (e) {
20
- return;
21
- }
22
-
23
- function serializeNode (node) {
24
- switch (node.nodeType) {
25
- case 1:
26
- return serializeElementNode(node);
27
- case 3:
28
- return serializeTextNode(node);
29
- case 8:
30
- return serializeCommentNode(node);
31
- }
32
- }
33
-
34
- function serializeTextNode (node) {
35
- return node.textContent.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
36
- }
37
-
38
- function serializeCommentNode (node) {
39
- return '<!--' + node.nodeValue + '-->'
40
- }
41
-
42
- function serializeElementNode (node) {
43
- var output = '';
44
-
45
- output += '<' + node.tagName;
46
-
47
- if (node.hasAttributes()) {
48
- [].forEach.call(node.attributes, function(attrNode) {
49
- output += ' ' + attrNode.name + '="' + attrNode.value + '"';
50
- });
51
- }
52
-
53
- output += '>';
54
-
55
- if (node.hasChildNodes()) {
56
- [].forEach.call(node.childNodes, function(childNode) {
57
- output += serializeNode(childNode);
58
- });
59
- }
60
-
61
- output += '</' + node.tagName + '>';
62
-
63
- return output;
64
- }
65
-
66
- Object.defineProperty(SVGElement.prototype, 'innerHTML', {
67
- get: function () {
68
- var output = '';
69
-
70
- [].forEach.call(this.childNodes, function(childNode) {
71
- output += serializeNode(childNode);
72
- });
73
-
74
- return output;
75
- },
76
- set: function (markup) {
77
- while (this.firstChild) {
78
- this.removeChild(this.firstChild);
79
- }
80
-
81
- try {
82
- var dXML = new DOMParser();
83
- dXML.async = false;
84
-
85
- var sXML = '<svg xmlns=\'http://www.w3.org/2000/svg\' xmlns:xlink=\'http://www.w3.org/1999/xlink\'>' + markup + '</svg>';
86
- var svgDocElement = dXML.parseFromString(sXML, 'text/xml').documentElement;
87
-
88
- [].forEach.call(svgDocElement.childNodes, function(childNode) {
89
- this.appendChild(this.ownerDocument.importNode(childNode, true));
90
- }.bind(this));
91
- } catch (e) {
92
- throw new Error('Error parsing markup string');
93
- }
94
- }
95
- });
96
-
97
- Object.defineProperty(SVGElement.prototype, 'innerSVG', {
98
- get: function () {
99
- return this.innerHTML;
100
- },
101
- set: function (markup) {
102
- this.innerHTML = markup;
103
- }
104
- });
105
-
106
- })();
107
- }
108
-
109
- }));
110
-
111
7
  (function (global, factory) {
112
8
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('html-to-image'), require('file-saver')) :
113
9
  typeof define === 'function' && define.amd ? define('@d3plus/export', ['exports', 'html-to-image', 'file-saver'], factory) :
@@ -119,27 +15,26 @@
119
15
  type: "png"
120
16
  };
121
17
  /**
122
- @function saveElement
123
- @desc Downloads an HTML Element as a bitmap PNG image.
124
- @param {HTMLElement} elem A single element to be saved to one file.
125
- @param {Object} [options] Additional options to specify.
126
- @param {String} [options.filename = "download"] Filename for the downloaded file, without the extension.
127
- @param {String} [options.type = "png"] File type of the saved document. Accepted values are `"png"` and `"jpg"`.
128
- @param {Function} [options.callback] Function to be invoked after saving is complete.
129
- @param {Object} [renderOptions] Custom options to be passed to the html-to-image function.
18
+ Downloads an HTML Element as a bitmap PNG image.
19
+ @param elem The DOM element or d3 selection to export.
20
+ @param options Additional options to specify.
21
+ @param options .filename = "download"] Filename for the downloaded file, without the extension.
22
+ @param options .type = "png"] File type of the saved document. Accepted values are `"png"` and `"jpg"`.
23
+ @param options .callback] Function to be invoked after saving is complete.
24
+ @param renderOptions Custom options to be passed to the html-to-image function.
130
25
  */ function saveElement(elem, options = {}, renderOptions = {}) {
131
26
  if (!elem) return;
132
- options = Object.assign({}, defaultOptions, options);
27
+ const opts = Object.assign({}, defaultOptions, options);
133
28
  // rename renderOptions.background to backgroundColor for backwards compatibility
134
- renderOptions = Object.assign({
29
+ const renderOpts = Object.assign({
135
30
  backgroundColor: renderOptions.background
136
31
  }, renderOptions);
137
32
  function finish(blob) {
138
- fileSaver.saveAs(blob, `${options.filename}.${options.type}`);
139
- if (options.callback) options.callback();
33
+ fileSaver.saveAs(blob, `${opts.filename}.${opts.type}`);
34
+ if (opts.callback) opts.callback();
140
35
  }
141
- if (options.type === "svg") {
142
- htmlToImage.toSvg(elem, renderOptions).then((dataUrl)=>{
36
+ if (opts.type === "svg") {
37
+ htmlToImage.toSvg(elem, renderOpts).then((dataUrl)=>{
143
38
  const xhr = new XMLHttpRequest();
144
39
  xhr.open("GET", dataUrl);
145
40
  xhr.responseType = "blob";
@@ -147,7 +42,9 @@
147
42
  xhr.send();
148
43
  });
149
44
  } else {
150
- htmlToImage.toBlob(elem, renderOptions).then(finish);
45
+ htmlToImage.toBlob(elem, renderOpts).then((blob)=>{
46
+ if (blob) finish(blob);
47
+ });
151
48
  }
152
49
  }
153
50
 
@@ -1 +1 @@
1
- {"version":3,"file":"d3plus-export.js","sources":["../src/saveElement.js"],"sourcesContent":["import {toBlob, toSvg} from \"html-to-image\";\nimport {saveAs} from \"file-saver\";\n\nconst defaultOptions = {\n filename: \"download\",\n type: \"png\"\n};\n\n/**\n @function saveElement\n @desc Downloads an HTML Element as a bitmap PNG image.\n @param {HTMLElement} elem A single element to be saved to one file.\n @param {Object} [options] Additional options to specify.\n @param {String} [options.filename = \"download\"] Filename for the downloaded file, without the extension.\n @param {String} [options.type = \"png\"] File type of the saved document. Accepted values are `\"png\"` and `\"jpg\"`.\n @param {Function} [options.callback] Function to be invoked after saving is complete.\n @param {Object} [renderOptions] Custom options to be passed to the html-to-image function.\n*/\nexport default function(elem, options = {}, renderOptions = {}) {\n\n if (!elem) return;\n options = Object.assign({}, defaultOptions, options);\n\n // rename renderOptions.background to backgroundColor for backwards compatibility\n renderOptions = Object.assign({backgroundColor: renderOptions.background}, renderOptions);\n\n function finish(blob) {\n saveAs(blob, `${options.filename}.${options.type}`);\n if (options.callback) options.callback();\n }\n\n if (options.type === \"svg\") {\n\n toSvg(elem, renderOptions)\n .then(dataUrl => {\n\n const xhr = new XMLHttpRequest();\n xhr.open(\"GET\", dataUrl);\n xhr.responseType = \"blob\";\n xhr.onload = () => finish(xhr.response);\n xhr.send();\n\n });\n\n }\n else {\n\n toBlob(elem, renderOptions)\n .then(finish);\n\n }\n\n}\n"],"names":["defaultOptions","filename","type","elem","options","renderOptions","Object","assign","backgroundColor","background","finish","blob","saveAs","callback","toSvg","then","dataUrl","xhr","XMLHttpRequest","open","responseType","onload","response","send","toBlob"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAGA,MAAMA,cAAiB,GAAA;MACrBC,QAAU,EAAA,UAAA;MACVC,IAAM,EAAA;EACR,CAAA;EAEA;;;;;;;;;EASA,GACe,oBAASC,CAAAA,IAAI,EAAEC,OAAAA,GAAU,EAAE,EAAEC,aAAgB,GAAA,EAAE,EAAA;EAE5D,IAAA,IAAI,CAACF,IAAM,EAAA;EACXC,IAAAA,OAAAA,GAAUE,MAAOC,CAAAA,MAAM,CAAC,IAAIP,cAAgBI,EAAAA,OAAAA,CAAAA;;MAG5CC,aAAgBC,GAAAA,MAAAA,CAAOC,MAAM,CAAC;EAACC,QAAAA,eAAAA,EAAiBH,cAAcI;OAAaJ,EAAAA,aAAAA,CAAAA;EAE3E,IAAA,SAASK,OAAOC,IAAI,EAAA;UAClBC,gBAAOD,CAAAA,IAAAA,EAAM,GAAGP,OAAQH,CAAAA,QAAQ,CAAC,CAAC,EAAEG,OAAQF,CAAAA,IAAI,CAAE,CAAA,CAAA;EAClD,QAAA,IAAIE,OAAQS,CAAAA,QAAQ,EAAET,OAAAA,CAAQS,QAAQ,EAAA;EACxC;MAEA,IAAIT,OAAAA,CAAQF,IAAI,KAAK,KAAO,EAAA;EAE1BY,QAAAA,iBAAAA,CAAMX,IAAME,EAAAA,aAAAA,CAAAA,CACTU,IAAI,CAACC,CAAAA,OAAAA,GAAAA;EAEJ,YAAA,MAAMC,MAAM,IAAIC,cAAAA,EAAAA;cAChBD,GAAIE,CAAAA,IAAI,CAAC,KAAOH,EAAAA,OAAAA,CAAAA;EAChBC,YAAAA,GAAAA,CAAIG,YAAY,GAAG,MAAA;EACnBH,YAAAA,GAAAA,CAAII,MAAM,GAAG,IAAMX,MAAAA,CAAOO,IAAIK,QAAQ,CAAA;EACtCL,YAAAA,GAAAA,CAAIM,IAAI,EAAA;EAEV,SAAA,CAAA;OAGC,MAAA;UAEHC,kBAAOrB,CAAAA,IAAAA,EAAME,aACVU,CAAAA,CAAAA,IAAI,CAACL,MAAAA,CAAAA;EAEV;EAEF;;;;;;;;"}
1
+ {"version":3,"file":"d3plus-export.js","sources":["../src/saveElement.ts"],"sourcesContent":["import {toBlob, toSvg} from \"html-to-image\";\nimport {saveAs} from \"file-saver\";\n\nexport interface SaveElementOptions {\n /** Filename for the downloaded file, without the extension. */\n filename?: string;\n /** File type of the saved document. Accepted values are \"png\", \"jpg\", and \"svg\". */\n type?: \"png\" | \"jpg\" | \"svg\";\n /** Function to be invoked after saving is complete. */\n callback?: () => void;\n}\n\nexport interface SaveElementRenderOptions {\n /** Background color for the rendered image. */\n background?: string;\n /** Background color for the rendered image (alias). */\n backgroundColor?: string;\n [key: string]: unknown;\n}\n\nconst defaultOptions: Required<Pick<SaveElementOptions, \"filename\" | \"type\">> =\n {\n filename: \"download\",\n type: \"png\",\n };\n\n/**\n Downloads an HTML Element as a bitmap PNG image.\n @param elem The DOM element or d3 selection to export.\n @param options Additional options to specify.\n @param options .filename = \"download\"] Filename for the downloaded file, without the extension.\n @param options .type = \"png\"] File type of the saved document. Accepted values are `\"png\"` and `\"jpg\"`.\n @param options .callback] Function to be invoked after saving is complete.\n @param renderOptions Custom options to be passed to the html-to-image function.\n*/\nexport default function (\n elem: HTMLElement,\n options: SaveElementOptions = {},\n renderOptions: SaveElementRenderOptions = {},\n): void {\n if (!elem) return;\n const opts = Object.assign({}, defaultOptions, options);\n\n // rename renderOptions.background to backgroundColor for backwards compatibility\n const renderOpts = Object.assign(\n {backgroundColor: renderOptions.background},\n renderOptions,\n );\n\n function finish(blob: Blob): void {\n saveAs(blob, `${opts.filename}.${opts.type}`);\n if (opts.callback) opts.callback();\n }\n\n if (opts.type === \"svg\") {\n toSvg(elem, renderOpts).then((dataUrl: string) => {\n const xhr = new XMLHttpRequest();\n xhr.open(\"GET\", dataUrl);\n xhr.responseType = \"blob\";\n xhr.onload = () => finish(xhr.response as Blob);\n xhr.send();\n });\n } else {\n toBlob(elem, renderOpts).then((blob: Blob | null) => {\n if (blob) finish(blob);\n });\n }\n}\n"],"names":["defaultOptions","filename","type","elem","options","renderOptions","opts","Object","assign","renderOpts","backgroundColor","background","finish","blob","saveAs","callback","toSvg","then","dataUrl","xhr","XMLHttpRequest","open","responseType","onload","response","send","toBlob"],"mappings":";;;;;;;;;;;;EAoBA,MAAMA,cAAAA,GACJ;MACEC,QAAAA,EAAU,UAAA;MACVC,IAAAA,EAAM;EACR,CAAA;EAEF;;;;;;;;EAQA,GACe,oBAAA,CACbC,IAAiB,EACjBC,OAAAA,GAA8B,EAAE,EAChCC,aAAAA,GAA0C,EAAE,EAAA;EAE5C,IAAA,IAAI,CAACF,IAAAA,EAAM;EACX,IAAA,MAAMG,OAAOC,MAAAA,CAAOC,MAAM,CAAC,IAAIR,cAAAA,EAAgBI,OAAAA,CAAAA;;MAG/C,MAAMK,UAAAA,GAAaF,MAAAA,CAAOC,MAAM,CAC9B;EAACE,QAAAA,eAAAA,EAAiBL,cAAcM;OAAU,EAC1CN,aAAAA,CAAAA;EAGF,IAAA,SAASO,OAAOC,IAAU,EAAA;UACxBC,gBAAAA,CAAOD,IAAAA,EAAM,GAAGP,IAAAA,CAAKL,QAAQ,CAAC,CAAC,EAAEK,IAAAA,CAAKJ,IAAI,CAAA,CAAE,CAAA;EAC5C,QAAA,IAAII,IAAAA,CAAKS,QAAQ,EAAET,IAAAA,CAAKS,QAAQ,EAAA;EAClC,IAAA;MAEA,IAAIT,IAAAA,CAAKJ,IAAI,KAAK,KAAA,EAAO;EACvBc,QAAAA,iBAAAA,CAAMb,IAAAA,EAAMM,UAAAA,CAAAA,CAAYQ,IAAI,CAAC,CAACC,OAAAA,GAAAA;EAC5B,YAAA,MAAMC,MAAM,IAAIC,cAAAA,EAAAA;cAChBD,GAAAA,CAAIE,IAAI,CAAC,KAAA,EAAOH,OAAAA,CAAAA;EAChBC,YAAAA,GAAAA,CAAIG,YAAY,GAAG,MAAA;EACnBH,YAAAA,GAAAA,CAAII,MAAM,GAAG,IAAMX,MAAAA,CAAOO,IAAIK,QAAQ,CAAA;EACtCL,YAAAA,GAAAA,CAAIM,IAAI,EAAA;EACV,QAAA,CAAA,CAAA;MACF,CAAA,MAAO;EACLC,QAAAA,kBAAAA,CAAOvB,IAAAA,EAAMM,UAAAA,CAAAA,CAAYQ,IAAI,CAAC,CAACJ,IAAAA,GAAAA;EAC7B,YAAA,IAAIA,MAAMD,MAAAA,CAAOC,IAAAA,CAAAA;EACnB,QAAA,CAAA,CAAA;EACF,IAAA;EACF;;;;;;;;"}
@@ -4,17 +4,16 @@
4
4
  Copyright (c) 2026 D3plus - https://d3plus.org
5
5
  @license MIT
6
6
  */
7
- (e=>{"function"==typeof define&&define.amd?define(e):e()})(function(){if("undefined"!=typeof window){try{if("undefined"==typeof SVGElement||Boolean(SVGElement.prototype.innerHTML))return}catch(e){return}function o(e){switch(e.nodeType){case 1:var t=e,n="";return n+="<"+t.tagName,t.hasAttributes()&&[].forEach.call(t.attributes,function(e){n+=" "+e.name+'="'+e.value+'"'}),n+=">",t.hasChildNodes()&&[].forEach.call(t.childNodes,function(e){n+=o(e)}),n+="</"+t.tagName+">";case 3:return e.textContent.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");case 8:return"\x3c!--"+e.nodeValue+"--\x3e"}}Object.defineProperty(SVGElement.prototype,"innerHTML",{get:function(){var t="";return[].forEach.call(this.childNodes,function(e){t+=o(e)}),t},set:function(e){for(;this.firstChild;)this.removeChild(this.firstChild);try{var t=new DOMParser,n=(t.async=!1,"<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>"+e+"</svg>"),o=t.parseFromString(n,"text/xml").documentElement;[].forEach.call(o.childNodes,function(e){this.appendChild(this.ownerDocument.importNode(e,!0))}.bind(this))}catch(e){throw new Error("Error parsing markup string")}}}),Object.defineProperty(SVGElement.prototype,"innerSVG",{get:function(){return this.innerHTML},set:function(e){this.innerHTML=e}})}}),((e,t)=>{"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("html-to-image"),require("file-saver")):"function"==typeof define&&define.amd?define("@d3plus/export",["exports","html-to-image","file-saver"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).d3plus={},e.htmlToImage,e.fileSaver)})(this,function(e,r,i){let a={filename:"download",type:"png"};
7
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("html-to-image"),require("file-saver")):"function"==typeof define&&define.amd?define("@d3plus/export",["exports","html-to-image","file-saver"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).d3plus={},e.htmlToImage,e.fileSaver)}(this,function(e,t,n){"use strict";const o={filename:"download",type:"png"};
8
8
  /**
9
- @function saveElement
10
- @desc Downloads an HTML Element as a bitmap PNG image.
11
- @param {HTMLElement} elem A single element to be saved to one file.
12
- @param {Object} [options] Additional options to specify.
13
- @param {String} [options.filename = "download"] Filename for the downloaded file, without the extension.
14
- @param {String} [options.type = "png"] File type of the saved document. Accepted values are `"png"` and `"jpg"`.
15
- @param {Function} [options.callback] Function to be invoked after saving is complete.
16
- @param {Object} [renderOptions] Custom options to be passed to the html-to-image function.
17
- */e.saveElement=function(e,t={},n={}){function o(e){i.saveAs(e,t.filename+"."+t.type),t.callback&&t.callback()}e&&(t=Object.assign({},a,t),
9
+ Downloads an HTML Element as a bitmap PNG image.
10
+ @param elem The DOM element or d3 selection to export.
11
+ @param options Additional options to specify.
12
+ @param options .filename = "download"] Filename for the downloaded file, without the extension.
13
+ @param options .type = "png"] File type of the saved document. Accepted values are `"png"` and `"jpg"`.
14
+ @param options .callback] Function to be invoked after saving is complete.
15
+ @param renderOptions Custom options to be passed to the html-to-image function.
16
+ */e.saveElement=function(e,s={},i={}){if(!e)return;const l=Object.assign({},o,s),a=Object.assign({backgroundColor:i.background},i);
18
17
  // rename renderOptions.background to backgroundColor for backwards compatibility
19
- n=Object.assign({backgroundColor:n.background},n),"svg"===t.type?r.toSvg(e,n).then(e=>{let t=new XMLHttpRequest;t.open("GET",e),t.responseType="blob",t.onload=()=>o(t.response),t.send()}):r.toBlob(e,n).then(o))}});
18
+ function f(e){n.saveAs(e,`${l.filename}.${l.type}`),l.callback&&l.callback()}"svg"===l.type?t.toSvg(e,a).then(e=>{const t=new XMLHttpRequest;t.open("GET",e),t.responseType="blob",t.onload=()=>f(t.response),t.send()}):t.toBlob(e,a).then(e=>{e&&f(e)})}});
20
19
  //# sourceMappingURL=d3plus-export.js.map