@opendata-ai/openchart-vanilla 8.4.0 → 8.5.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.
Files changed (37) hide show
  1. package/README.md +59 -0
  2. package/dist/chunk-2OJZBMXM.js +377 -0
  3. package/dist/chunk-2OJZBMXM.js.map +1 -0
  4. package/dist/{chunk-45XZOWYC.js → chunk-5KV3ZBBL.js} +58 -437
  5. package/dist/chunk-5KV3ZBBL.js.map +1 -0
  6. package/dist/{chunk-HGRNXLDF.js → chunk-5RX6ZQGZ.js} +10 -1
  7. package/dist/chunk-5RX6ZQGZ.js.map +1 -0
  8. package/dist/{chunk-UOB422LY.js → chunk-6B5OBGIO.js} +2 -2
  9. package/dist/chunk-NG7CVCI2.js +58 -0
  10. package/dist/chunk-NG7CVCI2.js.map +1 -0
  11. package/dist/{chunk-FETYAVTZ.js → chunk-RYVV3YIG.js} +3 -3
  12. package/dist/{chunk-LNPRDSK3.js → chunk-UAK6HWOC.js} +2 -2
  13. package/dist/chunk-WOLX5EZT.js +3577 -0
  14. package/dist/chunk-WOLX5EZT.js.map +1 -0
  15. package/dist/{chunk-YGYMB7KB.js → chunk-XGII4ZRT.js} +55 -30
  16. package/dist/chunk-XGII4ZRT.js.map +1 -0
  17. package/dist/export-gif.js +3 -3
  18. package/dist/graph-3d/index.d.ts +272 -0
  19. package/dist/graph-3d/index.js +1556 -0
  20. package/dist/graph-3d/index.js.map +1 -0
  21. package/dist/index.d.ts +4 -252
  22. package/dist/index.js +27 -3471
  23. package/dist/index.js.map +1 -1
  24. package/dist/renderer-registry-B5tW6yAZ.d.ts +376 -0
  25. package/dist/static.js +4 -3
  26. package/dist/static.js.map +1 -1
  27. package/dist/story/index.js +10 -7
  28. package/dist/story/index.js.map +1 -1
  29. package/dist/styles.css +1 -1
  30. package/dist/styles.css.map +1 -1
  31. package/package.json +26 -5
  32. package/dist/chunk-45XZOWYC.js.map +0 -1
  33. package/dist/chunk-HGRNXLDF.js.map +0 -1
  34. package/dist/chunk-YGYMB7KB.js.map +0 -1
  35. /package/dist/{chunk-UOB422LY.js.map → chunk-6B5OBGIO.js.map} +0 -0
  36. /package/dist/{chunk-FETYAVTZ.js.map → chunk-RYVV3YIG.js.map} +0 -0
  37. /package/dist/{chunk-LNPRDSK3.js.map → chunk-UAK6HWOC.js.map} +0 -0
@@ -9,6 +9,14 @@ function setAttrs(el, attrs) {
9
9
  el.setAttribute(key, String(value));
10
10
  }
11
11
  }
12
+ function applyKnockoutHalo(el, color, fontSize) {
13
+ setAttrs(el, {
14
+ stroke: color,
15
+ "stroke-width": Math.round(fontSize * 0.3),
16
+ "stroke-linejoin": "round",
17
+ "paint-order": "stroke"
18
+ });
19
+ }
12
20
  function applyTextStyle(el, style) {
13
21
  const inline = el.style;
14
22
  inline.setProperty("fill", style.fill);
@@ -111,8 +119,9 @@ export {
111
119
  XLINK_NS,
112
120
  createSVGElement,
113
121
  setAttrs,
122
+ applyKnockoutHalo,
114
123
  applyTextStyle,
115
124
  buildThemeStyleBlock,
116
125
  injectThemeStyleBlock
117
126
  };
118
- //# sourceMappingURL=chunk-HGRNXLDF.js.map
127
+ //# sourceMappingURL=chunk-5RX6ZQGZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/renderers/svg-dom.ts","../src/theme-style-block.ts"],"sourcesContent":["/**\n * Shared SVG DOM helpers used across the per-concern renderers.\n *\n * Pure, stateless utilities. No layout/theme knowledge.\n */\n\nimport type { TextStyle } from '@opendata-ai/openchart-core';\n\nexport const SVG_NS = 'http://www.w3.org/2000/svg';\nexport const XLINK_NS = 'http://www.w3.org/1999/xlink';\n\nexport function createSVGElement(tag: string): SVGElement {\n return document.createElementNS(SVG_NS, tag);\n}\n\nexport function setAttrs(el: SVGElement, attrs: Record<string, string | number>): void {\n for (const [key, value] of Object.entries(attrs)) {\n el.setAttribute(key, String(value));\n }\n}\n\n/**\n * Cut a knockout halo behind text so it stays legible where it crosses\n * gridlines, marks, or a neighbouring series: a surface-colored stroke painted\n * under the glyphs.\n *\n * Presentation attributes, not inline styles, so a stylesheet can still\n * override the halo. The width scales with the font size -- a fixed width rings\n * small glyphs and disappears behind large ones.\n */\nexport function applyKnockoutHalo(el: SVGElement, color: string, fontSize: number): void {\n setAttrs(el, {\n stroke: color,\n 'stroke-width': Math.round(fontSize * 0.3),\n 'stroke-linejoin': 'round',\n 'paint-order': 'stroke',\n });\n}\n\nexport function applyTextStyle(el: SVGElement, style: TextStyle): void {\n // Use inline styles so engine-computed values take priority over CSS class\n // defaults (e.g. .oc-title { font-size: var(--oc-title-size) } would otherwise\n // override the responsive scaling applied by the chrome layout).\n const inline = (el as SVGElement & ElementCSSInlineStyle).style;\n inline.setProperty('fill', style.fill);\n inline.setProperty('font-size', `${style.fontSize}px`);\n inline.setProperty('font-weight', String(style.fontWeight));\n inline.setProperty('font-family', style.fontFamily);\n if (style.textAnchor) {\n el.setAttribute('text-anchor', style.textAnchor);\n }\n if (style.dominantBaseline) {\n el.setAttribute('dominant-baseline', style.dominantBaseline);\n }\n if (style.fontVariant) {\n el.setAttribute('font-variant', style.fontVariant);\n }\n}\n","/**\n * Theme `<style>` block for self-contained SVG export.\n *\n * Charts render most fills as inline SVG attributes, but a handful of chrome\n * elements (metric cells, the brand watermark dot, legend text, endpoint labels)\n * take their fill from CSS classes in `chrome.css` via `--oc-*` variables. That\n * works on-screen because the live SVG inherits the page stylesheet — but a\n * serialized/rasterized export (PNG/JPG/GIF) is detached from the page, so those\n * class-based fills vanish. This module builds a `<style>` block that resolves\n * every such rule against a concrete `ResolvedTheme`, so injecting it into an\n * export clone makes the SVG fully self-contained.\n *\n * Both the headless renderer (`static.ts`) and the browser export path use this,\n * so class-based styling round-trips identically no matter which path produced\n * the SVG. Browser-safe (no Node imports) so the browser exporters can import it.\n */\n\nimport type { ResolvedTheme } from '@opendata-ai/openchart-core';\nimport { adaptForLightLineStroke, cssTokenDefault } from '@opendata-ai/openchart-core';\nimport { SVG_NS } from './renderers/svg-dom';\n\n/**\n * Build the theme `<style>` block CSS text for a resolved theme. Sets the\n * `--oc-*` custom properties on `svg.oc-chart` and defines every class-based\n * chrome rule against them.\n */\nexport function buildThemeStyleBlock(theme: ResolvedTheme): string {\n const accent = theme.colors.categorical[0] ?? cssTokenDefault('--oc-accent', 'light');\n const bg = theme.colors.neutral.surface;\n\n const props = [\n `--oc-font-family: ${theme.fonts.family}`,\n `--oc-font-mono: ${theme.fonts.mono}`,\n `--oc-title-size: ${theme.chrome.title.fontSize}px`,\n `--oc-title-weight: ${theme.chrome.title.fontWeight}`,\n `--oc-title-tracking: ${cssTokenDefault('--oc-title-tracking', 'light')}`,\n `--oc-subtitle-size: ${theme.chrome.subtitle.fontSize}px`,\n `--oc-subtitle-weight: ${theme.chrome.subtitle.fontWeight}`,\n `--oc-source-size: ${theme.chrome.source.fontSize}px`,\n `--oc-source-weight: ${theme.chrome.source.fontWeight}`,\n `--oc-body-size: ${theme.fonts.sizes.body}px`,\n `--oc-eyebrow-size: ${theme.chrome.eyebrow.fontSize}px`,\n `--oc-eyebrow-weight: ${theme.chrome.eyebrow.fontWeight}`,\n `--oc-eyebrow-tracking: ${cssTokenDefault('--oc-eyebrow-tracking', 'light')}`,\n `--oc-bg: ${bg}`,\n `--oc-text: ${theme.colors.text}`,\n `--oc-text-muted: ${theme.colors.axis}`,\n `--oc-text-secondary: ${theme.colors.neutral.secondary}`,\n `--oc-text-faint: ${theme.colors.neutral.faint}`,\n `--oc-border: ${theme.colors.neutral.border}`,\n `--oc-gridline: ${theme.colors.gridline}`,\n // Hairline, not the tick-label ink.\n `--oc-axis: ${theme.colors.hairline}`,\n `--oc-border-radius: ${theme.borderRadius}px`,\n `--oc-accent: ${accent}`,\n `--oc-accent-strong: ${adaptForLightLineStroke(accent)}`,\n `--oc-positive: ${theme.colors.positive}`,\n `--oc-negative: ${theme.colors.negative}`,\n `--oc-legend-text: ${theme.isDark ? cssTokenDefault('--oc-legend-text', 'dark') : cssTokenDefault('--oc-legend-text', 'light')}`,\n `--oc-space-2: ${theme.spacing.chromeGap * 2}px`,\n `--oc-space-4: ${theme.spacing.padding}px`,\n ];\n\n const rules = [\n // Tabular figures everywhere in the chart's own text: axis ticks, value\n // labels and legend entries all line up column-wise.\n `svg.oc-chart { ${props.join('; ')}; font-variant-numeric: tabular-nums; }`,\n `.oc-chrome { font-family: var(--oc-font-family); }`,\n `.oc-eyebrow { font-size: var(--oc-eyebrow-size); font-weight: var(--oc-eyebrow-weight); letter-spacing: var(--oc-eyebrow-tracking); text-transform: uppercase; fill: var(--oc-accent); }`,\n `.oc-title { font-size: var(--oc-title-size); font-weight: var(--oc-title-weight); letter-spacing: var(--oc-title-tracking); fill: var(--oc-text); }`,\n `.oc-subtitle { font-size: var(--oc-subtitle-size); font-weight: var(--oc-subtitle-weight); fill: var(--oc-text-muted); }`,\n `.oc-source, .oc-byline, .oc-footer { font-size: var(--oc-source-size); font-weight: var(--oc-source-weight); fill: var(--oc-text-muted); }`,\n `.oc-brand { font-size: 11px; font-weight: 500; letter-spacing: 0.02em; fill: var(--oc-text-faint); }`,\n `.oc-brand-dot { fill: var(--oc-accent); }`,\n `.oc-eyebrow-dot { fill: var(--oc-accent); }`,\n `.oc-metrics { font-family: var(--oc-font-family); }`,\n `.oc-metric-label { font-size: 11px; font-weight: 500; letter-spacing: 0.06em; text-transform: uppercase; fill: var(--oc-text-muted); }`,\n `.oc-metric-value { font-size: 22px; font-weight: 600; letter-spacing: -0.02em; fill: var(--oc-text); font-variant-numeric: tabular-nums; }`,\n `.oc-metric-delta-up { fill: var(--oc-positive); font-size: 12px; font-weight: 500; }`,\n `.oc-metric-delta-down { fill: var(--oc-negative); font-size: 12px; font-weight: 500; }`,\n `.oc-axis-tick-inline { font-size: 11px; font-weight: 400; fill: var(--oc-text-muted); }`,\n `.oc-endpoint-labels { font-family: var(--oc-font-family); }`,\n `.oc-endpoint-label { fill: var(--oc-endpoint-label-color, var(--oc-text)); }`,\n `.oc-endpoint-value { fill: var(--oc-endpoint-value-color, var(--oc-text-muted)); }`,\n `.oc-endpoint-leader { stroke: var(--oc-endpoint-leader-color, currentColor); }`,\n `.oc-annotation-subtitle { fill: var(--oc-annotation-subtitle-color, var(--oc-text-muted)); }`,\n `.oc-metric-secondary { fill: var(--oc-text-muted); font-size: 12px; font-weight: 400; }`,\n `.oc-legend { font-family: var(--oc-font-family); font-size: var(--oc-body-size); }`,\n `.oc-legend-entry { cursor: default; }`,\n `.oc-legend text { fill: var(--oc-legend-text); }`,\n ];\n\n return rules.join('\\n');\n}\n\n/**\n * Inject the theme style block into an SVG clone's `<defs>` so class-based fills\n * survive serialization. Idempotent-ish: adds one `<style data-oc-theme>` at the\n * front of `<defs>`; call once per clone before serializing. No-op if `theme` is\n * undefined (nothing to resolve against).\n */\nexport function injectThemeStyleBlock(svg: SVGElement, theme: ResolvedTheme | undefined): void {\n if (!theme) return;\n let defs = svg.querySelector('defs');\n if (!defs) {\n defs = document.createElementNS(SVG_NS, 'defs');\n svg.insertBefore(defs, svg.firstChild);\n }\n const style = document.createElementNS(SVG_NS, 'style');\n style.setAttribute('data-oc-theme', '');\n style.textContent = buildThemeStyleBlock(theme);\n defs.insertBefore(style, defs.firstChild);\n}\n"],"mappings":"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","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  injectThemeStyleBlock
3
- } from "./chunk-HGRNXLDF.js";
3
+ } from "./chunk-5RX6ZQGZ.js";
4
4
 
5
5
  // src/export.ts
6
6
  function getSVGDimensions(svg) {
@@ -279,4 +279,4 @@ export {
279
279
  exportJPG,
280
280
  exportCSV
281
281
  };
282
- //# sourceMappingURL=chunk-UOB422LY.js.map
282
+ //# sourceMappingURL=chunk-6B5OBGIO.js.map
@@ -0,0 +1,58 @@
1
+ // src/theme-tokens.ts
2
+ import { adaptForLightLineStroke, cssTokenDefault } from "@opendata-ai/openchart-core";
3
+ function resolvedSurface(theme) {
4
+ return theme.colors.neutral.surface;
5
+ }
6
+ function stampThemeProperties(el, theme) {
7
+ const accent = theme.colors.categorical[0] ?? cssTokenDefault("--oc-accent", "light");
8
+ const bg = resolvedSurface(theme);
9
+ const n = theme.colors.neutral;
10
+ const props = [
11
+ ["--oc-font-family", theme.fonts.family],
12
+ ["--oc-font-mono", theme.fonts.mono],
13
+ ["--oc-title-size", `${theme.chrome.title.fontSize}px`],
14
+ ["--oc-title-weight", `${theme.chrome.title.fontWeight}`],
15
+ ["--oc-subtitle-size", `${theme.chrome.subtitle.fontSize}px`],
16
+ ["--oc-subtitle-weight", `${theme.chrome.subtitle.fontWeight}`],
17
+ ["--oc-source-size", `${theme.chrome.source.fontSize}px`],
18
+ ["--oc-source-weight", `${theme.chrome.source.fontWeight}`],
19
+ ["--oc-body-size", `${theme.fonts.sizes.body}px`],
20
+ ["--oc-eyebrow-size", `${theme.chrome.eyebrow.fontSize}px`],
21
+ ["--oc-eyebrow-weight", `${theme.chrome.eyebrow.fontWeight}`],
22
+ ["--oc-bg", bg],
23
+ ["--oc-text", theme.colors.text],
24
+ ["--oc-text-muted", theme.colors.axis],
25
+ // Secondary grays are derived from the theme's own text/background pair
26
+ // (ResolvedTheme.colors.neutral), so a warm or cool theme gets warm or
27
+ // cool grays instead of zinc. One direction only: theme -> CSS.
28
+ ["--oc-text-secondary", n.secondary],
29
+ ["--oc-text-faint", n.faint],
30
+ ["--oc-border", n.border],
31
+ ["--oc-gray-100", n[100]],
32
+ ["--oc-gray-200", n[200]],
33
+ ["--oc-gray-300", n[300]],
34
+ ["--oc-gray-400", n[400]],
35
+ ["--oc-gray-600", n[600]],
36
+ ["--oc-gray-800", n[800]],
37
+ ["--oc-gridline", theme.colors.gridline],
38
+ // --oc-axis is the hairline the axis line is drawn with, not the ink its
39
+ // tick labels take (that is --oc-text-muted, above).
40
+ ["--oc-axis", theme.colors.hairline],
41
+ ["--oc-border-radius", `${theme.borderRadius}px`],
42
+ ["--oc-accent", accent],
43
+ ["--oc-accent-strong", adaptForLightLineStroke(accent)],
44
+ ["--oc-positive", theme.colors.positive],
45
+ ["--oc-negative", theme.colors.negative],
46
+ ["--oc-space-2", `${theme.spacing.chromeGap * 2}px`],
47
+ ["--oc-space-4", `${theme.spacing.padding}px`]
48
+ ];
49
+ for (const [name, value] of props) {
50
+ el.style.setProperty(name, value);
51
+ }
52
+ }
53
+
54
+ export {
55
+ resolvedSurface,
56
+ stampThemeProperties
57
+ };
58
+ //# sourceMappingURL=chunk-NG7CVCI2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/theme-tokens.ts"],"sourcesContent":["/**\n * Generate CSS custom properties from a resolved JS theme.\n *\n * Stamped on the .oc-root container at mount time so CSS consumers\n * read from the same source of truth as the JS engine. The static\n * values in tokens.css / dark.css serve as fallback defaults for\n * contexts where JS hasn't mounted (SSR, static HTML).\n */\n\nimport type { ResolvedTheme } from '@opendata-ai/openchart-core';\nimport { adaptForLightLineStroke, cssTokenDefault } from '@opendata-ai/openchart-core';\n\n/**\n * The opaque surface a theme paints on. A transparent theme background has no\n * color of its own, so it resolves to the static `--oc-bg` token for the mode --\n * the same value the engine's knockout strokes are cut in. Resolved once in\n * core, on `colors.neutral.surface`; this is a named read of it.\n */\nexport function resolvedSurface(theme: ResolvedTheme): string {\n return theme.colors.neutral.surface;\n}\n\nexport function stampThemeProperties(el: HTMLElement, theme: ResolvedTheme): void {\n const accent = theme.colors.categorical[0] ?? cssTokenDefault('--oc-accent', 'light');\n const bg = resolvedSurface(theme);\n\n const n = theme.colors.neutral;\n\n const props: [string, string][] = [\n ['--oc-font-family', theme.fonts.family],\n ['--oc-font-mono', theme.fonts.mono],\n ['--oc-title-size', `${theme.chrome.title.fontSize}px`],\n ['--oc-title-weight', `${theme.chrome.title.fontWeight}`],\n ['--oc-subtitle-size', `${theme.chrome.subtitle.fontSize}px`],\n ['--oc-subtitle-weight', `${theme.chrome.subtitle.fontWeight}`],\n ['--oc-source-size', `${theme.chrome.source.fontSize}px`],\n ['--oc-source-weight', `${theme.chrome.source.fontWeight}`],\n ['--oc-body-size', `${theme.fonts.sizes.body}px`],\n ['--oc-eyebrow-size', `${theme.chrome.eyebrow.fontSize}px`],\n ['--oc-eyebrow-weight', `${theme.chrome.eyebrow.fontWeight}`],\n ['--oc-bg', bg],\n ['--oc-text', theme.colors.text],\n ['--oc-text-muted', theme.colors.axis],\n // Secondary grays are derived from the theme's own text/background pair\n // (ResolvedTheme.colors.neutral), so a warm or cool theme gets warm or\n // cool grays instead of zinc. One direction only: theme -> CSS.\n ['--oc-text-secondary', n.secondary],\n ['--oc-text-faint', n.faint],\n ['--oc-border', n.border],\n ['--oc-gray-100', n[100]],\n ['--oc-gray-200', n[200]],\n ['--oc-gray-300', n[300]],\n ['--oc-gray-400', n[400]],\n ['--oc-gray-600', n[600]],\n ['--oc-gray-800', n[800]],\n ['--oc-gridline', theme.colors.gridline],\n // --oc-axis is the hairline the axis line is drawn with, not the ink its\n // tick labels take (that is --oc-text-muted, above).\n ['--oc-axis', theme.colors.hairline],\n ['--oc-border-radius', `${theme.borderRadius}px`],\n ['--oc-accent', accent],\n ['--oc-accent-strong', adaptForLightLineStroke(accent)],\n ['--oc-positive', theme.colors.positive],\n ['--oc-negative', theme.colors.negative],\n ['--oc-space-2', `${theme.spacing.chromeGap * 2}px`],\n ['--oc-space-4', `${theme.spacing.padding}px`],\n ];\n\n for (const [name, value] of props) {\n el.style.setProperty(name, value);\n }\n}\n"],"mappings":";AAUA,SAAS,yBAAyB,uBAAuB;AAQlD,SAAS,gBAAgB,OAA8B;AAC5D,SAAO,MAAM,OAAO,QAAQ;AAC9B;AAEO,SAAS,qBAAqB,IAAiB,OAA4B;AAChF,QAAM,SAAS,MAAM,OAAO,YAAY,CAAC,KAAK,gBAAgB,eAAe,OAAO;AACpF,QAAM,KAAK,gBAAgB,KAAK;AAEhC,QAAM,IAAI,MAAM,OAAO;AAEvB,QAAM,QAA4B;AAAA,IAChC,CAAC,oBAAoB,MAAM,MAAM,MAAM;AAAA,IACvC,CAAC,kBAAkB,MAAM,MAAM,IAAI;AAAA,IACnC,CAAC,mBAAmB,GAAG,MAAM,OAAO,MAAM,QAAQ,IAAI;AAAA,IACtD,CAAC,qBAAqB,GAAG,MAAM,OAAO,MAAM,UAAU,EAAE;AAAA,IACxD,CAAC,sBAAsB,GAAG,MAAM,OAAO,SAAS,QAAQ,IAAI;AAAA,IAC5D,CAAC,wBAAwB,GAAG,MAAM,OAAO,SAAS,UAAU,EAAE;AAAA,IAC9D,CAAC,oBAAoB,GAAG,MAAM,OAAO,OAAO,QAAQ,IAAI;AAAA,IACxD,CAAC,sBAAsB,GAAG,MAAM,OAAO,OAAO,UAAU,EAAE;AAAA,IAC1D,CAAC,kBAAkB,GAAG,MAAM,MAAM,MAAM,IAAI,IAAI;AAAA,IAChD,CAAC,qBAAqB,GAAG,MAAM,OAAO,QAAQ,QAAQ,IAAI;AAAA,IAC1D,CAAC,uBAAuB,GAAG,MAAM,OAAO,QAAQ,UAAU,EAAE;AAAA,IAC5D,CAAC,WAAW,EAAE;AAAA,IACd,CAAC,aAAa,MAAM,OAAO,IAAI;AAAA,IAC/B,CAAC,mBAAmB,MAAM,OAAO,IAAI;AAAA;AAAA;AAAA;AAAA,IAIrC,CAAC,uBAAuB,EAAE,SAAS;AAAA,IACnC,CAAC,mBAAmB,EAAE,KAAK;AAAA,IAC3B,CAAC,eAAe,EAAE,MAAM;AAAA,IACxB,CAAC,iBAAiB,EAAE,GAAG,CAAC;AAAA,IACxB,CAAC,iBAAiB,EAAE,GAAG,CAAC;AAAA,IACxB,CAAC,iBAAiB,EAAE,GAAG,CAAC;AAAA,IACxB,CAAC,iBAAiB,EAAE,GAAG,CAAC;AAAA,IACxB,CAAC,iBAAiB,EAAE,GAAG,CAAC;AAAA,IACxB,CAAC,iBAAiB,EAAE,GAAG,CAAC;AAAA,IACxB,CAAC,iBAAiB,MAAM,OAAO,QAAQ;AAAA;AAAA;AAAA,IAGvC,CAAC,aAAa,MAAM,OAAO,QAAQ;AAAA,IACnC,CAAC,sBAAsB,GAAG,MAAM,YAAY,IAAI;AAAA,IAChD,CAAC,eAAe,MAAM;AAAA,IACtB,CAAC,sBAAsB,wBAAwB,MAAM,CAAC;AAAA,IACtD,CAAC,iBAAiB,MAAM,OAAO,QAAQ;AAAA,IACvC,CAAC,iBAAiB,MAAM,OAAO,QAAQ;AAAA,IACvC,CAAC,gBAAgB,GAAG,MAAM,QAAQ,YAAY,CAAC,IAAI;AAAA,IACnD,CAAC,gBAAgB,GAAG,MAAM,QAAQ,OAAO,IAAI;AAAA,EAC/C;AAEA,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO;AACjC,OAAG,MAAM,YAAY,MAAM,KAAK;AAAA,EAClC;AACF;","names":[]}
@@ -5,10 +5,10 @@ import {
5
5
  getSVGBackgroundColor,
6
6
  getSVGDimensions,
7
7
  rasterizeSVGToCanvas
8
- } from "./chunk-UOB422LY.js";
8
+ } from "./chunk-6B5OBGIO.js";
9
9
  import {
10
10
  injectThemeStyleBlock
11
- } from "./chunk-HGRNXLDF.js";
11
+ } from "./chunk-5RX6ZQGZ.js";
12
12
 
13
13
  // src/gif-encode.ts
14
14
  function readCanvasSRGB(canvas) {
@@ -231,4 +231,4 @@ export {
231
231
  applyFrameState,
232
232
  exportGIF
233
233
  };
234
- //# sourceMappingURL=chunk-FETYAVTZ.js.map
234
+ //# sourceMappingURL=chunk-RYVV3YIG.js.map
@@ -3,7 +3,7 @@ import {
3
3
  renderChromeElement,
4
4
  renderLegend,
5
5
  stampAnimationVars
6
- } from "./chunk-YGYMB7KB.js";
6
+ } from "./chunk-XGII4ZRT.js";
7
7
 
8
8
  // src/tilemap-renderer.ts
9
9
  var SVG_NS = "http://www.w3.org/2000/svg";
@@ -327,4 +327,4 @@ function renderTileMapSVG(layout, opts) {
327
327
  export {
328
328
  renderTileMapSVG
329
329
  };
330
- //# sourceMappingURL=chunk-LNPRDSK3.js.map
330
+ //# sourceMappingURL=chunk-UAK6HWOC.js.map